Skip to content

[Product Gap] Bind TLS server identity to the verified TCP peer #6

Description

@seonghobae

Buyer-visible problem

OriginWeave can now prove that a policy-approved destination became the exact operating-system TCP peer, but TCP peer equality does not prove that the remote service owns the requested web identity. A machine at the approved address can present an untrusted, expired, misissued, or wrong-name certificate; an adapter can negotiate an unexpected protocol; or an unsafe verifier can silently disable authentication. Until TLS identity is bound to the canonical Origin and the verified TCP evidence, OriginWeave cannot safely claim authenticated HTTPS navigation.

Required bounded vertical slice

Create an independently reusable Rust originweave-tls crate that performs a client TLS handshake over an already verified DirectTcpConnection. It must never open another socket, resolve a hostname, inherit proxy settings, or bypass certificate and service-identity validation.

Identity authority

  • Accept the canonical HTTPS Origin, the existing verified direct TCP connection, an explicit trust-root set, a trusted verification time, an explicit ALPN allow-list, and bounded handshake settings.
  • Derive the TLS reference identity only from the canonical origin host.
  • For a DNS origin, require an applicable dNSName subjectAltName and validate it according to RFC 9525; do not fall back to the Common Name.
  • For a literal IP origin, require the exact IP address in an iPAddress subjectAltName.
  • Reject HTTP and other non-TLS origins before handshake I/O.
  • Permit only TLS 1.2 and TLS 1.3; disable TLS 1.0, TLS 1.1, renegotiation, 0-RTT, key logging, and custom dangerous verifier hooks in production.
  • Use the already connected stream; no reconnect, hostname-based API, alternate address selection, or proxy/PAC path is allowed.
  • Require the observed TCP peer in the supplied connection evidence to remain identical before and after handshake.
  • Bound handshake wall-clock time, read/write blocking, certificate-chain size, certificate count, root count, ALPN count, and ALPN identifier length.
  • Treat revocation evidence and policy explicitly. The first slice may report that no revocation data was configured, but it must not claim revocation validation in that state.

Protocol negotiation

  • Send SNI only for a DNS reference identity; never invent a DNS name for an IP literal.
  • Offer only caller-approved ALPN identifiers.
  • Reject a negotiated ALPN value that was not offered.
  • Make the absence of ALPN an explicit policy result rather than silently assuming HTTP/1.1.
  • Retain TLS version and cipher suite as typed evidence.

Evidence and errors

Emit credential-free, immutable evidence containing:

  • canonical HTTPS origin;
  • requested and observed TCP peer inherited from SocketConnectionEvidence;
  • reference identity type and value;
  • TLS protocol version and cipher suite;
  • negotiated ALPN or explicit absence;
  • SHA-256 hashes of the leaf certificate, leaf SPKI, and every validated chain certificate;
  • trust-root bundle identifier and hash;
  • trusted verification time;
  • certificate not-before and not-after times;
  • certificate-chain count and total encoded bytes;
  • revocation-policy result;
  • handshake duration and configured deadline.

Public errors must implement deterministic Display and std::error::Error, retain underlying rustls/I/O failures as sources without leaking full certificates or secrets, and distinguish invalid origin, invalid bounds, untrusted issuer, expired/not-yet-valid certificate, service-name mismatch, invalid chain, unsupported TLS version, unexpected or absent ALPN, handshake timeout, peer mutation, and I/O failure.

Tests

  • Real loopback TLS server with a test CA and a certificate whose SAN matches localhost succeeds over a managed loopback DirectTcpConnection.
  • A certificate for another DNS name fails service-identity validation.
  • An untrusted root fails.
  • Expired and not-yet-valid certificates fail under a fixed trusted verification time.
  • DNS origin validation never falls back to Common Name.
  • Literal IPv4 and IPv6 origins require exact IP SAN entries.
  • TLS 1.0/1.1 and unexpected ALPN are rejected.
  • Explicit no-ALPN behavior is tested.
  • Oversized chain, too many certificates or roots, excessive ALPN input, zero/excessive timeout, and malformed origin fail before exposing an authenticated stream.
  • No reconnect, DNS lookup, proxy environment use, key logging, dangerous custom verifier, or 0-RTT production path.
  • The inherited requested and observed TCP peers are unchanged after handshake.
  • Exact 100% production function, line, region, and branch coverage; complete public rustdoc.

Architecture and documentation

  • Add an ADR separating TCP peer proof from TLS service identity, HTTP semantics, proxy/PAC routing, Chromium integration, client certificates, and revocation distribution.
  • Update README, ARCHITECTURE.md, CHANGELOG.md, roadmap, quality gates, and APA 7th doctoring.
  • Cite RFC 8446 for TLS 1.3, RFC 9525 for service identity, RFC 5280 for PKIX certificate validation, and the exact pinned rustls documentation/version used by the implementation.
  • Record why RFC 9525 supersedes the older RFC 6125 identity guidance.

Out of scope

HTTP request/response parsing, redirects above the existing destination policy, proxy/PAC, QUIC/HTTP3, WebPKI root acquisition, automated root-store updates, OCSP/CRL fetching, delegated credentials, Encrypted ClientHello, client certificates, Chromium Network Service integration, downloads, MIME validation, and connection pooling remain later independently reviewable slices.

Commercial proof

A deterministic local integration suite shows that the same exact policy-approved TCP stream is authenticated only when its certificate chain is trusted, currently valid, and bound to the canonical origin identity, with no verifier bypass and with complete credential-free TLS evidence.

Standards references (APA 7th)

Cooper, D., Santesson, S., Farrell, S., Boeyen, S., Housley, R., & Polk, W. (2008). Internet X.509 public key infrastructure certificate and certificate revocation list (CRL) profile (RFC 5280). Internet Engineering Task Force. https://doi.org/10.17487/RFC5280

Rescorla, E. (2018). The Transport Layer Security (TLS) protocol version 1.3 (RFC 8446). Internet Engineering Task Force. https://doi.org/10.17487/RFC8446

Saint-Andre, P., & Salz, R. (2024). Service identity in TLS (RFC 9525). Internet Engineering Task Force. https://doi.org/10.17487/RFC9525

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions