镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

feat(ssh): implement the built-in internal SecurityKeyProvider for USB HID authenticators #331

Closed

Description

@inureyes

Background

Depends on #328. On 2026-10-22 FIDO security keys were put in scope for bssh, matching OpenSSH 10.3p1, including the default internal provider. #328 adds the sk-* host-key algorithms and their verification, user authentication through an external SecurityKeyProvider library (sk-api), and the provider interface. Under #328, internal returns an explicit "not yet supported" diagnostic. This issue makes internal work.

OpenSSH 10.3p1 defaults SecurityKeyProvider to internal (readconf.c:3014-3018). That is the built-in USB HID support in sk-usbhid.c, which is built on libfido2.

Scope

  • Implement the sign operation behind the fix(openssh): decide FIDO host-key coverage for the hostkey-agent sk certificate phases #328 provider interface for sk-ssh-ed25519@openssh.com and sk-ecdsa-sha2-nistp256@openssh.com private key files (key handle, application, flags), following sk-usbhid.c: CTAP2 getAssertion with the CTAP1/U2F fallback that sk-usbhid.c uses where applicable, device discovery, and selection of the device that holds the credential when several authenticators are attached (sk-usbhid.c probes each device with a dummy assertion).
  • Honor the key flags exactly as OpenSSH does: user presence (print OpenSSH's "Confirm user presence for key ..." prompt), verify-required (PIN prompt), and no-touch-required.
  • Platforms: Linux (hidraw) and macOS (IOKit HID), which covers every target in .github/workflows/release.yml.

Hard constraint: dependencies

Release builds include static musl binaries (x86_64-unknown-linux-musl, aarch64-unknown-linux-musl), which cannot dlopen, and the Debian, Launchpad PPA, and Homebrew packaging add no runtime library today. The implementation must build for every release.yml target without a new system library requirement. Evaluate the following options and record the choice and the reason in the PR: hidapi with its pure-Rust Linux backend (linux-native-basic-udev), ctap-hid-fido2, or a minimal in-tree CTAPHID plus CTAP2 getAssertion implementation over hidraw and IOKit. Linking libfido2 (fido2-rs, libfido2-sys) is rejected unless it meets this constraint.

Out of scope

Key enrollment (ssh-keygen -t ed25519-sk, sk_enroll) and resident-key loading (ssh-keygen -K, ssh-add -K). Note both in the PR as possible follow-ups.

Testing

CI has no authenticator, so behavior is covered by unit tests against a mock HID transport: CTAPHID framing (INIT and channel allocation, continuation packets, KEEPALIVE), CBOR getAssertion request encoding and response parsing, and conversion into the SSH sk signature (flags, counter, Ed25519 and ECDSA encodings). Add one end-to-end test through the provider interface with the mock transport whose signature verifies with ssh-key. State in the PR that a manual check with a real authenticator on Linux and macOS is pending user validation.

Acceptance Criteria

  • SecurityKeyProvider internal, and the default when the option is unset, signs with an attached FIDO2 authenticator for both sk key types, using OpenSSH's prompt wording. (PR feat(ssh): add the built-in internal SecurityKeyProvider over USB HID #334; verified against the mock authenticator only, a physical-key check on Linux and macOS is pending)
  • With no authenticator attached or no matching credential, bssh prints a clear error and authentication continues with the next identity, as OpenSSH does.
  • Every release.yml target builds, including both musl targets, and no new runtime library is added to debian/control, the PPA rules, or the Homebrew formula. (Linux gnu and macOS build in CI, no packaging change, Linux release binary links only libc/libm/libgcc_s; musl checked for the new crates only, full musl build first runs in the next release workflow)
  • The mock-transport tests above exist and each fails when its behavior is reverted.
  • The internal "not yet supported" diagnostic from fix(openssh): decide FIDO host-key coverage for the hostkey-agent sk certificate phases #328 is removed and docs/openssh-compatibility-status.md is updated.
  • cargo fmt --check, cargo clippy -- -D warnings, cargo test --lib, and cargo test --tests -- --skip integration_test pass, and the openssh-regress workflow shows no new failures on Linux or macOS. (PR feat(ssh): add the built-in internal SecurityKeyProvider over USB HID #334; CI regress Ubuntu 69/70, macOS 66/67, unchanged)
  • Implemented in one PR, with the local gate run once at the end and as few pushes as possible.

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