TLS/SSL negotiation for PostgreSQL connections.
Implements both libpq negotiation styles: the traditional SSLRequest handshake (sslnegotiation=postgres) and Direct SSL, which starts TLS immediately and requires the "postgresql" ALPN protocol (sslnegotiation=direct, PostgreSQL 17+). The TLS handshake itself is shared by establishTls under both async backends:
- chronos: BearSSL-based TLS via chronos/streams/tlsstream, with custom trust anchor parsing (parseTrustAnchors) and X.509 capture for SCRAM-SHA-256-PLUS channel binding (installX509Capture).
- asyncdispatch: OpenSSL via std/asyncnet.wrapConnectedSocket, with PEM trust anchors written to a temp file and SSL_get_peer_certificate used for channel binding.
User-visible backend differences and the stderr-only downgrade notices are listed in the async_postgres module doc ("Async Backend"), and the ones that matter for choosing a backend again in the README; update both with any behavior change here.
Internal module: not part of the public API. Import the pg_connection hub instead.
Procs
proc negotiateSSL(conn: PgConnection; config: ConnConfig; sslHost: string): owned( Future[void]) {....stackTrace: false, raises: [Exception, PgConfigError], tags: [RootEffect, WriteIOEffect], forbids: [].}
- Negotiate TLS (SSLRequest or Direct). sslHost is cert verification name. Only prefer falls back to plaintext on 'N'; without TLS in this build, prefer and allow return at once (a notice only if a client certificate is configured). Downgrade and fallback notices (plaintext fallback, dropped client certificate) go to stderr only; no tracer event is emitted (full list in the async_postgres module doc). Raises PgConfigError on an invalid config, PgProtocolError on a reply the server must not send, PgSecurityError on a security refusal (data trailing 'S' included), and PgConnectionError otherwise.
proc sniName(sslHost: string; sslSni: bool): string {....raises: [], tags: [], forbids: [].}
- SNI value. Empty = no SNI (IP literal or no host).
proc validateDirectSslCompatible(config: ConnConfig) {....raises: [PgConfigError], tags: [], forbids: [].}
- Reject sslnegotiation=direct with weak sslmode.