diff options
author | Heikki Linnakangas | 2024-04-29 15:12:24 +0000 |
---|---|---|
committer | Heikki Linnakangas | 2024-04-29 15:12:24 +0000 |
commit | 03a0e0d4bb78f23449802463ceea3c5bf8d4838a (patch) | |
tree | 00e9fd1f8e6e270e9e1386c02326e9349d6c0f69 | |
parent | 87d2801d4b247b85b70553e43b7e6db0a1e9e7cb (diff) |
libpq: Enforce ALPN in direct SSL connections
ALPN is mandatory with direct SSL connections. That is documented, and
the server checks it, but libpq was missing the check.
Reported-by: Jacob Champion
Reviewed-by: Michael Paquier
Discussion: https://www.postgresql.org/message-id/CAOYmi+=sj+1uydS0NR4nYzw-LRWp3Q-s5speBug5UCLSPMbvGA@mail.gmail.com
-rw-r--r-- | src/interfaces/libpq/fe-secure-openssl.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c index 33362000d3..0de21dc7e4 100644 --- a/src/interfaces/libpq/fe-secure-openssl.c +++ b/src/interfaces/libpq/fe-secure-openssl.c @@ -1585,6 +1585,34 @@ open_client_SSL(PGconn *conn) } } + /* ALPN is mandatory with direct SSL connections */ + if (conn->current_enc_method == ENC_DIRECT_SSL) + { + const unsigned char *selected; + unsigned int len; + + SSL_get0_alpn_selected(conn->ssl, &selected, &len); + + if (selected == NULL) + { + libpq_append_conn_error(conn, "direct SSL connection was established without ALPN protocol negotiation extension"); + pgtls_close(conn); + return PGRES_POLLING_FAILED; + } + + /* + * We only support one protocol so that's what the negotiation should + * always choose, but doesn't hurt to check. + */ + if (len != strlen(PG_ALPN_PROTOCOL) || + memcmp(selected, PG_ALPN_PROTOCOL, strlen(PG_ALPN_PROTOCOL)) != 0) + { + libpq_append_conn_error(conn, "SSL connection was established with unexpected ALPN protocol"); + pgtls_close(conn); + return PGRES_POLLING_FAILED; + } + } + /* * We already checked the server certificate in initialize_SSL() using * SSL_CTX_set_verify(), if root.crt exists. |