Skip to content

wolfsshd: bind certificate auth to user, fail closed without FPKI#1019

Open
yosuke-wolfssl wants to merge 1 commit into
wolfSSL:masterfrom
yosuke-wolfssl:fix/f_4578
Open

wolfsshd: bind certificate auth to user, fail closed without FPKI#1019
yosuke-wolfssl wants to merge 1 commit into
wolfSSL:masterfrom
yosuke-wolfssl:fix/f_4578

Conversation

@yosuke-wolfssl

Copy link
Copy Markdown
Contributor

wolfsshd: bind certificate auth to the requested user (fail closed without FPKI)

Summary

Fixes a high-severity authentication-defaults issue addressed by f_4578: on the
wolfSSHd certificate public-key path, a CA-signed certificate was accepted as
any requested SSH username when AuthorizedKeysFile was unset and the build
did not define WOLFSSL_FPKI. The username-to-certificate binding
(UPN-vs-username) is only compiled under WOLFSSL_FPKI, which is off by default,
so a default build using TrustedUserCAKeys would let any cert signed by the
trusted CA log in as root or any other user.

This binds the certificate to the requested user on the CA-only path and fails
closed when no binding mechanism is available.

Changes

apps/wolfsshd/auth.cRequestAuthentication()

The CA-only certificate branch (cert present, no AuthorizedKeysFile) is split
into three explicit cases:

Build Behavior
WIN32 get the user token via SetupUserTokenWin (unchanged)
WOLFSSL_FPKI rely on the CA chain — the UPN-vs-username check above already bound the cert to the user (unchanged)
neither fail closed: WOLFSSH_USERAUTH_REJECTED

Without FPKI the certificate UPN/principal cannot be read, so the requested user
cannot be bound to the certificate. The operator must either build wolfSSL with
FPKI (UPN binding) or set AuthorizedKeysFile (per-user key/cert mapping via
checkPublicKeyCb).

Note: WOLFSSL_FPKI (wolfSSL, enables UPN parsing in auth.c) and
WOLFSSH_NO_FPKI (wolfSSH, skips certman's strict FASCN profile) are
independent; an FPKI-enabled wolfSSL with -DWOLFSSH_NO_FPKI gets UPN binding
without requiring full FPKI profile extensions on the certificate.

.github/workflows/x509-interop.yml

The scheduled interop job built wolfSSL without FPKI and authenticated fred
via the CA-only path, so the auth change would have rejected it. Updated so the
interop job validates the secure binding path instead:

  • Build wolfSSL with --enable-all (defines WOLFSSL_FPKI, enabling the
    UPN-vs-username binding).
  • Keep -DWOLFSSH_NO_FPKI on the wolfSSHd build so the strict FPKI profile
    (FASCN) is not required of the fred test certificate.
  • Bump the wolfSSL cache key (...-all-...) so the new build config is not
    masked by a stale cached (non-FPKI) wolfSSL.
  • Add a negative test: a certificate issued for fred must not authenticate
    as a different user (otheruser). The assertion requires the failure to be an
    authentication denial (Permission denied), so an unrelated ssh/transport
    error cannot masquerade as a passing negative test.

Security impact

Before: any certificate signed by TrustedUserCAKeys could authenticate as any
username on a default (non-FPKI) build with no AuthorizedKeysFile.

After: certificate auth requires the requested username to be bound to the
certificate (UPN under FPKI, or AuthorizedKeysFile mapping); otherwise it is
rejected.

Compatibility

This is a behavior change for non-Windows, non-FPKI deployments that relied on
CA-only certificate auth without AuthorizedKeysFile — such logins now fail
closed. Affected operators should enable FPKI or configure AuthorizedKeysFile.

Verification

  • FPKI build (--enable-all / default): builds clean with -Werror.
  • Non-FPKI build (wolfSSL without FPKI): builds clean with -Werror; confirmed
    only the fail-closed reject branch is emitted (UPN block excluded).
  • wolfSSHd unit tests (apps/wolfsshd/test/test_configuration): no new failures
    (the one pre-existing test_CheckPasswordHashUnix failure is an unrelated
    macOS crypt() quirk, reproduced on the unmodified tree).
  • ASan + UBSan run of the affected tests: no sanitizer reports.

@yosuke-wolfssl yosuke-wolfssl self-assigned this Jun 11, 2026
Copilot AI review requested due to automatic review settings June 11, 2026 07:04

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.

Pull request overview

This PR fixes a certificate-authentication default that could allow a CA-signed client certificate to authenticate as an arbitrary requested SSH username when AuthorizedKeysFile is unset and the build lacks WOLFSSL_FPKI. The change ensures certificate authentication is bound to the requested user (via UPN parsing under FPKI), and otherwise fails closed.

Changes:

  • Split the CA-only certificate-auth path in wolfsshd to explicitly allow Windows token mapping, allow FPKI builds (UPN already checked), and reject non-Windows non-FPKI builds without AuthorizedKeysFile.
  • Update the scheduled X.509 interop workflow to build wolfSSL with --enable-all (enabling WOLFSSL_FPKI) and add a negative test ensuring a cert for fred cannot authenticate as otheruser.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
apps/wolfsshd/auth.c Fail-closed behavior for CA-only certificate auth when no user-binding mechanism is available (non-Windows, non-FPKI, no AuthorizedKeysFile).
.github/workflows/x509-interop.yml CI updated to exercise the secure binding path (WOLFSSL_FPKI) and add a regression negative-auth test.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@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 #1019

Scan targets checked: wolfssh-bugs, wolfssh-src

No new issues found in the changed files. ✅

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