cli: pin the SCEP GetCACert response - #17
Conversation
There was a problem hiding this comment.
Pull request overview
This PR hardens the reference CLI’s SCEP flow by adding CA fingerprint pinning so the client can authenticate the GetCACert response out-of-band and avoid trusting attacker-supplied CA/RA material over an untrusted transport.
Changes:
- Add
--ca-fingerprint(SCEP-only) and enforce pin validation before network access; use only the pinned cert as the envelope recipient and CertRep trust anchor. - Print SHA-256 fingerprints in
getcacertsto support operator pin acquisition; apply the same pin resolution togetnextca. - Extend the existing CLI integration test to cover option scoping, argument validation, and end-to-end pinning against
wolfcert-server; update docs accordingly.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| cli/wolfcert_client.c | Implements --ca-fingerprint parsing/enforcement and pins SCEP enroll/getnextca trust decisions to the matched cert. |
| tests/integration/cli_proto_scoping.sh | Adds argument-validation cases and an end-to-end pinning group using the in-tree test server. |
| README.md | Documents why/when to pin SCEP GetCACert and how to obtain/use the fingerprint via the CLI. |
| docs/MIGRATING-FROM-WOLFSCEP.md | Updates migration guidance to mention the new CLI fingerprint pinning option. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
2804065 to
e451137
Compare
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #17
Scan targets checked: wolfcert-bugs, wolfcert-src
Findings: 2
2 finding(s) posted as inline comments (see file-level comments below)
This review was generated automatically by Fenrir. Findings are non-blocking.
e451137 to
d6fc617
Compare
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #17
Scan targets checked: wolfcert-bugs, wolfcert-src
Findings: 2
2 finding(s) posted as inline comments (see file-level comments below)
This review was generated automatically by Fenrir. Findings are non-blocking.
- --ca-fingerprint takes [sha256:|sha1:|sha512:]HEX. parse_ca_fingerprint decodes it into a CaPin, ignoring ':' and ' ' between hex digits, and refuses malformed hex, an unnamed digest, a length that disagrees with the named digest, and, through NO_SHA and WOLFSSL_SHA512, a digest wolfSSL was not built with. scep_pin_setup resolves it for the SCEP commands and, when it is absent, notes that the served CA is trusted unverified. check_proto_only_opts refuses the option under EST. - pem_cert_at converts the idx-th PEM certificate of a GetCACert response to DER, find_pinned_cert returns the one matching the pin and clears the mismatches recorded for those it rejected first, der_to_pem re-encodes a match, and print_ca_fingerprints writes each certificate's SHA-256 to stderr. - scep_enroll carries the SCEP arm of cmd_enroll. With a pin the matched certificate is the envelope recipient and the only CertRep trust anchor and the bundle is not fetched; unpinned, the bundle remains the trust set. cmd_getcacerts reports the fingerprints, fails on a pin that matches nothing, and writes only the matched certificate. cmd_getnextca resolves the current CA from the pinned certificate. - cli_proto_scoping.sh covers the scoping and the argument rejections, and starts wolfcert-server for a group that reads the fingerprint from getcacerts, then runs enroll and getnextca with a mismatched and a matching pin. - README.md documents fetching and pinning the fingerprint; docs/MIGRATING-FROM-WOLFSCEP.md names the flag beside the API. Issue: F-8046
d6fc617 to
386b2ff
Compare
Problem
The reference CLI never authenticated the SCEP CA it enrolled against.
cmd_enrollfetchedGetCACertover the same (usually plaintext) transport it was about to trust, made the first certificate the CSR envelope recipient, and made the whole response the CertRep trust set. Sincewolfcert_scep_verify_rep_signeraccepts any signer whose SPKI matches any bundle member, an active attacker answeringGetCACertwith their own RSA certificate both decrypts the CSR with itschallengePasswordand returns a certificate the client accepts.wolfcert_scep_verify_ca_fingerprintwas written for exactly this bootstrap and had zero callers incli/. A caller using the library API correctly is unaffected.Fix (
cli/wolfcert_client.c)Adds
--ca-fingerprint [sha256:|sha1:|sha512:]HEX, rejected under EST and validated before any network access.getcacertsprints each certificate's SHA-256, so the value can be read once over a trusted path and pinned thereafter.getnextcaresolves the current CA through the same pin, closing the circularity its own comment documented.Closes
f-8046.Tests
tests/integration/cli_proto_scoping.sh, the repo's existing CLI test, gains the option scoping and argument rejections plus a group that startswolfcert-server, reads the fingerprint fromgetcacerts, and runsenrollandgetnextcaagainst a mismatched and a matching pin. The group skips itself when the server was not built, so no new build-file registration is needed.Verification
scep_enrollorcmd_getnextcamakes the matching mismatched-pin case pass.