diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c index fc46a33539..60cf68aac4 100644 --- a/src/backend/libpq/be-secure-openssl.c +++ b/src/backend/libpq/be-secure-openssl.c @@ -1336,10 +1336,14 @@ alpn_cb(SSL *ssl, if (retval == OPENSSL_NPN_NEGOTIATED) return SSL_TLSEXT_ERR_OK; - else if (retval == OPENSSL_NPN_NO_OVERLAP) - return SSL_TLSEXT_ERR_NOACK; else - return SSL_TLSEXT_ERR_NOACK; + { + /* + * The client doesn't support our protocol. Reject the connection + * with TLS "no_application_protocol" alert, per RFC 7301. + */ + return SSL_TLSEXT_ERR_ALERT_FATAL; + } } diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c index 0de21dc7e4..ee1a47f2b1 100644 --- a/src/interfaces/libpq/fe-secure-openssl.c +++ b/src/interfaces/libpq/fe-secure-openssl.c @@ -1741,6 +1741,18 @@ SSLerrmessage(unsigned long ecode) return errbuf; } + if (ERR_GET_LIB(ecode) == ERR_LIB_SSL && + ERR_GET_REASON(ecode) == SSL_AD_REASON_OFFSET + SSL_AD_NO_APPLICATION_PROTOCOL) + { + /* + * Server aborted the connection with TLS "no_application_protocol" + * alert. The ERR_reason_error_string() function doesn't give any + * error string for that for some reason, so do it ourselves. + */ + snprintf(errbuf, SSL_ERR_LEN, libpq_gettext("no application protocol")); + return errbuf; + } + /* * In OpenSSL 3.0.0 and later, ERR_reason_error_string randomly refuses to * map system errno values. We can cover that shortcoming with this bit