Repository navigation
feat(keygen): enroll FIDO security keys and load resident keys #337
Description
Problem / Background
bssh signs with FIDO sk-* keys (#333, #334) but cannot create them, so users still need OpenSSH ssh-keygen to produce id_ed25519_sk / id_ecdsa_sk. bssh-keygen accepts only ed25519 and rsa (src/bin/bssh_keygen.rs:98, src/keygen/mod.rs:69,94). SecurityKeyProvider (src/ssh/security_key/mod.rs:179) has only sign. The external path checks that sk_enroll and sk_load_resident_keys resolve but never calls them (src/ssh/security_key/external.rs:18,186). The internal provider encodes makeCredential and U2F REGISTER only as dummy touch probes for device selection (internal/ctap2.rs:395, internal/u2f.rs:76).
Proposed Solution
Add enroll and load_resident_keys to SecurityKeyProvider, implement them in both providers, and wire them into bssh-keygen with OpenSSH's flags: -t ed25519-sk|ecdsa-sk, -w provider (resolved through resolve_provider, default internal), -K, and -O application=, resident, verify-required, no-touch-required, user=, challenge=, write-attestation=, device=. Write files with ssh-key (KeypairData::SkEd25519 / SkEcdsaSha2NistP256), the same types security_key_signer.rs:76 reads.
Out of scope: an ssh-add -K equivalent. bssh ships no agent client tool and reads key files directly; -K output files cover the use case.
Acceptance Criteria
-
bssh-keygen -t ed25519-skand-t ecdsa-skenroll through the external library andinternal, writing private (key handle) and public files that OpenSSHsshand bssh both accept. - Each listed
-Ooption works or is rejected with a message naming it;ed25519-skon a U2F-only device fails clearly. -
bssh-keygen -Kwrites one key pair per resident credential using OpenSSH'sid_*_sk_rk*naming, prompting for the PIN. - Internal provider implements CTAP2 makeCredential, credential management with PIN, and U2F registration for
ecdsa-sk, with tests in themock_handlers.rsstyle. - External path calls
sk_enroll/sk_load_resident_keyswith the pointer and length checkssk_signuses, tested inexternal_tests.rs. - CLI help and
docs/man/bssh-keygen.1document the new types and options. - Manual check with a physical authenticator, pending user validation if none is available.
Verification
cargo test --lib security_key
cargo clippy --all-targets -- -D warnings
cargo fmt --check
Implementation Notes
Built-in resident enrollment requires CTAP2 credential management and a PIN to prevent replacing an existing application/user credential; resident and verification-required keys require credProtect. The write-attestation option is explicitly rejected, and ssh-key serialization limits credential handles to 255 bytes.
Physical-authenticator validation remains pending: this environment has no HID authenticator.
Activity
feat(keygen): enroll and download FIDO security keys (#347)
docs: update security-key compatibility ledger (#348)