Skip to content

Add OpenSSH certificate user authentication#1060

Open
yosuke-wolfssl wants to merge 1 commit into
wolfSSL:masterfrom
yosuke-wolfssl:feat/osshCert
Open

Add OpenSSH certificate user authentication#1060
yosuke-wolfssl wants to merge 1 commit into
wolfSSL:masterfrom
yosuke-wolfssl:feat/osshCert

Conversation

@yosuke-wolfssl

Copy link
Copy Markdown
Contributor

Add OpenSSH certificate user authentication

Adds support for authenticating users with OpenSSH certificates
(*-cert-v01@openssh.com) in wolfSSHd, behind a new --enable-ossh-certs
configure option (also enabled by --enable-all).

Motivation

OpenSSH certificates let an operator authorize users by trusting a single CA
(via TrustedUserCAKeys) instead of distributing every user's public key into
authorized_keys. This brings wolfSSHd in line with stock OpenSSH sshd for
certificate-based user auth.

What's implemented (Unix)

Library (src/ossh.c, src/internal.c) — portable, no platform deps:

  • Parse the OpenSSH certificate wire format and validate type.
  • Verify the certificate's CA signature against the CA key embedded in the
    certificate (RSA incl. rsa-sha2-256/512, ECDSA P-256/P-384/P-521, Ed25519).
  • Reject unknown critical options; extract force-command and
    source-address; tolerate unknown extensions.
  • Reconstruct the certified base user key and verify the user's signature
    against it (proving possession of the certified private key), using the
    on-the-wire signed length so it works with the reconstructed key.
  • Parsed policy fields (caKey, principals, validity, source-address,
    force-command) are handed to the user-auth callback for enforcement.

Daemon (apps/wolfsshd/auth.c, wolfsshd.c)CheckPublicKeyUnix enforces,
fail-closed and in order:

  1. CA trust — the signing CA must be in TrustedUserCAKeys.
  2. Principal binding — the login user must be a listed principal (a
    principal-less certificate is rejected, matching OpenSSH sshd).
  3. Validity window — valid_after/valid_before.
  4. Source-address — peer IP must match the certificate's CIDR list.
  5. Force-command — a verified certificate's force-command overrides the
    requested command for shell, exec, SFTP, and SCP sessions
    (internal-sftp still permits SFTP).

Security model

  • The library proves only that the certificate is self-consistent (signed by
    its embedded CA) and that the client holds the certified private key. It
    does not decide trust — that is the application callback's responsibility
    (check caKey against a trust store, bind the principal, enforce
    validity/source-address). This mirrors how regular public-key auth delegates
    the authorized_keys check.
  • The library fails closed when no user-auth callback is set.

Configuration

# wolfsshd config
TrustedUserCAKeys /etc/wolfssh/trusted-user-ca-keys.pub
./configure --enable-ossh-certs --enable-sshd   # or --enable-all

Platform support

  • Unix: fully supported and enforced.
  • Windows: intentionally fails closed — a certificate is never accepted
    on the Windows threaded path. Follow-up work is planned in two PRs
    (per-connection cert-state relocation, then Windows enforcement + a Windows CI
    cert-auth job).

Testing

  • tests/api.c — certificate parse, CA-signature verify, and
    critical-option/extension handling (self-contained binary vectors).
  • tests/unit.c — Ed25519 public-key parse and the user-signature
    wire-length path (wire-derived length equals the legacy field-sum).
  • apps/wolfsshd/test/test_configuration.c — direct unit tests for the
    enforcement helpers (principal binding incl. empty-list rejection, validity
    window, source-address CIDR/prefix matching).
  • apps/wolfsshd/test/sshd_ossh_cert_test.sh — end-to-end against both the
    wolfSSH example client and the system OpenSSH client: valid cert (Ed25519/RSA/
    ECDSA CAs and user keys), untrusted CA, wrong principal, empty principal,
    expired cert, unknown critical option, source-address match/deny,
    force-command, internal-sftp, and SFTP/SCP force-command gating.
  • Wired into CI (--enable-all compiles the option in; the e2e runs via
    run_all_sshd_tests.sh).

Known limitations

  • Windows: fail-closed only (see above).
  • Source-address negation (!entry) is not implemented; a negated entry
    fails the whole list closed (denies) and logs the offending entry.
  • Host certificates are not implemented; wolfSSH_CTX_UseOsshCert_buffer
    returns WS_UNIMPLEMENTED_E.

Notes for reviewers

  • The OSSH cert fields in WS_UserAuthData_PublicKey are appended after the
    existing members so the default (WOLFSSH_OSSH_CERTS disabled) struct layout
    is unchanged; enabling the option changes the layout, so the app and library
    must be built with the same setting.
  • src/ossh.c is added to the Windows MSVC project (wolfssh.vcxproj) because
    the OpenSSH key decoders it defines are referenced unconditionally.

@yosuke-wolfssl yosuke-wolfssl self-assigned this Jun 25, 2026
Copilot AI review requested due to automatic review settings June 25, 2026 01:59
@yosuke-wolfssl yosuke-wolfssl marked this pull request as draft June 25, 2026 01:59

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@yosuke-wolfssl yosuke-wolfssl force-pushed the feat/osshCert branch 2 times, most recently from 2576e03 to 1c40cc1 Compare June 25, 2026 02:53

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fenrir Automated Review — PR #1060

Scan targets checked: wolfssh-bugs, wolfssh-src

No new issues found in the changed files. ✅

@yosuke-wolfssl yosuke-wolfssl marked this pull request as ready for review June 25, 2026 04:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants