Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions docs/design.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,24 @@ cannot replace it because a KEM cannot produce the CMS signature.
blocked; the RFC posture only shapes defaults and opinion).
- **pkiStatus:** SUCCESS (0), FAILURE (2), PENDING (3). **failInfo:** badAlg (0), badMessageCheck
(1), badRequest (2), badTime (3), badCertId (4), plus optional `failInfoText`.
- **CMS content type (RFC 8894 §3.2):** the outer SignedData `encapContentInfo.eContentType` (and the
matching `content-type` signed attribute) is `id-data` - the `envelopedData` OID belongs only to the
inner pkcsPKIEnvelope's own `ContentInfo`, not the outer encapsulated content.
- **CertRep signature verification:** the response signature is checked against the certs embedded in
the CertRep **and** the cached GetCACert bundle, so a valid signature whose signer cert the server did
not embed is still confirmed. A mismatch/failure is diagnosed, not just flagged: the note reports the
*claimed* signer (issuer+serial or subjectKeyIdentifier), the cert actually used to verify (and whether
it came from the CertRep or GetCACert), and how many candidates were tried - so a server-implementor can
tell a genuinely invalid signature from "we picked cert X but cert Y signed / the signer cert was not
provided."

### PENDING enrollment lifecycle

When `get`/`enroll` returns PENDING the subject key and request metadata are persisted under
`servers/<id>/pending/<txn>/` (keyed by transaction id). A later `poll` reloads that key, signs the
CertPoll with it (RFC 8894 §3.3.2 - the GetCertInitial must be signed by the original enrollment key, so
the CA returns the certificate bound to it), and on success stores the issued cert paired with the key
(then clears the pending record) so it lists, renews, and exports like a synchronous enrollment.

### Renewal variants

Expand Down
4 changes: 2 additions & 2 deletions docs/scepclient-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ Unknown flags are rejected (e.g. a typo'd `--keyspec` errors rather than silentl
## Test with it - exercise a server for RFC 8894 compliance
| Command | Purpose |
|---|---|
| `scepclient diagnose <serverId>` | read-only health check: caps, CA/RA cert details, and whether requests can be enveloped (spot a wrong RA/CA cert without enrolling) |
| `scepclient diagnose <serverId> [-v]` | read-only health check: caps, CA/RA cert details, and whether requests can be enveloped (spot a wrong RA/CA cert without enrolling). On an HTTP error the server's response body is surfaced inline (so a 500 shows *why*, not a bare status); `-v` traces the resolved request URLs |
| `scepclient getcacaps <serverId>` | GetCACaps |
| `scepclient getcacert <serverId> [-v]` | GetCACert (`-v` prints full cert details: KeyUsage, EKU, validity, thumbprint) / `getnextcacert <serverId>` |
| `scepclient poll <serverId> --issuer <dn> --subject <dn> --txn <id>` | CertPoll |
| `scepclient poll <serverId> --issuer <dn> --subject <dn> --txn <id> [--key-pass <pw>]` | CertPoll: completes a PENDING enrollment. Signs the poll with the original enrollment key (saved when `get`/`enroll` returned PENDING) and, on success, stores the issued cert+key so it appears in `certs list` and can be renewed/exported. `--key-pass` unlocks the saved key if it was encrypted |
| `scepclient getcert <serverId> --issuer <dn> --serial <hex>` | GetCert |
| `scepclient getcrl <serverId> --issuer <dn> --serial <hex>` | GetCRL |
| `scepclient servers suggest <id>` | capability/security advice |
Expand Down