task 2: handshake-level suites — pin, fail-closed, RFC 7250 paths executed (U-3)

tests/handshake_behavior.rs (tcp-gated, tokio duplex + tokio-rustls,
no new deps) turns the fail-closed / pin / raw-key language into
executed behavior:

- pin match: X.509 server + SHA256 pin -> handshake completes, app
  data round-trips, server extracts the client cert fingerprint
- pin mismatch: wrong pin -> handshake error (the pin IS the anchor)
- fail closed: remote_identity None + raw-key server -> HandshakeFailure
- raw-key server path end-to-end: completes with the iroh-shaped
  client verifier (requires_raw_public_keys == true); presented cert
  asserted to be the SPKI carrying the raw Ed25519 key
- N-4's interop trap executed: raw-key client resolver vs
  AcceptAnyCertVerifier -> IncorrectCertificateTypeExtension alert

Major finding, recorded as OQ-TLS-10 (open): a crate-built pin
client cannot reach a crate-built raw-key server over rustls TCP+TLS
— the raw-key resolver requires the client to offer [RawPublicKey]
server cert types, sent only when the client verifier overrides
requires_raw_public_keys() == true. FingerprintPinVerifier keeps the
trait default false (AcceptAnyCertVerifier too); iroh's verifier
overrides true on both sides. Gap inherited from alknet
(behavior-preserving); pinned both ways by the suite.

client.md / server.md carry the interop notes; task file updated
(premise adjustments documented in Notes, summary filled).

Verification: 81 default / 91 tcp / 99 all-features tests green
(+5 new), clippy -D warnings clean both configs, fmt clean,
cargo doc warning-free, taskgraph validate 14 tasks.
This commit is contained in:
2026-09-11 08:17:28 +00:00
parent d82956385b
commit 4a4fae64af
5 changed files with 511 additions and 7 deletions
+13 -1
View File
@@ -1,6 +1,6 @@
---
status: reviewed
last_updated: 2026-09-10
last_updated: 2026-09-11
---
# alktls — Server side
@@ -108,6 +108,18 @@ 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
`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).
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.
## The ACME path
For `TlsIdentity::Acme`, `new` (feature `acme`):