diff options
author | Yann Ylavic <ylavic@apache.org> | 2020-04-24 18:09:02 +0200 |
---|---|---|
committer | Yann Ylavic <ylavic@apache.org> | 2020-04-24 18:09:02 +0200 |
commit | 316aea784d9423688ea38943d95d1d2b614fc921 (patch) | |
tree | 7ac34435edba49660bdb50f8cb97cd041f93ba59 /modules/ssl | |
parent | Revert r1876869 because on trunk server/listen.c (diff) | |
download | apache2-316aea784d9423688ea38943d95d1d2b614fc921.tar.xz apache2-316aea784d9423688ea38943d95d1d2b614fc921.zip |
mod_ssl: add compatibility with OpenSSL 3.0.0
Wrappers around deprecated API:
* X509_STORE_load_locations() => modssl_X509_STORE_load_locations(),
* CTX_load_verify_locations() => modssl_CTX_load_verify_locations(),
* ERR_peek_error_line_data() => modssl_ERR_peek_error_data(),
* DH_bits(dh) => BN_num_bits(DH_get0_p(dh)).
Provide a compatible version of ssl_callback_SessionTicket() which does not
use the deprecated HMAC_CTX and HMAC_Init_ex(), replaced by EVP_MAC_CTX and
EVP_MAC_CTX_set_params() respectively. This requires adapting struct
modssl_ticket_key_t to replace hmac_secret[] with OSSL_PARAM mac_params[],
created once at load time still.
The callback is registered by SSL_CTX_set_tlsext_ticket_key_evp_cb() instead
of SSL_CTX_set_tlsext_ticket_key_cb().
Since BIO_eof() may now be called openssl-3 state machine, the never-called
assertion in bio_filter_in_ctrl() does not hold anymore, and we have to
handle BIO_CTRL_EOF. For any other cmd, we continue to AP_DEBUG_ASSERT(0) and
log an error, yet the return value is changed from -1 to 0 which is the usual
unhandled value.
Note that OpenSSL 3.0.0 is still in alpha stage as of now, the API shouldn't
change though, neither breakage to 1.x.x API.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1876934 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'modules/ssl')
-rw-r--r-- | modules/ssl/ssl_engine_init.c | 76 | ||||
-rw-r--r-- | modules/ssl/ssl_engine_io.c | 15 | ||||
-rw-r--r-- | modules/ssl/ssl_engine_kernel.c | 22 | ||||
-rw-r--r-- | modules/ssl/ssl_engine_log.c | 12 | ||||
-rw-r--r-- | modules/ssl/ssl_private.h | 19 |
5 files changed, 119 insertions, 25 deletions
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c index 29810726c5..9a64ce5760 100644 --- a/modules/ssl/ssl_engine_init.c +++ b/modules/ssl/ssl_engine_init.c @@ -894,6 +894,23 @@ static void ssl_init_ctx_callbacks(server_rec *s, #endif } +static APR_INLINE +int modssl_CTX_load_verify_locations(SSL_CTX *ctx, + const char *file, + const char *path) +{ +#if OPENSSL_VERSION_NUMBER < 0x30000000L + if (!SSL_CTX_load_verify_locations(ctx, file, path)) + return 0; +#else + if (file && !SSL_CTX_load_verify_file(ctx, file)) + return 0; + if (path && !SSL_CTX_load_verify_dir(ctx, path)) + return 0; +#endif + return 1; +} + static apr_status_t ssl_init_ctx_verify(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp, @@ -934,10 +951,8 @@ static apr_status_t ssl_init_ctx_verify(server_rec *s, ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s, "Configuring client authentication"); - if (!SSL_CTX_load_verify_locations(ctx, - mctx->auth.ca_cert_file, - mctx->auth.ca_cert_path)) - { + if (!modssl_CTX_load_verify_locations(ctx, mctx->auth.ca_cert_file, + mctx->auth.ca_cert_path)) { ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01895) "Unable to configure verify locations " "for client authentication"); @@ -1022,6 +1037,23 @@ static apr_status_t ssl_init_ctx_cipher_suite(server_rec *s, return APR_SUCCESS; } +static APR_INLINE +int modssl_X509_STORE_load_locations(X509_STORE *store, + const char *file, + const char *path) +{ +#if OPENSSL_VERSION_NUMBER < 0x30000000L + if (!X509_STORE_load_locations(store, file, path)) + return 0; +#else + if (file && !X509_STORE_load_file(store, file)) + return 0; + if (path && !X509_STORE_load_path(store, path)) + return 0; +#endif + return 1; +} + static apr_status_t ssl_init_ctx_crl(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp, @@ -1060,8 +1092,8 @@ static apr_status_t ssl_init_ctx_crl(server_rec *s, ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01900) "Configuring certificate revocation facility"); - if (!store || !X509_STORE_load_locations(store, mctx->crl_file, - mctx->crl_path)) { + if (!store || modssl_X509_STORE_load_locations(store, mctx->crl_file, + mctx->crl_path)) { ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01901) "Host %s: unable to configure X.509 CRL storage " "for certificate revocation", mctx->sc->vhost_id); @@ -1300,7 +1332,7 @@ static apr_status_t ssl_init_server_certs(server_rec *s, const char *vhost_id = mctx->sc->vhost_id, *key_id, *certfile, *keyfile; int i; X509 *cert; - DH *dhparams; + DH *dh; #ifdef HAVE_ECC EC_GROUP *ecparams = NULL; int nid; @@ -1485,12 +1517,12 @@ static apr_status_t ssl_init_server_certs(server_rec *s, */ certfile = APR_ARRAY_IDX(mctx->pks->cert_files, 0, const char *); if (certfile && !modssl_is_engine_id(certfile) - && (dhparams = ssl_dh_GetParamFromFile(certfile))) { - SSL_CTX_set_tmp_dh(mctx->ssl_ctx, dhparams); + && (dh = ssl_dh_GetParamFromFile(certfile))) { + SSL_CTX_set_tmp_dh(mctx->ssl_ctx, dh); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02540) "Custom DH parameters (%d bits) for %s loaded from %s", - DH_bits(dhparams), vhost_id, certfile); - DH_free(dhparams); + BN_num_bits(DH_get0_p(dh)), vhost_id, certfile); + DH_free(dh); } #ifdef HAVE_ECC @@ -1541,6 +1573,7 @@ static apr_status_t ssl_init_ticket_key(server_rec *s, char buf[TLSEXT_TICKET_KEY_LEN]; char *path; modssl_ticket_key_t *ticket_key = mctx->ticket_key; + int res; if (!ticket_key->file_path) { return APR_SUCCESS; @@ -1568,11 +1601,22 @@ static apr_status_t ssl_init_ticket_key(server_rec *s, } memcpy(ticket_key->key_name, buf, 16); - memcpy(ticket_key->hmac_secret, buf + 16, 16); memcpy(ticket_key->aes_key, buf + 32, 16); - - if (!SSL_CTX_set_tlsext_ticket_key_cb(mctx->ssl_ctx, - ssl_callback_SessionTicket)) { +#if OPENSSL_VERSION_NUMBER < 0x30000000L + memcpy(ticket_key->hmac_secret, buf + 16, 16); + res = SSL_CTX_set_tlsext_ticket_key_cb(mctx->ssl_ctx, + ssl_callback_SessionTicket); +#else + ticket_key->mac_params[0] = + OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, buf + 16, 16); + ticket_key->mac_params[1] = + OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, "sha256", 0); + ticket_key->mac_params[2] = + OSSL_PARAM_construct_end(); + res = SSL_CTX_set_tlsext_ticket_key_evp_cb(mctx->ssl_ctx, + ssl_callback_SessionTicket); +#endif + if (!res) { ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01913) "Unable to initialize TLS session ticket key callback " "(incompatible OpenSSL version?)"); @@ -1703,7 +1747,7 @@ static apr_status_t ssl_init_proxy_certs(server_rec *s, return ssl_die(s); } - X509_STORE_load_locations(store, pkp->ca_cert_file, NULL); + modssl_X509_STORE_load_locations(store, pkp->ca_cert_file, NULL); for (n = 0; n < ncerts; n++) { int i; diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c index 2249faf2c7..771d29c675 100644 --- a/modules/ssl/ssl_engine_io.c +++ b/modules/ssl/ssl_engine_io.c @@ -613,10 +613,19 @@ static int bio_filter_in_gets(BIO *bio, char *buf, int size) static long bio_filter_in_ctrl(BIO *bio, int cmd, long num, void *ptr) { bio_filter_in_ctx_t *inctx = (bio_filter_in_ctx_t *)BIO_get_data(bio); + switch (cmd) { +#ifdef BIO_CTRL_EOF + case BIO_CTRL_EOF: + return inctx->rc == APR_EOF; +#endif + default: + break; + } ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, inctx->f->c, - "BUG: %s() should not be called", "bio_filter_in_ctrl"); + "BUG: bio_filter_in_ctrl() should not be called with cmd=%i", + cmd); AP_DEBUG_ASSERT(0); - return -1; + return 0; } #if MODSSL_USE_OPENSSL_PRE_1_1_API @@ -641,7 +650,7 @@ static BIO_METHOD bio_filter_in_method = { bio_filter_in_read, bio_filter_in_puts, /* puts is never called */ bio_filter_in_gets, /* gets is never called */ - bio_filter_in_ctrl, /* ctrl is never called */ + bio_filter_in_ctrl, /* ctrl is called for EOF check */ bio_filter_create, bio_filter_destroy, NULL diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c index a9adea3100..21df1eeb8f 100644 --- a/modules/ssl/ssl_engine_kernel.c +++ b/modules/ssl/ssl_engine_kernel.c @@ -2611,7 +2611,11 @@ int ssl_callback_SessionTicket(SSL *ssl, unsigned char *keyname, unsigned char *iv, EVP_CIPHER_CTX *cipher_ctx, - HMAC_CTX *hctx, +#if OPENSSL_VERSION_NUMBER < 0x30000000L + HMAC_CTX *hmac_ctx, +#else + EVP_MAC_CTX *mac_ctx, +#endif int mode) { conn_rec *c = (conn_rec *)SSL_get_app_data(ssl); @@ -2638,7 +2642,13 @@ int ssl_callback_SessionTicket(SSL *ssl, } EVP_EncryptInit_ex(cipher_ctx, EVP_aes_128_cbc(), NULL, ticket_key->aes_key, iv); - HMAC_Init_ex(hctx, ticket_key->hmac_secret, 16, tlsext_tick_md(), NULL); + +#if OPENSSL_VERSION_NUMBER < 0x30000000L + HMAC_Init_ex(hmac_ctx, ticket_key->hmac_secret, 16, + tlsext_tick_md(), NULL); +#else + EVP_MAC_CTX_set_params(mac_ctx, ticket_key->mac_params); +#endif ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(02289) "TLS session ticket key for %s successfully set, " @@ -2659,7 +2669,13 @@ int ssl_callback_SessionTicket(SSL *ssl, EVP_DecryptInit_ex(cipher_ctx, EVP_aes_128_cbc(), NULL, ticket_key->aes_key, iv); - HMAC_Init_ex(hctx, ticket_key->hmac_secret, 16, tlsext_tick_md(), NULL); + +#if OPENSSL_VERSION_NUMBER < 0x30000000L + HMAC_Init_ex(hmac_ctx, ticket_key->hmac_secret, 16, + tlsext_tick_md(), NULL); +#else + EVP_MAC_CTX_set_params(mac_ctx, ticket_key->mac_params); +#endif ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(02290) "TLS session ticket key for %s successfully set, " diff --git a/modules/ssl/ssl_engine_log.c b/modules/ssl/ssl_engine_log.c index 451b83e497..6bca827d50 100644 --- a/modules/ssl/ssl_engine_log.c +++ b/modules/ssl/ssl_engine_log.c @@ -78,6 +78,16 @@ apr_status_t ssl_die(server_rec *s) return APR_EGENERAL; } +static APR_INLINE +unsigned long modssl_ERR_peek_error_data(const char **data, int *flags) +{ +#if OPENSSL_VERSION_NUMBER < 0x30000000L + return ERR_peek_error_line_data(NULL, NULL, data, flags); +#else + return ERR_peek_error_data(data, flags); +#endif +} + /* * Prints the SSL library error information. */ @@ -87,7 +97,7 @@ void ssl_log_ssl_error(const char *file, int line, int level, server_rec *s) const char *data; int flags; - while ((e = ERR_peek_error_line_data(NULL, NULL, &data, &flags))) { + while ((e = modssl_ERR_peek_error_data(&data, &flags))) { const char *annotation; char err[256]; diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h index 12d79208b1..d8213eef7e 100644 --- a/modules/ssl/ssl_private.h +++ b/modules/ssl/ssl_private.h @@ -88,6 +88,9 @@ /* must be defined before including ssl.h */ #define OPENSSL_NO_SSL_INTERN #endif +#if OPENSSL_VERSION_NUMBER >= 0x30000000 +#include <openssl/core_names.h> +#endif #include <openssl/ssl.h> #include <openssl/err.h> #include <openssl/x509.h> @@ -667,7 +670,11 @@ typedef struct { typedef struct { const char *file_path; unsigned char key_name[16]; +#if OPENSSL_VERSION_NUMBER < 0x30000000L unsigned char hmac_secret[16]; +#else + OSSL_PARAM mac_params[3]; +#endif unsigned char aes_key[16]; } modssl_ticket_key_t; #endif @@ -935,8 +942,16 @@ int ssl_callback_ServerNameIndication(SSL *, int *, modssl_ctx_t *); int ssl_callback_ClientHello(SSL *, int *, void *); #endif #ifdef HAVE_TLS_SESSION_TICKETS -int ssl_callback_SessionTicket(SSL *, unsigned char *, unsigned char *, - EVP_CIPHER_CTX *, HMAC_CTX *, int); +int ssl_callback_SessionTicket(SSL *ssl, + unsigned char *keyname, + unsigned char *iv, + EVP_CIPHER_CTX *cipher_ctx, +#if OPENSSL_VERSION_NUMBER < 0x30000000L + HMAC_CTX *hmac_ctx, +#else + EVP_MAC_CTX *mac_ctx, +#endif + int mode); #endif #ifdef HAVE_TLS_ALPN |