Skip to content

internal, ossh: sign RSA user auth through ssh-agent - #1296

Open
yosuke-wolfssl wants to merge 3 commits into
wolfSSL:masterfrom
yosuke-wolfssl:fix/rsa-auth
Open

yosuke-wolfssl wants to merge 3 commits into
wolfSSL:masterfrom
yosuke-wolfssl:fix/rsa-auth

Conversation

@yosuke-wolfssl

@yosuke-wolfssl yosuke-wolfssl commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Problem

RSA public-key user auth through ssh-agent (--enable-agent) has never worked. Three defects stack up:

  • Wrong decoder: the agent path hands the SSH-format public key to wc_RsaPublicKeyDecode(), an ASN.1 decoder, and fails with a raw wolfCrypt ASN_PARSE_E (-140).
  • Signature buffer too small: the agent is given room for the bare signature only, but it returns string name, string sig, so the call fails with WS_BUFFER_E.
  • Wrong signature algorithm: the sign request passes flags = 0, so the agent returns an SHA-1 ssh-rsa signature under an rsa-sha2-* request, which sshd rejects.

Agent-held OpenSSH RSA certificates fail too: GetOpenSshPublicKey() has no certificate case. Follows up on the #1196 review.

Fix (src/internal.c)

  • PrepareUserAuthRequestRsa() checks that the agent key blob's type matches the request, decodes it with GetOpenSshPublicKey(), and reserves the signature name by sigNameSz.
  • BuildUserAuthRequestRsa() sizes the agent's reply room from the requested signature algorithm, passes AGENT_SIGN_RSA_SHA2_256 or _512, and refuses a signature made with another algorithm (agents before OpenSSH 7.2 ignore the flags).
  • GetOpenSshPublicKey() (src/ossh.c) is built under WOLFSSH_AGENT as well as WOLFSSH_TPM, and decodes ssh-rsa-cert-v01@openssh.com.

The shared decoder also lets a TPM-held key be offered as an OpenSSH user certificate. The second commit tests that in tpm-ssh.yml and documents it in the README.

Tests

  • tests/regress.c: a mock agent that answers the way OpenSSH's does and checks the key blob it is asked to sign with. Covers an RSA key and a certificate, a refusing agent, ignored flags, a mismatched blob, and an oversize signature.
  • tests/api.c: test_GetOpenSshPublicKey_type() now runs in agent builds, with truncated-certificate vectors.
  • scripts/openssh-interop.test part 3: a real ssh-agent and sshd, once per compiled rsa-sha2-* algorithm.
  • tpm-ssh.yml: a TPM key offered as an OpenSSH certificate logs in; a certificate for another key is refused by the server.

Verification

  • make check: 14/14. Interop passes against OpenSSH 10.3 (macOS) and 9.6 (Ubuntu 24.04).
  • tpm-ssh.yml cells reproduced in Ubuntu 24.04 (RSA on ibmswtpm2 and fwTPM, ECC raw and X.509): all pass. The new certificate step fails against master with WS_UNIMPLEMENTED_E.
  • Reverting the decoder, reply-room, flags, signature-name or blob-type fix on its own fails its test. The sigNameSz reservation fix can't be observed: the packet's padding slack absorbs the 5-byte shortfall.
  • ASan + UBSan + LeakSanitizer clean on Linux; GCC -Werror sweep clean.

Not in this PR: the X.509 (x509v3-ssh-rsa) agent path; the client not offering OpenSSH certificates to OpenSSH's sshd (it requires the certificate algorithm in server-sig-algs); the same blob-type check for the TPM branch.

@yosuke-wolfssl yosuke-wolfssl self-assigned this Oct 5, 2026
Copilot AI balanced review requested due to automatic review settings October 5, 2026 07:12

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 review overview

🟢 Approval recommended

The implementation consistently addresses the reported protocol defects with matching unit, regression, interoperability, and TPM coverage.

Review effort: Balanced
Findings: None

What changed in this PR

Enables RSA user authentication through ssh-agent, including OpenSSH RSA certificates and TPM-backed certificate use.

Changes:

  • Corrects RSA key decoding, signature sizing, and SHA-2 agent flags.
  • Validates agent signature algorithms and adds comprehensive regression/API coverage.
  • Adds OpenSSH interop and TPM certificate tests plus documentation.
File Description
wolfssh/​internal.h Exposes and documents shared public-key decoding.
src/​internal.c Implements corrected RSA agent signing.
src/​ossh.c Adds RSA certificate public-key decoding.
tests/​regress.c Adds mocked RSA agent regression tests.
tests/​api.c Extends decoder tests to agent builds.
scripts/​openssh-interop.test Tests authentication with a real ssh-agent.
README.md Documents TPM-backed OpenSSH certificates.
.github/​workflows/​tpm-ssh.yml Tests positive and negative TPM certificate authentication.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

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

Scan targets checked: wolfssh-src, wolfssh-bugs
Coverage: 2 of 5 in-scope changed file(s) opened by the reviewer; not opened: tests/api.c, tests/regress.c, wolfssh/internal.h

Fenrir result: Approved ✅

No new issues found in the changed files.

Advisory only — this automated result does not count as a GitHub approval.

Review tier: Lite

- PrepareUserAuthRequestRsa() checks the agent-backed key blob's type
  against the request, decodes it with GetOpenSshPublicKey(), and
  reserves the signature name by sigNameSz.
- BuildUserAuthRequestRsa() sizes the agent's reply room from the
  requested signature algorithm, requests the rsa-sha2-* hash the
  request names, and refuses a signature made with another algorithm.
- GetOpenSshPublicKey() is built under WOLFSSH_AGENT too, decodes an
  OpenSSH RSA certificate, and is documented in internal.h.
- api: run test_GetOpenSshPublicKey_type() in agent builds, with
  truncated OpenSSH RSA certificate vectors.
- regress: share the agent user auth helpers across key types; the
  mock agent checks the key blob it is asked to sign with. Add tests
  for an RSA key against OpenSSH's and an rsa-sha2-256-only server,
  a certificate against a wolfSSH server, a refusing agent, a
  mismatched blob, and ignored flags and an oversize signature for
  both the key and the certificate.
- openssh-interop.test: part 3 authenticates to sshd with an RSA key
  held by ssh-agent, once per rsa-sha2 algorithm the client was built
  with.
- tpm-ssh.yml builds wolfSSH with --enable-ossh-certs, and the RSA
  raw cells log in with the TPM key offered as an OpenSSH user
  certificate, and fail with a certificate for another key.
- README: a TPM PUBLIC KEY AUTHENTICATION subsection on offering the
  TPM key as an OpenSSH user certificate.
- openssh-interop.test fails at each skip point when
  WOLFSSH_TEST_REQUIRE_OPENSSH=1, and skips through skip_rest() for
  the sshd and ssh-agent parts.
- sanitizer.yml sets WOLFSSH_TEST_REQUIRE_OPENSSH=1 for make check.
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.

3 participants