GPG User Authentication: In-memory gpg keygen + keytocard and GPG key material backup enabling (plus a lot of code cleanup and UX improvements) - #1515
Conversation
|
As you can see in this screenshot, some guidelines were added in warnings so that the user is made aware of signing errors that can happen under Heads if TPM reset is needed to re-create TPM counter which otherwise sealing operations fail. As of now, the user faces a loop when doing TPM Disk Unlock Key resealing and is now informed that he should do a TPM reset in such corner case. |
a4ab0dd to
5468082
Compare
66c03b7 to
b7c4f1a
Compare
|
With last commit b7c4f1a NK3 is supported with ECC p256 in-memory keygen and keytocard (as well as non-officially supported RSA2048 subkeys). It looks like this when asking recovery shell access or USB boot (non-debug qemu tpm2 whiptail): Normal behavior (default) is to authenticate against USB Security dongle (NK3 here): Otherwise GPG Thumb drive key material backup looks like this: |
|
Next step is to reprovision USB Security dongle (keytocard) from GPG key material backup thumb drive. |
|
As current state:
A lot of code cleanup has been made along the way. @JonathonHall-Purism Please check left TODO in code. The check for TPM2 primary handle has been removed from now since if causes a lot of issues linked to default boot and it not being signed. That would need to be fixed on master separately and would need some advice/coop.
Here is a quick preview of what to expect: |
JonathonHall-Purism
left a comment
There was a problem hiding this comment.
Thanks @tlaurion. I think the ideas here and general structure are good. I haven't tested any of it yet, but I did review it thoroughly keeping in mind it's still WIP.
Specific comments above, but as some key highlights:
- I suggest moving the "boot authentication" (gpg_auth) to a separate PR so we can more easily discuss the goals and behavior of that feature (but I think it is a great idea and on a good path).
- I suggested wording improvements for the new prompts in OEM reset but I think the strategy makes sense
- I'll look into the issues with the TPM2 primary handle hash as there are some clear gaps there as we've discussed before
I looked over the new GPG functionality and don't have any problems with it, with that said I'm not really a GPG expert at this point so testing will be pretty important there IMO.
…up exists. Might want to discuss that implementation. Some functions needed to be moved from functions to ash_functions so that gpg_auth can be called from recovery function. That might need to be discussed as well, recovery could be moved from ash_functions to functions instead. Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…s linked to detach signing errors Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…not so and adapt further troubleshooting notes in code when keys cannot be accessed on media for whatever cause so user can understand what is happening when accessing GPG material on backup thumb drive Signed-off-by: Thierry Laurion <insurgo@riseup.net>
Signed-off-by: Thierry Laurion <insurgo@riseup.net>
Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…used with GPG key material thumb drive backup Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…should be written to file and reused since not all in same functions/files for TPM2 Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…o to recovery shell instead of rebooting Signed-off-by: Thierry Laurion <insurgo@riseup.net>
- Add gpg_card_factory_reset() shared function for factory-reset + forcesig + key-attr setting (RSA and ECC/P-256), extracted from oem-factory-reset.sh with explicit --passphrase-file support - Add gpg_keytocard_subkeys() shared function: enable USB, verify card, move subkeys to slots 1-3 (sign, encrypt, auth) - Add gpg_set_card_identity() shared function for cardholder name and login fields with explicit admin PIN - Add gpg_reset_nk3_secret_app() shared function for Nitrokey 3 Secrets app reset, parameterized on admin PIN - Replace oem-factory-reset.sh function bodies with thin wrappers that call the shared gpg_* functions via positional args - Add reprovision_smartcard_from_backup(): 10-phase flow that mounts the LUKS backup, detects key type from imported key, mounts public partition, factory-resets card, restores subkeys, sets identity, offers ROM flash - Add k option to GPG Management Menu (gpg-gui.sh), always visible - Add K option in prompt_missing_gpg_key_action (gui-init.sh) - Add clean boot wizard offering OEM reset, reprovision, or ignore - Update doc/gpg.md, doc/configuring-keys.md, doc/architecture.md for the new recovery path - Document QEMU testing workflow and hardlink preservation pattern in doc/qemu.md (USB flash drive workflow + reprovision test) - Add Authentication and Resetting Configuration sections to doc/recovery-shell.md Extends PR linuxboot#1515 (2023): authentication via gpg_auth can now be enforced with key material restored from a backup, allowing recovery shell access control even after dongle replacement. Tested on Nitrokey 3: OEM factory reset creates LUKS backup + provisions dongle successfully. Tested on Nitrokey Pro 2: reprovision from backup restores subkeys to (new) dongle, PIN changes, public key import, ROM flash, and gpg_auth works after reboot. Config wipe from Options menu correctly triggers clean boot wizard with OEM/reprovision/ignore choice. Signed-off-by: Thierry Laurion <insurgo@riseup.net>
- Add gpg_card_factory_reset() shared function for factory-reset + forcesig + key-attr setting (RSA and ECC/P-256), extracted from oem-factory-reset.sh with explicit --passphrase-file support - Add gpg_keytocard_subkeys() shared function: enable USB, verify card, move subkeys to slots 1-3 (sign, encrypt, auth) - Add gpg_set_card_identity() shared function for cardholder name and login fields with explicit admin PIN - Add gpg_reset_nk3_secret_app() shared function for Nitrokey 3 Secrets app reset, parameterized on admin PIN - Replace oem-factory-reset.sh function bodies with thin wrappers that call the shared gpg_* functions via positional args - Add reprovision_smartcard_from_backup(): 10-phase flow that mounts the LUKS backup, detects key type from imported key, mounts public partition, factory-resets card, restores subkeys, sets identity, offers ROM flash - Add k option to GPG Management Menu (gpg-gui.sh), always visible - Add K option in prompt_missing_gpg_key_action (gui-init.sh) - Add clean boot wizard offering OEM reset, reprovision, or ignore - Update doc/gpg.md, doc/configuring-keys.md, doc/architecture.md for the new recovery path - Document QEMU testing workflow and hardlink preservation pattern in doc/qemu.md (USB flash drive workflow + reprovision test) - Add Authentication and Resetting Configuration sections to doc/recovery-shell.md Extends PR linuxboot#1515 (2023): authentication via gpg_auth can now be enforced with key material restored from a backup, allowing recovery shell access control even after dongle replacement. Tested on Nitrokey 3: OEM factory reset creates LUKS backup + provisions dongle successfully. Tested on Nitrokey Pro 2: reprovision from backup restores subkeys to (new) dongle, PIN changes, public key import, ROM flash, and gpg_auth works after reboot. Config wipe from Options menu correctly triggers clean boot wizard with OEM/reprovision/ignore choice. Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…use, add reprovision flow Extract shared OpenPGP smartcard management functions from initrd/bin/oem-factory-reset.sh into initrd/etc/gpg_functions.sh so they can be reused by multiple callers. OEM functions become thin wrappers passing global variables as positional args; the reprovision flow calls the same shared functions to restore GPG subkeys from a LUKS-encrypted backup USB onto a replacement USB Security dongle. Shared functions (replacing OEM inline code): - gpg_card_factory_reset(): factory-reset + forcesig + key-attr (RSA and ECC/P-256), parameterized on admin PIN - gpg_keytocard_subkeys(): enable USB, verify card, move subkeys to slots 1-3 (sign, encrypt, auth) - gpg_set_card_identity(): cardholder name and login fields - gpg_reset_nk3_secret_app(): Nitrokey 3 Secrets app reset - gpg_card_change_pin(): GPG User PIN change New reprovision flow (reprovision_smartcard_from_backup()): 10-phase flow: mount LUKS backup -> detect key type -> factory- reset card -> import subkeys -> set identity -> sign /boot -> flash GUI integration: - k option in GPG Management Menu (gpg-gui.sh), always visible - K option in prompt_missing_gpg_key_action (gui-init.sh) - Clean boot wizard: OEM reset, reprovision, or ignore Code quality fixes from review: - Fix 6 sites where $? was clobbered by TRACE_FUNC/DEBUG calls - Replace --passphrase-file with --passphrase-fd 3 3< to avoid leaking PIN through /proc/<pid>/cmdline - Fix algo_code/bit_len extraction: head -1 for multi-key backups - Fix STATUS_OK mount emission: only on success - Fix gpg_reset_nk3_secret_app: return actual error code from hotp_verification, explicit return 0 for non-NK3 - Remove incorrect || [ $? -eq 2 ] patch: gpg --import exit code 2 is a fatal error, not unchanged - Fix pubkey.asc import: check success properly, fall back to keyring export on failure - Fix partition derivation for NVMe/MMC: stable [0-9]+$ regex - Add _luks_cleanup helper for every error return path (replaces broken EXIT trap pattern) - Re-run NK3 Secrets app reset with custom PIN on factory-reset retry - Add chmod 600 on /tmp/secret/gpg_pin - Write backup passphrase to /tmp/secret/backup_pass, use mount-usb.sh --pass-file to avoid argv leak - Shred /tmp/secret/backup_pass on mount success and failure - Strip trailing <email> from cardholder name when no comment is present in UID line - Reset card_admin_pin to default after factory-reset step so subsequent forcesig/key-attr use the correct PIN - Add --pass-file option to mount-usb.sh Documentation: - doc/gpg.md, doc/configuring-keys.md, doc/architecture.md: updated for the new recovery path - doc/qemu.md: USB flash drive workflow, hardlink preservation, reprovision test - doc/recovery-shell.md: Authentication and Resetting Config sections Extends PR linuxboot#1515 (2023): authentication via gpg_auth can now be enforced with key material restored from a backup. Tested on Nitrokey Pro 2 (reprovision end-to-end: factory reset, keytocard, PIN change, public key import, flash, reboot, gpg_auth works). Tested on Nitrokey 3 (OEM factory reset creates LUKS backup + provisions dongle). Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…use, add reprovision flow Extract shared OpenPGP smartcard management functions from initrd/bin/oem-factory-reset.sh into initrd/etc/gpg_functions.sh so they can be reused by multiple callers. OEM functions become thin wrappers passing global variables as positional args; the reprovision flow calls the same shared functions to restore GPG subkeys from a LUKS-encrypted backup USB onto a replacement USB Security dongle. Shared functions (replacing OEM inline code): - gpg_card_factory_reset(): factory-reset + forcesig + key-attr (RSA and ECC/P-256), parameterized on admin PIN - gpg_keytocard_subkeys(): enable USB, verify card, move subkeys to slots 1-3 (sign, encrypt, auth) - gpg_set_card_identity(): cardholder name and login fields - gpg_reset_nk3_secret_app(): Nitrokey 3 Secrets app reset - gpg_card_change_pin(): GPG User PIN change New reprovision flow (reprovision_smartcard_from_backup()): 10-phase flow: mount LUKS backup -> detect key type -> factory- reset card -> import subkeys -> set identity -> sign /boot -> flash GUI integration: - k option in GPG Management Menu (gpg-gui.sh), always visible - K option in prompt_missing_gpg_key_action (gui-init.sh) - Clean boot wizard: OEM reset, reprovision, or ignore Code quality fixes from review: - Fix 6 sites where $? was clobbered by TRACE_FUNC/DEBUG calls - Replace --passphrase-file with --passphrase-fd 3 3< to avoid leaking PIN through /proc/<pid>/cmdline - Fix algo_code/bit_len extraction: head -1 for multi-key backups - Fix STATUS_OK mount emission: only on success - Fix gpg_reset_nk3_secret_app: return actual error code from hotp_verification, explicit return 0 for non-NK3 - Remove incorrect || [ $? -eq 2 ] patch: gpg --import exit code 2 is a fatal error, not unchanged - Fix pubkey.asc import: check success properly, fall back to keyring export on failure - Fix partition derivation for NVMe/MMC: stable [0-9]+$ regex - Add _luks_cleanup helper for every error return path (replaces broken EXIT trap pattern) - Re-run NK3 Secrets app reset with custom PIN on factory-reset retry - Add chmod 600 on /tmp/secret/gpg_pin - Write backup passphrase to /tmp/secret/backup_pass, use mount-usb.sh --pass-file to avoid argv leak - Shred /tmp/secret/backup_pass on mount success and failure - Strip trailing <email> from cardholder name when no comment is present in UID line - Reset card_admin_pin to default after factory-reset step so subsequent forcesig/key-attr use the correct PIN - Ensure /tmp/secret exists before writing backup_pass (mkdir -p) - Export public key from keyring instead of referencing mount file: after successful pubkey.asc import, re-export from the keyring to /tmp/reprovision_pubkey.asc rather than pointing PUBKEY at the potentially-stale /media/pubkey.asc - Fix gpg_reset_nk3_secret_app header comment: removes inaccurate "to factory default" phrasing - Add --pass-file option to mount-usb.sh Documentation: - doc/gpg.md, doc/configuring-keys.md, doc/architecture.md: updated for the new recovery path - doc/qemu.md: USB flash drive workflow, hardlink preservation, reprovision test - doc/recovery-shell.md: Authentication and Resetting Config sections Extends PR linuxboot#1515 (2023): authentication via gpg_auth can now be enforced with key material restored from a backup. Tested on Nitrokey Pro 2 (reprovision end-to-end: factory reset, keytocard, PIN change, public key import, flash, reboot, gpg_auth works). Tested on Nitrokey 3 (OEM factory reset creates LUKS backup + provisions dongle). Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…use, add reprovision flow Extract shared OpenPGP smartcard management functions from initrd/bin/oem-factory-reset.sh into initrd/etc/gpg_functions.sh so they can be reused by multiple callers. OEM functions become thin wrappers passing global variables as positional args; the reprovision flow calls the same shared functions to restore GPG subkeys from a LUKS-encrypted backup USB onto a replacement USB Security dongle. Shared functions (replacing OEM inline code): - gpg_card_factory_reset(): factory-reset + forcesig + key-attr (RSA and ECC/P-256), parameterized on admin PIN - gpg_keytocard_subkeys(): enable USB, verify card, move subkeys to slots 1-3 (sign, encrypt, auth) - gpg_set_card_identity(): cardholder name and login fields - gpg_reset_nk3_secret_app(): Nitrokey 3 Secrets app reset - gpg_card_change_pin(): GPG User PIN change New reprovision flow (reprovision_smartcard_from_backup()): 10-phase flow: mount LUKS backup -> detect key type -> factory- reset card -> import subkeys -> set identity -> sign /boot -> flash GUI integration: - k option in GPG Management Menu (gpg-gui.sh), always visible - K option in prompt_missing_gpg_key_action (gui-init.sh) - Clean boot wizard: OEM reset, reprovision, or ignore Code quality fixes from review: - Fix 6 sites where $? was clobbered by TRACE_FUNC/DEBUG calls - Replace --passphrase-file with --passphrase-fd 3 3< to avoid leaking PIN through /proc/<pid>/cmdline - Fix algo_code/bit_len extraction: head -1 for multi-key backups - Fix STATUS_OK mount emission: only on success - Fix gpg_reset_nk3_secret_app: return actual error code from hotp_verification, explicit return 0 for non-NK3 - Remove incorrect || [ $? -eq 2 ] patch: gpg --import exit code 2 is a fatal error, not unchanged - Fix pubkey.asc import: check success properly, fall back to keyring export on failure - Fix partition derivation for NVMe/MMC: stable [0-9]+$ regex - Add _luks_cleanup helper for every error return path (replaces broken EXIT trap pattern) - Re-run NK3 Secrets app reset with custom PIN on factory-reset retry - Add chmod 600 on /tmp/secret/gpg_pin - Write backup passphrase to /tmp/secret/backup_pass, use mount-usb.sh --pass-file to avoid argv leak - Shred /tmp/secret/backup_pass on mount success and failure - Strip trailing <email> from cardholder name when no comment is present in UID line - Reset card_admin_pin to default after factory-reset step so subsequent forcesig/key-attr use the correct PIN - Ensure /tmp/secret exists before writing backup_pass (mkdir -p) - Export public key from keyring instead of referencing mount file: after successful pubkey.asc import, re-export from the keyring to /tmp/reprovision_pubkey.asc rather than pointing PUBKEY at the potentially-stale /media/pubkey.asc - Fix gpg_reset_nk3_secret_app header comment: removes inaccurate "to factory default" phrasing - Add --pass-file option to mount-usb.sh Documentation: - doc/gpg.md, doc/configuring-keys.md, doc/architecture.md: updated for the new recovery path - doc/qemu.md: USB flash drive workflow, hardlink preservation, reprovision test - doc/recovery-shell.md: Authentication and Resetting Config sections Extends PR linuxboot#1515 (2023): authentication via gpg_auth can now be enforced with key material restored from a backup. Tested on Nitrokey Pro 2 (reprovision end-to-end: factory reset, keytocard, PIN change, public key import, flash, reboot, gpg_auth works). Tested on Nitrokey 3 (OEM factory reset creates LUKS backup + provisions dongle). Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…use, add reprovision flow Extract shared OpenPGP smartcard management functions from initrd/bin/oem-factory-reset.sh into initrd/etc/gpg_functions.sh so they can be reused by multiple callers. OEM functions become thin wrappers passing global variables as positional args; the reprovision flow calls the same shared functions to restore GPG subkeys from a LUKS-encrypted backup USB onto a replacement USB Security dongle. Shared functions (replacing OEM inline code): - gpg_card_factory_reset(): factory-reset + forcesig + key-attr (RSA and ECC/P-256), parameterized on admin PIN - gpg_keytocard_subkeys(): enable USB, verify card, move subkeys to slots 1-3 (sign, encrypt, auth) - gpg_set_card_identity(): cardholder name and login fields - gpg_reset_nk3_secret_app(): Nitrokey 3 Secrets app reset - gpg_card_change_pin(): GPG User PIN change New reprovision flow (reprovision_smartcard_from_backup()): 10-phase flow: mount LUKS backup -> detect key type -> factory- reset card -> import subkeys -> set identity -> sign /boot -> flash GUI integration: - k option in GPG Management Menu (gpg-gui.sh), always visible - K option in prompt_missing_gpg_key_action (gui-init.sh) - Clean boot wizard: OEM reset, reprovision, or ignore Code quality fixes from review: - Fix 6 sites where $? was clobbered by TRACE_FUNC/DEBUG calls - Replace --passphrase-file with --passphrase-fd 3 3< to avoid leaking PIN through /proc/<pid>/cmdline - Fix algo_code/bit_len extraction: head -1 for multi-key backups - Fix STATUS_OK mount emission: only on success - Fix gpg_reset_nk3_secret_app: return actual error code from hotp_verification, explicit return 0 for non-NK3 - Remove incorrect || [ $? -eq 2 ] patch: gpg --import exit code 2 is a fatal error, not unchanged - Fix pubkey.asc import: check success properly, fall back to keyring export on failure - Fix partition derivation for NVMe/MMC: stable [0-9]+$ regex - Add _luks_cleanup helper for every error return path (replaces broken EXIT trap pattern) - Re-run NK3 Secrets app reset with custom PIN on factory-reset retry - Add chmod 600 on /tmp/secret/gpg_pin - Write backup passphrase to /tmp/secret/backup_pass, use mount-usb.sh --pass-file to avoid argv leak - Shred /tmp/secret/backup_pass on mount success and failure - Shred /tmp/secret/gpg_pin after all GPG operations complete - Limit key_id derivation to first match (head -1) to prevent multi-line values breaking gpg --edit-key calls - Strip trailing <email> from cardholder name when no comment is present in UID line - Reset card_admin_pin to default after factory-reset step so subsequent forcesig/key-attr use the correct PIN - Ensure /tmp/secret exists before writing backup_pass (mkdir -p) - Export public key from keyring instead of referencing mount file: after successful pubkey.asc import, re-export from the keyring to /tmp/reprovision_pubkey.asc rather than pointing PUBKEY at the potentially-stale /media/pubkey.asc - Fix gpg_reset_nk3_secret_app header comment: removes inaccurate "to factory default" phrasing - Add --pass-file option to mount-usb.sh Documentation: - doc/gpg.md, doc/configuring-keys.md, doc/architecture.md: updated for the new recovery path - doc/qemu.md: USB flash drive workflow, hardlink preservation, reprovision test - doc/recovery-shell.md: Authentication and Resetting Config sections Extends PR linuxboot#1515 (2023): authentication via gpg_auth can now be enforced with key material restored from a backup. Tested on Nitrokey Pro 2 (reprovision end-to-end: factory reset, keytocard, PIN change, public key import, flash, reboot, gpg_auth works). Tested on Nitrokey 3 (OEM factory reset creates LUKS backup + provisions dongle). Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…use, add reprovision flow Extract shared OpenPGP smartcard management functions from initrd/bin/oem-factory-reset.sh into initrd/etc/gpg_functions.sh so they can be reused by multiple callers. OEM functions become thin wrappers passing global variables as positional args; the reprovision flow calls the same shared functions to restore GPG subkeys from a LUKS-encrypted backup USB onto a replacement USB Security dongle. Shared functions (replacing OEM inline code): - gpg_card_factory_reset(): factory-reset + forcesig + key-attr (RSA and ECC/P-256), parameterized on admin PIN - gpg_keytocard_subkeys(): enable USB, verify card, move subkeys to slots 1-3 (sign, encrypt, auth) - gpg_set_card_identity(): cardholder name and login fields - gpg_reset_nk3_secret_app(): Nitrokey 3 Secrets app reset - gpg_card_change_pin(): GPG User PIN change New reprovision flow (reprovision_smartcard_from_backup()): 10-phase flow: mount LUKS backup -> detect key type -> factory- reset card -> import subkeys -> set identity -> sign /boot -> flash GUI integration: - k option in GPG Management Menu (gpg-gui.sh), always visible - K option in prompt_missing_gpg_key_action (gui-init.sh) - Clean boot wizard: OEM reset, reprovision, or ignore Code quality fixes from review: - Fix 6 sites where $? was clobbered by TRACE_FUNC/DEBUG calls - Replace --passphrase-file with --passphrase-fd 3 3< to avoid leaking PIN through /proc/<pid>/cmdline - Fix algo_code/bit_len extraction: head -1 for multi-key backups - Fix STATUS_OK mount emission: only on success - Fix gpg_reset_nk3_secret_app: return actual error code from hotp_verification, explicit return 0 for non-NK3 - Remove incorrect || [ $? -eq 2 ] patch: gpg --import exit code 2 is a fatal error, not unchanged - Fix pubkey.asc import: check success properly, fall back to keyring export on failure - Fix partition derivation for NVMe/MMC: stable [0-9]+$ regex - Add _luks_cleanup helper for every error return path (replaces broken EXIT trap pattern) - Re-run NK3 Secrets app reset with custom PIN on factory-reset retry - Add chmod 600 on /tmp/secret/gpg_pin - Write backup passphrase to /tmp/secret/backup_pass, use mount-usb.sh --pass-file to avoid argv leak - Shred /tmp/secret/backup_pass on mount success and failure - Shred /tmp/secret/gpg_pin after all GPG operations complete - Limit key_id derivation to first match (head -1) to prevent multi-line values breaking gpg --edit-key calls - Strip trailing <email> from cardholder name when no comment is present in UID line - Reset card_admin_pin to default after factory-reset step so subsequent forcesig/key-attr use the correct PIN - Ensure /tmp/secret exists before writing backup_pass (mkdir -p) - Export public key from keyring instead of referencing mount file: after successful pubkey.asc import, re-export from the keyring to /tmp/reprovision_pubkey.asc rather than pointing PUBKEY at the potentially-stale /media/pubkey.asc - Fix gpg_reset_nk3_secret_app header comment: removes inaccurate "to factory default" phrasing - Add --pass-file option to mount-usb.sh Documentation: - doc/gpg.md, doc/configuring-keys.md, doc/architecture.md: updated for the new recovery path - doc/qemu.md: USB flash drive workflow, hardlink preservation, reprovision test - doc/recovery-shell.md: Authentication and Resetting Config sections Extends PR linuxboot#1515 (2023): authentication via gpg_auth can now be enforced with key material restored from a backup. Tested on Nitrokey Pro 2 (reprovision end-to-end: factory reset, keytocard, PIN change, public key import, flash, reboot, gpg_auth works). Tested on Nitrokey 3 (OEM factory reset creates LUKS backup + provisions dongle). Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…use, add reprovision flow Extract shared OpenPGP smartcard management functions from initrd/bin/oem-factory-reset.sh into initrd/etc/gpg_functions.sh so they can be reused by multiple callers. OEM functions become thin wrappers passing global variables as positional args; the reprovision flow calls the same shared functions to restore GPG subkeys from a LUKS-encrypted backup USB onto a replacement USB Security dongle. Shared functions (replacing OEM inline code): - gpg_card_factory_reset(): factory-reset + forcesig + key-attr (RSA and ECC/P-256), parameterized on admin PIN - gpg_keytocard_subkeys(): enable USB, verify card, move subkeys to slots 1-3 (sign, encrypt, auth) - gpg_set_card_identity(): cardholder name and login fields - gpg_reset_nk3_secret_app(): Nitrokey 3 Secrets app reset - gpg_card_change_pin(): GPG User PIN change New reprovision flow (reprovision_smartcard_from_backup()): 10-phase flow: mount LUKS backup -> detect key type -> factory- reset card -> import subkeys -> set identity -> sign /boot -> flash GUI integration: - k option in GPG Management Menu (gpg-gui.sh), always visible - K option in prompt_missing_gpg_key_action (gui-init.sh) - Clean boot wizard: OEM reset, reprovision, or ignore Code quality fixes from review: - Fix 6 sites where $? was clobbered by TRACE_FUNC/DEBUG calls - Replace --passphrase-file with --passphrase-fd 3 3< to avoid leaking PIN through /proc/<pid>/cmdline - Fix algo_code/bit_len extraction: head -1 for multi-key backups - Fix STATUS_OK mount emission: only on success - Fix gpg_reset_nk3_secret_app: return actual error code from hotp_verification, explicit return 0 for non-NK3 - Remove incorrect || [ $? -eq 2 ] patch: gpg --import exit code 2 is a fatal error, not unchanged - Fix pubkey.asc import: check success properly, fall back to keyring export on failure - Fix partition derivation for NVMe/MMC: stable [0-9]+$ regex - Add _luks_cleanup helper for every error return path (replaces broken EXIT trap pattern) - Re-run NK3 Secrets app reset with custom PIN on factory-reset retry - Add chmod 600 on /tmp/secret/gpg_pin - Write backup passphrase to /tmp/secret/backup_pass, use mount-usb.sh --pass-file to avoid argv leak - Shred /tmp/secret/backup_pass on mount success and failure - Shred /tmp/secret/gpg_pin after all GPG operations complete - Limit key_id derivation to first match (head -1) to prevent multi-line values breaking gpg --edit-key calls - Strip trailing <email> from cardholder name when no comment is present in UID line - Reset card_admin_pin to default after factory-reset step so subsequent forcesig/key-attr use the correct PIN - Ensure /tmp/secret exists before writing backup_pass (mkdir -p) - Export public key from keyring instead of referencing mount file: after successful pubkey.asc import, re-export from the keyring to /tmp/reprovision_pubkey.asc rather than pointing PUBKEY at the potentially-stale /media/pubkey.asc - Fix gpg_reset_nk3_secret_app header comment: removes inaccurate "to factory default" phrasing - Remove unused uid_decoded local variable from reprovision_smartcard_from_backup - Add --pass-file option to mount-usb.sh Documentation: - doc/gpg.md, doc/configuring-keys.md, doc/architecture.md: updated for the new recovery path - doc/qemu.md: USB flash drive workflow, hardlink preservation, reprovision test - doc/recovery-shell.md: Authentication and Resetting Config sections Extends PR linuxboot#1515 (2023): authentication via gpg_auth can now be enforced with key material restored from a backup. Tested on Nitrokey Pro 2 (reprovision end-to-end: factory reset, keytocard, PIN change, public key import, flash, reboot, gpg_auth works). Tested on Nitrokey 3 (OEM factory reset creates LUKS backup + provisions dongle). Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…use, add reprovision flow Extract shared OpenPGP smartcard management functions from initrd/bin/oem-factory-reset.sh into initrd/etc/gpg_functions.sh so they can be reused by multiple callers. OEM functions become thin wrappers passing global variables as positional args; the reprovision flow calls the same shared functions to restore GPG subkeys from a LUKS-encrypted backup USB onto a replacement USB Security dongle. Shared functions (replacing OEM inline code): - gpg_card_factory_reset(): factory-reset + forcesig + key-attr (RSA and ECC/P-256), parameterized on admin PIN - gpg_keytocard_subkeys(): enable USB, verify card, move subkeys to slots 1-3 (sign, encrypt, auth) - gpg_set_card_identity(): cardholder name and login fields - gpg_reset_nk3_secret_app(): Nitrokey 3 Secrets app reset - gpg_card_change_pin(): GPG User PIN change New reprovision flow (reprovision_smartcard_from_backup()): 10-phase flow: mount LUKS backup -> detect key type -> factory- reset card -> import subkeys -> set identity -> sign /boot -> flash GUI integration: - k option in GPG Management Menu (gpg-gui.sh), always visible - K option in prompt_missing_gpg_key_action (gui-init.sh) - Clean boot wizard: OEM reset, reprovision, or ignore Code quality fixes from review: - Fix 6 sites where $? was clobbered by TRACE_FUNC/DEBUG calls - Replace --passphrase-file with --passphrase-fd 3 3< to avoid leaking PIN through /proc/<pid>/cmdline - Fix algo_code/bit_len extraction: head -1 for multi-key backups - Fix STATUS_OK mount emission: only on success - Fix gpg_reset_nk3_secret_app: return actual error code from hotp_verification, explicit return 0 for non-NK3 - Remove incorrect || [ $? -eq 2 ] patch: gpg --import exit code 2 is a fatal error, not unchanged - Fix pubkey.asc import: check success properly, fall back to keyring export on failure - Fix partition derivation for NVMe/MMC: stable [0-9]+$ regex - Add _luks_cleanup helper for every error return path (replaces broken EXIT trap pattern) - Re-run NK3 Secrets app reset with custom PIN on factory-reset retry - Add chmod 600 on /tmp/secret/gpg_pin - Write backup passphrase to /tmp/secret/backup_pass, use mount-usb.sh --pass-file to avoid argv leak - Shred /tmp/secret/backup_pass on mount success and failure - Shred /tmp/secret/gpg_pin after all GPG operations complete - Limit key_id derivation to first match (head -1) to prevent multi-line values breaking gpg --edit-key calls - Strip trailing <email> from cardholder name when no comment is present in UID line - Reset card_admin_pin to default after factory-reset step so subsequent forcesig/key-attr use the correct PIN - Ensure /tmp/secret exists before writing backup_pass (mkdir -p) - Export public key from keyring instead of referencing mount file: after successful pubkey.asc import, re-export from the keyring to /tmp/reprovision_pubkey.asc rather than pointing PUBKEY at the potentially-stale /media/pubkey.asc - Fix gpg_reset_nk3_secret_app header comment: removes inaccurate "to factory default" phrasing - Remove unused uid_decoded local variable from reprovision_smartcard_from_backup - Fix parent_disk derivation for NVMe/MMC: use p?[0-9]+$ regex that handles both regular (sda1) and p-suffixed (nvme0n1p1) partitions - Fix ownertrust import regex: use [0-9A-Fa-f] to handle lowercase hex fingerprints from gpg --with-colons - Add --pass-file option to mount-usb.sh Documentation: - doc/gpg.md, doc/configuring-keys.md, doc/architecture.md: updated for the new recovery path - doc/qemu.md: USB flash drive workflow, hardlink preservation, reprovision test - doc/recovery-shell.md: Authentication and Resetting Config sections Extends PR linuxboot#1515 (2023): authentication via gpg_auth can now be enforced with key material restored from a backup. Tested on Nitrokey Pro 2 (reprovision end-to-end: factory reset, keytocard, PIN change, public key import, flash, reboot, gpg_auth works). Tested on Nitrokey 3 (OEM factory reset creates LUKS backup + provisions dongle). Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…use, add reprovision flow Extract shared OpenPGP smartcard management functions from initrd/bin/oem-factory-reset.sh into initrd/etc/gpg_functions.sh so they can be reused by multiple callers. OEM functions become thin wrappers passing global variables as positional args; the reprovision flow calls the same shared functions to restore GPG subkeys from a LUKS-encrypted backup USB onto a replacement USB Security dongle. Shared functions (replacing OEM inline code): - gpg_card_factory_reset(): factory-reset + forcesig + key-attr (RSA and ECC/P-256), parameterized on admin PIN - gpg_keytocard_subkeys(): enable USB, verify card, move subkeys to slots 1-3 (sign, encrypt, auth) - gpg_set_card_identity(): cardholder name and login fields - gpg_reset_nk3_secret_app(): Nitrokey 3 Secrets app reset - gpg_card_change_pin(): GPG User PIN change New reprovision flow (reprovision_smartcard_from_backup()): 10-phase flow: mount LUKS backup -> detect key type -> factory- reset card -> import subkeys -> set identity -> sign /boot -> flash GUI integration: - k option in GPG Management Menu (gpg-gui.sh), always visible - K option in prompt_missing_gpg_key_action (gui-init.sh) - Clean boot wizard: OEM reset, reprovision, or ignore Code quality fixes from review: - Fix 6 sites where $? was clobbered by TRACE_FUNC/DEBUG calls - Replace --passphrase-file with --passphrase-fd 3 3< to avoid leaking PIN through /proc/<pid>/cmdline - Fix algo_code/bit_len extraction: head -1 for multi-key backups - Fix STATUS_OK mount emission: only on success - Fix gpg_reset_nk3_secret_app: return actual error code from hotp_verification, explicit return 0 for non-NK3 - Remove incorrect || [ $? -eq 2 ] patch: gpg --import exit code 2 is a fatal error, not unchanged - Fix pubkey.asc import: check success properly, fall back to keyring export on failure - Fix partition derivation for NVMe/MMC: stable [0-9]+$ regex - Add _luks_cleanup helper for every error return path (replaces broken EXIT trap pattern) - Re-run NK3 Secrets app reset with custom PIN on factory-reset retry - Add chmod 600 on /tmp/secret/gpg_pin - Write backup passphrase to /tmp/secret/backup_pass, use mount-usb.sh --pass-file to avoid argv leak - Shred /tmp/secret/backup_pass on mount success and failure - Shred /tmp/secret/gpg_pin after all GPG operations complete - Limit key_id derivation to first match (head -1) to prevent multi-line values breaking gpg --edit-key calls - Strip trailing <email> from cardholder name when no comment is present in UID line - Reset card_admin_pin to default after factory-reset step so subsequent forcesig/key-attr use the correct PIN - Ensure /tmp/secret exists before writing backup_pass (mkdir -p) - Export public key from keyring instead of referencing mount file: after successful pubkey.asc import, re-export from the keyring to /tmp/reprovision_pubkey.asc rather than pointing PUBKEY at the potentially-stale /media/pubkey.asc - Fix gpg_reset_nk3_secret_app header comment: removes inaccurate "to factory default" phrasing - Remove unused uid_decoded local variable from reprovision_smartcard_from_backup - Fix parent_disk derivation for NVMe/MMC: use p?[0-9]+$ regex that handles both regular (sda1) and p-suffixed (nvme0n1p1) partitions - Fix ownertrust import regex: use [0-9A-Fa-f] to handle lowercase hex fingerprints from gpg --with-colons - Add --pass-file option to mount-usb.sh: use PASS_FILE variable and pass path directly to cryptsetup --key-file instead of reading into PASS and echoing via process substitution, eliminating the argv leak that --pass-file was meant to fix Documentation: - doc/gpg.md, doc/configuring-keys.md, doc/architecture.md: updated for the new recovery path - doc/qemu.md: USB flash drive workflow, hardlink preservation, reprovision test - doc/recovery-shell.md: Authentication and Resetting Config sections Extends PR linuxboot#1515 (2023): authentication via gpg_auth can now be enforced with key material restored from a backup. Tested on Nitrokey Pro 2 (reprovision end-to-end: factory reset, keytocard, PIN change, public key import, flash, reboot, gpg_auth works). Tested on Nitrokey 3 (OEM factory reset creates LUKS backup + provisions dongle). Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…use, add reprovision flow Extract shared OpenPGP smartcard management functions from initrd/bin/oem-factory-reset.sh into initrd/etc/gpg_functions.sh so they can be reused by multiple callers. OEM functions become thin wrappers passing global variables as positional args; the reprovision flow calls the same shared functions to restore GPG subkeys from a LUKS-encrypted backup USB onto a replacement USB Security dongle. Shared functions (replacing OEM inline code): - gpg_card_factory_reset(): factory-reset + forcesig + key-attr (RSA and ECC/P-256), parameterized on admin PIN - gpg_keytocard_subkeys(): enable USB, verify card, move subkeys to slots 1-3 (sign, encrypt, auth) - gpg_set_card_identity(): cardholder name and login fields - gpg_reset_nk3_secret_app(): Nitrokey 3 Secrets app reset - gpg_card_change_pin(): GPG User PIN change New reprovision flow (reprovision_smartcard_from_backup()): 10-phase flow: mount LUKS backup -> detect key type -> factory- reset card -> import subkeys -> set identity -> sign /boot -> flash GUI integration: - k option in GPG Management Menu (gpg-gui.sh), always visible - K option in prompt_missing_gpg_key_action (gui-init.sh) - Clean boot wizard: OEM reset, reprovision, or ignore Code quality fixes from review: - Fix 6 sites where $? was clobbered by TRACE_FUNC/DEBUG calls - Replace --passphrase-file with --passphrase-fd 3 3< to avoid leaking PIN through /proc/<pid>/cmdline - Fix algo_code/bit_len extraction: head -1 for multi-key backups - Fix STATUS_OK mount emission: only on success - Fix gpg_reset_nk3_secret_app: return actual error code from hotp_verification, explicit return 0 for non-NK3 - Remove incorrect || [ $? -eq 2 ] patch: gpg --import exit code 2 is a fatal error, not unchanged - Fix pubkey.asc import: check success properly, fall back to keyring export on failure - Fix partition derivation for NVMe/MMC: stable [0-9]+$ regex - Add _luks_cleanup helper for every error return path (replaces broken EXIT trap pattern) - Re-run NK3 Secrets app reset with custom PIN on factory-reset retry - Add chmod 600 on /tmp/secret/gpg_pin - Write backup passphrase to /tmp/secret/backup_pass, use mount-usb.sh --pass-file to avoid argv leak - Shred /tmp/secret/backup_pass on mount success and failure - Shred /tmp/secret/gpg_pin after all GPG operations complete - Limit key_id derivation to first match (head -1) to prevent multi-line values breaking gpg --edit-key calls - Strip trailing <email> from cardholder name when no comment is present in UID line - Reset card_admin_pin to default after factory-reset step so subsequent forcesig/key-attr use the correct PIN - Ensure /tmp/secret exists before writing backup_pass (mkdir -p) - Export public key from keyring instead of referencing mount file: after successful pubkey.asc import, re-export from the keyring to /tmp/reprovision_pubkey.asc rather than pointing PUBKEY at the potentially-stale /media/pubkey.asc - Fix gpg_reset_nk3_secret_app header comment: removes inaccurate "to factory default" phrasing - Remove unused uid_decoded local variable from reprovision_smartcard_from_backup - Fix parent_disk derivation for NVMe/MMC: use p?[0-9]+$ regex that handles both regular (sda1) and p-suffixed (nvme0n1p1) partitions - Fix pub_partition derivation for p-suffixed devices: detect whether the original partition used a p<num> separator and reconstruct the public partition as parent_disk+p2 vs parent_disk+2 accordingly that handles both regular (sda1) and p-suffixed (nvme0n1p1) partitions - Fix ownertrust import regex: use [0-9A-Fa-f] to handle lowercase hex fingerprints from gpg --with-colons - Add --pass-file option to mount-usb.sh: use PASS_FILE variable and pass path directly to cryptsetup --key-file instead of reading into PASS and echoing via process substitution, eliminating the argv leak that --pass-file was meant to fix Documentation: - doc/gpg.md, doc/configuring-keys.md, doc/architecture.md: updated for the new recovery path - doc/qemu.md: USB flash drive workflow, hardlink preservation, reprovision test - doc/recovery-shell.md: Authentication and Resetting Config sections Extends PR linuxboot#1515 (2023): authentication via gpg_auth can now be enforced with key material restored from a backup. Tested on Nitrokey Pro 2 (reprovision end-to-end: factory reset, keytocard, PIN change, public key import, flash, reboot, gpg_auth works). Tested on Nitrokey 3 (OEM factory reset creates LUKS backup + provisions dongle). Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…use, add reprovision flow Extract shared OpenPGP smartcard management functions from initrd/bin/oem-factory-reset.sh into initrd/etc/gpg_functions.sh so they can be reused by multiple callers. OEM functions become thin wrappers passing global variables as positional args; the reprovision flow calls the same shared functions to restore GPG subkeys from a LUKS-encrypted backup USB onto a replacement USB Security dongle. Shared functions (replacing OEM inline code): - gpg_card_factory_reset(): factory-reset + forcesig + key-attr (RSA and ECC/P-256), parameterized on admin PIN - gpg_keytocard_subkeys(): enable USB, verify card, move subkeys to slots 1-3 (sign, encrypt, auth) - gpg_set_card_identity(): cardholder name and login fields - gpg_reset_nk3_secret_app(): Nitrokey 3 Secrets app reset - gpg_card_change_pin(): GPG User PIN change New reprovision flow (reprovision_smartcard_from_backup()): 10-phase flow: mount LUKS backup -> detect key type -> factory- reset card -> import subkeys -> set identity -> sign /boot -> flash GUI integration: - k option in GPG Management Menu (gpg-gui.sh), always visible - K option in prompt_missing_gpg_key_action (gui-init.sh) - Clean boot wizard: OEM reset, reprovision, or ignore Code quality fixes from review: - Fix 6 sites where $? was clobbered by TRACE_FUNC/DEBUG calls - Replace --passphrase-file with --passphrase-fd 3 3< to avoid leaking PIN through /proc/<pid>/cmdline - Fix algo_code/bit_len extraction: head -1 for multi-key backups - Fix STATUS_OK mount emission: only on success - Fix gpg_reset_nk3_secret_app: return actual error code from hotp_verification, explicit return 0 for non-NK3 - Remove incorrect || [ $? -eq 2 ] patch: gpg --import exit code 2 is a fatal error, not unchanged - Fix pubkey.asc import: check success properly, fall back to keyring export on failure - Fix partition derivation for NVMe/MMC: stable [0-9]+$ regex - Add _luks_cleanup helper for every error return path (replaces broken EXIT trap pattern) - Re-run NK3 Secrets app reset with custom PIN on factory-reset retry - Add chmod 600 on /tmp/secret/gpg_pin - Write backup passphrase to /tmp/secret/backup_pass, use mount-usb.sh --pass-file to avoid argv leak - Shred /tmp/secret/backup_pass on mount success and failure - Shred /tmp/secret/gpg_pin after all GPG operations complete - Limit key_id derivation to first match (head -1) to prevent multi-line values breaking gpg --edit-key calls - Strip trailing <email> from cardholder name when no comment is present in UID line - Reset card_admin_pin to default after factory-reset step so subsequent forcesig/key-attr use the correct PIN - Ensure /tmp/secret exists before writing backup_pass (mkdir -p) - Export public key from keyring instead of referencing mount file: after successful pubkey.asc import, re-export from the keyring to /tmp/reprovision_pubkey.asc rather than pointing PUBKEY at the potentially-stale /media/pubkey.asc - Fix gpg_reset_nk3_secret_app header comment: removes inaccurate "to factory default" phrasing - Remove unused uid_decoded local variable from reprovision_smartcard_from_backup - Fix key_email extraction: add head -1 to prevent multi-line values when UID contains multiple <...> blocks - Fix parent_disk derivation for NVMe/MMC: use p?[0-9]+$ regex that handles both regular (sda1) and p-suffixed (nvme0n1p1) partitions - Fix pub_partition derivation for p-suffixed devices: detect whether the original partition used a p<num> separator and reconstruct the public partition as parent_disk+p2 vs parent_disk+2 accordingly that handles both regular (sda1) and p-suffixed (nvme0n1p1) partitions - Fix ownertrust import regex: use [0-9A-Fa-f] to handle lowercase hex fingerprints from gpg --with-colons - Add --pass-file option to mount-usb.sh: use PASS_FILE variable and pass path directly to cryptsetup --key-file instead of reading into PASS and echoing via process substitution, eliminating the argv leak that --pass-file was meant to fix Documentation: - doc/gpg.md, doc/configuring-keys.md, doc/architecture.md: updated for the new recovery path - doc/qemu.md: USB flash drive workflow, hardlink preservation, reprovision test - doc/recovery-shell.md: Authentication and Resetting Config sections Extends PR linuxboot#1515 (2023): authentication via gpg_auth can now be enforced with key material restored from a backup. Tested on Nitrokey Pro 2 (reprovision end-to-end: factory reset, keytocard, PIN change, public key import, flash, reboot, gpg_auth works). Tested on Nitrokey 3 (OEM factory reset creates LUKS backup + provisions dongle). Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…use, add reprovision flow Extract shared OpenPGP smartcard management functions from initrd/bin/oem-factory-reset.sh into initrd/etc/gpg_functions.sh so they can be reused by multiple callers. OEM functions become thin wrappers passing global variables as positional args; the reprovision flow calls the same shared functions to restore GPG subkeys from a LUKS-encrypted backup USB onto a replacement USB Security dongle. Shared functions (replacing OEM inline code): - gpg_card_factory_reset(): factory-reset + forcesig + key-attr (RSA and ECC/P-256), parameterized on admin PIN - gpg_keytocard_subkeys(): enable USB, verify card, move subkeys to slots 1-3 (sign, encrypt, auth) - gpg_set_card_identity(): cardholder name and login fields - gpg_reset_nk3_secret_app(): Nitrokey 3 Secrets app reset - gpg_card_change_pin(): GPG User PIN change New reprovision flow (reprovision_smartcard_from_backup()): 10-phase flow: mount LUKS backup -> detect key type -> factory- reset card -> import subkeys -> set identity -> sign /boot -> flash GUI integration: - k option in GPG Management Menu (gpg-gui.sh), always visible - K option in prompt_missing_gpg_key_action (gui-init.sh) - Clean boot wizard: OEM reset, reprovision, or ignore Code quality fixes from review: - Fix 6 sites where $? was clobbered by TRACE_FUNC/DEBUG calls - Replace --passphrase-file with --passphrase-fd 3 3< to avoid leaking PIN through /proc/<pid>/cmdline - Fix algo_code/bit_len extraction: head -1 for multi-key backups - Fix STATUS_OK mount emission: only on success - Fix gpg_reset_nk3_secret_app: return actual error code from hotp_verification, explicit return 0 for non-NK3 - Remove incorrect || [ $? -eq 2 ] patch: gpg --import exit code 2 is a fatal error, not unchanged - Fix pubkey.asc import: check success properly, fall back to keyring export on failure - Fix partition derivation for NVMe/MMC: stable [0-9]+$ regex - Add _luks_cleanup helper for every error return path (replaces broken EXIT trap pattern) - Re-run NK3 Secrets app reset with custom PIN on factory-reset retry - Add chmod 600 on /tmp/secret/gpg_pin - Write backup passphrase to /tmp/secret/backup_pass, use mount-usb.sh --pass-file to avoid argv leak - Shred /tmp/secret/backup_pass on mount success and failure - Shred /tmp/secret/gpg_pin after all GPG operations complete - Limit key_id derivation to first match (head -1) to prevent multi-line values breaking gpg --edit-key calls - Strip trailing <email> from cardholder name when no comment is present in UID line - Reset card_admin_pin to default after factory-reset step so subsequent forcesig/key-attr use the correct PIN - Ensure /tmp/secret exists before writing backup_pass (mkdir -p) - Export public key from keyring instead of referencing mount file: after successful pubkey.asc import, re-export from the keyring to /tmp/reprovision_pubkey.asc rather than pointing PUBKEY at the potentially-stale /media/pubkey.asc - Fix gpg_reset_nk3_secret_app header comment: removes inaccurate "to factory default" phrasing - Remove unused uid_decoded local variable from reprovision_smartcard_from_backup - Fix key_email extraction: add head -1 to prevent multi-line values when UID contains multiple <...> blocks - Fix parent_disk derivation for NVMe/MMC: use p?[0-9]+$ regex that handles both regular (sda1) and p-suffixed (nvme0n1p1) partitions - Fix pub_partition derivation for p-suffixed devices: detect whether the original partition used a p<num> separator and reconstruct the public partition as parent_disk+p2 vs parent_disk+2 accordingly that handles both regular (sda1) and p-suffixed (nvme0n1p1) partitions - Fix ownertrust import regex: use [0-9A-Fa-f] to handle lowercase hex fingerprints from gpg --with-colons - Add --pass-file option to mount-usb.sh: use PASS_FILE variable and pass path directly to cryptsetup --key-file instead of reading into PASS and echoing via process substitution, eliminating the argv leak that --pass-file was meant to fix Documentation: - doc/gpg.md, doc/configuring-keys.md, doc/architecture.md: updated for the new recovery path - doc/qemu.md: USB flash drive workflow, hardlink preservation, reprovision test - doc/recovery-shell.md: Authentication and Resetting Config sections Extends PR linuxboot#1515 (2023): authentication via gpg_auth can now be enforced with key material restored from a backup. Tested on Nitrokey Pro 2 (reprovision end-to-end: factory reset, keytocard, PIN change, public key import, flash, reboot, gpg_auth works). Tested on Nitrokey 3 (OEM factory reset creates LUKS backup + provisions dongle). Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…use, add reprovision flow Extract shared OpenPGP smartcard management functions from initrd/bin/oem-factory-reset.sh into initrd/etc/gpg_functions.sh so they can be reused by multiple callers. OEM functions become thin wrappers passing global variables as positional args; the reprovision flow calls the same shared functions to restore GPG subkeys from a LUKS-encrypted backup USB onto a replacement USB Security dongle. Shared functions (replacing OEM inline code): - gpg_card_factory_reset(): factory-reset + forcesig + key-attr (RSA and ECC/P-256), parameterized on admin PIN - gpg_keytocard_subkeys(): enable USB, verify card, move subkeys to slots 1-3 (sign, encrypt, auth) - gpg_set_card_identity(): cardholder name and login fields - gpg_reset_nk3_secret_app(): Nitrokey 3 Secrets app reset - gpg_card_change_pin(): GPG User PIN change New reprovision flow (reprovision_smartcard_from_backup()): 10-phase flow: mount LUKS backup -> detect key type -> factory- reset card -> import subkeys -> set identity -> sign /boot -> flash GUI integration: - k option in GPG Management Menu (gpg-gui.sh), always visible - K option in prompt_missing_gpg_key_action (gui-init.sh) - Clean boot wizard: OEM reset, reprovision, or ignore Code quality fixes from review: - Fix 6 sites where $? was clobbered by TRACE_FUNC/DEBUG calls - Replace --passphrase-file with --passphrase-fd 3 3< to avoid leaking PIN through /proc/<pid>/cmdline - Fix algo_code/bit_len extraction: head -1 for multi-key backups - Fix STATUS_OK mount emission: only on success - Fix gpg_reset_nk3_secret_app: return actual error code from hotp_verification, explicit return 0 for non-NK3 - Remove incorrect || [ $? -eq 2 ] patch: gpg --import exit code 2 is a fatal error, not unchanged - Fix pubkey.asc import: check success properly, fall back to keyring export on failure - Fix partition derivation for NVMe/MMC: stable [0-9]+$ regex - Add _luks_cleanup helper for every error return path (replaces broken EXIT trap pattern) - Re-run NK3 Secrets app reset with custom PIN on factory-reset retry - Add chmod 600 on /tmp/secret/gpg_pin - Write backup passphrase to /tmp/secret/backup_pass, use mount-usb.sh --pass-file to avoid argv leak - Shred /tmp/secret/backup_pass on mount success and failure - Shred /tmp/secret/gpg_pin after all GPG operations complete - Limit key_id derivation to first match (head -1) to prevent multi-line values breaking gpg --edit-key calls - Strip trailing <email> from cardholder name when no comment is present in UID line - Reset card_admin_pin to default after factory-reset step so subsequent forcesig/key-attr use the correct PIN - Ensure /tmp/secret exists before writing backup_pass (mkdir -p) - Export public key from keyring instead of referencing mount file: after successful pubkey.asc import, re-export from the keyring to /tmp/reprovision_pubkey.asc rather than pointing PUBKEY at the potentially-stale /media/pubkey.asc - Fix gpg_reset_nk3_secret_app header comment: removes inaccurate "to factory default" phrasing - Remove unused uid_decoded local variable from reprovision_smartcard_from_backup - Fix key_email extraction: add head -1 to prevent multi-line values when UID contains multiple <...> blocks - Fix parent_disk derivation for NVMe/MMC: use p?[0-9]+$ regex the original partition used a p<num> separator and reconstruct the public partition as parent_disk+p2 vs parent_disk+2 accordingly hex fingerprints from gpg --with-colons - Add --pass-file option to mount-usb.sh: use PASS_FILE variable and pass path directly to cryptsetup --key-file instead of reading into PASS and echoing via process substitution, eliminating the argv leak that --pass-file was meant to fix Documentation: - doc/gpg.md, doc/configuring-keys.md, doc/architecture.md: updated for the new recovery path - doc/qemu.md: USB flash drive workflow, hardlink preservation, reprovision test - doc/recovery-shell.md: Authentication and Resetting Config sections Extends PR linuxboot#1515 (2023): authentication via gpg_auth can now be enforced with key material restored from a backup. Tested on Nitrokey Pro 2 (reprovision end-to-end: factory reset, keytocard, PIN change, public key import, flash, reboot, gpg_auth works). Tested on Nitrokey 3 (OEM factory reset creates LUKS backup + provisions dongle). Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…use, add reprovision flow Extract shared OpenPGP smartcard management functions from initrd/bin/oem-factory-reset.sh into initrd/etc/gpg_functions.sh so they can be reused by multiple callers. OEM functions become thin wrappers passing global variables as positional args; the reprovision flow calls the same shared functions to restore GPG subkeys from a LUKS-encrypted backup USB onto a replacement USB Security dongle. Shared functions (replacing OEM inline code): - gpg_card_factory_reset(): factory-reset + forcesig + key-attr (RSA and ECC/P-256), parameterized on admin PIN - gpg_keytocard_subkeys(): enable USB, verify card, move subkeys to slots 1-3 (sign, encrypt, auth) - gpg_set_card_identity(): cardholder name and login fields - gpg_reset_nk3_secret_app(): Nitrokey 3 Secrets app reset - gpg_card_change_pin(): GPG User PIN change New reprovision flow (reprovision_smartcard_from_backup()): 10-phase flow: mount LUKS backup -> detect key type -> factory- reset card -> import subkeys -> set identity -> sign /boot -> flash GUI integration: - k option in GPG Management Menu (gpg-gui.sh), always visible - K option in prompt_missing_gpg_key_action (gui-init.sh) - Clean boot wizard: OEM reset, reprovision, or ignore Code quality fixes from review: - Fix 6 sites where $? was clobbered by TRACE_FUNC/DEBUG calls - Replace --passphrase-file with --passphrase-fd 3 3< to avoid leaking PIN through /proc/<pid>/cmdline - Fix algo_code/bit_len extraction: head -1 for multi-key backups - Fix STATUS_OK mount emission: only on success - Fix gpg_reset_nk3_secret_app: return actual error code from hotp_verification, explicit return 0 for non-NK3 - Remove incorrect || [ $? -eq 2 ] patch: gpg --import exit code 2 is a fatal error, not unchanged - Fix pubkey.asc import: check success properly, fall back to keyring export on failure - Fix partition derivation for NVMe/MMC: stable [0-9]+$ regex - Add _luks_cleanup helper for every error return path (replaces broken EXIT trap pattern) - Re-run NK3 Secrets app reset with custom PIN on factory-reset retry - Add chmod 600 on /tmp/secret/gpg_pin - Write backup passphrase to /tmp/secret/backup_pass, use mount-usb.sh --pass-file to avoid argv leak - Shred /tmp/secret/backup_pass on mount success and failure - Shred /tmp/secret/gpg_pin after all GPG operations complete - Limit key_id derivation to first match (head -1) to prevent multi-line values breaking gpg --edit-key calls - Strip trailing <email> from cardholder name when no comment is present in UID line - Reset card_admin_pin to default after factory-reset step so subsequent forcesig/key-attr use the correct PIN - Ensure /tmp/secret exists before writing backup_pass (mkdir -p) - Export public key from keyring instead of referencing mount file: after successful pubkey.asc import, re-export from the keyring to /tmp/reprovision_pubkey.asc rather than pointing PUBKEY at the potentially-stale /media/pubkey.asc - Fix gpg_reset_nk3_secret_app header comment: removes inaccurate "to factory default" phrasing - Remove unused uid_decoded local variable from reprovision_smartcard_from_backup - Fix key_email extraction: add head -1 to prevent multi-line values when UID contains multiple <...> blocks - Fix parent_disk derivation for NVMe/MMC: use p?[0-9]+$ regex the original partition used a p<num> separator and reconstruct the public partition as parent_disk+p2 vs parent_disk+2 accordingly hex fingerprints from gpg --with-colons - Add --pass-file option to mount-usb.sh: use PASS_FILE variable and pass path directly to cryptsetup --key-file instead of reading into PASS and echoing via process substitution, eliminating the argv leak that --pass-file was meant to fix Documentation: - doc/gpg.md, doc/configuring-keys.md, doc/architecture.md: updated for the new recovery path - doc/qemu.md: USB flash drive workflow, hardlink preservation, reprovision test - doc/recovery-shell.md: Authentication and Resetting Config sections Extends PR linuxboot#1515 (2023): authentication via gpg_auth can now be enforced with key material restored from a backup. Tested on Nitrokey Pro 2 (reprovision end-to-end: factory reset, keytocard, PIN change, public key import, flash, reboot, gpg_auth works). Tested on Nitrokey 3 (OEM factory reset creates LUKS backup + provisions dongle). Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…use, add reprovision flow Extract shared OpenPGP smartcard management functions from initrd/bin/oem-factory-reset.sh into initrd/etc/gpg_functions.sh so they can be reused by multiple callers. OEM functions become thin wrappers passing global variables as positional args; the reprovision flow calls the same shared functions to restore GPG subkeys from a LUKS-encrypted backup USB onto a replacement USB Security dongle. Shared functions (replacing OEM inline code): - gpg_card_factory_reset(): factory-reset + forcesig + key-attr (RSA and ECC/P-256), parameterized on admin PIN - gpg_keytocard_subkeys(): enable USB, verify card, move subkeys to slots 1-3 (sign, encrypt, auth) - gpg_set_card_identity(): cardholder name and login fields - gpg_reset_nk3_secret_app(): Nitrokey 3 Secrets app reset - gpg_card_change_pin(): GPG User PIN change New reprovision flow (reprovision_smartcard_from_backup()): 10-phase flow: mount LUKS backup -> detect key type -> factory- reset card -> import subkeys -> set identity -> sign /boot -> flash GUI integration: - k option in GPG Management Menu (gpg-gui.sh), always visible - K option in prompt_missing_gpg_key_action (gui-init.sh) - Clean boot wizard: OEM reset, reprovision, or ignore Code quality fixes from review: - Fix 6 sites where $? was clobbered by TRACE_FUNC/DEBUG calls - Replace --passphrase-file with --passphrase-fd 3 3< to avoid leaking PIN through /proc/<pid>/cmdline - Fix algo_code/bit_len extraction: head -1 for multi-key backups - Fix STATUS_OK mount emission: only on success - Fix gpg_reset_nk3_secret_app: return actual error code from hotp_verification, explicit return 0 for non-NK3 - Remove incorrect || [ $? -eq 2 ] patch: gpg --import exit code 2 is a fatal error, not unchanged - Fix pubkey.asc import: check success properly, fall back to keyring export on failure - Fix partition derivation for NVMe/MMC: stable [0-9]+$ regex - Add _luks_cleanup helper for every error return path (replaces broken EXIT trap pattern) - Re-run NK3 Secrets app reset with custom PIN on factory-reset retry - Add chmod 600 on /tmp/secret/gpg_pin - Write backup passphrase to /tmp/secret/backup_pass, use mount-usb.sh --pass-file to avoid argv leak - Shred /tmp/secret/backup_pass on mount success and failure - Shred /tmp/secret/gpg_pin after all GPG operations complete - Limit key_id derivation to first match (head -1) to prevent multi-line values breaking gpg --edit-key calls - Strip trailing <email> from cardholder name when no comment is present in UID line - Reset card_admin_pin to default after factory-reset step so subsequent forcesig/key-attr use the correct PIN - Ensure /tmp/secret exists before writing backup_pass (mkdir -p) - Export public key from keyring instead of referencing mount file: after successful pubkey.asc import, re-export from the keyring to /tmp/reprovision_pubkey.asc rather than pointing PUBKEY at the potentially-stale /media/pubkey.asc - Fix gpg_reset_nk3_secret_app header comment: removes inaccurate "to factory default" phrasing - Remove unused uid_decoded local variable from reprovision_smartcard_from_backup - Fix key_email extraction: add head -1 to prevent multi-line values when UID contains multiple <...> blocks - Fix parent_disk derivation for NVMe/MMC: use p?[0-9]+$ regex the original partition used a p<num> separator and reconstruct the public partition as parent_disk+p2 vs parent_disk+2 accordingly hex fingerprints from gpg --with-colons - Add --pass-file option to mount-usb.sh: use PASS_FILE variable and pass path directly to cryptsetup --key-file instead of reading into PASS and echoing via process substitution, eliminating the argv leak that --pass-file was meant to fix Documentation: - doc/gpg.md, doc/configuring-keys.md, doc/architecture.md: updated for the new recovery path - doc/qemu.md: USB flash drive workflow, hardlink preservation, reprovision test - doc/recovery-shell.md: Authentication and Resetting Config sections Extends PR linuxboot#1515 (2023): authentication via gpg_auth can now be enforced with key material restored from a backup. Tested on Nitrokey Pro 2 (reprovision end-to-end: factory reset, keytocard, PIN change, public key import, flash, reboot, gpg_auth works). Tested on Nitrokey 3 (OEM factory reset creates LUKS backup + provisions dongle). Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…use, add reprovision flow Extract shared OpenPGP smartcard management functions from initrd/bin/oem-factory-reset.sh into initrd/etc/gpg_functions.sh so they can be reused by multiple callers. OEM functions become thin wrappers passing global variables as positional args; the reprovision flow calls the same shared functions to restore GPG subkeys from a LUKS-encrypted backup USB onto a replacement USB Security dongle. Shared functions (replacing OEM inline code): - gpg_card_factory_reset(): factory-reset + forcesig + key-attr (RSA and ECC/P-256), parameterized on admin PIN - gpg_keytocard_subkeys(): enable USB, verify card, move subkeys to slots 1-3 (sign, encrypt, auth) - gpg_set_card_identity(): cardholder name and login fields - gpg_reset_nk3_secret_app(): Nitrokey 3 Secrets app reset - gpg_card_change_pin(): GPG User PIN change New reprovision flow (reprovision_smartcard_from_backup()): 10-phase flow: mount LUKS backup -> detect key type -> factory- reset card -> import subkeys -> set identity -> sign /boot -> flash GUI integration: - k option in GPG Management Menu (gpg-gui.sh), always visible - K option in prompt_missing_gpg_key_action (gui-init.sh) - Clean boot wizard: OEM reset, reprovision, or ignore Code quality fixes from review: - Fix 6 sites where $? was clobbered by TRACE_FUNC/DEBUG calls - Replace --passphrase-file with --passphrase-fd 3 3< to avoid leaking PIN through /proc/<pid>/cmdline - Fix algo_code/bit_len extraction: head -1 for multi-key backups - Fix STATUS_OK mount emission: only on success - Fix gpg_reset_nk3_secret_app: return actual error code from hotp_verification, explicit return 0 for non-NK3 - Remove incorrect || [ $? -eq 2 ] patch: gpg --import exit code 2 is a fatal error, not unchanged - Fix pubkey.asc import: check success properly, fall back to keyring export on failure - Fix partition derivation for NVMe/MMC: stable [0-9]+$ regex - Add _luks_cleanup helper for every error return path (replaces broken EXIT trap pattern) - Re-run NK3 Secrets app reset with custom PIN on factory-reset retry - Add chmod 600 on /tmp/secret/gpg_pin - Write backup passphrase to /tmp/secret/backup_pass, use mount-usb.sh --pass-file to avoid argv leak - Shred /tmp/secret/backup_pass on mount success and failure - Shred /tmp/secret/gpg_pin after all GPG operations complete - Limit key_id derivation to first match (head -1) to prevent multi-line values breaking gpg --edit-key calls - Strip trailing <email> from cardholder name when no comment is present in UID line - Reset card_admin_pin to default after factory-reset step so subsequent forcesig/key-attr use the correct PIN - Ensure /tmp/secret exists before writing backup_pass (mkdir -p) - Export public key from keyring instead of referencing mount file: after successful pubkey.asc import, re-export from the keyring to /tmp/reprovision_pubkey.asc rather than pointing PUBKEY at the potentially-stale /media/pubkey.asc - Fix gpg_reset_nk3_secret_app header comment: removes inaccurate "to factory default" phrasing - Remove unused uid_decoded local variable from reprovision_smartcard_from_backup - Fix key_email extraction: add head -1 to prevent multi-line values when UID contains multiple <...> blocks - Fix parent_disk derivation for NVMe/MMC: use p?[0-9]+$ regex the original partition used a p<num> separator and reconstruct the public partition as parent_disk+p2 vs parent_disk+2 accordingly hex fingerprints from gpg --with-colons - Add --pass-file option to mount-usb.sh: use PASS_FILE variable and pass path directly to cryptsetup --key-file instead of reading into PASS and echoing via process substitution, eliminating the argv leak that --pass-file was meant to fix Documentation: - doc/gpg.md, doc/configuring-keys.md, doc/architecture.md: updated for the new recovery path - doc/qemu.md: USB flash drive workflow, hardlink preservation, reprovision test - doc/recovery-shell.md: Authentication and Resetting Config sections Extends PR linuxboot#1515 (2023): authentication via gpg_auth can now be enforced with key material restored from a backup. Tested on Nitrokey Pro 2 (reprovision end-to-end: factory reset, keytocard, PIN change, public key import, flash, reboot, gpg_auth works). Tested on Nitrokey 3 (OEM factory reset creates LUKS backup + provisions dongle). Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…use, add reprovision flow Extract shared OpenPGP smartcard management functions from initrd/bin/oem-factory-reset.sh into initrd/etc/gpg_functions.sh so they can be reused by multiple callers. OEM functions become thin wrappers passing global variables as positional args; the reprovision flow calls the same shared functions to restore GPG subkeys from a LUKS-encrypted backup USB onto a replacement USB Security dongle. Shared functions (replacing OEM inline code): - gpg_card_factory_reset(): factory-reset + forcesig + key-attr (RSA and ECC/P-256), parameterized on admin PIN - gpg_keytocard_subkeys(): enable USB, verify card, move subkeys to slots 1-3 (sign, encrypt, auth) - gpg_set_card_identity(): cardholder name and login fields - gpg_reset_nk3_secret_app(): Nitrokey 3 Secrets app reset - gpg_card_change_pin(): GPG User PIN change New reprovision flow (reprovision_smartcard_from_backup()): 10-phase flow: mount LUKS backup -> detect key type -> factory- reset card -> import subkeys -> set identity -> sign /boot -> flash GUI integration: - k option in GPG Management Menu (gpg-gui.sh), always visible - K option in prompt_missing_gpg_key_action (gui-init.sh) - Clean boot wizard: OEM reset, reprovision, or ignore Code quality fixes from review: - Fix 6 sites where $? was clobbered by TRACE_FUNC/DEBUG calls - Replace --passphrase-file with --passphrase-fd 3 3< to avoid leaking PIN through /proc/<pid>/cmdline - Fix algo_code/bit_len extraction: head -1 for multi-key backups - Fix STATUS_OK mount emission: only on success - Fix gpg_reset_nk3_secret_app: return actual error code from hotp_verification, explicit return 0 for non-NK3 - Remove incorrect || [ $? -eq 2 ] patch: gpg --import exit code 2 is a fatal error, not unchanged - Fix pubkey.asc import: check success properly, fall back to keyring export on failure - Fix partition derivation for NVMe/MMC: stable [0-9]+$ regex - Add _luks_cleanup helper for every error return path (replaces broken EXIT trap pattern) - Re-run NK3 Secrets app reset with custom PIN on factory-reset retry - Add chmod 600 on /tmp/secret/gpg_pin - Write backup passphrase to /tmp/secret/backup_pass, use mount-usb.sh --pass-file to avoid argv leak - Shred /tmp/secret/backup_pass on mount success and failure - Shred /tmp/secret/gpg_pin after all GPG operations complete - Limit key_id derivation to first match (head -1) to prevent multi-line values breaking gpg --edit-key calls - Strip trailing <email> from cardholder name when no comment is present in UID line - Reset card_admin_pin to default after factory-reset step so subsequent forcesig/key-attr use the correct PIN - Ensure /tmp/secret exists before writing backup_pass (mkdir -p) - Export public key from keyring instead of referencing mount file: after successful pubkey.asc import, re-export from the keyring to /tmp/reprovision_pubkey.asc rather than pointing PUBKEY at the potentially-stale /media/pubkey.asc - Fix gpg_reset_nk3_secret_app header comment: removes inaccurate "to factory default" phrasing - Remove unused uid_decoded local variable from reprovision_smartcard_from_backup - Fix key_email extraction: add head -1 to prevent multi-line values when UID contains multiple <...> blocks - Fix parent_disk derivation for NVMe/MMC: use p?[0-9]+$ regex the original partition used a p<num> separator and reconstruct the public partition as parent_disk+p2 vs parent_disk+2 accordingly hex fingerprints from gpg --with-colons - Add --pass-file option to mount-usb.sh: use PASS_FILE variable and pass path directly to cryptsetup --key-file instead of reading into PASS and echoing via process substitution, eliminating the argv leak that --pass-file was meant to fix Documentation: - doc/gpg.md, doc/configuring-keys.md, doc/architecture.md: updated for the new recovery path - doc/qemu.md: USB flash drive workflow, hardlink preservation, reprovision test - doc/recovery-shell.md: Authentication and Resetting Config sections Extends PR linuxboot#1515 (2023): authentication via gpg_auth can now be enforced with key material restored from a backup. Tested on Nitrokey Pro 2 (reprovision end-to-end: factory reset, keytocard, PIN change, public key import, flash, reboot, gpg_auth works). Tested on Nitrokey 3 (OEM factory reset creates LUKS backup + provisions dongle). Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…use, add reprovision flow Extract shared OpenPGP smartcard management functions from initrd/bin/oem-factory-reset.sh into initrd/etc/gpg_functions.sh so they can be reused by multiple callers. OEM functions become thin wrappers passing global variables as positional args; the reprovision flow calls the same shared functions to restore GPG subkeys from a LUKS-encrypted backup USB onto a replacement USB Security dongle. Shared functions (replacing OEM inline code): - gpg_card_factory_reset(): factory-reset + forcesig + key-attr (RSA and ECC/P-256), parameterized on admin PIN - gpg_keytocard_subkeys(): enable USB, verify card, move subkeys to slots 1-3 (sign, encrypt, auth) - gpg_set_card_identity(): cardholder name and login fields - gpg_reset_nk3_secret_app(): Nitrokey 3 Secrets app reset - gpg_card_change_pin(): GPG User PIN change New reprovision flow (reprovision_smartcard_from_backup()): 10-phase flow: mount LUKS backup -> detect key type -> factory- reset card -> import subkeys -> set identity -> sign /boot -> flash GUI integration: - k option in GPG Management Menu (gpg-gui.sh), always visible - K option in prompt_missing_gpg_key_action (gui-init.sh) - Clean boot wizard: OEM reset, reprovision, or ignore Code quality fixes from review: - Fix 6 sites where $? was clobbered by TRACE_FUNC/DEBUG calls - Replace --passphrase-file with --passphrase-fd 3 3< to avoid leaking PIN through /proc/<pid>/cmdline - Fix algo_code/bit_len extraction: head -1 for multi-key backups - Fix STATUS_OK mount emission: only on success - Fix gpg_reset_nk3_secret_app: return actual error code from hotp_verification, explicit return 0 for non-NK3 - Remove incorrect || [ $? -eq 2 ] patch: gpg --import exit code 2 is a fatal error, not unchanged - Fix pubkey.asc import: check success properly, fall back to keyring export on failure - Fix partition derivation for NVMe/MMC: stable [0-9]+$ regex - Add _luks_cleanup helper for every error return path (replaces broken EXIT trap pattern) - Re-run NK3 Secrets app reset with custom PIN on factory-reset retry - Add chmod 600 on /tmp/secret/gpg_pin - Write backup passphrase to /tmp/secret/backup_pass, use mount-usb.sh --pass-file to avoid argv leak - Shred /tmp/secret/backup_pass on mount success and failure - Shred /tmp/secret/gpg_pin after all GPG operations complete - Limit key_id derivation to first match (head -1) to prevent multi-line values breaking gpg --edit-key calls - Strip trailing <email> from cardholder name when no comment is present in UID line - Reset card_admin_pin to default after factory-reset step so subsequent forcesig/key-attr use the correct PIN - Ensure /tmp/secret exists before writing backup_pass (mkdir -p) - Export public key from keyring instead of referencing mount file: after successful pubkey.asc import, re-export from the keyring to /tmp/reprovision_pubkey.asc rather than pointing PUBKEY at the potentially-stale /media/pubkey.asc - Fix gpg_reset_nk3_secret_app header comment: removes inaccurate "to factory default" phrasing - Remove unused uid_decoded local variable from reprovision_smartcard_from_backup - Fix key_email extraction: add head -1 to prevent multi-line values when UID contains multiple <...> blocks - Fix parent_disk derivation for NVMe/MMC: use p?[0-9]+$ regex the original partition used a p<num> separator and reconstruct the public partition as parent_disk+p2 vs parent_disk+2 accordingly hex fingerprints from gpg --with-colons - Add --pass-file option to mount-usb.sh: use PASS_FILE variable and pass path directly to cryptsetup --key-file instead of reading into PASS and echoing via process substitution, eliminating the argv leak that --pass-file was meant to fix Documentation: - doc/gpg.md, doc/configuring-keys.md, doc/architecture.md: updated for the new recovery path - doc/qemu.md: USB flash drive workflow, hardlink preservation, reprovision test - doc/recovery-shell.md: Authentication and Resetting Config sections Extends PR linuxboot#1515 (2023): authentication via gpg_auth can now be enforced with key material restored from a backup. Tested on Nitrokey Pro 2 (reprovision end-to-end: factory reset, keytocard, PIN change, public key import, flash, reboot, gpg_auth works). Tested on Nitrokey 3 (OEM factory reset creates LUKS backup + provisions dongle). Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…use, add reprovision flow Extract shared OpenPGP smartcard management functions from initrd/bin/oem-factory-reset.sh into initrd/etc/gpg_functions.sh so they can be reused by multiple callers. OEM functions become thin wrappers passing global variables as positional args; the reprovision flow calls the same shared functions to restore GPG subkeys from a LUKS-encrypted backup USB onto a replacement USB Security dongle. Shared functions (replacing OEM inline code): - gpg_card_factory_reset(): factory-reset + forcesig + key-attr (RSA and ECC/P-256), parameterized on admin PIN - gpg_keytocard_subkeys(): enable USB, verify card, move subkeys to slots 1-3 (sign, encrypt, auth) - gpg_set_card_identity(): cardholder name and login fields - gpg_reset_nk3_secret_app(): Nitrokey 3 Secrets app reset - gpg_card_change_pin(): GPG User PIN change New reprovision flow (reprovision_smartcard_from_backup()): 10-phase flow: mount LUKS backup -> detect key type -> factory- reset card -> import subkeys -> set identity -> sign /boot -> flash GUI integration: - k option in GPG Management Menu (gpg-gui.sh), always visible - K option in prompt_missing_gpg_key_action (gui-init.sh) - Clean boot wizard: OEM reset, reprovision, or ignore Code quality fixes from review: - Fix 6 sites where $? was clobbered by TRACE_FUNC/DEBUG calls - Replace --passphrase-file with --passphrase-fd 3 3< to avoid leaking PIN through /proc/<pid>/cmdline - Fix algo_code/bit_len extraction: head -1 for multi-key backups - Fix STATUS_OK mount emission: only on success - Fix gpg_reset_nk3_secret_app: return actual error code from hotp_verification, explicit return 0 for non-NK3 - Remove incorrect || [ $? -eq 2 ] patch: gpg --import exit code 2 is a fatal error, not unchanged - Fix pubkey.asc import: check success properly, fall back to keyring export on failure - Fix partition derivation for NVMe/MMC: stable [0-9]+$ regex - Add _luks_cleanup helper for every error return path (replaces broken EXIT trap pattern) - Re-run NK3 Secrets app reset with custom PIN on factory-reset retry - Add chmod 600 on /tmp/secret/gpg_pin - Write backup passphrase to /tmp/secret/backup_pass, use mount-usb.sh --pass-file to avoid argv leak - Shred /tmp/secret/backup_pass on mount success and failure - Shred /tmp/secret/gpg_pin after all GPG operations complete - Limit key_id derivation to first match (head -1) to prevent multi-line values breaking gpg --edit-key calls - Strip trailing <email> from cardholder name when no comment is present in UID line - Reset card_admin_pin to default after factory-reset step so subsequent forcesig/key-attr use the correct PIN - Ensure /tmp/secret exists before writing backup_pass (mkdir -p) - Export public key from keyring instead of referencing mount file: after successful pubkey.asc import, re-export from the keyring to /tmp/reprovision_pubkey.asc rather than pointing PUBKEY at the potentially-stale /media/pubkey.asc - Fix gpg_reset_nk3_secret_app header comment: removes inaccurate "to factory default" phrasing - Remove unused uid_decoded local variable from reprovision_smartcard_from_backup - Fix key_email extraction: add head -1 to prevent multi-line values when UID contains multiple <...> blocks - Fix parent_disk derivation for NVMe/MMC: use p?[0-9]+$ regex the original partition used a p<num> separator and reconstruct the public partition as parent_disk+p2 vs parent_disk+2 accordingly hex fingerprints from gpg --with-colons - Add --pass-file option to mount-usb.sh: use PASS_FILE variable and pass path directly to cryptsetup --key-file instead of reading into PASS and echoing via process substitution, eliminating the argv leak that --pass-file was meant to fix Documentation: - doc/gpg.md, doc/configuring-keys.md, doc/architecture.md: updated for the new recovery path - doc/qemu.md: USB flash drive workflow, hardlink preservation, reprovision test - doc/recovery-shell.md: Authentication and Resetting Config sections Extends PR linuxboot#1515 (2023): authentication via gpg_auth can now be enforced with key material restored from a backup. Tested on Nitrokey Pro 2 (reprovision end-to-end: factory reset, keytocard, PIN change, public key import, flash, reboot, gpg_auth works). Tested on Nitrokey 3 (OEM factory reset creates LUKS backup + provisions dongle). Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…use, add reprovision flow Extract shared OpenPGP smartcard management functions from initrd/bin/oem-factory-reset.sh into initrd/etc/gpg_functions.sh so they can be reused by multiple callers. OEM functions become thin wrappers passing global variables as positional args; the reprovision flow calls the same shared functions to restore GPG subkeys from a LUKS-encrypted backup USB onto a replacement USB Security dongle. Shared functions (replacing OEM inline code): - gpg_card_factory_reset(): factory-reset + forcesig + key-attr (RSA and ECC/P-256), parameterized on admin PIN - gpg_keytocard_subkeys(): enable USB, verify card, move subkeys to slots 1-3 (sign, encrypt, auth) - gpg_set_card_identity(): cardholder name and login fields - gpg_reset_nk3_secret_app(): Nitrokey 3 Secrets app reset - gpg_card_change_pin(): GPG User PIN change New reprovision flow (reprovision_smartcard_from_backup()): 10-phase flow: mount LUKS backup -> detect key type -> factory- reset card -> import subkeys -> set identity -> sign /boot -> flash GUI integration: - k option in GPG Management Menu (gpg-gui.sh), always visible - K option in prompt_missing_gpg_key_action (gui-init.sh) - Clean boot wizard: OEM reset, reprovision, or ignore Code quality fixes from review: - Fix 6 sites where $? was clobbered by TRACE_FUNC/DEBUG calls - Replace --passphrase-file with --passphrase-fd 3 3< to avoid leaking PIN through /proc/<pid>/cmdline - Fix algo_code/bit_len extraction: head -1 for multi-key backups - Fix STATUS_OK mount emission: only on success - Fix gpg_reset_nk3_secret_app: return actual error code from hotp_verification, explicit return 0 for non-NK3 - Remove incorrect || [ $? -eq 2 ] patch: gpg --import exit code 2 is a fatal error, not unchanged - Fix pubkey.asc import: check success properly, fall back to keyring export on failure - Fix partition derivation for NVMe/MMC: stable [0-9]+$ regex - Add _luks_cleanup helper for every error return path (replaces broken EXIT trap pattern) - Re-run NK3 Secrets app reset with custom PIN on factory-reset retry - Add chmod 600 on /tmp/secret/gpg_pin - Write backup passphrase to /tmp/secret/backup_pass, use mount-usb.sh --pass-file to avoid argv leak - Shred /tmp/secret/backup_pass on mount success and failure - Shred /tmp/secret/gpg_pin after all GPG operations complete - Limit key_id derivation to first match (head -1) to prevent multi-line values breaking gpg --edit-key calls - Strip trailing <email> from cardholder name when no comment is present in UID line - Reset card_admin_pin to default after factory-reset step so subsequent forcesig/key-attr use the correct PIN - Ensure /tmp/secret exists before writing backup_pass (mkdir -p) - Export public key from keyring instead of referencing mount file: after successful pubkey.asc import, re-export from the keyring to /tmp/reprovision_pubkey.asc rather than pointing PUBKEY at the potentially-stale /media/pubkey.asc - Fix gpg_reset_nk3_secret_app header comment: removes inaccurate "to factory default" phrasing - Remove unused uid_decoded local variable from reprovision_smartcard_from_backup - Fix key_email extraction: add head -1 to prevent multi-line values when UID contains multiple <...> blocks - Fix parent_disk derivation for NVMe/MMC: use p?[0-9]+$ regex the original partition used a p<num> separator and reconstruct the public partition as parent_disk+p2 vs parent_disk+2 accordingly hex fingerprints from gpg --with-colons - Add --pass-file option to mount-usb.sh: use PASS_FILE variable and pass path directly to cryptsetup --key-file instead of reading into PASS and echoing via process substitution, eliminating the argv leak that --pass-file was meant to fix Documentation: - doc/gpg.md, doc/configuring-keys.md, doc/architecture.md: updated for the new recovery path - doc/qemu.md: USB flash drive workflow, hardlink preservation, reprovision test - doc/recovery-shell.md: Authentication and Resetting Config sections Extends PR linuxboot#1515 (2023): authentication via gpg_auth can now be enforced with key material restored from a backup. Tested on Nitrokey Pro 2 (reprovision end-to-end: factory reset, keytocard, PIN change, public key import, flash, reboot, gpg_auth works). Tested on Nitrokey 3 (OEM factory reset creates LUKS backup + provisions dongle). Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…use, add reprovision flow Extract shared OpenPGP smartcard management functions from initrd/bin/oem-factory-reset.sh into initrd/etc/gpg_functions.sh so they can be reused by multiple callers. OEM functions become thin wrappers passing global variables as positional args; the reprovision flow calls the same shared functions to restore GPG subkeys from a LUKS-encrypted backup USB onto a replacement USB Security dongle. Shared functions (replacing OEM inline code): - gpg_card_factory_reset(): factory-reset + forcesig + key-attr (RSA and ECC/P-256), parameterized on admin PIN - gpg_keytocard_subkeys(): enable USB, verify card, move subkeys to slots 1-3 (sign, encrypt, auth) - gpg_set_card_identity(): cardholder name and login fields - gpg_reset_nk3_secret_app(): Nitrokey 3 Secrets app reset - gpg_card_change_pin(): GPG User PIN change New reprovision flow (reprovision_smartcard_from_backup()): 10-phase flow: mount LUKS backup -> detect key type -> factory- reset card -> import subkeys -> set identity -> sign /boot -> flash GUI integration: - k option in GPG Management Menu (gpg-gui.sh), always visible - K option in prompt_missing_gpg_key_action (gui-init.sh) - Clean boot wizard: OEM reset, reprovision, or ignore Code quality fixes from review: - Fix 6 sites where $? was clobbered by TRACE_FUNC/DEBUG calls - Replace --passphrase-file with --passphrase-fd 3 3< to avoid leaking PIN through /proc/<pid>/cmdline - Fix algo_code/bit_len extraction: head -1 for multi-key backups - Fix STATUS_OK mount emission: only on success - Fix gpg_reset_nk3_secret_app: return actual error code from hotp_verification, explicit return 0 for non-NK3 - Remove incorrect || [ $? -eq 2 ] patch: gpg --import exit code 2 is a fatal error, not unchanged - Fix pubkey.asc import: check success properly, fall back to keyring export on failure - Fix partition derivation for NVMe/MMC: stable [0-9]+$ regex - Add _luks_cleanup helper for every error return path (replaces broken EXIT trap pattern) - Re-run NK3 Secrets app reset with custom PIN on factory-reset retry - Add chmod 600 on /tmp/secret/gpg_pin - Write backup passphrase to /tmp/secret/backup_pass, use mount-usb.sh --pass-file to avoid argv leak - Shred /tmp/secret/backup_pass on mount success and failure - Shred /tmp/secret/gpg_pin after all GPG operations complete - Limit key_id derivation to first match (head -1) to prevent multi-line values breaking gpg --edit-key calls - Strip trailing <email> from cardholder name when no comment is present in UID line - Reset card_admin_pin to default after factory-reset step so subsequent forcesig/key-attr use the correct PIN - Ensure /tmp/secret exists before writing backup_pass (mkdir -p) - Export public key from keyring instead of referencing mount file: after successful pubkey.asc import, re-export from the keyring to /tmp/reprovision_pubkey.asc rather than pointing PUBKEY at the potentially-stale /media/pubkey.asc - Fix gpg_reset_nk3_secret_app header comment: removes inaccurate "to factory default" phrasing - Remove unused uid_decoded local variable from reprovision_smartcard_from_backup - Fix key_email extraction: add head -1 to prevent multi-line values when UID contains multiple <...> blocks - Fix parent_disk derivation for NVMe/MMC: use p?[0-9]+$ regex the original partition used a p<num> separator and reconstruct the public partition as parent_disk+p2 vs parent_disk+2 accordingly hex fingerprints from gpg --with-colons - Add --pass-file option to mount-usb.sh: use PASS_FILE variable and pass path directly to cryptsetup --key-file instead of reading into PASS and echoing via process substitution, eliminating the argv leak that --pass-file was meant to fix Documentation: - doc/gpg.md, doc/configuring-keys.md, doc/architecture.md: updated for the new recovery path - doc/qemu.md: USB flash drive workflow, hardlink preservation, reprovision test - doc/recovery-shell.md: Authentication and Resetting Config sections Extends PR linuxboot#1515 (2023): authentication via gpg_auth can now be enforced with key material restored from a backup. Tested on Nitrokey Pro 2 (reprovision end-to-end: factory reset, keytocard, PIN change, public key import, flash, reboot, gpg_auth works). Tested on Nitrokey 3 (OEM factory reset creates LUKS backup + provisions dongle). Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…use, add reprovision flow Extract shared OpenPGP smartcard management functions from initrd/bin/oem-factory-reset.sh into initrd/etc/gpg_functions.sh so they can be reused by multiple callers. OEM functions become thin wrappers passing global variables as positional args; the reprovision flow calls the same shared functions to restore GPG subkeys from a LUKS-encrypted backup USB onto a replacement USB Security dongle. Shared functions (replacing OEM inline code): - gpg_card_factory_reset(): factory-reset + forcesig + key-attr (RSA and ECC/P-256), parameterized on admin PIN - gpg_keytocard_subkeys(): enable USB, verify card, move subkeys to slots 1-3 (sign, encrypt, auth) - gpg_set_card_identity(): cardholder name and login fields - gpg_reset_nk3_secret_app(): Nitrokey 3 Secrets app reset - gpg_card_change_pin(): GPG User PIN change New reprovision flow (reprovision_smartcard_from_backup()): 10-phase flow: mount LUKS backup -> detect key type -> factory- reset card -> import subkeys -> set identity -> sign /boot -> flash GUI integration: - k option in GPG Management Menu (gpg-gui.sh), always visible - K option in prompt_missing_gpg_key_action (gui-init.sh) - Clean boot wizard: OEM reset, reprovision, or ignore Code quality fixes from review: - Fix 6 sites where $? was clobbered by TRACE_FUNC/DEBUG calls - Replace --passphrase-file with --passphrase-fd 3 3< to avoid leaking PIN through /proc/<pid>/cmdline - Fix algo_code/bit_len extraction: head -1 for multi-key backups - Fix STATUS_OK mount emission: only on success - Fix gpg_reset_nk3_secret_app: return actual error code from hotp_verification, explicit return 0 for non-NK3 - Remove incorrect || [ $? -eq 2 ] patch: gpg --import exit code 2 is a fatal error, not unchanged - Fix pubkey.asc import: check success properly, fall back to keyring export on failure - Fix partition derivation for NVMe/MMC: stable [0-9]+$ regex - Add _luks_cleanup helper for every error return path (replaces broken EXIT trap pattern) - Re-run NK3 Secrets app reset with custom PIN on factory-reset retry - Add chmod 600 on /tmp/secret/gpg_pin - Write backup passphrase to /tmp/secret/backup_pass, use mount-usb.sh --pass-file to avoid argv leak - Shred /tmp/secret/backup_pass on mount success and failure - Shred /tmp/secret/gpg_pin after all GPG operations complete - Limit key_id derivation to first match (head -1) to prevent multi-line values breaking gpg --edit-key calls - Strip trailing <email> from cardholder name when no comment is present in UID line - Reset card_admin_pin to default after factory-reset step so subsequent forcesig/key-attr use the correct PIN - Ensure /tmp/secret exists before writing backup_pass (mkdir -p) - Export public key from keyring instead of referencing mount file: after successful pubkey.asc import, re-export from the keyring to /tmp/reprovision_pubkey.asc rather than pointing PUBKEY at the potentially-stale /media/pubkey.asc - Fix gpg_reset_nk3_secret_app header comment: removes inaccurate "to factory default" phrasing - Remove unused uid_decoded local variable from reprovision_smartcard_from_backup - Fix key_email extraction: add head -1 to prevent multi-line values when UID contains multiple <...> blocks - Fix parent_disk derivation for NVMe/MMC: use p?[0-9]+$ regex the original partition used a p<num> separator and reconstruct the public partition as parent_disk+p2 vs parent_disk+2 accordingly hex fingerprints from gpg --with-colons - Add --pass-file option to mount-usb.sh: use PASS_FILE variable and pass path directly to cryptsetup --key-file instead of reading into PASS and echoing via process substitution, eliminating the argv leak that --pass-file was meant to fix Documentation: - doc/gpg.md, doc/configuring-keys.md, doc/architecture.md: updated for the new recovery path - doc/qemu.md: USB flash drive workflow, hardlink preservation, reprovision test - doc/recovery-shell.md: Authentication and Resetting Config sections Extends PR linuxboot#1515 (2023): authentication via gpg_auth can now be enforced with key material restored from a backup. Tested on Nitrokey Pro 2 (reprovision end-to-end: factory reset, keytocard, PIN change, public key import, flash, reboot, gpg_auth works). Tested on Nitrokey 3 (OEM factory reset creates LUKS backup + provisions dongle). Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…use, add reprovision flow Extract shared OpenPGP smartcard management functions from initrd/bin/oem-factory-reset.sh into initrd/etc/gpg_functions.sh so they can be reused by multiple callers. OEM functions become thin wrappers passing global variables as positional args; the reprovision flow calls the same shared functions to restore GPG subkeys from a LUKS-encrypted backup USB onto a replacement USB Security dongle. Shared functions (replacing OEM inline code): - gpg_card_factory_reset(): factory-reset + forcesig + key-attr (RSA and ECC/P-256), parameterized on admin PIN - gpg_keytocard_subkeys(): enable USB, verify card, move subkeys to slots 1-3 (sign, encrypt, auth) - gpg_set_card_identity(): cardholder name and login fields - gpg_reset_nk3_secret_app(): Nitrokey 3 Secrets app reset - gpg_card_change_pin(): GPG User PIN change New reprovision flow (reprovision_smartcard_from_backup()): 10-phase flow: mount LUKS backup -> detect key type -> factory- reset card -> import subkeys -> set identity -> sign /boot -> flash GUI integration: - k option in GPG Management Menu (gpg-gui.sh), always visible - K option in prompt_missing_gpg_key_action (gui-init.sh) - Clean boot wizard: OEM reset, reprovision, or ignore Code quality fixes from review: - Fix 6 sites where $? was clobbered by TRACE_FUNC/DEBUG calls - Replace --passphrase-file with --passphrase-fd 3 3< to avoid leaking PIN through /proc/<pid>/cmdline - Fix algo_code/bit_len extraction: head -1 for multi-key backups - Fix STATUS_OK mount emission: only on success - Fix gpg_reset_nk3_secret_app: return actual error code from hotp_verification, explicit return 0 for non-NK3 - Remove incorrect || [ $? -eq 2 ] patch: gpg --import exit code 2 is a fatal error, not unchanged - Fix pubkey.asc import: check success properly, fall back to keyring export on failure - Fix partition derivation for NVMe/MMC: stable [0-9]+$ regex - Add _luks_cleanup helper for every error return path (replaces broken EXIT trap pattern) - Re-run NK3 Secrets app reset with custom PIN on factory-reset retry - Add chmod 600 on /tmp/secret/gpg_pin - Write backup passphrase to /tmp/secret/backup_pass, use mount-usb.sh --pass-file to avoid argv leak - Shred /tmp/secret/backup_pass on mount success and failure - Shred /tmp/secret/gpg_pin after all GPG operations complete - Limit key_id derivation to first match (head -1) to prevent multi-line values breaking gpg --edit-key calls - Strip trailing <email> from cardholder name when no comment is present in UID line - Reset card_admin_pin to default after factory-reset step so subsequent forcesig/key-attr use the correct PIN - Ensure /tmp/secret exists before writing backup_pass (mkdir -p) - Export public key from keyring instead of referencing mount file: after successful pubkey.asc import, re-export from the keyring to /tmp/reprovision_pubkey.asc rather than pointing PUBKEY at the potentially-stale /media/pubkey.asc - Fix gpg_reset_nk3_secret_app header comment: removes inaccurate "to factory default" phrasing - Remove unused uid_decoded local variable from reprovision_smartcard_from_backup - Fix key_email extraction: add head -1 to prevent multi-line values when UID contains multiple <...> blocks - Fix parent_disk derivation for NVMe/MMC: use p?[0-9]+$ regex the original partition used a p<num> separator and reconstruct the public partition as parent_disk+p2 vs parent_disk+2 accordingly hex fingerprints from gpg --with-colons - Add --pass-file option to mount-usb.sh: use PASS_FILE variable and pass path directly to cryptsetup --key-file instead of reading into PASS and echoing via process substitution, eliminating the argv leak that --pass-file was meant to fix Documentation: - doc/gpg.md, doc/configuring-keys.md, doc/architecture.md: updated for the new recovery path - doc/qemu.md: USB flash drive workflow, hardlink preservation, reprovision test - doc/recovery-shell.md: Authentication and Resetting Config sections Extends PR linuxboot#1515 (2023): authentication via gpg_auth can now be enforced with key material restored from a backup. Tested on Nitrokey Pro 2 (reprovision end-to-end: factory reset, keytocard, PIN change, public key import, flash, reboot, gpg_auth works). Tested on Nitrokey 3 (OEM factory reset creates LUKS backup + provisions dongle). Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…use, add reprovision flow Extract shared OpenPGP smartcard management functions from initrd/bin/oem-factory-reset.sh into initrd/etc/gpg_functions.sh so they can be reused by multiple callers. OEM functions become thin wrappers passing global variables as positional args; the reprovision flow calls the same shared functions to restore GPG subkeys from a LUKS-encrypted backup USB onto a replacement USB Security dongle. Shared functions (replacing OEM inline code): - gpg_card_factory_reset(): factory-reset + forcesig + key-attr (RSA and ECC/P-256), parameterized on admin PIN - gpg_keytocard_subkeys(): enable USB, verify card, move subkeys to slots 1-3 (sign, encrypt, auth) - gpg_set_card_identity(): cardholder name and login fields - gpg_reset_nk3_secret_app(): Nitrokey 3 Secrets app reset - gpg_card_change_pin(): GPG User PIN change New reprovision flow (reprovision_smartcard_from_backup()): 10-phase flow: mount LUKS backup -> detect key type -> factory- reset card -> import subkeys -> set identity -> sign /boot -> flash GUI integration: - k option in GPG Management Menu (gpg-gui.sh), always visible - K option in prompt_missing_gpg_key_action (gui-init.sh) - Clean boot wizard: OEM reset, reprovision, or ignore Code quality fixes from review: - Fix 6 sites where $? was clobbered by TRACE_FUNC/DEBUG calls - Replace --passphrase-file with --passphrase-fd 3 3< to avoid leaking PIN through /proc/<pid>/cmdline - Fix algo_code/bit_len extraction: head -1 for multi-key backups - Fix STATUS_OK mount emission: only on success - Fix gpg_reset_nk3_secret_app: return actual error code from hotp_verification, explicit return 0 for non-NK3 - Remove incorrect || [ $? -eq 2 ] patch: gpg --import exit code 2 is a fatal error, not unchanged - Fix pubkey.asc import: check success properly, fall back to keyring export on failure - Fix partition derivation for NVMe/MMC: stable [0-9]+$ regex - Add _luks_cleanup helper for every error return path (replaces broken EXIT trap pattern) - Re-run NK3 Secrets app reset with custom PIN on factory-reset retry - Add chmod 600 on /tmp/secret/gpg_pin - Write backup passphrase to /tmp/secret/backup_pass, use mount-usb.sh --pass-file to avoid argv leak - Shred /tmp/secret/backup_pass on mount success and failure - Shred /tmp/secret/gpg_pin after all GPG operations complete - Limit key_id derivation to first match (head -1) to prevent multi-line values breaking gpg --edit-key calls - Strip trailing <email> from cardholder name when no comment is present in UID line - Reset card_admin_pin to default after factory-reset step so subsequent forcesig/key-attr use the correct PIN - Ensure /tmp/secret exists before writing backup_pass (mkdir -p) - Export public key from keyring instead of referencing mount file: after successful pubkey.asc import, re-export from the keyring to /tmp/reprovision_pubkey.asc rather than pointing PUBKEY at the potentially-stale /media/pubkey.asc - Fix gpg_reset_nk3_secret_app header comment: removes inaccurate "to factory default" phrasing - Remove unused uid_decoded local variable from reprovision_smartcard_from_backup - Fix key_email extraction: add head -1 to prevent multi-line values when UID contains multiple <...> blocks - Fix parent_disk derivation for NVMe/MMC: use p?[0-9]+$ regex the original partition used a p<num> separator and reconstruct the public partition as parent_disk+p2 vs parent_disk+2 accordingly hex fingerprints from gpg --with-colons - Add --pass-file option to mount-usb.sh: use PASS_FILE variable and pass path directly to cryptsetup --key-file instead of reading into PASS and echoing via process substitution, eliminating the argv leak that --pass-file was meant to fix Documentation: - doc/gpg.md, doc/configuring-keys.md, doc/architecture.md: updated for the new recovery path - doc/qemu.md: USB flash drive workflow, hardlink preservation, reprovision test - doc/recovery-shell.md: Authentication and Resetting Config sections Extends PR linuxboot#1515 (2023): authentication via gpg_auth can now be enforced with key material restored from a backup. Tested on Nitrokey Pro 2 (reprovision end-to-end: factory reset, keytocard, PIN change, public key import, flash, reboot, gpg_auth works). Tested on Nitrokey 3 (OEM factory reset creates LUKS backup + provisions dongle). Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…use, add reprovision flow Extract shared OpenPGP smartcard management functions from initrd/bin/oem-factory-reset.sh into initrd/etc/gpg_functions.sh so they can be reused by multiple callers. OEM functions become thin wrappers passing global variables as positional args; the reprovision flow calls the same shared functions to restore GPG subkeys from a LUKS-encrypted backup USB onto a replacement USB Security dongle. Shared functions (replacing OEM inline code): - gpg_card_factory_reset(): factory-reset + forcesig + key-attr (RSA and ECC/P-256), parameterized on admin PIN - gpg_keytocard_subkeys(): enable USB, verify card, move subkeys to slots 1-3 (sign, encrypt, auth) - gpg_set_card_identity(): cardholder name and login fields - gpg_reset_nk3_secret_app(): Nitrokey 3 Secrets app reset - gpg_card_change_pin(): GPG User PIN change New reprovision flow (reprovision_smartcard_from_backup()): 10-phase flow: mount LUKS backup -> detect key type -> factory- reset card -> import subkeys -> set identity -> sign /boot -> flash GUI integration: - k option in GPG Management Menu (gpg-gui.sh), always visible - K option in prompt_missing_gpg_key_action (gui-init.sh) - Clean boot wizard: OEM reset, reprovision, or ignore Code quality fixes from review: - Fix 6 sites where $? was clobbered by TRACE_FUNC/DEBUG calls - Replace --passphrase-file with --passphrase-fd 3 3< to avoid leaking PIN through /proc/<pid>/cmdline - Fix algo_code/bit_len extraction: head -1 for multi-key backups - Fix STATUS_OK mount emission: only on success - Fix gpg_reset_nk3_secret_app: return actual error code from hotp_verification, explicit return 0 for non-NK3 - Remove incorrect || [ $? -eq 2 ] patch: gpg --import exit code 2 is a fatal error, not unchanged - Fix pubkey.asc import: check success properly, fall back to keyring export on failure - Fix partition derivation for NVMe/MMC: stable [0-9]+$ regex - Add _luks_cleanup helper for every error return path (replaces broken EXIT trap pattern) - Re-run NK3 Secrets app reset with custom PIN on factory-reset retry - Add chmod 600 on /tmp/secret/gpg_pin - Write backup passphrase to /tmp/secret/backup_pass, use mount-usb.sh --pass-file to avoid argv leak - Shred /tmp/secret/backup_pass on mount success and failure - Shred /tmp/secret/gpg_pin after all GPG operations complete - Limit key_id derivation to first match (head -1) to prevent multi-line values breaking gpg --edit-key calls - Strip trailing <email> from cardholder name when no comment is present in UID line - Reset card_admin_pin to default after factory-reset step so subsequent forcesig/key-attr use the correct PIN - Ensure /tmp/secret exists before writing backup_pass (mkdir -p) - Export public key from keyring instead of referencing mount file: after successful pubkey.asc import, re-export from the keyring to /tmp/reprovision_pubkey.asc rather than pointing PUBKEY at the potentially-stale /media/pubkey.asc - Fix gpg_reset_nk3_secret_app header comment: removes inaccurate "to factory default" phrasing - Remove unused uid_decoded local variable from reprovision_smartcard_from_backup - Fix key_email extraction: add head -1 to prevent multi-line values when UID contains multiple <...> blocks - Fix parent_disk derivation for NVMe/MMC: use p?[0-9]+$ regex the original partition used a p<num> separator and reconstruct the public partition as parent_disk+p2 vs parent_disk+2 accordingly hex fingerprints from gpg --with-colons - Add --pass-file option to mount-usb.sh: use PASS_FILE variable and pass path directly to cryptsetup --key-file instead of reading into PASS and echoing via process substitution, eliminating the argv leak that --pass-file was meant to fix Documentation: - doc/gpg.md, doc/configuring-keys.md, doc/architecture.md: updated for the new recovery path - doc/qemu.md: USB flash drive workflow, hardlink preservation, reprovision test - doc/recovery-shell.md: Authentication and Resetting Config sections Extends PR linuxboot#1515 (2023): authentication via gpg_auth can now be enforced with key material restored from a backup. Tested on Nitrokey Pro 2 (reprovision end-to-end: factory reset, keytocard, PIN change, public key import, flash, reboot, gpg_auth works). Tested on Nitrokey 3 (OEM factory reset creates LUKS backup + provisions dongle). Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…use, add reprovision flow Extract shared OpenPGP smartcard management functions from initrd/bin/oem-factory-reset.sh into initrd/etc/gpg_functions.sh so they can be reused by multiple callers. OEM functions become thin wrappers passing global variables as positional args; the reprovision flow calls the same shared functions to restore GPG subkeys from a LUKS-encrypted backup USB onto a replacement USB Security dongle. Shared functions (replacing OEM inline code): - gpg_card_factory_reset(): factory-reset + forcesig + key-attr (RSA and ECC/P-256), parameterized on admin PIN - gpg_keytocard_subkeys(): enable USB, verify card, move subkeys to slots 1-3 (sign, encrypt, auth) - gpg_set_card_identity(): cardholder name and login fields - gpg_reset_nk3_secret_app(): Nitrokey 3 Secrets app reset - gpg_card_change_pin(): GPG User PIN change New reprovision flow (reprovision_smartcard_from_backup()): 10-phase flow: mount LUKS backup -> detect key type -> factory- reset card -> import subkeys -> set identity -> sign /boot -> flash GUI integration: - k option in GPG Management Menu (gpg-gui.sh), always visible - K option in prompt_missing_gpg_key_action (gui-init.sh) - Clean boot wizard: OEM reset, reprovision, or ignore Code quality fixes from review: - Fix 6 sites where $? was clobbered by TRACE_FUNC/DEBUG calls - Replace --passphrase-file with --passphrase-fd 3 3< to avoid leaking PIN through /proc/<pid>/cmdline - Fix algo_code/bit_len extraction: head -1 for multi-key backups - Fix STATUS_OK mount emission: only on success - Fix gpg_reset_nk3_secret_app: return actual error code from hotp_verification, explicit return 0 for non-NK3 - Remove incorrect || [ $? -eq 2 ] patch: gpg --import exit code 2 is a fatal error, not unchanged - Fix pubkey.asc import: check success properly, fall back to keyring export on failure - Fix partition derivation for NVMe/MMC: stable [0-9]+$ regex - Add _luks_cleanup helper for every error return path (replaces broken EXIT trap pattern) - Re-run NK3 Secrets app reset with custom PIN on factory-reset retry - Add chmod 600 on /tmp/secret/gpg_pin - Write backup passphrase to /tmp/secret/backup_pass, use mount-usb.sh --pass-file to avoid argv leak - Shred /tmp/secret/backup_pass on mount success and failure - Shred /tmp/secret/gpg_pin after all GPG operations complete - Limit key_id derivation to first match (head -1) to prevent multi-line values breaking gpg --edit-key calls - Strip trailing <email> from cardholder name when no comment is present in UID line - Reset card_admin_pin to default after factory-reset step so subsequent forcesig/key-attr use the correct PIN - Ensure /tmp/secret exists before writing backup_pass (mkdir -p) - Export public key from keyring instead of referencing mount file: after successful pubkey.asc import, re-export from the keyring to /tmp/reprovision_pubkey.asc rather than pointing PUBKEY at the potentially-stale /media/pubkey.asc - Fix gpg_reset_nk3_secret_app header comment: removes inaccurate "to factory default" phrasing - Remove unused uid_decoded local variable from reprovision_smartcard_from_backup - Fix key_email extraction: add head -1 to prevent multi-line values when UID contains multiple <...> blocks - Fix parent_disk derivation for NVMe/MMC: use p?[0-9]+$ regex the original partition used a p<num> separator and reconstruct the public partition as parent_disk+p2 vs parent_disk+2 accordingly hex fingerprints from gpg --with-colons - Add --pass-file option to mount-usb.sh: use PASS_FILE variable and pass path directly to cryptsetup --key-file instead of reading into PASS and echoing via process substitution, eliminating the argv leak that --pass-file was meant to fix Documentation: - doc/gpg.md, doc/configuring-keys.md, doc/architecture.md: updated for the new recovery path - doc/qemu.md: USB flash drive workflow, hardlink preservation, reprovision test - doc/recovery-shell.md: Authentication and Resetting Config sections Extends PR linuxboot#1515 (2023): authentication via gpg_auth can now be enforced with key material restored from a backup. Tested on Nitrokey Pro 2 (reprovision end-to-end: factory reset, keytocard, PIN change, public key import, flash, reboot, gpg_auth works). Tested on Nitrokey 3 (OEM factory reset creates LUKS backup + provisions dongle). Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…use, add reprovision flow Extract shared OpenPGP smartcard management functions from initrd/bin/oem-factory-reset.sh into initrd/etc/gpg_functions.sh so they can be reused by multiple callers. OEM functions become thin wrappers passing global variables as positional args; the reprovision flow calls the same shared functions to restore GPG subkeys from a LUKS-encrypted backup USB onto a replacement USB Security dongle. Shared functions (replacing OEM inline code): - gpg_card_factory_reset(): factory-reset + forcesig + key-attr (RSA and ECC/P-256), parameterized on admin PIN - gpg_keytocard_subkeys(): enable USB, verify card, move subkeys to slots 1-3 (sign, encrypt, auth) - gpg_set_card_identity(): cardholder name and login fields - gpg_reset_nk3_secret_app(): Nitrokey 3 Secrets app reset - gpg_card_change_pin(): GPG User PIN change New reprovision flow (reprovision_smartcard_from_backup()): 10-phase flow: mount LUKS backup -> detect key type -> factory- reset card -> import subkeys -> set identity -> sign /boot -> flash GUI integration: - k option in GPG Management Menu (gpg-gui.sh), always visible - K option in prompt_missing_gpg_key_action (gui-init.sh) - Clean boot wizard: OEM reset, reprovision, or ignore Code quality fixes from review: - Fix 6 sites where $? was clobbered by TRACE_FUNC/DEBUG calls - Replace --passphrase-file with --passphrase-fd 3 3< to avoid leaking PIN through /proc/<pid>/cmdline - Fix algo_code/bit_len extraction: head -1 for multi-key backups - Fix STATUS_OK mount emission: only on success - Fix gpg_reset_nk3_secret_app: return actual error code from hotp_verification, explicit return 0 for non-NK3 - Remove incorrect || [ $? -eq 2 ] patch: gpg --import exit code 2 is a fatal error, not unchanged - Fix pubkey.asc import: check success properly, fall back to keyring export on failure - Fix partition derivation for NVMe/MMC: stable [0-9]+$ regex - Add _luks_cleanup helper for every error return path (replaces broken EXIT trap pattern) - Re-run NK3 Secrets app reset with custom PIN on factory-reset retry - Add chmod 600 on /tmp/secret/gpg_pin - Write backup passphrase to /tmp/secret/backup_pass, use mount-usb.sh --pass-file to avoid argv leak - Shred /tmp/secret/backup_pass on mount success and failure - Shred /tmp/secret/gpg_pin after all GPG operations complete - Limit key_id derivation to first match (head -1) to prevent multi-line values breaking gpg --edit-key calls - Strip trailing <email> from cardholder name when no comment is present in UID line - Reset card_admin_pin to default after factory-reset step so subsequent forcesig/key-attr use the correct PIN - Ensure /tmp/secret exists before writing backup_pass (mkdir -p) - Export public key from keyring instead of referencing mount file: after successful pubkey.asc import, re-export from the keyring to /tmp/reprovision_pubkey.asc rather than pointing PUBKEY at the potentially-stale /media/pubkey.asc - Fix gpg_reset_nk3_secret_app header comment: removes inaccurate "to factory default" phrasing - Remove unused uid_decoded local variable from reprovision_smartcard_from_backup - Fix key_email extraction: add head -1 to prevent multi-line values when UID contains multiple <...> blocks - Fix parent_disk derivation for NVMe/MMC: use p?[0-9]+$ regex the original partition used a p<num> separator and reconstruct the public partition as parent_disk+p2 vs parent_disk+2 accordingly hex fingerprints from gpg --with-colons - Add --pass-file option to mount-usb.sh: use PASS_FILE variable and pass path directly to cryptsetup --key-file instead of reading into PASS and echoing via process substitution, eliminating the argv leak that --pass-file was meant to fix Documentation: - doc/gpg.md, doc/configuring-keys.md, doc/architecture.md: updated for the new recovery path - doc/qemu.md: USB flash drive workflow, hardlink preservation, reprovision test - doc/recovery-shell.md: Authentication and Resetting Config sections Extends PR linuxboot#1515 (2023): authentication via gpg_auth can now be enforced with key material restored from a backup. Tested on Nitrokey Pro 2 (reprovision end-to-end: factory reset, keytocard, PIN change, public key import, flash, reboot, gpg_auth works). Tested on Nitrokey 3 (OEM factory reset creates LUKS backup + provisions dongle). Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…use, add reprovision flow Extract shared OpenPGP smartcard management functions from initrd/bin/oem-factory-reset.sh into initrd/etc/gpg_functions.sh so they can be reused by multiple callers. OEM functions become thin wrappers passing global variables as positional args; the reprovision flow calls the same shared functions to restore GPG subkeys from a LUKS-encrypted backup USB onto a replacement USB Security dongle. Shared functions (replacing OEM inline code): - gpg_card_factory_reset(): factory-reset + forcesig + key-attr (RSA and ECC/P-256), parameterized on admin PIN - gpg_keytocard_subkeys(): enable USB, verify card, move subkeys to slots 1-3 (sign, encrypt, auth) - gpg_set_card_identity(): cardholder name and login fields - gpg_reset_nk3_secret_app(): Nitrokey 3 Secrets app reset - gpg_card_change_pin(): GPG User PIN change New reprovision flow (reprovision_smartcard_from_backup()): 10-phase flow: mount LUKS backup -> detect key type -> factory- reset card -> import subkeys -> set identity -> sign /boot -> flash GUI integration: - k option in GPG Management Menu (gpg-gui.sh), always visible - K option in prompt_missing_gpg_key_action (gui-init.sh) - Clean boot wizard: OEM reset, reprovision, or ignore Code quality fixes from review: - Fix 6 sites where $? was clobbered by TRACE_FUNC/DEBUG calls - Replace --passphrase-file with --passphrase-fd 3 3< to avoid leaking PIN through /proc/<pid>/cmdline - Fix algo_code/bit_len extraction: head -1 for multi-key backups - Fix STATUS_OK mount emission: only on success - Fix gpg_reset_nk3_secret_app: return actual error code from hotp_verification, explicit return 0 for non-NK3 - Remove incorrect || [ $? -eq 2 ] patch: gpg --import exit code 2 is a fatal error, not unchanged - Fix pubkey.asc import: check success properly, fall back to keyring export on failure - Fix partition derivation for NVMe/MMC: stable [0-9]+$ regex - Add _luks_cleanup helper for every error return path (replaces broken EXIT trap pattern) - Re-run NK3 Secrets app reset with custom PIN on factory-reset retry - Add chmod 600 on /tmp/secret/gpg_pin - Write backup passphrase to /tmp/secret/backup_pass, use mount-usb.sh --pass-file to avoid argv leak - Shred /tmp/secret/backup_pass on mount success and failure - Shred /tmp/secret/gpg_pin after all GPG operations complete - Limit key_id derivation to first match (head -1) to prevent multi-line values breaking gpg --edit-key calls - Strip trailing <email> from cardholder name when no comment is present in UID line - Reset card_admin_pin to default after factory-reset step so subsequent forcesig/key-attr use the correct PIN - Ensure /tmp/secret exists before writing backup_pass (mkdir -p) - Export public key from keyring instead of referencing mount file: after successful pubkey.asc import, re-export from the keyring to /tmp/reprovision_pubkey.asc rather than pointing PUBKEY at the potentially-stale /media/pubkey.asc - Fix gpg_reset_nk3_secret_app header comment: removes inaccurate "to factory default" phrasing - Remove unused uid_decoded local variable from reprovision_smartcard_from_backup - Fix key_email extraction: add head -1 to prevent multi-line values when UID contains multiple <...> blocks - Fix parent_disk derivation for NVMe/MMC: use p?[0-9]+$ regex the original partition used a p<num> separator and reconstruct the public partition as parent_disk+p2 vs parent_disk+2 accordingly hex fingerprints from gpg --with-colons - Add --pass-file option to mount-usb.sh: use PASS_FILE variable and pass path directly to cryptsetup --key-file instead of reading into PASS and echoing via process substitution, eliminating the argv leak that --pass-file was meant to fix Documentation: - doc/gpg.md, doc/configuring-keys.md, doc/architecture.md: updated for the new recovery path - doc/qemu.md: USB flash drive workflow, hardlink preservation, reprovision test - doc/recovery-shell.md: Authentication and Resetting Config sections Extends PR linuxboot#1515 (2023): authentication via gpg_auth can now be enforced with key material restored from a backup. Tested on Nitrokey Pro 2 (reprovision end-to-end: factory reset, keytocard, PIN change, public key import, flash, reboot, gpg_auth works). Tested on Nitrokey 3 (OEM factory reset creates LUKS backup + provisions dongle). Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…use, add reprovision flow Extract shared OpenPGP smartcard management functions from initrd/bin/oem-factory-reset.sh into initrd/etc/gpg_functions.sh so they can be reused by multiple callers. OEM functions become thin wrappers passing global variables as positional args; the reprovision flow calls the same shared functions to restore GPG subkeys from a LUKS-encrypted backup USB onto a replacement USB Security dongle. Shared functions (replacing OEM inline code): - gpg_card_factory_reset(): factory-reset + forcesig + key-attr (RSA and ECC/P-256), parameterized on admin PIN - gpg_keytocard_subkeys(): enable USB, verify card, move subkeys to slots 1-3 (sign, encrypt, auth) - gpg_set_card_identity(): cardholder name and login fields - gpg_reset_nk3_secret_app(): Nitrokey 3 Secrets app reset - gpg_card_change_pin(): GPG User PIN change New reprovision flow (reprovision_smartcard_from_backup()): 10-phase flow: mount LUKS backup -> detect key type -> factory- reset card -> import subkeys -> set identity -> sign /boot -> flash GUI integration: - k option in GPG Management Menu (gpg-gui.sh), always visible - K option in prompt_missing_gpg_key_action (gui-init.sh) - Clean boot wizard: OEM reset, reprovision, or ignore Code quality fixes from review: - Fix 6 sites where $? was clobbered by TRACE_FUNC/DEBUG calls - Replace --passphrase-file with --passphrase-fd 3 3< to avoid leaking PIN through /proc/<pid>/cmdline - Fix algo_code/bit_len extraction: head -1 for multi-key backups - Fix STATUS_OK mount emission: only on success - Fix gpg_reset_nk3_secret_app: return actual error code from hotp_verification, explicit return 0 for non-NK3 - Remove incorrect || [ $? -eq 2 ] patch: gpg --import exit code 2 is a fatal error, not unchanged - Fix pubkey.asc import: check success properly, fall back to keyring export on failure - Fix partition derivation for NVMe/MMC: stable [0-9]+$ regex - Add _luks_cleanup helper for every error return path (replaces broken EXIT trap pattern) - Re-run NK3 Secrets app reset with custom PIN on factory-reset retry - Add chmod 600 on /tmp/secret/gpg_pin - Write backup passphrase to /tmp/secret/backup_pass, use mount-usb.sh --pass-file to avoid argv leak - Shred /tmp/secret/backup_pass on mount success and failure - Shred /tmp/secret/gpg_pin after all GPG operations complete - Limit key_id derivation to first match (head -1) to prevent multi-line values breaking gpg --edit-key calls - Strip trailing <email> from cardholder name when no comment is present in UID line - Reset card_admin_pin to default after factory-reset step so subsequent forcesig/key-attr use the correct PIN - Ensure /tmp/secret exists before writing backup_pass (mkdir -p) - Export public key from keyring instead of referencing mount file: after successful pubkey.asc import, re-export from the keyring to /tmp/reprovision_pubkey.asc rather than pointing PUBKEY at the potentially-stale /media/pubkey.asc - Fix gpg_reset_nk3_secret_app header comment: removes inaccurate "to factory default" phrasing - Remove unused uid_decoded local variable from reprovision_smartcard_from_backup - Fix key_email extraction: add head -1 to prevent multi-line values when UID contains multiple <...> blocks - Fix parent_disk derivation for NVMe/MMC: use p?[0-9]+$ regex the original partition used a p<num> separator and reconstruct the public partition as parent_disk+p2 vs parent_disk+2 accordingly hex fingerprints from gpg --with-colons - Add --pass-file option to mount-usb.sh: use PASS_FILE variable and pass path directly to cryptsetup --key-file instead of reading into PASS and echoing via process substitution, eliminating the argv leak that --pass-file was meant to fix Documentation: - doc/gpg.md, doc/configuring-keys.md, doc/architecture.md: updated for the new recovery path - doc/qemu.md: USB flash drive workflow, hardlink preservation, reprovision test - doc/recovery-shell.md: Authentication and Resetting Config sections Extends PR linuxboot#1515 (2023): authentication via gpg_auth can now be enforced with key material restored from a backup. Tested on Nitrokey Pro 2 (reprovision end-to-end: factory reset, keytocard, PIN change, public key import, flash, reboot, gpg_auth works). Tested on Nitrokey 3 (OEM factory reset creates LUKS backup + provisions dongle). Signed-off-by: Thierry Laurion <insurgo@riseup.net>













Goal of this PR: Permit User Authentication prior of going to Recovery Shell or USB boot. But prior of enabling that functionality, we need to make sure that the user has a backup of his key material. And to have a backup of key material, we need to generate master key and subkeys in memory and backup over encrypted partition and then keytocard the subkeys to the USB Security dongle. This PR does that and clean the code that was reviewed along the way.
EDIT: this comment from @JonathonHall-Purism shows the new flow graphically: #1515 (comment)
Ok! from #1515 (comment):
Unrelated work under this PR:
Discussions on how GPG Authentication and OEM Factory Reset/Re-Ownership features should evolve are happening under #1520 and #1521 respectively.
Please participate, your voice is important to be considered!
Old:
Creating WiP PR to track changes.
WARNING: At current stage, prior merged PR #1476 makes it possible (warning with Intel 3rd gen I3 laptops without RDRAND: crng is not ready early on boot, will need to update board configs for notice even though those CPUs are not widely used).
Raw notes:
usb_security_token_capabilities_check(My only testing key is NK3 and I wanted to support RSA first.... so stay tuned here for latest changes and squashing prior of testing this if you have NK3 and not testing pre-releases, this is not ready to use).CONFIG_HAVE_GPG_KEY_BACKUPand saves it in config.user, injects it and then checks against in in codebase to automatically activate authentication on recovery shell and usb boot codepathCreating PR since I came across changes needed and wanted to be able to discuss them with stakeholders prior of proposing final version. Will comment on those in next comments, and will come back to OP and modify it with current state as I progress up to proposing final version. Will set PR as draft after creating PR.