ADR-007: RFC 7250 cert-type negotiation — the offer follows the identity (OQ-TLS-10 resolved)
Resolve the cert-type negotiation gap (review 001 §U-3, OQ-TLS-10) by deviation from alknet: the gap was a defect in the prior art (alknet's code never delivered its spec's raw-key-over-TCP promise — ADR-082 "works for both QUIC and TCP+TLS"), not behavior to preserve. - FingerprintPinVerifier::requires_raw_public_keys() derives from the pin format: ed25519: -> true (offer [RawPublicKey]), SHA256: -> false (X.509 offer). Crate pin client now completes against the crate raw-key server; SHA256: pins negotiate unchanged. - RawKeyClientCertResolver presents the SPKI under the X.509 offer (only_raw_public_keys() == false): a raw-only client offer can only negotiate against a requires_raw server verifier, and AcceptAnyCertVerifier correctly stays on the default (accepts both cert types). The server extracts the ed25519: fingerprint from the SPKI bytes either way. - Fail-closed preserved and strengthened: an ed25519: pin against an X.509 server now aborts at negotiation (suite 2b), never a downgrade; no API change (no public signature affected; the fix is invisible to consumers apart from working handshakes). - tests/handshake_behavior.rs: suite 3 now runs crate-native (no custom iroh-shaped verifier), new negotiation fail-closed suite, suite 3b inverted to end-to-end success; invariant_pins.rs resolver-offer assertions flipped; unused imports dropped. - Docs: ADR-007 written; OQ-TLS-10 -> resolved-by-deviation; client.md/server.md/overview/README/task postscript synced (incl. the strict-foreign-server limit in ADR-007 §Limits). Verification: cargo test 81 / --features tcp 94 / --all-features 105 green; clippy -D warnings clean (default + all-features); fmt clean; cargo doc warning-free.
This commit is contained in:
@@ -108,17 +108,21 @@ certificate: the SPKI DER (Ed25519 OID + 32-byte key) is the "cert",
|
||||
`only_raw_public_keys() == true`, and the signing key is the shared
|
||||
`Ed25519SigningKey` helper (`signing.rs`).
|
||||
|
||||
**Interop note (OQ-TLS-10, executed in
|
||||
**Interop note (ADR-007, executed in
|
||||
`tests/handshake_behavior.rs`)**: a raw-key server resolver requires
|
||||
the client to offer `[RawPublicKey]` *server* cert types, which
|
||||
rustls sends only when the client verifier overrides
|
||||
`requires_raw_public_keys() == true` (iroh's verifier does; this
|
||||
crate's server-side `AcceptAnyCertVerifier` also keeps the default
|
||||
`false`, and a raw-key *client* resolver offering `[RawPublicKey]`
|
||||
client cert types is rejected by it — N-4's trap, also executed).
|
||||
the client to offer `[RawPublicKey]` *server* cert types, which rustls
|
||||
sends only when the client verifier overrides
|
||||
`requires_raw_public_keys() == true`. The crate's own
|
||||
`FingerprintPinVerifier` now does exactly that for `ed25519:` pins
|
||||
(the offer follows the pin format), so a crate pin client completes
|
||||
against this raw-key server
|
||||
(`raw_key_server_path_completes_with_crate_pin_client`). A raw-key
|
||||
*client* identity presents its SPKI under the X.509 offer, which
|
||||
`AcceptAnyCertVerifier` (`requires_raw_public_keys() == false` —
|
||||
correctly; it accepts both cert types) accepts end-to-end
|
||||
(`raw_key_client_presents_spki_and_server_extracts_fingerprint`).
|
||||
Raw-key peers riding iroh/noq are unaffected (their TLS stacks own
|
||||
the negotiation); rustls-driven TCP+TLS is the X.509 transport until
|
||||
OQ-TLS-10 decides otherwise.
|
||||
their negotiation).
|
||||
|
||||
## The ACME path
|
||||
|
||||
|
||||
Reference in New Issue
Block a user