Skip to content

feat(keygen): enroll FIDO security keys and load resident keys #337

Closed

Description

@inureyes

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-sk and -t ecdsa-sk enroll through the external library and internal, writing private (key handle) and public files that OpenSSH ssh and bssh both accept.
  • Each listed -O option works or is rejected with a message naming it; ed25519-sk on a U2F-only device fails clearly.
  • bssh-keygen -K writes one key pair per resident credential using OpenSSH's id_*_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 the mock_handlers.rs style.
  • External path calls sk_enroll / sk_load_resident_keys with the pointer and length checks sk_sign uses, tested in external_tests.rs.
  • CLI help and docs/man/bssh-keygen.1 document 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

  1. added 2 commits that reference this issue on Oct 22, 2026
    f2d5e05
    cd3bf24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions