diff options
author | Heikki Linnakangas | 2024-04-08 01:24:51 +0000 |
---|---|---|
committer | Heikki Linnakangas | 2024-04-08 01:24:51 +0000 |
commit | 91044ae4baeac2e501e34164a69bd5d9c4976d21 (patch) | |
tree | 030ae118927d18f14ecb8840ec6719932b79773c /src/interfaces/libpq/fe-secure-openssl.c | |
parent | d39a49c1e459804831302807c724fa6512e90cf0 (diff) |
Send ALPN in TLS handshake, require it in direct SSL connections
libpq now always tries to send ALPN. With the traditional negotiated
SSL connections, the server accepts the ALPN, and refuses the
connection if it's not what we expect, but connecting without ALPN is
still OK. With the new direct SSL connections, ALPN is mandatory.
NOTE: This uses "TBD-pgsql" as the protocol ID. We must register a
proper one with IANA before the release!
Author: Greg Stark, Heikki Linnakangas
Reviewed-by: Matthias van de Meent, Jacob Champion
Diffstat (limited to 'src/interfaces/libpq/fe-secure-openssl.c')
-rw-r--r-- | src/interfaces/libpq/fe-secure-openssl.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c index a43e74284f2..d559ed86e8d 100644 --- a/src/interfaces/libpq/fe-secure-openssl.c +++ b/src/interfaces/libpq/fe-secure-openssl.c @@ -885,6 +885,9 @@ destroy_ssl_system(void) #endif } +/* See pqcomm.h comments on OpenSSL implementation of ALPN (RFC 7301) */ +static unsigned char alpn_protos[] = PG_ALPN_PROTOCOL_VECTOR; + /* * Create per-connection SSL object, and load the client certificate, * private key, and trusted CA certs. @@ -1233,6 +1236,22 @@ initialize_SSL(PGconn *conn) } } + /* Set ALPN */ + { + int retval; + + retval = SSL_set_alpn_protos(conn->ssl, alpn_protos, sizeof(alpn_protos)); + + if (retval != 0) + { + char *err = SSLerrmessage(ERR_get_error()); + + libpq_append_conn_error(conn, "could not set ssl alpn extension: %s", err); + SSLerrfree(err); + return -1; + } + } + /* * Read the SSL key. If a key is specified, treat it as an engine:key * combination if there is colon present - we don't support files with @@ -1754,6 +1773,7 @@ PQsslAttributeNames(PGconn *conn) "cipher", "compression", "protocol", + "alpn", NULL }; static const char *const empty_attrs[] = {NULL}; @@ -1808,6 +1828,21 @@ PQsslAttribute(PGconn *conn, const char *attribute_name) if (strcmp(attribute_name, "protocol") == 0) return SSL_get_version(conn->ssl); + if (strcmp(attribute_name, "alpn") == 0) + { + const unsigned char *data; + unsigned int len; + static char alpn_str[256]; /* alpn doesn't support longer than 255 + * bytes */ + + SSL_get0_alpn_selected(conn->ssl, &data, &len); + if (data == NULL || len == 0 || len > sizeof(alpn_str) - 1) + return NULL; + memcpy(alpn_str, data, len); + alpn_str[len] = 0; + return alpn_str; + } + return NULL; /* unknown attribute */ } |