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.
Internal module: not part of the public API. Import the pg_connection hub instead; what it re-exports is the supported surface (see tests/api_surface.golden).
Procs
proc negotiateSSL(conn: PgConnection; config: ConnConfig; sslHost: string): owned( Future[void]) {....stackTrace: false, raises: [Exception, PgConfigError, PgConnectionError, ValueError, CancelledError, PgStateError, CatchableError], tags: [RootEffect, WriteIOEffect], forbids: [].}
- Negotiate TLS (SSLRequest or Direct). sslHost is cert verification name.
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.