mirror of
https://github.com/linuxboot/heads.git
synced 2025-03-13 07:54:34 +00:00
oem-factory-reset+seal-hotp nk3 hotp-verification info adaptations
- oem-factory-reset: fix strings for nk3 is from https://github.com/Nitrokey/nitrokey-hotp-verification/pull/43 is Secrets app, not Secret App singular, not App capitalized - initrd/bin/seal-hotpkey: adapt to check nk3 Secrets App PIN counter if nk3, keep Card counters for <nk3 from https://github.com/Nitrokey/nitrokey-hotp-verification/pull/43 - Unattended hotp_initialize output removed since we need physical presence to seal HOTP until https://github.com/Nitrokey/nitrokey-hotp-verification/issues/41 is fixed - Finally make seal_hotp use logic to detect if public key <1m old, use HOTP related PIN by default if counter is not <3, warn that re-ownership needs to be ran to change it since no security offered at all otherwise with HOTP - unify format with linting tool Tested in local tree against https://patch-diff.githubusercontent.com/raw/Nitrokey/nitrokey-hotp-verification/pull/43.patch, removing https://patch-diff.githubusercontent.com/raw/Nitrokey/nitrokey-hotp-verification/pull/46.patch - will revert the change above in PR once testing is over Signed-off-by: Thierry Laurion <insurgo@riseup.net>
This commit is contained in:
parent
4fd710696e
commit
ebf4d1d221
@ -143,13 +143,15 @@ mount_boot() {
|
|||||||
|
|
||||||
reset_nk3_secret_app() {
|
reset_nk3_secret_app() {
|
||||||
TRACE_FUNC
|
TRACE_FUNC
|
||||||
# Reset Nitrokey 3 Secret App
|
# Reset Nitrokey 3 Secrets App
|
||||||
if lsusb | grep -q "20a0:42b2"; then
|
if lsusb | grep -q "20a0:42b2"; then
|
||||||
echo
|
echo
|
||||||
echo "Resetting Nitrokey 3 Secret App PIN. Physical presence (touch) will be required"
|
warn "Resetting Nitrokey 3 Secrets App PIN. Physical presence (touch) will be required"
|
||||||
#TODO, change message when https://github.com/Nitrokey/nitrokey-hotp-verification/issues/41 is fixed
|
#TODO, change message when https://github.com/Nitrokey/nitrokey-hotp-verification/issues/41 is fixed
|
||||||
# Reset Nitrokey 3 secret app with PIN
|
# Reset Nitrokey 3 secret app with PIN
|
||||||
/bin/hotp_verification reset "${ADMIN_PIN}"
|
if ! /bin/hotp_verification reset "${ADMIN_PIN}"; then
|
||||||
|
whiptail_error_die "Failed to reset Nitrokey 3 Secrets App with error code $?, contact Nitrokey support"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -552,7 +554,6 @@ gpg_key_factory_reset() {
|
|||||||
whiptail_error_die "GPG Key factory reset failed!\n\n$ERROR"
|
whiptail_error_die "GPG Key factory reset failed!\n\n$ERROR"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
# If Nitrokey Storage is inserted, reset AES keys as well
|
# If Nitrokey Storage is inserted, reset AES keys as well
|
||||||
if lsusb | grep -q "20a0:4109" && [ -x /bin/hotp_verification ]; then
|
if lsusb | grep -q "20a0:4109" && [ -x /bin/hotp_verification ]; then
|
||||||
DEBUG "Nitrokey Storage detected, resetting AES keys..."
|
DEBUG "Nitrokey Storage detected, resetting AES keys..."
|
||||||
@ -1388,7 +1389,7 @@ fi
|
|||||||
|
|
||||||
#if nk3 detected, we add the NK3 Secre App PIN. Detect by product ID
|
#if nk3 detected, we add the NK3 Secre App PIN. Detect by product ID
|
||||||
if lsusb | grep -q "20a0:42b2"; then
|
if lsusb | grep -q "20a0:42b2"; then
|
||||||
passphrases+="Nitrokey 3 Secret App PIN: ${ADMIN_PIN}\n"
|
passphrases+="Nitrokey 3 Secrets App PIN: ${ADMIN_PIN}\n"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#GPG PINs output
|
#GPG PINs output
|
||||||
@ -1403,7 +1404,6 @@ if [ "$GPG_GEN_KEY_IN_MEMORY" = "y" ]; then
|
|||||||
passphrases+="GPG key material backup passphrase: ${ADMIN_PIN}\n"
|
passphrases+="GPG key material backup passphrase: ${ADMIN_PIN}\n"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
# Show configured secrets in whiptail and loop until user confirms qr code was scanned
|
# Show configured secrets in whiptail and loop until user confirms qr code was scanned
|
||||||
while true; do
|
while true; do
|
||||||
whiptail --msgbox "
|
whiptail --msgbox "
|
||||||
|
@ -8,28 +8,26 @@ HOTP_SECRET="/tmp/secret/hotp.key"
|
|||||||
HOTP_COUNTER="/boot/kexec_hotp_counter"
|
HOTP_COUNTER="/boot/kexec_hotp_counter"
|
||||||
HOTP_KEY="/boot/kexec_hotp_key"
|
HOTP_KEY="/boot/kexec_hotp_key"
|
||||||
|
|
||||||
mount_boot()
|
mount_boot() {
|
||||||
{
|
TRACE_FUNC
|
||||||
TRACE_FUNC
|
# Mount local disk if it is not already mounted
|
||||||
# Mount local disk if it is not already mounted
|
if ! grep -q /boot /proc/mounts; then
|
||||||
if ! grep -q /boot /proc/mounts; then
|
if ! mount -o ro /boot; then
|
||||||
if ! mount -o ro /boot; then
|
whiptail_error --title 'ERROR' \
|
||||||
whiptail_error --title 'ERROR' \
|
--msgbox "Couldn't mount /boot.\n\nCheck the /boot device in configuration settings, or perform an OEM reset." 0 80
|
||||||
--msgbox "Couldn't mount /boot.\n\nCheck the /boot device in configuration settings, or perform an OEM reset." 0 80
|
return 1
|
||||||
return 1
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE_FUNC
|
TRACE_FUNC
|
||||||
|
|
||||||
fatal_error()
|
fatal_error() {
|
||||||
{
|
echo -e "\nERROR: ${1}; press Enter to continue."
|
||||||
echo -e "\nERROR: ${1}; press Enter to continue."
|
read
|
||||||
read
|
# get lsusb output for debugging
|
||||||
# get lsusb output for debugging
|
DEBUG "lsusb output: $(lsusb)"
|
||||||
DEBUG "lsusb output: $(lsusb)"
|
die "$1"
|
||||||
die "$1"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Use stored HOTP key branding (this might be useful after OEM reset)
|
# Use stored HOTP key branding (this might be useful after OEM reset)
|
||||||
@ -41,11 +39,11 @@ fi
|
|||||||
|
|
||||||
if [ "$CONFIG_TPM" = "y" ]; then
|
if [ "$CONFIG_TPM" = "y" ]; then
|
||||||
DEBUG "Sealing HOTP secret reuses TOTP sealed secret..."
|
DEBUG "Sealing HOTP secret reuses TOTP sealed secret..."
|
||||||
tpmr unseal 4d47 0,1,2,3,4,7 312 "$HOTP_SECRET" \
|
tpmr unseal 4d47 0,1,2,3,4,7 312 "$HOTP_SECRET" ||
|
||||||
|| fatal_error "Unable to unseal HOTP secret"
|
fatal_error "Unable to unseal HOTP secret"
|
||||||
else
|
else
|
||||||
# without a TPM, generate a secret based on the SHA-256 of the ROM
|
# without a TPM, generate a secret based on the SHA-256 of the ROM
|
||||||
secret_from_rom_hash > "$HOTP_SECRET" || die "Reading ROM failed"
|
secret_from_rom_hash >"$HOTP_SECRET" || die "Reading ROM failed"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Store counter in file instead of TPM for now, as it conflicts with Heads
|
# Store counter in file instead of TPM for now, as it conflicts with Heads
|
||||||
@ -69,20 +67,20 @@ counter_value=1
|
|||||||
enable_usb
|
enable_usb
|
||||||
# While making sure the key is inserted, capture the status so we can check how
|
# While making sure the key is inserted, capture the status so we can check how
|
||||||
# many PIN attempts remain
|
# many PIN attempts remain
|
||||||
if ! hotp_token_info="$(hotp_verification info)" ; then
|
if ! hotp_token_info="$(hotp_verification info)"; then
|
||||||
echo -e "\nInsert your $HOTPKEY_BRANDING and press Enter to configure it"
|
echo -e "\nInsert your $HOTPKEY_BRANDING and press Enter to configure it"
|
||||||
read
|
read
|
||||||
if ! hotp_token_info="$(hotp_verification info)" ; then
|
if ! hotp_token_info="$(hotp_verification info)"; then
|
||||||
# don't leak key on failure
|
# don't leak key on failure
|
||||||
shred -n 10 -z -u "$HOTP_SECRET" 2> /dev/null
|
shred -n 10 -z -u "$HOTP_SECRET" 2>/dev/null
|
||||||
fatal_error "Unable to find $HOTPKEY_BRANDING"
|
fatal_error "Unable to find $HOTPKEY_BRANDING"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Set HOTP USB Security Dongle branding based on VID
|
# Set HOTP USB Security Dongle branding based on VID
|
||||||
if lsusb | grep -q "20a0:" ; then
|
if lsusb | grep -q "20a0:"; then
|
||||||
HOTPKEY_BRANDING="Nitrokey"
|
HOTPKEY_BRANDING="Nitrokey"
|
||||||
elif lsusb | grep -q "316d:" ; then
|
elif lsusb | grep -q "316d:"; then
|
||||||
HOTPKEY_BRANDING="Librem Key"
|
HOTPKEY_BRANDING="Librem Key"
|
||||||
else
|
else
|
||||||
HOTPKEY_BRANDING="HOTP USB Security Dongle"
|
HOTPKEY_BRANDING="HOTP USB Security Dongle"
|
||||||
@ -99,19 +97,25 @@ gpg_key_create_time="${gpg_key_create_time:-0}"
|
|||||||
DEBUG "Signature key was created at $(date -d "@$gpg_key_create_time")"
|
DEBUG "Signature key was created at $(date -d "@$gpg_key_create_time")"
|
||||||
now_date="$(date '+%s')"
|
now_date="$(date '+%s')"
|
||||||
|
|
||||||
# Get the number of admin PIN retry attempts remaining
|
# Get the number of HOTP related PIN retry attempts remaining
|
||||||
awk_admin_counter_regex='/^\s*Card counters: Admin (\d),.*$/'
|
# if nk3 detected by lsusb, use different regex to get admin counter
|
||||||
awk_get_admin_counter="$awk_admin_counter_regex"' { print gensub('"$awk_admin_counter_regex"', "\\1", "") }'
|
if lsusb | grep -q "20a0:42b2"; then
|
||||||
admin_pin_retries="$(echo "$hotp_token_info" | awk "$awk_get_admin_counter")"
|
# Nitrokey 3: Secrets app PIN counter: 8
|
||||||
|
admin_pin_retries=$(echo "$hotp_token_info" | grep "Secrets app PIN counter:" | cut -d ':' -f 2 | tr -d ' ')
|
||||||
|
prompt_message="Secrets app"
|
||||||
|
else
|
||||||
|
admin_pin_retries=$(echo "$hotp_token_info" | grep "Card counters: Admin" | cut -d ':' -f 2 | tr -d ' ')
|
||||||
|
prompt_message="GPG Admin"
|
||||||
|
fi
|
||||||
|
|
||||||
admin_pin_retries="${admin_pin_retries:-0}"
|
admin_pin_retries="${admin_pin_retries:-0}"
|
||||||
DEBUG "Admin PIN retry counter is $admin_pin_retries"
|
DEBUG "HOTP related PIN retry counter is $admin_pin_retries"
|
||||||
#TODO: as per hotp_verification 1.6: this is 8 for nk3 and wrong. FIX
|
|
||||||
|
|
||||||
# Try using factory default admin PIN for 1 month following OEM reset to ease
|
# Try using factory default admin PIN for 1 month following OEM reset to ease
|
||||||
# initial setup. But don't do it forever to encourage changing the PIN and
|
# initial setup. But don't do it forever to encourage changing the PIN and
|
||||||
# so PIN attempts are not consumed by the default attempt.
|
# so PIN attempts are not consumed by the default attempt.
|
||||||
admin_pin="12345678"
|
admin_pin="12345678"
|
||||||
month_secs="$((30*24*60*60))"
|
month_secs="$((30 * 24 * 60 * 60))"
|
||||||
admin_pin_status=1
|
admin_pin_status=1
|
||||||
if [ "$((now_date - gpg_key_create_time))" -gt "$month_secs" ]; then
|
if [ "$((now_date - gpg_key_create_time))" -gt "$month_secs" ]; then
|
||||||
# Remind what the default PIN was in case it still hasn't been changed
|
# Remind what the default PIN was in case it still hasn't been changed
|
||||||
@ -122,48 +126,42 @@ if [ "$((now_date - gpg_key_create_time))" -gt "$month_secs" ]; then
|
|||||||
elif [ "$admin_pin_retries" -lt 3 ]; then
|
elif [ "$admin_pin_retries" -lt 3 ]; then
|
||||||
echo "Not trying default PIN ($admin_pin), only $admin_pin_retries attempt(s) left"
|
echo "Not trying default PIN ($admin_pin), only $admin_pin_retries attempt(s) left"
|
||||||
else
|
else
|
||||||
hotp_initialize "$admin_pin" $HOTP_SECRET $counter_value "$HOTPKEY_BRANDING" >/dev/null 2>&1
|
echo "Trying $prompt_message PIN ($admin_pin) to seal HOTP secret on $HOTPKEY_BRANDING... You may be requested to touch the dongle..."
|
||||||
|
#TODO: silence the output of hotp_initialize once https://github.com/Nitrokey/nitrokey-hotp-verification/issues/41 is fixed
|
||||||
|
#hotp_initialize "$admin_pin" $HOTP_SECRET $counter_value "$HOTPKEY_BRANDING" >/dev/null 2>&1
|
||||||
|
hotp_initialize "$admin_pin" $HOTP_SECRET $counter_value "$HOTPKEY_BRANDING"
|
||||||
admin_pin_status="$?"
|
admin_pin_status="$?"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$admin_pin_status" -ne 0 ]; then
|
if [ "$admin_pin_status" -ne 0 ]; then
|
||||||
|
|
||||||
# create custom message for PIN prompt based on nk3 lsusb product id
|
# prompt user for PIN and retry
|
||||||
prompt_message=""
|
echo ""
|
||||||
if lsusb | grep -q "20a0:42b2"; then
|
read -s -p "Enter your $HOTPKEY_BRANDING $prompt_message PIN: " admin_pin
|
||||||
prompt_message="Secure App"
|
echo -e "\n"
|
||||||
else
|
|
||||||
prompt_message="GPG Admin"
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
hotp_initialize "$admin_pin" $HOTP_SECRET $counter_value "$HOTPKEY_BRANDING"
|
||||||
# prompt user for PIN and retry
|
if [ $? -ne 0 ]; then
|
||||||
echo ""
|
echo -e "\n"
|
||||||
read -s -p "Enter your $HOTPKEY_BRANDING $prompt_message PIN: " admin_pin
|
read -s -p "Error setting HOTP secret, re-enter $prompt_message PIN and try again: " admin_pin
|
||||||
echo -e "\n"
|
echo -e "\n"
|
||||||
|
if ! hotp_initialize "$admin_pin" $HOTP_SECRET $counter_value "$HOTPKEY_BRANDING"; then
|
||||||
hotp_initialize "$admin_pin" $HOTP_SECRET $counter_value "$HOTPKEY_BRANDING"
|
# don't leak key on failure
|
||||||
if [ $? -ne 0 ]; then
|
shred -n 10 -z -u "$HOTP_SECRET" 2>/dev/null
|
||||||
echo -e "\n"
|
if [ "$HOTPKEY_BRANDING" == "Nitrokey" ]; then
|
||||||
read -s -p "Error setting HOTP secret, re-enter $prompt_message PIN and try again: " admin_pin
|
fatal_error "Setting HOTP secret failed, to reset $prompt_message PIN, redo Re-Ownership procedure, use the Nitrokey App 2 or contact Nitrokey support"
|
||||||
echo -e "\n"
|
else
|
||||||
if ! hotp_initialize "$admin_pin" $HOTP_SECRET $counter_value "$HOTPKEY_BRANDING" ; then
|
fatal_error "Setting HOTP secret failed"
|
||||||
# don't leak key on failure
|
fi
|
||||||
shred -n 10 -z -u "$HOTP_SECRET" 2> /dev/null
|
fi
|
||||||
if [ "$HOTPKEY_BRANDING" == "Nitrokey" ]; then
|
fi
|
||||||
fatal_error "Setting HOTP secret failed, to reset $prompt_message PIN, redo Re-Ownership procedure, the Nitrokey App 2 or contact Nitrokey support"
|
|
||||||
else
|
|
||||||
fatal_error "Setting HOTP secret failed"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
else
|
else
|
||||||
# remind user to change admin password
|
# remind user to change admin password
|
||||||
echo -e "\nWARNING: default admin PIN detected: please change this as soon as possible."
|
warn "Factory $prompt_message default PIN detected: please change this PIN as soon as possible through OEM Factory Reset/User Re-Ownership"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# HOTP key no longer needed
|
# HOTP key no longer needed
|
||||||
shred -n 10 -z -u "$HOTP_SECRET" 2> /dev/null
|
shred -n 10 -z -u "$HOTP_SECRET" 2>/dev/null
|
||||||
|
|
||||||
# Make sure our counter is incremented ahead of the next check
|
# Make sure our counter is incremented ahead of the next check
|
||||||
#increment_tpm_counter $counter > /dev/null \
|
#increment_tpm_counter $counter > /dev/null \
|
||||||
@ -173,13 +171,13 @@ shred -n 10 -z -u "$HOTP_SECRET" 2> /dev/null
|
|||||||
|
|
||||||
mount -o remount,rw /boot
|
mount -o remount,rw /boot
|
||||||
|
|
||||||
counter_value=`expr $counter_value + 1`
|
counter_value=$(expr $counter_value + 1)
|
||||||
echo $counter_value > $HOTP_COUNTER \
|
echo $counter_value >$HOTP_COUNTER ||
|
||||||
|| fatal_error "Unable to create hotp counter file"
|
fatal_error "Unable to create hotp counter file"
|
||||||
|
|
||||||
# Store/overwrite HOTP USB Security Dongle branding found out beforehand
|
# Store/overwrite HOTP USB Security Dongle branding found out beforehand
|
||||||
echo $HOTPKEY_BRANDING > $HOTP_KEY \
|
echo $HOTPKEY_BRANDING >$HOTP_KEY ||
|
||||||
|| die "Unable to store hotp key file"
|
die "Unable to store hotp key file"
|
||||||
|
|
||||||
#sha256sum /tmp/counter-$counter > $HOTP_COUNTER \
|
#sha256sum /tmp/counter-$counter > $HOTP_COUNTER \
|
||||||
#|| die "Unable to create hotp counter file"
|
#|| die "Unable to create hotp counter file"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user