internal, ossh: sign RSA user auth through ssh-agent - #1296
yosuke-wolfssl wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
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
left a comment
There was a problem hiding this comment.
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.
e0edbc1 to
c930316
Compare
- 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.
Problem
RSA public-key user auth through ssh-agent (
--enable-agent) has never worked. Three defects stack up:wc_RsaPublicKeyDecode(), an ASN.1 decoder, and fails with a raw wolfCryptASN_PARSE_E(-140).string name, string sig, so the call fails withWS_BUFFER_E.flags = 0, so the agent returns an SHA-1ssh-rsasignature under anrsa-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 withGetOpenSshPublicKey(), and reserves the signature name bysigNameSz.BuildUserAuthRequestRsa()sizes the agent's reply room from the requested signature algorithm, passesAGENT_SIGN_RSA_SHA2_256or_512, and refuses a signature made with another algorithm (agents before OpenSSH 7.2 ignore the flags).GetOpenSshPublicKey()(src/ossh.c) is built underWOLFSSH_AGENTas well asWOLFSSH_TPM, and decodesssh-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.ymland 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.testpart 3: a realssh-agentandsshd, once per compiledrsa-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.ymlcells reproduced in Ubuntu 24.04 (RSA on ibmswtpm2 and fwTPM, ECC raw and X.509): all pass. The new certificate step fails against master withWS_UNIMPLEMENTED_E.sigNameSzreservation fix can't be observed: the packet's padding slack absorbs the 5-byte shortfall.-Werrorsweep 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 inserver-sig-algs); the same blob-type check for the TPM branch.