diff options
Diffstat (limited to 'src/backend/libpq/be-secure-openssl.c')
-rw-r--r-- | src/backend/libpq/be-secure-openssl.c | 56 |
1 files changed, 36 insertions, 20 deletions
diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c index 9d503104be3..c8cd81d8537 100644 --- a/src/backend/libpq/be-secure-openssl.c +++ b/src/backend/libpq/be-secure-openssl.c @@ -76,6 +76,7 @@ static int alpn_cb(SSL *ssl, void *userdata); static bool initialize_dh(SSL_CTX *context, bool isServerStart); static bool initialize_ecdh(SSL_CTX *context, bool isServerStart); +static const char *SSLerrmessageExt(unsigned long ecode, const char *replacement); static const char *SSLerrmessage(unsigned long ecode); static char *X509_NAME_to_cstring(X509_NAME *name); @@ -1409,36 +1410,51 @@ static bool initialize_ecdh(SSL_CTX *context, bool isServerStart) { #ifndef OPENSSL_NO_ECDH - EC_KEY *ecdh; - int nid; - - nid = OBJ_sn2nid(SSLECDHCurve); - if (!nid) - { - ereport(isServerStart ? FATAL : LOG, - (errcode(ERRCODE_CONFIG_FILE_ERROR), - errmsg("ECDH: unrecognized curve name: %s", SSLECDHCurve))); - return false; - } - - ecdh = EC_KEY_new_by_curve_name(nid); - if (!ecdh) + if (SSL_CTX_set1_groups_list(context, SSLECDHCurve) != 1) { + /* + * OpenSSL 3.3.0 introduced proper error messages for group parsing + * errors, earlier versions returns "no SSL error reported" which is + * far from helpful. For older versions, we replace with a better + * error message. Injecting the error into the OpenSSL error queue + * need APIs from OpenSSL 3.0. + */ ereport(isServerStart ? FATAL : LOG, - (errcode(ERRCODE_CONFIG_FILE_ERROR), - errmsg("ECDH: could not create key"))); + errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("failed to set group names specified in ssl_groups: %s", + SSLerrmessageExt(ERR_get_error(), + _("No valid groups found"))), + errhint("Ensure that each group name is spelled correctly and supported by the installed version of OpenSSL")); return false; } - - SSL_CTX_set_options(context, SSL_OP_SINGLE_ECDH_USE); - SSL_CTX_set_tmp_ecdh(context, ecdh); - EC_KEY_free(ecdh); #endif return true; } /* + * Obtain reason string for passed SSL errcode with replacement + * + * The error message supplied in replacement will be used in case the error + * code from OpenSSL is 0, else the error message from SSLerrmessage() will + * be returned. + * + * Not all versions of OpenSSL place an error on the queue even for failing + * operations, which will yield "no SSL error reported" by SSLerrmessage. This + * function can be used to ensure that a proper error message is displayed for + * versions reporting no error, while using the OpenSSL error via SSLerrmessage + * for versions where there is one. + */ +static const char * +SSLerrmessageExt(unsigned long ecode, const char *replacement) +{ + if (ecode == 0) + return replacement; + else + return SSLerrmessage(ecode); +} + +/* * Obtain reason string for passed SSL errcode * * ERR_get_error() is used by caller to get errcode to pass here. |