Skip to content

tls-util: support tls-server-end-point channel binding for rustls - #39431

Draft
jasonhernandez wants to merge 1 commit into
jason/tls-stack-2-rustls-connectorfrom
jason/tls-stack-3-channel-binding
Draft

jasonhernandez wants to merge 1 commit into
jason/tls-stack-2-rustls-connectorfrom
jason/tls-stack-3-channel-binding

Conversation

@jasonhernandez

@jasonhernandez jasonhernandez commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Motivation

Part 3 of the TLS migration stack replacing #36085. Stack: #39428 → #39430 → #39431 and #39432 (both based on #39430).

Without channel binding, connections through make_tls_rustls cannot use SCRAM-SHA-256-PLUS, which the OpenSSL connector supports.

Description

  • Add tls_server_end_point, the RFC 5929 tls-server-end-point digest. It hashes the leaf certificate with its signature algorithm's hash, upgrades MD5 and SHA-1 to SHA-256, and returns None for algorithms without a single hash, such as Ed25519 and RSASSA-PSS. OpenSSL behaves the same way.
  • RustlsTlsStream::channel_binding now returns the digest.
  • Parses the certificate with x509-cert and hashes with sha2. This adds three new Cargo.lock entries: x509-cert, plus der_derive and flagset, which it pulls in. der, spki and const-oid are already locked.

Verification

tls_server_end_point_digests compares the digest with OpenSSL's certificate digest for RSA signed with SHA-224/256/384/512 and SHA-1, and for ECDSA signed with SHA-256/384. It also checks that Ed25519 returns None. tls_server_end_point_rejects_garbage covers unparseable input.

🤖 Generated with Claude Code

@jasonhernandez
jasonhernandez force-pushed the jason/tls-stack-2-rustls-connector branch from 0f0a2dc to 95855dc Compare October 27, 2026 07:09
@jasonhernandez
jasonhernandez force-pushed the jason/tls-stack-3-channel-binding branch from 0558f48 to c6dd533 Compare October 27, 2026 07:09
jasonhernandez added a commit that referenced this pull request Oct 27, 2026
### Motivation

First PR in the TLS migration stack replacing #36085: #39428 (this,
OpenSSL handshake tests) → #39430 (rustls Postgres connector) → #39431
(channel binding) and #39432 (nightly public-CA check). #39433
(pgwire-common `TlsStream` bridge) is independent, based on main.

These tests pin down today's OpenSSL TLS client behavior in
`mz-tls-util` ahead of the rustls migration, which will extend each test
with a rustls leg. Split out of #36085.

### Description

- `verify_full_trusts_default_store`: with `sslmode=verify-full` and no
`sslrootcert`, `make_tls` trusts a CA from the default store
(`SSL_CERT_FILE`).
- `client_certs_accepted`: `make_tls` presents the configured client
certificate to a server that requires one.
- Harness: a throwaway `TestCa`, a blocking OpenSSL `SslAcceptor` server
on a background thread, and connect/assert helpers.
- `tempfile` and `tokio` added as dev-dependencies (both existing
workspace deps). No production code changes.

### Verification

Ran the tests repeatedly under nextest. Confirmed each fails when its
property is broken (no `SSL_CERT_FILE`, no client cert).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Jason Hernandez <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
@jasonhernandez
jasonhernandez force-pushed the jason/tls-stack-2-rustls-connector branch from 95855dc to 0017751 Compare October 28, 2026 00:32
`RustlsTlsStream::channel_binding` now reports the RFC 5929
tls-server-end-point binding of the server's leaf certificate, so
connections through `make_tls_rustls` can authenticate with
SCRAM-SHA-256-PLUS like the openssl connector. The certificate is hashed
with its signature algorithm's hash function, MD5 and SHA-1 upgraded to
SHA-256. Algorithms without a single hash function, such as Ed25519,
report no binding, as openssl does.

Tests compare the binding against openssl's certificate digest for RSA
and ECDSA certificates across hash functions, and check that Ed25519 and
unparseable certificates yield none.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@jasonhernandez
jasonhernandez force-pushed the jason/tls-stack-3-channel-binding branch from c6dd533 to 843bc92 Compare October 28, 2026 05:53

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant