-
Notifications
You must be signed in to change notification settings - Fork 8
fix(ssl): sslmode=verify-ca and verify-full fail with UnknownIssuer when server does not send full chain #712
Copy link
Copy link
Description
Problem
sslmode=verify-ca and sslmode=verify-full fail with:
rpg: SSL error: certificate verification failed: invalid peer certificate: UnknownIssuer
even when the correct CA cert is provided via sslrootcert, if the Postgres server does not include intermediate/CA certificates in its TLS handshake.
psql (via OpenSSL) handles this correctly: OpenSSL can validate a chain using only the root cert and the leaf cert. rustls (used by rpg) requires the full intermediate chain to be present in the TLS handshake.
Reproduction
# Server configured with: ssl_cert_file = server.crt (leaf only, CA-signed)
# CA cert available locally at /path/to/ca.crt
rpg -h host -p 5432 -U postgres sslmode=verify-ca sslrootcert=/path/to/ca.crt -c "SELECT 1"
# => SSL error: certificate verification failed: invalid peer certificate: UnknownIssuerpsql with the same flags succeeds.
Root cause
rustls's WebPkiServerVerifier requires the full certificate chain in the TLS handshake. Postgres by default only sends the leaf cert. OpenSSL can complete the chain from the local trust store; rustls cannot.
Possible fixes
- Configure Postgres to send the full chain via
ssl_cert_filecontaining concatenated leaf + CA certs (workaround, not a fix in rpg) - Implement AIA (Authority Information Access) fetching to retrieve intermediates — complex
- Use a different chain-building strategy: try matching intermediates from the local root store when they are not sent by the server
References
- Fixed in PR fix(ssl): implement sslmode=require without cert verification #711:
sslmode=require(no cert verification) — unrelated - Discovered during connection path matrix audit (issue test: verify all connection paths work correctly #709, Section D)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels