summaryrefslogtreecommitdiffstats
path: root/modules/ssl
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 10:03:19 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 10:03:19 +0000
commitac45e40b4d3cdc2497d5b6f5efe7d8a927beca21 (patch)
tree96057c4c489cab1e8c112d689befe2b2b9fa34e7 /modules/ssl
parentReleasing progress-linux version 2.4.57-2~progress6.99u1. (diff)
downloadapache2-ac45e40b4d3cdc2497d5b6f5efe7d8a927beca21.tar.xz
apache2-ac45e40b4d3cdc2497d5b6f5efe7d8a927beca21.zip
Merging upstream version 2.4.59.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--modules/ssl/mod_ssl.c5
-rw-r--r--modules/ssl/mod_ssl_openssl.h9
-rw-r--r--modules/ssl/ssl_engine_config.c15
-rw-r--r--modules/ssl/ssl_engine_init.c281
-rw-r--r--modules/ssl/ssl_engine_io.c51
-rw-r--r--modules/ssl/ssl_engine_kernel.c10
-rw-r--r--modules/ssl/ssl_engine_pphrase.c7
-rw-r--r--modules/ssl/ssl_private.h67
-rw-r--r--modules/ssl/ssl_util.c2
-rw-r--r--modules/ssl/ssl_util_ocsp.c5
-rw-r--r--modules/ssl/ssl_util_ssl.c35
-rw-r--r--modules/ssl/ssl_util_stapling.c14
12 files changed, 288 insertions, 213 deletions
diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c
index 5b8c4d5..fb66d18 100644
--- a/modules/ssl/mod_ssl.c
+++ b/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 @@ static const command_rec ssl_config_cmds[] = {
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]')")
diff --git a/modules/ssl/mod_ssl_openssl.h b/modules/ssl/mod_ssl_openssl.h
index d4f684f..e251bd9 100644
--- a/modules/ssl/mod_ssl_openssl.h
+++ b/modules/ssl/mod_ssl_openssl.h
@@ -30,14 +30,17 @@
/* OpenSSL headers */
-#ifndef SSL_PRIVATE_H
#include <openssl/opensslv.h>
-#if (OPENSSL_VERSION_NUMBER >= 0x10001000)
+#if OPENSSL_VERSION_NUMBER >= 0x30000000
+#include <openssl/macros.h> /* for OPENSSL_API_LEVEL */
+#endif
+#if OPENSSL_VERSION_NUMBER >= 0x10001000
/* must be defined before including ssl.h */
#define OPENSSL_NO_SSL_INTERN
#endif
#include <openssl/ssl.h>
-#endif
+#include <openssl/evp.h>
+#include <openssl/x509.h>
/**
* init_server hook -- allow SSL_CTX-specific initialization to be performed by
diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c
index de18b8f..9af6f70 100644
--- a/modules/ssl/ssl_engine_config.c
+++ b/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"
@@ -592,14 +593,15 @@ const char *ssl_cmd_SSLPassPhraseDialog(cmd_parms *cmd,
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;
@@ -608,13 +610,16 @@ const char *ssl_cmd_SSLCryptoDevice(cmd_parms *cmd,
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),
@@ -623,12 +628,12 @@ const char *ssl_cmd_SSLCryptoDevice(cmd_parms *cmd,
* 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,
@@ -856,10 +861,12 @@ const char *ssl_cmd_SSLCompression(cmd_parms *cmd, void *dcfg, int flag)
}
}
sc->compression = flag ? TRUE : FALSE;
- return NULL;
#else
- return "Setting Compression mode unsupported; not implemented by the SSL library";
+ if (flag) {
+ return "Setting Compression mode unsupported; not implemented by the SSL library";
+ }
#endif
+ return NULL;
}
const char *ssl_cmd_SSLHonorCipherOrder(cmd_parms *cmd, void *dcfg, int flag)
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
index 825621d..c2ec048 100644
--- a/modules/ssl/ssl_engine_init.c
+++ b/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 @@ static apr_status_t modssl_fips_cleanup(void *data)
}
#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_status_t ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
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 @@ apr_status_t ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
/*
* 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 @@ apr_status_t ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
* 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 @@ apr_status_t ssl_init_Engine(server_rec *s, apr_pool_t *p)
ENGINE_free(e);
}
-
+#endif
return APR_SUCCESS;
}
-#endif
#ifdef HAVE_TLSEXT
static apr_status_t ssl_init_ctx_tls_extensions(server_rec *s,
@@ -833,6 +843,14 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s,
SSL_CTX_set_keylog_callback(ctx, modssl_callback_keylog);
}
#endif
+
+#ifdef SSL_OP_IGNORE_UNEXPECTED_EOF
+ /* For server-side SSL_CTX, enable ignoring unexpected EOF */
+ /* (OpenSSL 1.1.1 behavioural compatibility).. */
+ if (!mctx->pkp) {
+ SSL_CTX_set_options(ctx, SSL_OP_IGNORE_UNEXPECTED_EOF);
+ }
+#endif
return APR_SUCCESS;
}
@@ -1302,15 +1320,6 @@ static int ssl_no_passwd_prompt_cb(char *buf, int size, int rwflag,
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
@@ -1336,15 +1345,10 @@ static apr_status_t ssl_init_server_certs(server_rec *s,
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 */
@@ -1355,7 +1359,7 @@ static apr_status_t ssl_init_server_certs(server_rec *s,
(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);
@@ -1398,8 +1402,6 @@ static apr_status_t ssl_init_server_certs(server_rec *s,
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))) {
@@ -1470,22 +1472,21 @@ static apr_status_t ssl_init_server_certs(server_rec *s,
* 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);
- if (ssl) {
- /* Workaround bug in SSL_get_certificate in OpenSSL 0.9.8y */
- SSL_set_connect_state(ssl);
- cert = SSL_get_certificate(ssl);
+ {
+ 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;
}
@@ -1507,10 +1508,6 @@ static apr_status_t ssl_init_server_certs(server_rec *s,
}
#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);
@@ -1520,15 +1517,33 @@ static apr_status_t ssl_init_server_certs(server_rec *s,
* 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+. */
- 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",
- modssl_DH_bits(dh), vhost_id, certfile);
- DH_free(dh);
+ 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",
+ num_bits, vhost_id, certfile);
+ }
}
#if !MODSSL_USE_OPENSSL_PRE_1_1_API
else {
@@ -1543,13 +1558,27 @@ static apr_status_t ssl_init_server_certs(server_rec *s,
* 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))) {
- SSL_CTX_set_tmp_ecdh(mctx->ssl_ctx, eckey);
- 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);
+ && (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(curve_nid), vhost_id, certfile);
+ }
}
/*
* ...otherwise, enable auto curve selection (OpenSSL 1.0.2)
@@ -1557,18 +1586,20 @@ static apr_status_t ssl_init_server_certs(server_rec *s,
* 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);
- SSL_CTX_set_tmp_ecdh(mctx->ssl_ctx, eckey);
+ 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;
@@ -1680,8 +1711,12 @@ static apr_status_t ssl_init_proxy_certs(server_rec *s,
STACK_OF(X509) *chain;
X509_STORE_CTX *sctx;
X509_STORE *store = SSL_CTX_get_cert_store(mctx->ssl_ctx);
+ int addl_chain = 0; /* non-zero if additional chain certs were
+ * added to store */
-#if OPENSSL_VERSION_NUMBER >= 0x1010100fL
+ ap_assert(store != NULL); /* safe to assume always non-NULL? */
+
+#if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(LIBRESSL_VERSION_NUMBER)
/* For OpenSSL >=1.1.1, turn on client cert support which is
* otherwise turned off by default (by design).
* https://github.com/openssl/openssl/issues/6933 */
@@ -1705,20 +1740,28 @@ static apr_status_t ssl_init_proxy_certs(server_rec *s,
ssl_init_ca_cert_path(s, ptemp, pkp->cert_path, NULL, sk);
}
- if ((ncerts = sk_X509_INFO_num(sk)) <= 0) {
- sk_X509_INFO_free(sk);
- ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(02206)
- "no client certs found for SSL proxy");
- return APR_SUCCESS;
- }
-
/* Check that all client certs have got certificates and private
- * keys. */
- for (n = 0; n < ncerts; n++) {
+ * keys. Note the number of certs in the stack may decrease
+ * during the loop. */
+ for (n = 0; n < sk_X509_INFO_num(sk); n++) {
X509_INFO *inf = sk_X509_INFO_value(sk, n);
+ int has_privkey = inf->x_pkey && inf->x_pkey->dec_pkey;
- if (!inf->x509 || !inf->x_pkey || !inf->x_pkey->dec_pkey ||
- inf->enc_data) {
+ /* For a lone certificate in the file, trust it as a
+ * CA/intermediate certificate. */
+ if (inf->x509 && !has_privkey && !inf->enc_data) {
+ ssl_log_xerror(SSLLOG_MARK, APLOG_DEBUG, 0, ptemp, s, inf->x509,
+ APLOGNO(10261) "Trusting non-leaf certificate");
+ X509_STORE_add_cert(store, inf->x509); /* increments inf->x509 */
+ /* Delete from the stack and iterate again. */
+ X509_INFO_free(inf);
+ sk_X509_INFO_delete(sk, n);
+ n--;
+ addl_chain = 1;
+ continue;
+ }
+
+ if (!has_privkey || inf->enc_data) {
sk_X509_INFO_free(sk);
ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, APLOGNO(02252)
"incomplete client cert configured for SSL proxy "
@@ -1735,13 +1778,21 @@ static apr_status_t ssl_init_proxy_certs(server_rec *s,
}
}
+ if ((ncerts = sk_X509_INFO_num(sk)) <= 0) {
+ sk_X509_INFO_free(sk);
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(02206)
+ "no client certs found for SSL proxy");
+ return APR_SUCCESS;
+ }
+
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02207)
"loaded %d client certs for SSL proxy",
ncerts);
pkp->certs = sk;
-
- if (!pkp->ca_cert_file || !store) {
+ /* If any chain certs are configured, build the ->ca_certs chains
+ * corresponding to the loaded keypairs. */
+ if (!pkp->ca_cert_file && !addl_chain) {
return APR_SUCCESS;
}
@@ -1757,6 +1808,7 @@ static apr_status_t ssl_init_proxy_certs(server_rec *s,
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02208)
"SSL proxy client cert initialization failed");
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
+ sk_X509_INFO_free(sk);
return ssl_die(s);
}
@@ -1766,7 +1818,11 @@ static apr_status_t ssl_init_proxy_certs(server_rec *s,
int i;
X509_INFO *inf = sk_X509_INFO_value(pkp->certs, n);
- X509_STORE_CTX_init(sctx, store, inf->x509, NULL);
+ if (!X509_STORE_CTX_init(sctx, store, inf->x509, NULL)) {
+ sk_X509_INFO_free(sk);
+ X509_STORE_CTX_free(sctx);
+ return ssl_die(s);
+ }
/* Attempt to verify the client cert */
if (X509_verify_cert(sctx) != 1) {
@@ -2186,52 +2242,6 @@ int ssl_proxy_section_post_config(apr_pool_t *p, apr_pool_t *plog,
return OK;
}
-static int ssl_init_FindCAList_X509NameCmp(const X509_NAME * const *a,
- const X509_NAME * const *b)
-{
- return(X509_NAME_cmp(*a, *b));
-}
-
-static void ssl_init_PushCAList(STACK_OF(X509_NAME) *ca_list,
- server_rec *s, apr_pool_t *ptemp,
- const char *file)
-{
- int n;
- STACK_OF(X509_NAME) *sk;
-
- sk = (STACK_OF(X509_NAME) *)
- SSL_load_client_CA_file(file);
-
- if (!sk) {
- return;
- }
-
- for (n = 0; n < sk_X509_NAME_num(sk); n++) {
- X509_NAME *name = sk_X509_NAME_value(sk, n);
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02209)
- "CA certificate: %s",
- modssl_X509_NAME_to_string(ptemp, name, 0));
-
- /*
- * note that SSL_load_client_CA_file() checks for duplicates,
- * but since we call it multiple times when reading a directory
- * we must also check for duplicates ourselves.
- */
-
- if (sk_X509_NAME_find(ca_list, name) < 0) {
- /* this will be freed when ca_list is */
- sk_X509_NAME_push(ca_list, name);
- }
- else {
- /* need to free this ourselves, else it will leak */
- X509_NAME_free(name);
- }
- }
-
- sk_X509_NAME_free(sk);
-}
-
static apr_status_t ssl_init_ca_cert_path(server_rec *s,
apr_pool_t *ptemp,
const char *path,
@@ -2254,7 +2264,7 @@ static apr_status_t ssl_init_ca_cert_path(server_rec *s,
}
file = apr_pstrcat(ptemp, path, "/", direntry.name, NULL);
if (ca_list) {
- ssl_init_PushCAList(ca_list, s, ptemp, file);
+ SSL_add_file_cert_subjects_to_stack(ca_list, file);
}
if (xi_list) {
load_x509_info(ptemp, xi_list, file);
@@ -2271,19 +2281,13 @@ STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s,
const char *ca_file,
const char *ca_path)
{
- STACK_OF(X509_NAME) *ca_list;
-
- /*
- * Start with a empty stack/list where new
- * entries get added in sorted order.
- */
- ca_list = sk_X509_NAME_new(ssl_init_FindCAList_X509NameCmp);
+ STACK_OF(X509_NAME) *ca_list = sk_X509_NAME_new_null();;
/*
* Process CA certificate bundle file
*/
if (ca_file) {
- ssl_init_PushCAList(ca_list, s, ptemp, ca_file);
+ SSL_add_file_cert_subjects_to_stack(ca_list, ca_file);
/*
* If ca_list is still empty after trying to load ca_file
* then the file failed to load, and users should hear about that.
@@ -2307,11 +2311,6 @@ STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s,
return NULL;
}
- /*
- * Cleanup
- */
- (void) sk_X509_NAME_set_cmp_func(ca_list, NULL);
-
return ca_list;
}
diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c
index f14fc9b..b91f784 100644
--- a/modules/ssl/ssl_engine_io.c
+++ b/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 @@ void ssl_io_filter_init(conn_rec *c, request_rec *r, SSL *ssl)
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 @@ static void ssl_io_data_dump(conn_rec *c, server_rec *s,
"+-------------------------------------------------------------------------+");
}
-long ssl_io_data_cb(BIO *bio, int cmd,
- const char *argp,
- int argi, long argl, long rc)
+#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 @@ long ssl_io_data_cb(BIO *bio, int cmd,
"%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 @@ long ssl_io_data_cb(BIO *bio, int cmd,
}
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);
+ }
+}
diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c
index 591f6ae..fe0496f 100644
--- a/modules/ssl/ssl_engine_kernel.c
+++ b/modules/ssl/ssl_engine_kernel.c
@@ -2581,6 +2581,7 @@ static int ssl_find_vhost(void *servername, conn_rec *c, server_rec *s)
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 @@ static int ssl_find_vhost(void *servername, conn_rec *c, server_rec *s)
* 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;
diff --git a/modules/ssl/ssl_engine_pphrase.c b/modules/ssl/ssl_engine_pphrase.c
index d1859f7..699019f 100644
--- a/modules/ssl/ssl_engine_pphrase.c
+++ b/modules/ssl/ssl_engine_pphrase.c
@@ -30,6 +30,8 @@
-- Clifford Stoll */
#include "ssl_private.h"
+#include <openssl/ui.h>
+
typedef struct {
server_rec *s;
apr_pool_t *p;
@@ -606,8 +608,7 @@ int ssl_pphrase_Handle_CB(char *buf, int bufsize, int verify, void *srv)
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 @@ apr_status_t modssl_load_engine_keypair(server_rec *s, apr_pool_t *p,
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);
diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h
index cd8df07..859e932 100644
--- a/modules/ssl/ssl_private.h
+++ b/modules/ssl/ssl_private.h
@@ -83,16 +83,13 @@
#include "ap_expr.h"
-/* OpenSSL headers */
-#include <openssl/opensslv.h>
-#if (OPENSSL_VERSION_NUMBER >= 0x10001000)
-/* must be defined before including ssl.h */
-#define OPENSSL_NO_SSL_INTERN
-#endif
-#if OPENSSL_VERSION_NUMBER >= 0x30000000
-#include <openssl/core_names.h>
+/* keep first for compat API */
+#ifndef OPENSSL_API_COMPAT
+#define OPENSSL_API_COMPAT 0x10101000 /* for ENGINE_ API */
#endif
-#include <openssl/ssl.h>
+#include "mod_ssl_openssl.h"
+
+/* OpenSSL headers */
#include <openssl/err.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
@@ -102,12 +99,23 @@
#include <openssl/x509v3.h>
#include <openssl/x509_vfy.h>
#include <openssl/ocsp.h>
+#include <openssl/dh.h>
+#if OPENSSL_VERSION_NUMBER >= 0x30000000
+#include <openssl/core_names.h>
+#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 <openssl/engine.h>
+#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 <openssl/srp.h>
#endif
@@ -254,6 +273,14 @@ void free_bio_methods(void);
#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
@@ -625,9 +652,7 @@ typedef struct {
* index), for example the string "vhost.example.com:443:0". */
apr_hash_t *tPrivateKey;
-#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
- const char *szCryptoDevice;
-#endif
+ const char *szCryptoDevice; /* ENGINE device (if available) */
#ifdef HAVE_OCSP_STAPLING
const ap_socache_provider_t *stapling_cache;
@@ -1019,7 +1044,7 @@ void modssl_callback_keylog(const SSL *ssl, const char *line);
/** 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 +1082,13 @@ apr_status_t modssl_load_engine_keypair(server_rec *s, apr_pool_t *p,
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
diff --git a/modules/ssl/ssl_util.c b/modules/ssl/ssl_util.c
index c889295..87ddfa7 100644
--- a/modules/ssl/ssl_util.c
+++ b/modules/ssl/ssl_util.c
@@ -476,7 +476,7 @@ void ssl_util_thread_id_setup(apr_pool_t *p)
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
diff --git a/modules/ssl/ssl_util_ocsp.c b/modules/ssl/ssl_util_ocsp.c
index b9c8a0b..a202a72 100644
--- a/modules/ssl/ssl_util_ocsp.c
+++ b/modules/ssl/ssl_util_ocsp.c
@@ -370,8 +370,11 @@ static STACK_OF(X509) *modssl_read_ocsp_certificates(const char *file)
while ((x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) {
if (!other_certs) {
other_certs = sk_X509_new_null();
- if (!other_certs)
+ if (!other_certs) {
+ X509_free(x509);
+ BIO_free(bio);
return NULL;
+ }
}
if (!sk_X509_push(other_certs, x509)) {
diff --git a/modules/ssl/ssl_util_ssl.c b/modules/ssl/ssl_util_ssl.c
index 38079a9..44930b7 100644
--- a/modules/ssl/ssl_util_ssl.c
+++ b/modules/ssl/ssl_util_ssl.c
@@ -464,29 +464,52 @@ BOOL modssl_X509_match_name(apr_pool_t *p, X509 *x509, const char *name,
** _________________________________________________________________
*/
-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
diff --git a/modules/ssl/ssl_util_stapling.c b/modules/ssl/ssl_util_stapling.c
index ab77e4a..563de55 100644
--- a/modules/ssl/ssl_util_stapling.c
+++ b/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,
@@ -117,8 +117,10 @@ static X509 *stapling_get_issuer(modssl_ctx_t *mctx, X509 *x)
}
inctx = X509_STORE_CTX_new();
- if (!X509_STORE_CTX_init(inctx, st, NULL, NULL))
+ if (!X509_STORE_CTX_init(inctx, st, NULL, NULL)) {
+ X509_STORE_CTX_free(inctx);
return 0;
+ }
if (X509_STORE_CTX_get1_issuer(&issuer, inctx, x) <= 0)
issuer = NULL;
X509_STORE_CTX_cleanup(inctx);
@@ -445,7 +447,7 @@ static int stapling_check_response(server_rec *s, modssl_ctx_t *mctx,
rv = SSL_TLSEXT_ERR_NOACK;
}
- if (status != V_OCSP_CERTSTATUS_GOOD) {
+ if (status != V_OCSP_CERTSTATUS_GOOD && pok) {
char snum[MAX_STRING_LEN] = { '\0' };
BIO *bio = BIO_new(BIO_s_mem());
@@ -466,12 +468,6 @@ static int stapling_check_response(server_rec *s, modssl_ctx_t *mctx,
(reason != OCSP_REVOKED_STATUS_NOSTATUS) ?
OCSP_crl_reason_str(reason) : "n/a",
snum[0] ? snum : "[n/a]");
-
- if (mctx->stapling_return_errors == FALSE) {
- if (pok)
- *pok = FALSE;
- rv = SSL_TLSEXT_ERR_NOACK;
- }
}
}