mirror of
https://github.com/Dasharo/heads.git
synced 2026-06-13 10:16:29 -07:00
NK3: use device-specific branding and PIN labels consistently across codebase
The NK3 uses 'Secrets app' terminology and has 8 PIN retry attempts (vs 3 for older devices), but the codebase had inconsistent UX messaging that referred to 'GPG Admin PIN', 'USB security dongle', 'TOKEN', etc. instead of the actual brand and PIN type. Fix 1: PIN label - $prompt_message is used in all user-facing strings (status, prompts, error messages, reminder note) with correct value: 'Secrets app' for NK3, 'GPG Admin' for older devices. Fix 2: Dynamic attempt counting - after the default PIN trial consumes an attempt, re-read the counter and limit user attempts to min(retries-1, 3). If the counter read is unreliable (0 or 1), fall back to 3 attempts so the user is never blocked from sealing. Documented with example outcomes for NK3 (8 retries) and pre-NK3 (3 retries). Fix 3: NK3-specific error message now references 'Secrets app PIN' instead of 'GPG Admin PIN' in the PIN reset instructions. Fix 4: Use $DONGLE_BRAND consistently in all USB security dongle messaging (STATUS, prompts, dialog titles, guidance strings, integrity report, DEBUG logs, error messages, NOTES) instead of hardcoded 'USB security dongle', 'OpenPGP signing card', 'GPG security dongle', 'dongle', 'signing card', 'Dongle key'. Also replaces 'TOKEN' in hotp_state/hotp_display with $DONGLE_BRAND so integrity report shows actual brand (e.g. 'Nitrokey 3 PRESENT' instead of 'TOKEN PRESENT'). Fix 5: Centralize branding detection in standalone script entry points: - gui-init.sh: already detects at boot flow entry (line ~965) - oem-factory-reset.sh: added detection at script start (was missing) - confirm_gpg_card: detects for gpg-gui.sh and kexec-sign-config.sh - report_integrity_measurements: detects for hotp/gpg flow - seal-hotpkey.sh: has its own detection at script start Fix 6: detect_usb_security_dongle_branding now guards against redundant re-detection while preserving USB init safety: it skips USB re-init and lsusb re-scan only when a specific DONGLE_BRAND is already set and _USB_ENABLED=y in the current process. In child scripts that inherit DONGLE_BRAND but reset _USB_ENABLED, it still runs enable_usb, then returns without re-scan if branding is already specific. Fix 7: Comment casing fix in oem-factory-reset.sh (Secrets App -> Secrets app) to match user-facing strings and hotp_verification output. Fix 8: Remove duplicate show_pin_retries call before PIN entry loop in seal-hotpkey.sh. The function was being called twice before the first prompt (once before the loop, once at loop start), showing 'Nitrokey 3 Secrets app PIN retries remaining: 8' twice. Fix 9: Clarify and enforce fast-path behavior for detect_usb_security_dongle_branding in mixed parent/child script contexts: avoid redundant module loads and scans in the same process, but do not skip USB initialization when only branding is inherited. Fix 10: detect_usb_security_dongle_branding now reuses wait_for_usb_devices after enable_usb only when USB was not already initialized in the current process. This avoids early lsusb enumeration races without regressing the no-redundant-load/no-re-scan fast path. Signed-off-by: Thierry Laurion <insurgo@riseup.net>
This commit is contained in:
@@ -249,17 +249,17 @@ gate_reseal_with_integrity_report() {
|
||||
# starting the NK3 CCID teardown. This safety call covers the
|
||||
# case where scdaemon was restarted between then and now.
|
||||
release_scdaemon
|
||||
STATUS "Checking USB security dongle presence before sealing"
|
||||
STATUS "Checking $DONGLE_BRAND presence before sealing"
|
||||
DEBUG "gate_reseal_with_integrity_report: checking HOTP token presence"
|
||||
if hotp_verification info >/dev/null 2>&1; then
|
||||
token_ok="y"
|
||||
STATUS_OK "USB security dongle present and accessible"
|
||||
STATUS_OK "$DONGLE_BRAND present and accessible"
|
||||
break
|
||||
fi
|
||||
DEBUG "gate_reseal_with_integrity_report: HOTP token not accessible"
|
||||
if ! whiptail_warning --title "USB Security Dongle Required" \
|
||||
if ! whiptail_warning --title "$DONGLE_BRAND Required" \
|
||||
--yes-button "Retry" --no-button "Abort" \
|
||||
--yesno "Your USB security dongle must be present before sealing new secrets.\n\nInsert the dongle and choose Retry, or Abort." 0 80; then
|
||||
--yesno "Your $DONGLE_BRAND must be present before sealing new secrets.\n\nInsert the dongle and choose Retry, or Abort." 0 80; then
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
@@ -292,7 +292,7 @@ generate_totp_hotp() {
|
||||
if [ -x /bin/hotp_verification ]; then
|
||||
# If we have a TPM and a HOTP USB Security dongle
|
||||
if [ "$CONFIG_TOTP_SKIP_QRCODE" != y ]; then
|
||||
INPUT "Once you have scanned the QR code, press Enter to configure your HOTP USB Security dongle (e.g. Librem Key or Nitrokey)"
|
||||
INPUT "Once you have scanned the QR code, press Enter to configure your $DONGLE_BRAND"
|
||||
fi
|
||||
TRACE_FUNC
|
||||
/bin/seal-hotpkey.sh || DIE "Failed to generate HOTP secret"
|
||||
@@ -314,11 +314,11 @@ prompt_missing_gpg_key_action() {
|
||||
TRACE_FUNC
|
||||
local retry_label retry_msg
|
||||
if [ "$CONFIG_HAVE_GPG_KEY_BACKUP" = "y" ]; then
|
||||
retry_label=' Retry (insert signing card or backup USB drive)'
|
||||
retry_msg="Cannot sign /boot because no private GPG signing key is available (card not inserted, wiped, or key not set up).\n\nInsert your signing card or backup USB drive and retry.\n\nHow would you like to proceed?"
|
||||
retry_label=" Retry (insert $DONGLE_BRAND or backup USB drive)"
|
||||
retry_msg="Cannot sign /boot because no private GPG signing key is available ($DONGLE_BRAND not inserted, wiped, or key not set up).\n\nInsert your $DONGLE_BRAND or backup USB drive and retry.\n\nHow would you like to proceed?"
|
||||
else
|
||||
retry_label=' Retry (after connecting the correct signing card)'
|
||||
retry_msg="Cannot sign /boot because no private GPG signing key is available (card not inserted, wiped, or key not set up).\n\nIf you have the correct signing card, insert it and retry.\n\nHow would you like to proceed?"
|
||||
retry_label=" Retry (after connecting $DONGLE_BRAND)"
|
||||
retry_msg="Cannot sign /boot because no private GPG signing key is available ($DONGLE_BRAND not inserted, wiped, or key not set up).\n\nInsert your $DONGLE_BRAND and retry.\n\nHow would you like to proceed?"
|
||||
fi
|
||||
whiptail_error --title "ERROR: GPG signing key unavailable" \
|
||||
--menu "$retry_msg" 0 80 4 \
|
||||
|
||||
@@ -23,6 +23,10 @@ rm -f /tmp/hotpkey_fw_shown
|
||||
|
||||
TRACE_FUNC
|
||||
|
||||
# Enable USB and detect branding early — $DONGLE_BRAND is used throughout this script.
|
||||
enable_usb
|
||||
detect_usb_security_dongle_branding
|
||||
|
||||
# use TERM to exit on error
|
||||
trap "exit 1" TERM
|
||||
export TOP_PID=$$
|
||||
@@ -180,7 +184,7 @@ reset_nk3_secret_app() {
|
||||
else
|
||||
error_code=$?
|
||||
if [ $error_code -eq 3 ] && [ $attempt -lt 3 ]; then
|
||||
whiptail_warning --msgbox "Nitrokey 3 requires physical presence: touch the dongle when requested" $HEIGHT $WIDTH --title "Nk3 secrets app reset attempt: $attempt/3"
|
||||
whiptail_warning --msgbox "$DONGLE_BRAND requires physical presence: touch the dongle when requested" $HEIGHT $WIDTH --title "$DONGLE_BRAND secrets app reset attempt: $attempt/3"
|
||||
else
|
||||
whiptail_error_die "Nitrokey 3's Secrets app reset failed with error:$error_code. Contact Nitrokey support"
|
||||
fi
|
||||
@@ -1043,7 +1047,7 @@ usb_security_token_capabilities_check() {
|
||||
DONGLE_FW_VERSION="$(echo "$hotp_token_info" | grep "Firmware:" | sed 's/.*: *//')"
|
||||
case "$DONGLE_FW_VERSION" in v*) ;; *) DONGLE_FW_VERSION="v$DONGLE_FW_VERSION" ;; esac
|
||||
fi
|
||||
DEBUG "Dongle firmware version: $DONGLE_FW_VERSION"
|
||||
DEBUG "$DONGLE_BRAND firmware version: $DONGLE_FW_VERSION"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
@@ -1222,7 +1226,7 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then
|
||||
INPUT "Enter desired NK3 Secrets app PIN / GPG Admin PIN (6-${MAX_HOTP_GPG_PIN_LENGTH} chars):" -r ADMIN_PIN
|
||||
done
|
||||
else
|
||||
NOTE "GPG Admin PIN: management tasks on USB Security dongle, seal measurements under HOTP. 3 attempts max, locks Admin out. DO NOT FORGET. Recommended: 2 words"
|
||||
NOTE "GPG Admin PIN: management tasks on $DONGLE_BRAND, seal measurements under HOTP. 3 attempts max, locks Admin out. DO NOT FORGET. Recommended: 2 words"
|
||||
while [[ ${#ADMIN_PIN} -lt 6 ]] || [[ ${#ADMIN_PIN} -gt $MAX_HOTP_GPG_PIN_LENGTH ]]; do
|
||||
INPUT "Enter desired GPG Admin PIN (6-${MAX_HOTP_GPG_PIN_LENGTH} chars):" -r ADMIN_PIN
|
||||
done
|
||||
@@ -1320,10 +1324,10 @@ fi
|
||||
if [ "$GPG_GEN_KEY_IN_MEMORY" = "n" -o "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "y" ]; then
|
||||
enable_usb
|
||||
if ! gpg --card-status >/dev/null 2>&1; then
|
||||
local_whiptail_error "Can't access USB Security dongle; \nPlease remove and reinsert, then press Enter."
|
||||
local_whiptail_error "Can't access $DONGLE_BRAND; \nPlease remove and reinsert, then press Enter."
|
||||
if ! gpg --card-status >/dev/null 2>/tmp/error; then
|
||||
ERROR=$(tail -n 1 /tmp/error | fold -s)
|
||||
whiptail_error_die "Unable to detect USB Security dongle:\n\n${ERROR}"
|
||||
whiptail_error_die "Unable to detect $DONGLE_BRAND:\n\n${ERROR}"
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -1605,7 +1609,7 @@ if [ "$CONFIG_TPM" = "y" ]; then
|
||||
passphrases+="TPM Owner Passphrase: ${TPM_PASS}\n"
|
||||
fi
|
||||
|
||||
#if nk3 detected, we add the NK3 Secrets App PIN
|
||||
#if nk3 detected, we add the NK3 Secrets app PIN
|
||||
if [ "$DONGLE_BRAND" = "Nitrokey 3" ]; then
|
||||
passphrases+="Nitrokey 3 Secrets app PIN: ${ADMIN_PIN}\n"
|
||||
fi
|
||||
|
||||
+56
-12
@@ -88,7 +88,8 @@ DEBUG "Signature key was created at $(date -d "@$gpg_key_create_time")"
|
||||
now_date="$(date '+%s')"
|
||||
|
||||
# Get the number of HOTP related PIN retry attempts remaining.
|
||||
# NK3 uses "Secrets app PIN counter"; all pre-NK3 devices use "Card counters: Admin".
|
||||
# NK3 uses "Secrets app PIN counter" (factory default: 8 attempts);
|
||||
# all pre-NK3 devices use "Card counters: Admin" (factory default: 3 attempts).
|
||||
if [ "$DONGLE_BRAND" = "Nitrokey 3" ]; then
|
||||
admin_pin_retries=$(echo "$hotp_token_info" | grep "Secrets app PIN counter:" | cut -d ':' -f 2 | tr -d ' ')
|
||||
prompt_message="Secrets app"
|
||||
@@ -103,6 +104,8 @@ DEBUG "HOTP related PIN retry counter is $admin_pin_retries"
|
||||
hotpkey_fw_display "$hotp_token_info" "$DONGLE_BRAND"
|
||||
|
||||
# Re-query and display the current PIN retry counter before each manual prompt.
|
||||
# Updates the global $admin_pin_retries (no local keyword) so callers can use
|
||||
# the fresh value for decisions (e.g. max_attempts calculation below).
|
||||
# prompt_message is already set for the device type (NK3 vs older), reuse it.
|
||||
show_pin_retries() {
|
||||
local info
|
||||
@@ -113,7 +116,7 @@ show_pin_retries() {
|
||||
admin_pin_retries=$(echo "$info" | grep "Card counters: Admin" | grep -o 'Admin [0-9]*' | grep -o '[0-9]*')
|
||||
fi
|
||||
admin_pin_retries="${admin_pin_retries:-0}"
|
||||
STATUS "$DONGLE_BRAND GPG Admin PIN retries remaining: $(pin_color "$admin_pin_retries")${admin_pin_retries}\033[0m"
|
||||
STATUS "$DONGLE_BRAND ${prompt_message} PIN retries remaining: $(pin_color "$admin_pin_retries")${admin_pin_retries}\033[0m"
|
||||
}
|
||||
|
||||
# Try using factory default admin PIN for 1 month following OEM reset to ease
|
||||
@@ -131,7 +134,7 @@ if [ "$((now_date - gpg_key_create_time))" -gt "$month_secs" ]; then
|
||||
elif [ "$admin_pin_retries" -lt 3 ]; then
|
||||
DEBUG "Not trying default PIN ($admin_pin): only $admin_pin_retries attempt(s) left"
|
||||
else
|
||||
STATUS "Trying GPG Admin PIN to seal HOTP secret on $DONGLE_BRAND"
|
||||
STATUS "Trying ${prompt_message} PIN to seal HOTP secret on $DONGLE_BRAND"
|
||||
# NK3 requires physical touch confirmation for the initialize operation
|
||||
if [ "$DONGLE_BRAND" = "Nitrokey 3" ]; then
|
||||
NOTE "Nitrokey 3 requires physical presence: touch the dongle when prompted"
|
||||
@@ -144,30 +147,71 @@ fi
|
||||
|
||||
if [ "$admin_pin_status" -ne 0 ]; then
|
||||
|
||||
# If the default PIN was tried and failed, we consumed 1 attempt.
|
||||
# Re-read the counter and limit user attempts accordingly.
|
||||
# Leave at least 1 attempt unconsumed to avoid accidental lockout.
|
||||
#
|
||||
# max_attempts calculation:
|
||||
# - Read current retry counter (may be lower if default PIN consumed 1)
|
||||
# - Subtract 1 to preserve one final attempt for the user
|
||||
# - Cap at 3 to match the pre-NK3 factory default, so the user experience
|
||||
# is consistent regardless of device.
|
||||
# - If the counter read is unreliable (0 or 1), fall back to 3 attempts
|
||||
# so the user is never blocked from sealing.
|
||||
#
|
||||
# Example outcomes for NK3 (factory default: 8):
|
||||
# Default PIN skipped (key >1 month old) -> max_attempts = min(8-1, 3) = 3
|
||||
# Default PIN tried & failed (8 -> 7 remaining) -> max_attempts = min(7-1, 3) = 3
|
||||
# Default PIN tried & failed (4 -> 3 remaining) -> max_attempts = min(3-1, 3) = 2
|
||||
# Default PIN tried & failed (2 -> 1 remaining) -> max_attempts = 3 (fallback, don't block)
|
||||
# Counter read failed (0 or empty) -> max_attempts = 3 (fallback, don't block)
|
||||
#
|
||||
# Example outcomes for pre-NK3 (factory default: 3):
|
||||
# Default PIN skipped (key >1 month old) -> max_attempts = min(3-1, 3) = 2
|
||||
# Default PIN tried & failed (3 -> 2 remaining) -> max_attempts = min(2-1, 3) = 1
|
||||
# Counter read failed (0 or empty) -> max_attempts = 3 (fallback, don't block)
|
||||
# Re-read counter without displaying (loop will show it)
|
||||
info="$(hotp_verification info 2>/dev/null)" || true
|
||||
if [ "$DONGLE_BRAND" = "Nitrokey 3" ]; then
|
||||
admin_pin_retries=$(echo "$info" | grep "Secrets app PIN counter:" | cut -d ':' -f 2 | tr -d ' ')
|
||||
else
|
||||
admin_pin_retries=$(echo "$info" | grep "Card counters: Admin" | grep -o 'Admin [0-9]*' | grep -o '[0-9]*')
|
||||
fi
|
||||
admin_pin_retries="${admin_pin_retries:-0}"
|
||||
if [ "$admin_pin_retries" -ge 2 ]; then
|
||||
max_attempts=$((admin_pin_retries - 1))
|
||||
[ "$max_attempts" -gt 3 ] && max_attempts=3
|
||||
else
|
||||
max_attempts=3
|
||||
fi
|
||||
|
||||
# prompt user for PIN; re-query counter before each attempt so the user
|
||||
# sees the decremented count after a wrong PIN (same pattern as kexec-sign-config.sh)
|
||||
for tries in 1 2 3; do
|
||||
for tries in $(seq 1 $max_attempts); do
|
||||
show_pin_retries
|
||||
if [ "$tries" -eq 1 ]; then
|
||||
INPUT "Enter your $DONGLE_BRAND GPG Admin PIN (attempt $tries/3):" -r -s admin_pin
|
||||
INPUT "Enter your $DONGLE_BRAND ${prompt_message} PIN (attempt $tries/$max_attempts):" -r -s admin_pin
|
||||
else
|
||||
INPUT "Wrong PIN - re-enter your $DONGLE_BRAND GPG Admin PIN (attempt $tries/3):" -r -s admin_pin
|
||||
INPUT "Wrong PIN - re-enter your $DONGLE_BRAND ${prompt_message} PIN (attempt $tries/$max_attempts):" -r -s admin_pin
|
||||
fi
|
||||
if hotp_initialize "$admin_pin" $HOTP_SECRET $counter_value "$DONGLE_BRAND"; then
|
||||
break
|
||||
fi
|
||||
if [ "$tries" -eq 3 ]; then
|
||||
if [ "$tries" -eq "$max_attempts" ]; then
|
||||
# don't leak key on failure
|
||||
shred -n 10 -z -u "$HOTP_SECRET" 2>/dev/null
|
||||
case "$DONGLE_BRAND" in
|
||||
"Nitrokey Pro" | "Nitrokey Storage" | "Nitrokey 3")
|
||||
DIE "Setting HOTP secret on $DONGLE_BRAND failed after 3 attempts. To reset GPG Admin PIN: redo Re-Ownership, or use Nitrokey App 2, or contact Nitrokey support."
|
||||
"Nitrokey 3")
|
||||
DIE "Setting HOTP secret on $DONGLE_BRAND failed after $max_attempts attempts. To reset ${prompt_message} PIN: redo Re-Ownership, or use Nitrokey App 2, or contact Nitrokey support."
|
||||
;;
|
||||
"Nitrokey Pro" | "Nitrokey Storage")
|
||||
DIE "Setting HOTP secret on $DONGLE_BRAND failed after $max_attempts attempts. To reset GPG Admin PIN: redo Re-Ownership, or use Nitrokey App 2, or contact Nitrokey support."
|
||||
;;
|
||||
"Librem Key")
|
||||
DIE "Setting HOTP secret on $DONGLE_BRAND failed after 3 attempts. To reset GPG Admin PIN: redo Re-Ownership or contact Purism support."
|
||||
DIE "Setting HOTP secret on $DONGLE_BRAND failed after $max_attempts attempts. To reset GPG Admin PIN: redo Re-Ownership or contact Purism support."
|
||||
;;
|
||||
*)
|
||||
DIE "Setting HOTP secret failed after 3 attempts"
|
||||
DIE "Setting HOTP secret failed after $max_attempts attempts"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
@@ -175,7 +219,7 @@ if [ "$admin_pin_status" -ne 0 ]; then
|
||||
else
|
||||
# Default PIN was accepted — security reminder, not a fatal error.
|
||||
# NOTE prints blank lines before/after and is always visible; no INPUT needed.
|
||||
NOTE "Default GPG Admin PIN detected. Change it via Options --> OEM Factory Reset / Re-Ownership."
|
||||
NOTE "Default ${prompt_message} PIN detected. Change it via Options --> OEM Factory Reset / Re-Ownership."
|
||||
fi
|
||||
|
||||
# HOTP key no longer needed
|
||||
|
||||
+19
-1
@@ -500,6 +500,22 @@ pin_color() {
|
||||
# 1050:0404 Yubikey 5 (FIDO+CCID)
|
||||
detect_usb_security_dongle_branding() {
|
||||
TRACE_FUNC
|
||||
local usb_was_enabled="${_USB_ENABLED:-n}"
|
||||
# Fast path: avoid USB re-init and lsusb scan when branding is already known
|
||||
# and USB has already been initialized in this process.
|
||||
if [ "$DONGLE_BRAND" != "USB Security dongle" ] \
|
||||
&& [ -n "$DONGLE_BRAND" ] \
|
||||
&& [ "$usb_was_enabled" = "y" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
# Child scripts can inherit DONGLE_BRAND while _USB_ENABLED resets, so always
|
||||
# initialize USB unless the fast path above was taken.
|
||||
enable_usb
|
||||
[ "$usb_was_enabled" != "y" ] && wait_for_usb_devices
|
||||
|
||||
# If branding is already specific, USB is now ready and no re-scan is needed.
|
||||
[ "$DONGLE_BRAND" != "USB Security dongle" ] && [ -n "$DONGLE_BRAND" ] && return
|
||||
local lsusb_out
|
||||
lsusb_out="$(lsusb)"
|
||||
DEBUG "lsusb output: $lsusb_out"
|
||||
@@ -644,7 +660,7 @@ cache_gpg_signing_pin() {
|
||||
# keystrokes from previous prompts cannot silently satisfy this read.
|
||||
local card_confirm=""
|
||||
if [ "$CONFIG_HAVE_GPG_KEY_BACKUP" == "y" ]; then
|
||||
INPUT "Use your GPG security dongle (Enter/y) or backup thumb drive (b)? [Y/b]:" -n 1 -r card_confirm
|
||||
INPUT "Use your $DONGLE_BRAND (Enter/y) or backup thumb drive (b)? [Y/b]:" -n 1 -r card_confirm
|
||||
while [ "$card_confirm" != "y" \
|
||||
-a "$card_confirm" != "Y" \
|
||||
-a "$card_confirm" != "b" \
|
||||
@@ -831,6 +847,8 @@ cache_gpg_signing_pin() {
|
||||
}
|
||||
|
||||
confirm_gpg_card() {
|
||||
enable_usb
|
||||
detect_usb_security_dongle_branding
|
||||
cache_gpg_signing_pin "$@"
|
||||
}
|
||||
|
||||
|
||||
+28
-26
@@ -253,6 +253,10 @@ report_integrity_measurements() {
|
||||
DEBUG "integrity report generated at $date_now"
|
||||
STATUS "Preparing Measured Integrity Report - hashing and verifying /boot"
|
||||
|
||||
# Detect branding and initialize USB (detect_usb_security_dongle_branding calls
|
||||
# enable_usb internally and guards against redundant re-detection).
|
||||
detect_usb_security_dongle_branding
|
||||
|
||||
if [ "$CONFIG_TPM" = "y" ]; then
|
||||
totp_state="UNAVAILABLE"
|
||||
if [ "$CONFIG_TPM2_TOOLS" != "y" ] || [ -f /tmp/secret/primary.handle ]; then
|
||||
@@ -271,21 +275,19 @@ report_integrity_measurements() {
|
||||
fi
|
||||
|
||||
if [ -x /bin/hotp_verification ]; then
|
||||
enable_usb
|
||||
STATUS "Checking USB security dongle presence"
|
||||
local _dongle_brand _hotp_info
|
||||
_dongle_brand="$(detect_usb_security_dongle_branding)"
|
||||
STATUS "Checking $DONGLE_BRAND presence"
|
||||
local _hotp_info
|
||||
DEBUG "report_integrity_measurements: querying HOTP token info"
|
||||
if _hotp_info="$(hotp_verification info 2>/dev/null)"; then
|
||||
hotp_state="TOKEN PRESENT"
|
||||
STATUS_OK "USB security dongle detected"
|
||||
hotpkey_fw_display "$_hotp_info" "$_dongle_brand"
|
||||
elif [ "$_dongle_brand" != "USB Security dongle" ]; then
|
||||
hotp_state="TOKEN INCOMPATIBLE"
|
||||
DEBUG "report_integrity_measurements: $_dongle_brand detected but HOTP verification failed"
|
||||
hotp_state="$DONGLE_BRAND PRESENT"
|
||||
STATUS_OK "$DONGLE_BRAND detected"
|
||||
hotpkey_fw_display "$_hotp_info" "$DONGLE_BRAND"
|
||||
elif [ "$DONGLE_BRAND" != "USB Security dongle" ]; then
|
||||
hotp_state="$DONGLE_BRAND INCOMPATIBLE"
|
||||
DEBUG "report_integrity_measurements: $DONGLE_BRAND detected but HOTP verification failed"
|
||||
else
|
||||
hotp_state="TOKEN MISSING"
|
||||
DEBUG "report_integrity_measurements: hotp_verification info failed, hotp_state=TOKEN MISSING"
|
||||
hotp_state="$DONGLE_BRAND MISSING"
|
||||
DEBUG "report_integrity_measurements: hotp_verification info failed, hotp_state=$hotp_state"
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -351,7 +353,7 @@ report_integrity_measurements() {
|
||||
|
||||
# Check signing key: try card immediately (USB already up); only prompt if not accessible.
|
||||
# wait_for_gpg_card sets global gpg_output to the card-status output on success.
|
||||
STATUS "Verifying OpenPGP signing key on USB security dongle"
|
||||
STATUS "Verifying signing key on $DONGLE_BRAND"
|
||||
enable_usb
|
||||
gpg_output=""
|
||||
local _card_detected=0
|
||||
@@ -359,7 +361,7 @@ report_integrity_measurements() {
|
||||
_card_detected=1
|
||||
else
|
||||
whiptail_type "$BG_COLOR_MAIN_MENU" --title 'Signing Card Check' \
|
||||
--msgbox "Please insert your OpenPGP signing card (USB security key), then press OK." 0 80
|
||||
--msgbox "Please insert your $DONGLE_BRAND and press OK." 0 80
|
||||
if wait_for_gpg_card 2>/dev/null; then
|
||||
_card_detected=1
|
||||
fi
|
||||
@@ -368,14 +370,14 @@ report_integrity_measurements() {
|
||||
# Determine signing key state from card-status output (gpg_output set by wait_for_gpg_card).
|
||||
local _card_sig_fpr _rom_fprs signing_key_guidance
|
||||
if [ "$_card_detected" -eq 0 ]; then
|
||||
signing_key_state="NO DONGLE DETECTED"
|
||||
signing_key_guidance="No USB security dongle detected. Insert the correct dongle and retry, or perform OEM Factory Reset / Re-Ownership."
|
||||
signing_key_state="NO $DONGLE_BRAND DETECTED"
|
||||
signing_key_guidance="No $DONGLE_BRAND detected. Insert the correct dongle and retry, or perform OEM Factory Reset / Re-Ownership."
|
||||
else
|
||||
_card_sig_fpr=$(echo "$gpg_output" |
|
||||
awk -F: '/Signature key/ {gsub(/[[:space:]]/,"",$2); print $2; exit}')
|
||||
if [ -z "$_card_sig_fpr" ] || [ "$_card_sig_fpr" = "[none]" ]; then
|
||||
signing_key_state="DONGLE NOT PROVISIONED"
|
||||
signing_key_guidance="USB security dongle is connected but has no signing key (unprovisioned or wiped). Provision the dongle with the signing subkey, or perform OEM Factory Reset / Re-Ownership to start fresh with a new key."
|
||||
signing_key_guidance="$DONGLE_BRAND is connected but has no signing key (unprovisioned or wiped). Provision the dongle with the signing subkey, or perform OEM Factory Reset / Re-Ownership to start fresh with a new key."
|
||||
else
|
||||
_rom_fprs=$(gpg --with-colons --list-keys 2>/dev/null |
|
||||
awk -F: '/^fpr/ {print $10}')
|
||||
@@ -384,7 +386,7 @@ report_integrity_measurements() {
|
||||
signing_key_guidance=""
|
||||
else
|
||||
signing_key_state="DONGLE KEY NOT ROM-TRUSTED"
|
||||
signing_key_guidance="USB security dongle has a signing key that does not match this firmware's trusted key. OEM Factory Reset / Re-Ownership is required to establish new trusted ownership."
|
||||
signing_key_guidance="$DONGLE_BRAND has a signing key that does not match this firmware's trusted key. OEM Factory Reset / Re-Ownership is required to establish new trusted ownership."
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@@ -404,14 +406,14 @@ report_integrity_measurements() {
|
||||
;;
|
||||
esac
|
||||
case "$hotp_state" in
|
||||
"TOKEN MISSING")
|
||||
hotp_display="TOKEN NOT CONNECTED"
|
||||
*"MISSING")
|
||||
hotp_display="$DONGLE_BRAND NOT CONNECTED"
|
||||
;;
|
||||
"TOKEN PRESENT")
|
||||
hotp_display="TOKEN CONNECTED (presence confirmed)"
|
||||
*"PRESENT")
|
||||
hotp_display="$DONGLE_BRAND CONNECTED (presence confirmed)"
|
||||
;;
|
||||
"TOKEN INCOMPATIBLE")
|
||||
hotp_display="TOKEN INCOMPATIBLE ($_dongle_brand does not support HOTP)"
|
||||
*"INCOMPATIBLE")
|
||||
hotp_display="$DONGLE_BRAND INCOMPATIBLE ($DONGLE_BRAND does not support HOTP)"
|
||||
;;
|
||||
*)
|
||||
hotp_display="$hotp_state"
|
||||
@@ -424,7 +426,7 @@ report_integrity_measurements() {
|
||||
else
|
||||
action_guidance="$sig_guidance"
|
||||
fi
|
||||
report_body="Date: $date_now\nTOTP: $totp_display\nHOTP: $hotp_display\n\nBoot signature (/boot/kexec.sig): $signature_state\n$sig_detail\nBoot files: $hash_state\nDongle key: $signing_key_state\n\nAction: $action_guidance"
|
||||
report_body="Date: $date_now\nTOTP: $totp_display\nHOTP: $hotp_display\n\nBoot signature (/boot/kexec.sig): $signature_state\n$sig_detail\nBoot files: $hash_state\n$DONGLE_BRAND key: $signing_key_state\n\nAction: $action_guidance"
|
||||
if [ "$hash_state" != "OK" ]; then
|
||||
report_body="$report_body\n\nIf /boot integrity is not OK, investigate before sealing new secrets or performing TPM reset or re-ownership."
|
||||
fi
|
||||
@@ -438,7 +440,7 @@ report_integrity_measurements() {
|
||||
fi
|
||||
msg="Measured Integrity Report\n\n$report_body"
|
||||
# menu_msg omits the guidance paragraphs to keep the dialog within terminal height
|
||||
menu_msg="Measured Integrity Report\n\nDate: $date_now\nTOTP: $totp_display\nHOTP: $hotp_display\n\nBoot signature (/boot/kexec.sig): $signature_state\n$sig_detail\nBoot files: $hash_state\nDongle key: $signing_key_state\n\nChoose an action:"
|
||||
menu_msg="Measured Integrity Report\n\nDate: $date_now\nTOTP: $totp_display\nHOTP: $hotp_display\n\nBoot signature (/boot/kexec.sig): $signature_state\n$sig_detail\nBoot files: $hash_state\n$DONGLE_BRAND key: $signing_key_state\n\nChoose an action:"
|
||||
|
||||
if [ "$hash_state" = "OK" ] && [ "$signing_key_state" = "DONGLE MATCHES ROM-TRUSTED KEY" ]; then
|
||||
whiptail_type $BG_COLOR_MAIN_MENU --title 'Measured Integrity Report' \
|
||||
|
||||
Reference in New Issue
Block a user