# ./pullrev.sh 1891138 http://svn.apache.org/viewvc?view=revision&revision=1891138 https://bugzilla.redhat.com/show_bug.cgi?id=1976080 --- httpd-2.4.48/modules/ssl/ssl_engine_init.c.r1891138 +++ httpd-2.4.48/modules/ssl/ssl_engine_init.c @@ -1335,6 +1335,22 @@ return 0; } +/* SSL_CTX_use_PrivateKey_file() can fail either because the private + * key was encrypted, or due to a mismatch between an already-loaded + * cert and the key - a common misconfiguration - from calling + * X509_check_private_key(). This macro is passed the last error code + * off the OpenSSL stack and evaluates to true only for the first + * case. With OpenSSL < 3 the second case is identifiable by the + * function code, but function codes are not used from 3.0. */ +#if OPENSSL_VERSION_NUMBER < 0x30000000L +#define CHECK_PRIVKEY_ERROR(ec) (ERR_GET_FUNC(ec) != X509_F_X509_CHECK_PRIVATE_KEY) +#else +#define CHECK_PRIVKEY_ERROR(ec) (ERR_GET_LIB != ERR_LIB_X509 \ + || (ERR_GET_REASON(ec) != X509_R_KEY_TYPE_MISMATCH \ + && ERR_GET_REASON(ec) != X509_R_KEY_VALUES_MISMATCH \ + && ERR_GET_REASON(ec) != X509_R_UNKNOWN_KEY_TYPE)) +#endif + static apr_status_t ssl_init_server_certs(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp, @@ -1412,8 +1412,7 @@ } else if ((SSL_CTX_use_PrivateKey_file(mctx->ssl_ctx, keyfile, SSL_FILETYPE_PEM) < 1) - && (ERR_GET_FUNC(ERR_peek_last_error()) - != X509_F_X509_CHECK_PRIVATE_KEY)) { + && CHECK_PRIVKEY_ERROR(ERR_peek_last_error())) { ssl_asn1_t *asn1; const unsigned char *ptr;