diff --git a/apache2-CVE-2024-36387.patch b/apache2-CVE-2024-36387.patch new file mode 100644 index 0000000..3f5b019 --- /dev/null +++ b/apache2-CVE-2024-36387.patch @@ -0,0 +1,30 @@ +commit 62aa64e5aea21dd969db97aded4443c98c0735ac +Author: Eric Covener +Date: Mon Jun 24 17:51:42 2024 +0000 + + Merge r1918548 from trunk: + + mod_http2: early exit if bb is null + + + + git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1918557 13f79535-47bb-0310-9956-ffa450edef68 + +diff --git a/modules/http2/h2_c2.c b/modules/http2/h2_c2.c +index a955200944..c65a521ab8 100644 +--- a/modules/http2/h2_c2.c ++++ b/modules/http2/h2_c2.c +@@ -370,6 +370,13 @@ static apr_status_t h2_c2_filter_out(ap_filter_t* f, apr_bucket_brigade* bb) + h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(f->c); + apr_status_t rv; + ++ if (bb == NULL) { ++#if !AP_MODULE_MAGIC_AT_LEAST(20180720, 1) ++ f->c->data_in_output_filters = 0; ++#endif ++ return APR_SUCCESS; ++ } ++ + ap_assert(conn_ctx); + #if AP_HAS_RESPONSE_BUCKETS + if (!conn_ctx->has_final_response) { diff --git a/apache2-fips-compatibility-01.patch b/apache2-fips-compatibility-01.patch new file mode 100644 index 0000000..a475586 --- /dev/null +++ b/apache2-fips-compatibility-01.patch @@ -0,0 +1,25 @@ +From e2d689b4b25008e9d3e701e86c052e877452e1cc Mon Sep 17 00:00:00 2001 +From: StephenWall <35972871+StephenWall@users.noreply.github.com> +Date: Tue, 16 Jan 2024 08:26:12 -0500 +Subject: [PATCH] Check SSL_CTX_new() return value + +SSL_CTX_new() will return NULL if there was an error creating a new SSL context. +--- + modules/ssl/ssl_engine_init.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c +index 30fd6c5e4b5..2107cf44d7c 100644 +--- a/modules/ssl/ssl_engine_init.c ++++ b/modules/ssl/ssl_engine_init.c +@@ -738,6 +738,10 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, + TLS_server_method(); /* server */ + #endif + ctx = SSL_CTX_new(method); ++ if(ctx == NULL) { ++ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); ++ return ssl_die(s); ++ } + + mctx->ssl_ctx = ctx; + diff --git a/apache2-fips-compatibility-02.patch b/apache2-fips-compatibility-02.patch new file mode 100644 index 0000000..ac8d87f --- /dev/null +++ b/apache2-fips-compatibility-02.patch @@ -0,0 +1,849 @@ +# ./pullrev.sh 1913912 1915067 + +http://svn.apache.org/viewvc?view=revision&revision=1913912 +http://svn.apache.org/viewvc?view=revision&revision=1915067 + +Upstream-Status: merged for 2.4.59 + +--- httpd-2.4.58/modules/ssl/mod_ssl.c.r1913912 ++++ httpd-2.4.58/modules/ssl/mod_ssl.c +@@ -25,8 +25,7 @@ + */ + + #include "ssl_private.h" +-#include "mod_ssl.h" +-#include "mod_ssl_openssl.h" ++ + #include "util_md5.h" + #include "util_mutex.h" + #include "ap_provider.h" +@@ -75,11 +74,9 @@ + SSL_CMD_SRV(SessionCache, TAKE1, + "SSL Session Cache storage " + "('none', 'nonenotnull', 'dbm:/path/to/file')") +-#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT) + SSL_CMD_SRV(CryptoDevice, TAKE1, + "SSL external Crypto Device usage " + "('builtin', '...')") +-#endif + SSL_CMD_SRV(RandomSeed, TAKE23, + "SSL Pseudo Random Number Generator (PRNG) seeding source " + "('startup|connect builtin|file:/path|exec:/path [bytes]')") +--- httpd-2.4.58/modules/ssl/mod_ssl_openssl.h.r1913912 ++++ httpd-2.4.58/modules/ssl/mod_ssl_openssl.h +@@ -30,14 +30,17 @@ + + /* OpenSSL headers */ + +-#ifndef SSL_PRIVATE_H + #include +-#if (OPENSSL_VERSION_NUMBER >= 0x10001000) ++#if OPENSSL_VERSION_NUMBER >= 0x30000000 ++#include /* for OPENSSL_API_LEVEL */ ++#endif ++#if OPENSSL_VERSION_NUMBER >= 0x10001000 + /* must be defined before including ssl.h */ + #define OPENSSL_NO_SSL_INTERN + #endif + #include +-#endif ++#include ++#include + + /** + * init_server hook -- allow SSL_CTX-specific initialization to be performed by +--- httpd-2.4.58/modules/ssl/ssl_engine_config.c.r1913912 ++++ httpd-2.4.58/modules/ssl/ssl_engine_config.c +@@ -27,6 +27,7 @@ + damned if you don't.'' + -- Unknown */ + #include "ssl_private.h" ++ + #include "util_mutex.h" + #include "ap_provider.h" + +@@ -593,14 +594,15 @@ + return NULL; + } + +-#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT) + const char *ssl_cmd_SSLCryptoDevice(cmd_parms *cmd, + void *dcfg, + const char *arg) + { + SSLModConfigRec *mc = myModConfig(cmd->server); + const char *err; ++#if MODSSL_HAVE_ENGINE_API + ENGINE *e; ++#endif + + if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) { + return err; +@@ -609,13 +611,16 @@ + if (strcEQ(arg, "builtin")) { + mc->szCryptoDevice = NULL; + } ++#if MODSSL_HAVE_ENGINE_API + else if ((e = ENGINE_by_id(arg))) { + mc->szCryptoDevice = arg; + ENGINE_free(e); + } ++#endif + else { + err = "SSLCryptoDevice: Invalid argument; must be one of: " + "'builtin' (none)"; ++#if MODSSL_HAVE_ENGINE_API + e = ENGINE_get_first(); + while (e) { + err = apr_pstrcat(cmd->pool, err, ", '", ENGINE_get_id(e), +@@ -624,12 +629,12 @@ + * on the 'old' e, per the docs in engine.h. */ + e = ENGINE_get_next(e); + } ++#endif + return err; + } + + return NULL; + } +-#endif + + const char *ssl_cmd_SSLRandomSeed(cmd_parms *cmd, + void *dcfg, +--- httpd-2.4.58/modules/ssl/ssl_engine_init.c.r1913912 ++++ httpd-2.4.58/modules/ssl/ssl_engine_init.c +@@ -27,8 +27,7 @@ + see Recursive.'' + -- Unknown */ + #include "ssl_private.h" +-#include "mod_ssl.h" +-#include "mod_ssl_openssl.h" ++ + #include "mpm_common.h" + #include "mod_md.h" + +@@ -218,6 +217,16 @@ + } + #endif + ++static APR_INLINE unsigned long modssl_runtime_lib_version(void) ++{ ++#if MODSSL_USE_OPENSSL_PRE_1_1_API ++ return SSLeay(); ++#else ++ return OpenSSL_version_num(); ++#endif ++} ++ ++ + /* + * Per-module initialization + */ +@@ -225,18 +234,22 @@ + apr_pool_t *ptemp, + server_rec *base_server) + { ++ unsigned long runtime_lib_version = modssl_runtime_lib_version(); + SSLModConfigRec *mc = myModConfig(base_server); + SSLSrvConfigRec *sc; + server_rec *s; + apr_status_t rv; + apr_array_header_t *pphrases; + +- if (SSLeay() < MODSSL_LIBRARY_VERSION) { ++ AP_DEBUG_ASSERT(mc); ++ ++ if (runtime_lib_version < MODSSL_LIBRARY_VERSION) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, base_server, APLOGNO(01882) + "Init: this version of mod_ssl was compiled against " +- "a newer library (%s, version currently loaded is %s)" ++ "a newer library (%s (%s), version currently loaded is 0x%lX)" + " - may result in undefined or erroneous behavior", +- MODSSL_LIBRARY_TEXT, MODSSL_LIBRARY_DYNTEXT); ++ MODSSL_LIBRARY_TEXT, MODSSL_LIBRARY_DYNTEXT, ++ runtime_lib_version); + } + + /* We initialize mc->pid per-process in the child init, +@@ -313,11 +326,9 @@ + /* + * SSL external crypto device ("engine") support + */ +-#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT) + if ((rv = ssl_init_Engine(base_server, p)) != APR_SUCCESS) { + return rv; + } +-#endif + + ap_log_error(APLOG_MARK, APLOG_INFO, 0, base_server, APLOGNO(01883) + "Init: Initialized %s library", MODSSL_LIBRARY_NAME); +@@ -473,9 +484,9 @@ + * Support for external a Crypto Device ("engine"), usually + * a hardware accelerator card for crypto operations. + */ +-#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT) + apr_status_t ssl_init_Engine(server_rec *s, apr_pool_t *p) + { ++#if MODSSL_HAVE_ENGINE_API + SSLModConfigRec *mc = myModConfig(s); + ENGINE *e; + +@@ -507,10 +518,9 @@ + + ENGINE_free(e); + } +- ++#endif + return APR_SUCCESS; + } +-#endif + + #ifdef HAVE_TLSEXT + static apr_status_t ssl_init_ctx_tls_extensions(server_rec *s, +@@ -1320,15 +1330,6 @@ + return 0; + } + +-static APR_INLINE int modssl_DH_bits(DH *dh) +-{ +-#if OPENSSL_VERSION_NUMBER < 0x30000000L +- return DH_bits(dh); +-#else +- return BN_num_bits(DH_get0_p(dh)); +-#endif +-} +- + /* 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 +@@ -1354,15 +1355,10 @@ + SSLModConfigRec *mc = myModConfig(s); + const char *vhost_id = mctx->sc->vhost_id, *key_id, *certfile, *keyfile; + int i; +- X509 *cert; +- DH *dh; ++ EVP_PKEY *pkey; + #ifdef HAVE_ECC +- EC_GROUP *ecparams = NULL; +- int nid; +- EC_KEY *eckey = NULL; +-#endif +-#ifndef HAVE_SSL_CONF_CMD +- SSL *ssl; ++ EC_GROUP *ecgroup = NULL; ++ int curve_nid = 0; + #endif + + /* no OpenSSL default prompts for any of the SSL_CTX_use_* calls, please */ +@@ -1373,7 +1369,7 @@ + (certfile = APR_ARRAY_IDX(mctx->pks->cert_files, i, + const char *)); + i++) { +- EVP_PKEY *pkey; ++ X509 *cert = NULL; + const char *engine_certfile = NULL; + + key_id = apr_psprintf(ptemp, "%s:%d", vhost_id, i); +@@ -1416,8 +1412,6 @@ + if (modssl_is_engine_id(keyfile)) { + apr_status_t rv; + +- cert = NULL; +- + if ((rv = modssl_load_engine_keypair(s, ptemp, vhost_id, + engine_certfile, keyfile, + &cert, &pkey))) { +@@ -1488,22 +1482,21 @@ + * assume that if SSL_CONF is available, it's OpenSSL 1.0.2 or later, + * and SSL_CTX_get0_certificate is implemented.) + */ +- if (!(cert = SSL_CTX_get0_certificate(mctx->ssl_ctx))) { ++ cert = SSL_CTX_get0_certificate(mctx->ssl_ctx); + #else +- ssl = SSL_new(mctx->ssl_ctx); ++ { ++ SSL *ssl = SSL_new(mctx->ssl_ctx); + if (ssl) { + /* Workaround bug in SSL_get_certificate in OpenSSL 0.9.8y */ + SSL_set_connect_state(ssl); + cert = SSL_get_certificate(ssl); ++ SSL_free(ssl); ++ } + } +- if (!ssl || !cert) { + #endif ++ if (!cert) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02566) + "Unable to retrieve certificate %s", key_id); +-#ifndef HAVE_SSL_CONF_CMD +- if (ssl) +- SSL_free(ssl); +-#endif + return APR_EGENERAL; + } + +@@ -1525,10 +1518,6 @@ + } + #endif + +-#ifndef HAVE_SSL_CONF_CMD +- SSL_free(ssl); +-#endif +- + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(02568) + "Certificate and private key %s configured from %s and %s", + key_id, certfile, keyfile); +@@ -1538,15 +1527,33 @@ + * Try to read DH parameters from the (first) SSLCertificateFile + */ + certfile = APR_ARRAY_IDX(mctx->pks->cert_files, 0, const char *); +- if (certfile && !modssl_is_engine_id(certfile) +- && (dh = ssl_dh_GetParamFromFile(certfile))) { +- /* ### This should be replaced with SSL_CTX_set0_tmp_dh_pkey() +- * for OpenSSL 3.0+. */ ++ if (certfile && !modssl_is_engine_id(certfile)) { ++ int done = 0, num_bits = 0; ++#if OPENSSL_VERSION_NUMBER < 0x30000000L ++ DH *dh = modssl_dh_from_file(certfile); ++ if (dh) { ++ num_bits = DH_bits(dh); + SSL_CTX_set_tmp_dh(mctx->ssl_ctx, dh); ++ DH_free(dh); ++ done = 1; ++ } ++#else ++ pkey = modssl_dh_pkey_from_file(certfile); ++ if (pkey) { ++ num_bits = EVP_PKEY_get_bits(pkey); ++ if (!SSL_CTX_set0_tmp_dh_pkey(mctx->ssl_ctx, pkey)) { ++ EVP_PKEY_free(pkey); ++ } ++ else { ++ done = 1; ++ } ++ } ++#endif ++ if (done) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02540) + "Custom DH parameters (%d bits) for %s loaded from %s", +- modssl_DH_bits(dh), vhost_id, certfile); +- DH_free(dh); ++ num_bits, vhost_id, certfile); ++ } + } + #if !MODSSL_USE_OPENSSL_PRE_1_1_API + else { +@@ -1561,13 +1568,27 @@ + * Similarly, try to read the ECDH curve name from SSLCertificateFile... + */ + if (certfile && !modssl_is_engine_id(certfile) +- && (ecparams = ssl_ec_GetParamFromFile(certfile)) +- && (nid = EC_GROUP_get_curve_name(ecparams)) +- && (eckey = EC_KEY_new_by_curve_name(nid))) { ++ && (ecgroup = modssl_ec_group_from_file(certfile)) ++ && (curve_nid = EC_GROUP_get_curve_name(ecgroup))) { ++#if OPENSSL_VERSION_NUMBER < 0x30000000L ++ EC_KEY *eckey = EC_KEY_new_by_curve_name(curve_nid); ++ if (eckey) { + SSL_CTX_set_tmp_ecdh(mctx->ssl_ctx, eckey); ++ EC_KEY_free(eckey); ++ } ++ else { ++ curve_nid = 0; ++ } ++#else ++ if (!SSL_CTX_set1_curves(mctx->ssl_ctx, &curve_nid, 1)) { ++ curve_nid = 0; ++ } ++#endif ++ if (curve_nid) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02541) + "ECDH curve %s for %s specified in %s", +- OBJ_nid2sn(nid), vhost_id, certfile); ++ OBJ_nid2sn(curve_nid), vhost_id, certfile); ++ } + } + /* + * ...otherwise, enable auto curve selection (OpenSSL 1.0.2) +@@ -1575,18 +1596,20 @@ + * ECDH is always enabled in 1.1.0 unless excluded from SSLCipherList + */ + #if MODSSL_USE_OPENSSL_PRE_1_1_API +- else { ++ if (!curve_nid) { + #if defined(SSL_CTX_set_ecdh_auto) + SSL_CTX_set_ecdh_auto(mctx->ssl_ctx, 1); + #else +- eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); ++ EC_KEY *eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); ++ if (eckey) { + SSL_CTX_set_tmp_ecdh(mctx->ssl_ctx, eckey); ++ EC_KEY_free(eckey); ++ } + #endif + } + #endif + /* OpenSSL assures us that _free() is NULL-safe */ +- EC_KEY_free(eckey); +- EC_GROUP_free(ecparams); ++ EC_GROUP_free(ecgroup); + #endif + + return APR_SUCCESS; +--- httpd-2.4.58/modules/ssl/ssl_engine_io.c.r1913912 ++++ httpd-2.4.58/modules/ssl/ssl_engine_io.c +@@ -28,8 +28,7 @@ + core keeps dumping.'' + -- Unknown */ + #include "ssl_private.h" +-#include "mod_ssl.h" +-#include "mod_ssl_openssl.h" ++ + #include "apr_date.h" + + APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, proxy_post_handshake, +@@ -2283,14 +2282,7 @@ + ssl_io_filter_cleanup, apr_pool_cleanup_null); + + if (APLOG_CS_IS_LEVEL(c, mySrvFromConn(c), APLOG_TRACE4)) { +- BIO *rbio = SSL_get_rbio(ssl), +- *wbio = SSL_get_wbio(ssl); +- BIO_set_callback(rbio, ssl_io_data_cb); +- BIO_set_callback_arg(rbio, (void *)ssl); +- if (wbio && wbio != rbio) { +- BIO_set_callback(wbio, ssl_io_data_cb); +- BIO_set_callback_arg(wbio, (void *)ssl); +- } ++ modssl_set_io_callbacks(ssl); + } + + return; +@@ -2374,13 +2366,22 @@ + "+-------------------------------------------------------------------------+"); + } + +-long ssl_io_data_cb(BIO *bio, int cmd, +- const char *argp, ++#if OPENSSL_VERSION_NUMBER >= 0x30000000L ++static long modssl_io_cb(BIO *bio, int cmd, const char *argp, ++ size_t len, int argi, long argl, int rc, ++ size_t *processed) ++#else ++static long modssl_io_cb(BIO *bio, int cmd, const char *argp, + int argi, long argl, long rc) ++#endif + { + SSL *ssl; + conn_rec *c; + server_rec *s; ++#if OPENSSL_VERSION_NUMBER >= 0x30000000L ++ (void)len; ++ (void)processed; ++#endif + + if ((ssl = (SSL *)BIO_get_callback_arg(bio)) == NULL) + return rc; +@@ -2402,7 +2403,7 @@ + "%s: %s %ld/%d bytes %s BIO#%pp [mem: %pp] %s", + MODSSL_LIBRARY_NAME, + (cmd == (BIO_CB_WRITE|BIO_CB_RETURN) ? "write" : "read"), +- rc, argi, (cmd == (BIO_CB_WRITE|BIO_CB_RETURN) ? "to" : "from"), ++ (long)rc, argi, (cmd == (BIO_CB_WRITE|BIO_CB_RETURN) ? "to" : "from"), + bio, argp, dump); + if (*dump != '\0' && argp != NULL) + ssl_io_data_dump(c, s, argp, rc); +@@ -2417,3 +2418,25 @@ + } + return rc; + } ++ ++static APR_INLINE void set_bio_callback(BIO *bio, void *arg) ++{ ++#if OPENSSL_VERSION_NUMBER >= 0x30000000L ++ BIO_set_callback_ex(bio, modssl_io_cb); ++#else ++ BIO_set_callback(bio, modssl_io_cb); ++#endif ++ BIO_set_callback_arg(bio, arg); ++} ++ ++void modssl_set_io_callbacks(SSL *ssl) ++{ ++ BIO *rbio = SSL_get_rbio(ssl), ++ *wbio = SSL_get_wbio(ssl); ++ if (rbio) { ++ set_bio_callback(rbio, ssl); ++ } ++ if (wbio && wbio != rbio) { ++ set_bio_callback(wbio, ssl); ++ } ++} +--- httpd-2.4.58/modules/ssl/ssl_engine_kernel.c.r1913912 ++++ httpd-2.4.58/modules/ssl/ssl_engine_kernel.c +@@ -2581,6 +2581,7 @@ + sc->server->pks->service_unavailable : 0; + + ap_update_child_status_from_server(c->sbh, SERVER_BUSY_READ, c, s); ++ + /* + * There is one special filter callback, which is set + * very early depending on the base_server's log level. +@@ -2589,14 +2590,7 @@ + * we need to set that callback here. + */ + if (APLOGtrace4(s)) { +- BIO *rbio = SSL_get_rbio(ssl), +- *wbio = SSL_get_wbio(ssl); +- BIO_set_callback(rbio, ssl_io_data_cb); +- BIO_set_callback_arg(rbio, (void *)ssl); +- if (wbio && wbio != rbio) { +- BIO_set_callback(wbio, ssl_io_data_cb); +- BIO_set_callback_arg(wbio, (void *)ssl); +- } ++ modssl_set_io_callbacks(ssl); + } + + return 1; +--- httpd-2.4.58/modules/ssl/ssl_engine_pphrase.c.r1913912 ++++ httpd-2.4.58/modules/ssl/ssl_engine_pphrase.c +@@ -30,6 +30,8 @@ + -- Clifford Stoll */ + #include "ssl_private.h" + ++#include ++ + typedef struct { + server_rec *s; + apr_pool_t *p; +@@ -606,8 +608,7 @@ + return (len); + } + +- +-#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT) ++#if MODSSL_HAVE_ENGINE_API + + /* OpenSSL UI implementation for passphrase entry; largely duplicated + * from ssl_pphrase_Handle_CB but adjusted for UI API. TODO: Might be +@@ -831,7 +832,7 @@ + const char *certid, const char *keyid, + X509 **pubkey, EVP_PKEY **privkey) + { +-#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT) ++#if MODSSL_HAVE_ENGINE_API + const char *c, *scheme; + ENGINE *e; + UI_METHOD *ui_method = get_passphrase_ui(p); +--- httpd-2.4.58/modules/ssl/ssl_private.h.r1913912 ++++ httpd-2.4.58/modules/ssl/ssl_private.h +@@ -83,16 +83,13 @@ + + #include "ap_expr.h" + +-/* OpenSSL headers */ +-#include +-#if (OPENSSL_VERSION_NUMBER >= 0x10001000) +-/* must be defined before including ssl.h */ +-#define OPENSSL_NO_SSL_INTERN +-#endif +-#if OPENSSL_VERSION_NUMBER >= 0x30000000 +-#include ++/* keep first for compat API */ ++#ifndef OPENSSL_API_COMPAT ++#define OPENSSL_API_COMPAT 0x10101000 /* for ENGINE_ API */ + #endif +-#include ++#include "mod_ssl_openssl.h" ++ ++/* OpenSSL headers */ + #include + #include + #include +@@ -102,12 +99,23 @@ + #include + #include + #include ++#include ++#if OPENSSL_VERSION_NUMBER >= 0x30000000 ++#include ++#endif + + /* Avoid tripping over an engine build installed globally and detected + * when the user points at an explicit non-engine flavor of OpenSSL + */ +-#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT) ++#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT) \ ++ && (OPENSSL_VERSION_NUMBER < 0x30000000 \ ++ || (defined(OPENSSL_API_LEVEL) && OPENSSL_API_LEVEL < 30000)) \ ++ && !defined(OPENSSL_NO_ENGINE) + #include ++#define MODSSL_HAVE_ENGINE_API 1 ++#endif ++#ifndef MODSSL_HAVE_ENGINE_API ++#define MODSSL_HAVE_ENGINE_API 0 + #endif + + #if (OPENSSL_VERSION_NUMBER < 0x0090801f) +@@ -142,10 +150,18 @@ + * include most changes from OpenSSL >= 1.1 (new functions, macros, + * deprecations, ...), so we have to work around this... + */ +-#define MODSSL_USE_OPENSSL_PRE_1_1_API (LIBRESSL_VERSION_NUMBER < 0x2070000f) ++#if LIBRESSL_VERSION_NUMBER < 0x2070000f ++#define MODSSL_USE_OPENSSL_PRE_1_1_API 1 ++#else ++#define MODSSL_USE_OPENSSL_PRE_1_1_API 0 ++#endif + #else /* defined(LIBRESSL_VERSION_NUMBER) */ +-#define MODSSL_USE_OPENSSL_PRE_1_1_API (OPENSSL_VERSION_NUMBER < 0x10100000L) ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++#define MODSSL_USE_OPENSSL_PRE_1_1_API 1 ++#else ++#define MODSSL_USE_OPENSSL_PRE_1_1_API 0 + #endif ++#endif /* defined(LIBRESSL_VERSION_NUMBER) */ + + #if defined(OPENSSL_FIPS) || OPENSSL_VERSION_NUMBER >= 0x30000000L + #define HAVE_FIPS +@@ -211,7 +227,10 @@ + #endif + + /* Secure Remote Password */ +-#if !defined(OPENSSL_NO_SRP) && defined(SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB) ++#if !defined(OPENSSL_NO_SRP) \ ++ && (OPENSSL_VERSION_NUMBER < 0x30000000L \ ++ || (defined(OPENSSL_API_LEVEL) && OPENSSL_API_LEVEL < 30000)) \ ++ && defined(SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB) + #define HAVE_SRP + #include + #endif +@@ -254,6 +273,14 @@ + #endif + #endif + ++/* those may be deprecated */ ++#ifndef X509_get_notBefore ++#define X509_get_notBefore X509_getm_notBefore ++#endif ++#ifndef X509_get_notAfter ++#define X509_get_notAfter X509_getm_notAfter ++#endif ++ + #if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER) + #define HAVE_OPENSSL_KEYLOG + #endif +@@ -1019,7 +1046,7 @@ + /** I/O */ + void ssl_io_filter_init(conn_rec *, request_rec *r, SSL *); + void ssl_io_filter_register(apr_pool_t *); +-long ssl_io_data_cb(BIO *, int, const char *, int, long, long); ++void modssl_set_io_callbacks(SSL *ssl); + + /* ssl_io_buffer_fill fills the setaside buffering of the HTTP request + * to allow an SSL renegotiation to take place. */ +@@ -1057,9 +1084,13 @@ + X509 **pubkey, EVP_PKEY **privkey); + + /** Diffie-Hellman Parameter Support */ +-DH *ssl_dh_GetParamFromFile(const char *); ++#if OPENSSL_VERSION_NUMBER < 0x30000000L ++DH *modssl_dh_from_file(const char *); ++#else ++EVP_PKEY *modssl_dh_pkey_from_file(const char *); ++#endif + #ifdef HAVE_ECC +-EC_GROUP *ssl_ec_GetParamFromFile(const char *); ++EC_GROUP *modssl_ec_group_from_file(const char *); + #endif + + /* Store the EVP_PKEY key (serialized into DER) in the hash table with +--- httpd-2.4.58/modules/ssl/ssl_util.c.r1913912 ++++ httpd-2.4.58/modules/ssl/ssl_util.c +@@ -476,7 +476,7 @@ + + int modssl_is_engine_id(const char *name) + { +-#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT) ++#if MODSSL_HAVE_ENGINE_API + /* ### Can handle any other special ENGINE key names here? */ + return strncmp(name, "pkcs11:", 7) == 0; + #else +--- httpd-2.4.58/modules/ssl/ssl_util_ssl.c.r1913912 ++++ httpd-2.4.58/modules/ssl/ssl_util_ssl.c +@@ -464,29 +464,52 @@ + ** _________________________________________________________________ + */ + +-DH *ssl_dh_GetParamFromFile(const char *file) ++#if OPENSSL_VERSION_NUMBER < 0x30000000L ++DH *modssl_dh_from_file(const char *file) + { +- DH *dh = NULL; ++ DH *dh; + BIO *bio; + + if ((bio = BIO_new_file(file, "r")) == NULL) + return NULL; + dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); + BIO_free(bio); +- return (dh); ++ ++ return dh; ++} ++#else ++EVP_PKEY *modssl_dh_pkey_from_file(const char *file) ++{ ++ EVP_PKEY *pkey; ++ BIO *bio; ++ ++ if ((bio = BIO_new_file(file, "r")) == NULL) ++ return NULL; ++ pkey = PEM_read_bio_Parameters(bio, NULL); ++ BIO_free(bio); ++ ++ return pkey; + } ++#endif + + #ifdef HAVE_ECC +-EC_GROUP *ssl_ec_GetParamFromFile(const char *file) ++EC_GROUP *modssl_ec_group_from_file(const char *file) + { +- EC_GROUP *group = NULL; ++ EC_GROUP *group; + BIO *bio; + + if ((bio = BIO_new_file(file, "r")) == NULL) + return NULL; ++#if OPENSSL_VERSION_NUMBER < 0x30000000L + group = PEM_read_bio_ECPKParameters(bio, NULL, NULL, NULL); ++#else ++ group = PEM_ASN1_read_bio((void *)d2i_ECPKParameters, ++ PEM_STRING_ECPARAMETERS, bio, ++ NULL, NULL, NULL); ++#endif + BIO_free(bio); +- return (group); ++ ++ return group; + } + #endif + +--- httpd-2.4.58/modules/ssl/ssl_util_stapling.c.r1913912 ++++ httpd-2.4.58/modules/ssl/ssl_util_stapling.c +@@ -29,9 +29,9 @@ + -- Alexei Sayle */ + + #include "ssl_private.h" ++ + #include "ap_mpm.h" + #include "apr_thread_mutex.h" +-#include "mod_ssl_openssl.h" + + APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, init_stapling_status, + (server_rec *s, apr_pool_t *p, +--- httpd-2.4.58/support/ab.c.r1913912 ++++ httpd-2.4.58/support/ab.c +@@ -166,13 +166,18 @@ + + #if defined(HAVE_OPENSSL) + +-#include ++#include + #include + #include + #include + #include + #include + #include ++#include ++#if OPENSSL_VERSION_NUMBER >= 0x30000000L ++#include ++#endif ++ + #define USE_SSL + + #define SK_NUM(x) sk_X509_num(x) +@@ -555,22 +560,33 @@ + * + */ + #ifdef USE_SSL +-static long ssl_print_cb(BIO *bio,int cmd,const char *argp,int argi,long argl,long ret) ++#if OPENSSL_VERSION_NUMBER >= 0x30000000L ++static long ssl_print_cb(BIO *bio, int cmd, const char *argp, ++ size_t len, int argi, long argl, int ret, ++ size_t *processed) ++#else ++static long ssl_print_cb(BIO *bio, int cmd, const char *argp, ++ int argi, long argl, long ret) ++#endif + { + BIO *out; ++#if OPENSSL_VERSION_NUMBER >= 0x30000000L ++ (void)len; ++ (void)processed; ++#endif + + out=(BIO *)BIO_get_callback_arg(bio); + if (out == NULL) return(ret); + + if (cmd == (BIO_CB_READ|BIO_CB_RETURN)) { + BIO_printf(out,"read from %p [%p] (%d bytes => %ld (0x%lX))\n", +- bio, argp, argi, ret, ret); ++ bio, argp, argi, (long)ret, (long)ret); + BIO_dump(out,(char *)argp,(int)ret); + return(ret); + } + else if (cmd == (BIO_CB_WRITE|BIO_CB_RETURN)) { + BIO_printf(out,"write to %p [%p] (%d bytes => %ld (0x%lX))\n", +- bio, argp, argi, ret, ret); ++ bio, argp, argi, (long)ret, (long)ret); + BIO_dump(out,(char *)argp,(int)ret); + } + return ret; +@@ -765,17 +781,29 @@ + break; + #ifndef OPENSSL_NO_EC + case EVP_PKEY_EC: { ++#if OPENSSL_VERSION_NUMBER >= 0x30000000L ++ size_t len; ++ char cname[80]; ++ if (!EVP_PKEY_get_utf8_string_param(key, OSSL_PKEY_PARAM_GROUP_NAME, ++ cname, sizeof(cname), &len)) { ++ cname[0] = '?'; ++ len = 1; ++ } ++ cname[len] = '\0'; ++#else + const char *cname = NULL; + EC_KEY *ec = EVP_PKEY_get1_EC_KEY(key); + int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)); + EC_KEY_free(ec); + cname = EC_curve_nid2nist(nid); +- if (!cname) ++ if (!cname) { + cname = OBJ_nid2sn(nid); +- ++ if (!cname) ++ cname = "?"; ++ } ++#endif + apr_snprintf(ssl_tmp_key, 128, "ECDH %s %d bits", +- cname, +- EVP_PKEY_bits(key)); ++ cname, EVP_PKEY_bits(key)); + break; + } + #endif +@@ -1428,7 +1456,11 @@ + SSL_set_bio(c->ssl, bio, bio); + SSL_set_connect_state(c->ssl); + if (verbosity >= 4) { ++#if OPENSSL_VERSION_NUMBER >= 0x30000000L ++ BIO_set_callback_ex(bio, ssl_print_cb); ++#else + BIO_set_callback(bio, ssl_print_cb); ++#endif + BIO_set_callback_arg(bio, (void *)bio_err); + } + #ifdef HAVE_TLSEXT diff --git a/apache2-fips-compatibility-03.patch b/apache2-fips-compatibility-03.patch new file mode 100644 index 0000000..7717a31 --- /dev/null +++ b/apache2-fips-compatibility-03.patch @@ -0,0 +1,221 @@ +# ./pullrev.sh 1914365 +http://svn.apache.org/viewvc?view=revision&revision=1914365 + +Upstream-Status: in trunk, not proposed for 2.4.x + +--- httpd-2.4.58/modules/ssl/ssl_engine_init.c.r1914365 ++++ httpd-2.4.58/modules/ssl/ssl_engine_init.c +@@ -1421,8 +1421,10 @@ + if (cert) { + if (SSL_CTX_use_certificate(mctx->ssl_ctx, cert) < 1) { + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10137) +- "Failed to configure engine certificate %s, check %s", +- key_id, certfile); ++ "Failed to configure certificate %s from %s, check %s", ++ key_id, mc->szCryptoDevice ? ++ mc->szCryptoDevice : "provider", ++ certfile); + ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); + return APR_EGENERAL; + } +@@ -1433,8 +1435,9 @@ + + if (SSL_CTX_use_PrivateKey(mctx->ssl_ctx, pkey) < 1) { + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10130) +- "Failed to configure private key %s from engine", +- keyfile); ++ "Failed to configure private key %s from %s", ++ keyfile, mc->szCryptoDevice ? ++ mc->szCryptoDevice : "provider"); + ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); + return APR_EGENERAL; + } +--- httpd-2.4.58/modules/ssl/ssl_engine_pphrase.c.r1914365 ++++ httpd-2.4.58/modules/ssl/ssl_engine_pphrase.c +@@ -31,6 +31,9 @@ + #include "ssl_private.h" + + #include ++#if MODSSL_HAVE_OPENSSL_STORE ++#include ++#endif + + typedef struct { + server_rec *s; +@@ -608,7 +611,7 @@ + return (len); + } + +-#if MODSSL_HAVE_ENGINE_API ++#if MODSSL_HAVE_ENGINE_API || MODSSL_HAVE_OPENSSL_STORE + + /* OpenSSL UI implementation for passphrase entry; largely duplicated + * from ssl_pphrase_Handle_CB but adjusted for UI API. TODO: Might be +@@ -826,13 +829,14 @@ + } + #endif + +- +-apr_status_t modssl_load_engine_keypair(server_rec *s, apr_pool_t *p, ++#if MODSSL_HAVE_ENGINE_API ++static apr_status_t modssl_load_keypair_engine(server_rec *s, apr_pool_t *p, + const char *vhostid, +- const char *certid, const char *keyid, +- X509 **pubkey, EVP_PKEY **privkey) ++ const char *certid, ++ const char *keyid, ++ X509 **pubkey, ++ EVP_PKEY **privkey) + { +-#if MODSSL_HAVE_ENGINE_API + const char *c, *scheme; + ENGINE *e; + UI_METHOD *ui_method = get_passphrase_ui(p); +@@ -906,6 +910,118 @@ + ENGINE_free(e); + + return APR_SUCCESS; ++} ++#endif ++ ++#if MODSSL_HAVE_OPENSSL_STORE ++static OSSL_STORE_INFO *modssl_load_store_uri(server_rec *s, apr_pool_t *p, ++ const char *vhostid, ++ const char *uri, int info_type) ++{ ++ OSSL_STORE_CTX *sctx; ++ UI_METHOD *ui_method = get_passphrase_ui(p); ++ pphrase_cb_arg_t ppcb; ++ OSSL_STORE_INFO *info = NULL; ++ ++ memset(&ppcb, 0, sizeof ppcb); ++ ppcb.s = s; ++ ppcb.p = p; ++ ppcb.bPassPhraseDialogOnce = TRUE; ++ ppcb.key_id = vhostid; ++ ppcb.pkey_file = uri; ++ ++ sctx = OSSL_STORE_open(uri, ui_method, &ppcb, NULL, NULL); ++ if (!sctx) { ++ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(10491) ++ "Init: OSSL_STORE_open failed for PKCS#11 URI `%s'", ++ uri); ++ return NULL; ++ } ++ ++ while (!OSSL_STORE_eof(sctx)) { ++ info = OSSL_STORE_load(sctx); ++ if (!info) ++ break; ++ ++ if (OSSL_STORE_INFO_get_type(info) == info_type) ++ break; ++ ++ OSSL_STORE_INFO_free(info); ++ info = NULL; ++ } ++ ++ OSSL_STORE_close(sctx); ++ ++ return info; ++} ++ ++static apr_status_t modssl_load_keypair_store(server_rec *s, apr_pool_t *p, ++ const char *vhostid, ++ const char *certid, ++ const char *keyid, ++ X509 **pubkey, ++ EVP_PKEY **privkey) ++{ ++ OSSL_STORE_INFO *info = NULL; ++ ++ *privkey = NULL; ++ *pubkey = NULL; ++ ++ info = modssl_load_store_uri(s, p, vhostid, keyid, OSSL_STORE_INFO_PKEY); ++ if (!info) { ++ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10492) ++ "Init: OSSL_STORE_INFO_PKEY lookup failed for private key identifier `%s'", ++ keyid); ++ return ssl_die(s); ++ } ++ ++ *privkey = OSSL_STORE_INFO_get1_PKEY(info); ++ OSSL_STORE_INFO_free(info); ++ if (!*privkey) { ++ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10493) ++ "Init: OSSL_STORE_INFO_PKEY lookup failed for private key identifier `%s'", ++ keyid); ++ return ssl_die(s); ++ } ++ ++ if (certid) { ++ info = modssl_load_store_uri(s, p, vhostid, certid, OSSL_STORE_INFO_CERT); ++ if (!info) { ++ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10494) ++ "Init: OSSL_STORE_INFO_CERT lookup failed for certificate identifier `%s'", ++ keyid); ++ return ssl_die(s); ++ } ++ ++ *pubkey = OSSL_STORE_INFO_get1_CERT(info); ++ OSSL_STORE_INFO_free(info); ++ if (!*pubkey) { ++ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10495) ++ "Init: OSSL_STORE_INFO_CERT lookup failed for certificate identifier `%s'", ++ certid); ++ return ssl_die(s); ++ } ++ } ++ ++ return APR_SUCCESS; ++} ++#endif ++ ++apr_status_t modssl_load_engine_keypair(server_rec *s, apr_pool_t *p, ++ const char *vhostid, ++ const char *certid, const char *keyid, ++ X509 **pubkey, EVP_PKEY **privkey) ++{ ++#if MODSSL_HAVE_OPENSSL_STORE ++ SSLModConfigRec *mc = myModConfig(s); ++ ++ if (!mc->szCryptoDevice) ++ return modssl_load_keypair_store(s, p, vhostid, certid, keyid, ++ pubkey, privkey); ++#endif ++#if MODSSL_HAVE_ENGINE_API ++ return modssl_load_keypair_engine(s, p, vhostid, certid, keyid, ++ pubkey, privkey); + #else + return APR_ENOTIMPL; + #endif +--- httpd-2.4.58/modules/ssl/ssl_private.h.r1914365 ++++ httpd-2.4.58/modules/ssl/ssl_private.h +@@ -118,6 +118,15 @@ + #define MODSSL_HAVE_ENGINE_API 0 + #endif + ++/* Use OpenSSL 3.x STORE for loading URI keys and certificates starting with ++ * OpenSSL 3.0 ++ */ ++#if OPENSSL_VERSION_NUMBER >= 0x30000000 ++#define MODSSL_HAVE_OPENSSL_STORE 1 ++#else ++#define MODSSL_HAVE_OPENSSL_STORE 0 ++#endif ++ + #if (OPENSSL_VERSION_NUMBER < 0x0090801f) + #error mod_ssl requires OpenSSL 0.9.8a or later + #endif +--- httpd-2.4.58/modules/ssl/ssl_util.c.r1914365 ++++ httpd-2.4.58/modules/ssl/ssl_util.c +@@ -476,7 +476,7 @@ + + int modssl_is_engine_id(const char *name) + { +-#if MODSSL_HAVE_ENGINE_API ++#if MODSSL_HAVE_ENGINE_API || MODSSL_HAVE_OPENSSL_STORE + /* ### Can handle any other special ENGINE key names here? */ + return strncmp(name, "pkcs11:", 7) == 0; + #else diff --git a/apache2.changes b/apache2.changes index 1a5f224..bac1a5a 100644 --- a/apache2.changes +++ b/apache2.changes @@ -1,3 +1,13 @@ +------------------------------------------------------------------- +Sat Nov 16 12:31:03 UTC 2024 - Martin Schreiner + +- Add patches to improve FIPS compatibility (bsc#1220681): + * apache2-fips-compatibility-01.patch + * apache2-fips-compatibility-02.patch + * apache2-fips-compatibility-03.patch +- Fix build for SLFO:Main (bsc#1232273). + * Fix contributed by Petr Gajdos. + ------------------------------------------------------------------- Thu Oct 3 02:39:41 UTC 2024 - Martin Schreiner @@ -5,6 +15,13 @@ Thu Oct 3 02:39:41 UTC 2024 - Martin Schreiner Patch file added: * apache2-CVE-2024-40725.patch +------------------------------------------------------------------- +Wed Oct 2 18:22:25 UTC 2024 - Martin Schreiner + +- Security fix: + - CVE-2024-36387, bsc#1227272: DoS by null pointer in websocket over HTTP/2 + * Added apache2-CVE-2024-36387.patch + ------------------------------------------------------------------- Thu Aug 22 18:37:23 UTC 2024 - Martin Schreiner diff --git a/apache2.spec b/apache2.spec index 6cc1006..6e1ddfd 100644 --- a/apache2.spec +++ b/apache2.spec @@ -237,6 +237,12 @@ Patch100: apache-test-application-xml-type.patch # even if in live system I do not experience this inconsistency, let's turn off # these variables from the test Patch101: apache-test-turn-off-variables-in-ssl-var-lookup.patch +# FIX-UPSTREAM: CVE-2024-36387, bsc#1227272: DoS by null pointer in websocket over HTTP/2 +Patch102: apache2-CVE-2024-36387.patch +# [boo#1220681] apache refuses to start, asking for a rebuild with FIPS support +Patch103: apache2-fips-compatibility-01.patch +Patch104: apache2-fips-compatibility-02.patch +Patch105: apache2-fips-compatibility-03.patch BuildRequires: apache-rpm-macros-control #Since 2.4.7 the event MPM requires apr 1.5.0 or later. @@ -548,7 +554,8 @@ done mkdir -p %{buildroot}%{logfiledir} \ %{buildroot}%{proxycachedir} \ %{buildroot}%{localstatedir} \ - %{buildroot}%{libexecdir} + %{buildroot}%{libexecdir} \ + %{buildroot}%{datadir}/htdocs # save MODULE_MAGIC_NUMBER mkdir -p %{buildroot}/%{_libexecdir} @@ -930,6 +937,7 @@ exit 0 %{_datadir}/apache2 %{iconsdir} %{errordir} +%{datadir} %{_mandir}/man8/httpd.8.* %{_mandir}/man8/suexec.8.* %doc support/SHA1