From 8cac5434f8d0c4dbc55b1da9af0c76ffe01c7917 Mon Sep 17 00:00:00 2001 From: Graham Leggett Date: Tue, 28 Jul 2026 16:17:54 +0100 Subject: [PATCH 1/3] mod_ssl: Add support for OpenSSL providers across all certificates, CA certificates, CRLs and keys. --- CHANGES | 3 + modules/ssl/mod_ssl.c | 18 + modules/ssl/mod_ssl_openssl.h | 2 + modules/ssl/ssl_engine_config.c | 183 ++++- modules/ssl/ssl_engine_init.c | 1102 ++++++++++++++++++++++++++++-- modules/ssl/ssl_engine_kernel.c | 1 + modules/ssl/ssl_engine_pphrase.c | 21 +- modules/ssl/ssl_private.h | 44 +- 8 files changed, 1302 insertions(+), 72 deletions(-) diff --git a/CHANGES b/CHANGES index 1b7ada49993..93cde76456a 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,9 @@ -*- coding: utf-8 -*- Changes with Apache 2.5.1 + *) mod_ssl: Add support for OpenSSL providers across all certificates, + CA certificates, CRLs and keys. [Graham Leggett] + *) mod_proxy_beacon: Back-end reverse proxy servers can announce themselves and be auto-added to their front-end proxy balancer. [Jim Jagielski] diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c index 8f79d0a8bc0..20d3db1a0d5 100644 --- a/modules/ssl/mod_ssl.c +++ b/modules/ssl/mod_ssl.c @@ -110,6 +110,9 @@ static const command_rec ssl_config_cmds[] = { SSL_CMD_ALL(CipherSuite, TAKE12, "Colon-delimited list of permitted SSL Ciphers, optional preceded " "by protocol identifier ('XXX:...:XXX' - see manual)") + SSL_CMD_SRV(CertificateURI, TAKE1, + "SSL Server Certificate/Key uri " + "('file:', 'pkcs11:' - URI of certificate or key)") SSL_CMD_SRV(CertificateFile, TAKE1, "SSL Server Certificate file " "('/path/to/file' - PEM or DER encoded)") @@ -129,6 +132,9 @@ static const command_rec ssl_config_cmds[] = { "TLS ECH Key Directory" "('/path/to/dir' - directory with ECH key pairs)") #endif + SSL_CMD_SRV(CACertificateURI, TAKE1, + "SSL CA Certificate uri " + "('file:', 'pkcs11:' - URI of CA certificates)") SSL_CMD_ALL(CACertificatePath, TAKE1, "SSL CA Certificate path " "('/path/to/dir' - contains PEM encoded files)") @@ -141,6 +147,9 @@ static const command_rec ssl_config_cmds[] = { SSL_CMD_SRV(CADNRequestFile, TAKE1, "SSL CA Distinguished Name file " "('/path/to/file' - PEM encoded to derive acceptable CA names to request)") + SSL_CMD_SRV(CARevocationURI, TAKE1, + "SSL CA Certificate Revocation List (CRL) uri " + "('file:', 'pkcs11:' - URI of CRLs)") SSL_CMD_SRV(CARevocationPath, TAKE1, "SSL CA Certificate Revocation List (CRL) path " "('/path/to/dir' - contains PEM encoded files)") @@ -216,12 +225,18 @@ static const command_rec ssl_config_cmds[] = { SSL_CMD_PXY(ProxyVerifyDepth, TAKE1, "SSL Proxy: maximum certificate verification depth " "('N' - number of intermediate certificates)") + SSL_CMD_PXY(ProxyCACertificateURI, TAKE1, + "SSL Proxy: uri referring to server certificates " + "('file:', 'pkcs11:' - URI of CA certificates)") SSL_CMD_PXY(ProxyCACertificateFile, TAKE1, "SSL Proxy: file containing server certificates " "('/path/to/file' - PEM encoded certificates)") SSL_CMD_PXY(ProxyCACertificatePath, TAKE1, "SSL Proxy: directory containing server certificates " "('/path/to/dir' - contains PEM encoded certificates)") + SSL_CMD_PXY(ProxyCARevocationURI, TAKE1, + "SSL Proxy: CA Certificate Revocation List (CRL) uri " + "('file:', 'pkcs11:' - URI of CRLs)") SSL_CMD_PXY(ProxyCARevocationPath, TAKE1, "SSL Proxy: CA Certificate Revocation List (CRL) path " "('/path/to/dir' - contains PEM encoded files)") @@ -230,6 +245,9 @@ static const command_rec ssl_config_cmds[] = { "('/path/to/file' - PEM encoded)") SSL_CMD_PXY(ProxyCARevocationCheck, RAW_ARGS, "SSL Proxy: CA Certificate Revocation List (CRL) checking mode") + SSL_CMD_PXY(ProxyMachineCertificateURI, TAKE1, + "SSL Proxy: uri referring to client certificates " + "('file:', 'pkcs11:' - URI of certificate or key)") SSL_CMD_PXY(ProxyMachineCertificateFile, TAKE1, "SSL Proxy: file containing client certificates " "('/path/to/file' - PEM encoded certificates)") diff --git a/modules/ssl/mod_ssl_openssl.h b/modules/ssl/mod_ssl_openssl.h index e251bd9b77a..fa345b4069e 100644 --- a/modules/ssl/mod_ssl_openssl.h +++ b/modules/ssl/mod_ssl_openssl.h @@ -33,6 +33,8 @@ #include #if OPENSSL_VERSION_NUMBER >= 0x30000000 #include /* for OPENSSL_API_LEVEL */ +#include /* for OSSL_STORE_open_ex */ +#include /* for UI_null */ #endif #if OPENSSL_VERSION_NUMBER >= 0x10001000 /* must be defined before including ssl.h */ diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c index a38dd943e4c..af09a12b561 100644 --- a/modules/ssl/ssl_engine_config.c +++ b/modules/ssl/ssl_engine_config.c @@ -113,6 +113,7 @@ static void modssl_ctx_init(modssl_ctx_t *mctx, apr_pool_t *p) mctx->sc = NULL; /* set during module init */ mctx->ssl_ctx = NULL; /* set during module init */ + mctx->libctx = NULL; /* set during module init */ mctx->pks = NULL; mctx->pkp = NULL; @@ -131,8 +132,10 @@ static void modssl_ctx_init(modssl_ctx_t *mctx, apr_pool_t *p) mctx->crl_path = NULL; mctx->crl_file = NULL; + mctx->crl_uri = NULL; mctx->crl_check_mask = UNSET; + mctx->auth.ca_cert_uri = NULL; mctx->auth.ca_cert_path = NULL; mctx->auth.ca_cert_file = NULL; mctx->auth.cipher_suite = NULL; @@ -200,6 +203,7 @@ static void modssl_ctx_init_server(SSLSrvConfigRec *sc, mctx->pks = apr_pcalloc(p, sizeof(*mctx->pks)); + mctx->pks->uris = apr_array_make(p, 3, sizeof(char *)); mctx->pks->cert_files = apr_array_make(p, 3, sizeof(char *)); mctx->pks->key_files = apr_array_make(p, 3, sizeof(char *)); @@ -279,6 +283,7 @@ static void modssl_ctx_cfg_merge(apr_pool_t *p, cfgMerge(crl_file, NULL); cfgMergeInt(crl_check_mask); + cfgMergeString(auth.ca_cert_uri); cfgMergeString(auth.ca_cert_path); cfgMergeString(auth.ca_cert_file); cfgMergeString(auth.cipher_suite); @@ -333,9 +338,11 @@ static void modssl_ctx_cfg_merge_server(apr_pool_t *p, { modssl_ctx_cfg_merge(p, base, add, mrg); + cfgMergeArray(pks->uris); cfgMergeArray(pks->cert_files); cfgMergeArray(pks->key_files); + cfgMergeString(pks->ca_name_uri); cfgMergeString(pks->ca_name_path); cfgMergeString(pks->ca_name_file); @@ -386,6 +393,7 @@ static void modssl_ctx_init_proxy(SSLDirConfigRec *dc, mctx->pkp = apr_palloc(p, sizeof(*mctx->pkp)); + mctx->pkp->uris = apr_array_make(p, 3, sizeof(char *)); mctx->pkp->cert_file = NULL; mctx->pkp->cert_path = NULL; mctx->pkp->ca_cert_file = NULL; @@ -429,6 +437,7 @@ static void modssl_ctx_cfg_merge_proxy(apr_pool_t *p, { modssl_ctx_cfg_merge(p, base, add, mrg); + cfgMergeArray(pkp->uris); cfgMergeString(pkp->cert_file); cfgMergeString(pkp->cert_path); cfgMergeString(pkp->ca_cert_file); @@ -962,6 +971,44 @@ static const char *ssl_cmd_check_file(cmd_parms *parms, } +static const char *ssl_cmd_check_uri(cmd_parms *parms, + const char *uri) +{ + OSSL_STORE_CTX *ctx; + unsigned long err; + int reason; + + /* If only dumping the config, don't verify the paths */ + if (ap_state_query(AP_SQ_RUN_MODE) == AP_SQ_RM_CONFIG_DUMP) { + return NULL; + } + + ctx = OSSL_STORE_open_ex(uri, NULL, NULL, UI_null(), + NULL, NULL, NULL, NULL); + + if (ctx) { + OSSL_STORE_close(ctx); + return NULL; + } + + err = ERR_peek_last_error(); + if (ERR_GET_LIB(err) == ERR_LIB_OSSL_STORE) { + reason = ERR_GET_REASON(err); + + if (reason == OSSL_STORE_R_UNREGISTERED_SCHEME) { + + return apr_pstrcat(parms->pool, parms->cmd->name, + ": uri '", uri, + "' is not recognised", NULL); + + } + } + + ERR_clear_error(); + + return NULL; +} + const char *ssl_cmd_SSLCompression(cmd_parms *cmd, void *dcfg, int flag) { #if !defined(OPENSSL_NO_COMP) @@ -1048,6 +1095,22 @@ static const char *ssl_cmd_check_dir(cmd_parms *parms, } +const char *ssl_cmd_SSLCertificateURI(cmd_parms *cmd, + void *dcfg, + const char *arg) +{ + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + const char *err; + + if ((err = ssl_cmd_check_uri(cmd, arg))) { + return err; + } + + *(const char **)apr_array_push(sc->server->pks->uris) = arg; + + return NULL; +} + const char *ssl_cmd_SSLCertificateFile(cmd_parms *cmd, void *dcfg, const char *arg) @@ -1121,6 +1184,28 @@ const char *ssl_cmd_SSLSessionTicketKeyFile(cmd_parms *cmd, #define NO_PER_DIR_SSL_CA \ "Your SSL library does not have support for per-directory CA" +const char *ssl_cmd_SSLCACertificateURI(cmd_parms *cmd, + void *dcfg, + const char *arg) +{ + /*SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;*/ + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + const char *err; + + if ((err = ssl_cmd_check_uri(cmd, arg))) { + return err; + } + + if (cmd->path) { + return NO_PER_DIR_SSL_CA; + } + + /* XXX: bring back per-dir */ + sc->server->auth.ca_cert_uri = arg; + + return NULL; +} + const char *ssl_cmd_SSLCACertificatePath(cmd_parms *cmd, void *dcfg, const char *arg) @@ -1165,6 +1250,21 @@ const char *ssl_cmd_SSLCACertificateFile(cmd_parms *cmd, return NULL; } +const char *ssl_cmd_SSLCADNRequestURI(cmd_parms *cmd, void *dcfg, + const char *arg) +{ + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + const char *err; + + if ((err = ssl_cmd_check_uri(cmd, arg))) { + return err; + } + + sc->server->pks->ca_name_uri = arg; + + return NULL; +} + const char *ssl_cmd_SSLCADNRequestPath(cmd_parms *cmd, void *dcfg, const char *arg) { @@ -1195,6 +1295,22 @@ const char *ssl_cmd_SSLCADNRequestFile(cmd_parms *cmd, void *dcfg, return NULL; } +const char *ssl_cmd_SSLCARevocationURI(cmd_parms *cmd, + void *dcfg, + const char *arg) +{ + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + const char *err; + + if ((err = ssl_cmd_check_uri(cmd, arg))) { + return err; + } + + sc->server->crl_uri = arg; + + return NULL; +} + const char *ssl_cmd_SSLCARevocationPath(cmd_parms *cmd, void *dcfg, const char *arg) @@ -1740,6 +1856,22 @@ const char *ssl_cmd_SSLProxyVerifyDepth(cmd_parms *cmd, return NULL; } +const char *ssl_cmd_SSLProxyCACertificateURI(cmd_parms *cmd, + void *dcfg, + const char *arg) +{ + SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg; + const char *err; + + if ((err = ssl_cmd_check_uri(cmd, arg))) { + return err; + } + + dc->proxy->auth.ca_cert_uri = arg; + + return NULL; +} + const char *ssl_cmd_SSLProxyCACertificateFile(cmd_parms *cmd, void *dcfg, const char *arg) @@ -1772,6 +1904,22 @@ const char *ssl_cmd_SSLProxyCACertificatePath(cmd_parms *cmd, return NULL; } +const char *ssl_cmd_SSLProxyCARevocationURI(cmd_parms *cmd, + void *dcfg, + const char *arg) +{ + SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg; + const char *err; + + if ((err = ssl_cmd_check_uri(cmd, arg))) { + return err; + } + + dc->proxy->crl_uri = arg; + + return NULL; +} + const char *ssl_cmd_SSLProxyCARevocationPath(cmd_parms *cmd, void *dcfg, const char *arg) @@ -1813,6 +1961,22 @@ const char *ssl_cmd_SSLProxyCARevocationCheck(cmd_parms *cmd, return ssl_cmd_crlcheck_parse(cmd, arg, &dc->proxy->crl_check_mask); } +const char *ssl_cmd_SSLProxyMachineCertificateURI(cmd_parms *cmd, + void *dcfg, + const char *arg) +{ + SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg; + const char *err; + + if ((err = ssl_cmd_check_uri(cmd, arg))) { + return err; + } + + *(const char **)apr_array_push(dc->proxy->pkp->uris) = arg; + + return NULL; +} + const char *ssl_cmd_SSLProxyMachineCertificateFile(cmd_parms *cmd, void *dcfg, const char *arg) @@ -2293,7 +2457,7 @@ const char *ssl_cmd_SSLSRPUnknownUserSeed(cmd_parms *cmd, void *dcfg, /* OCSP Responder File Function to read in value */ const char *ssl_cmd_SSLOCSPResponderCertificateFile(cmd_parms *cmd, void *dcfg, - const char *arg) + const char *arg) { SSLSrvConfigRec *sc = mySrvConfig(cmd->server); const char *err; @@ -2332,6 +2496,14 @@ void ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s) modssl_pk_server_t *const pks = sc->server->pks; int i; + for (i = 0; (i < pks->uris->nelts) && + APR_ARRAY_IDX(pks->uris, i, const char *); + i++) { + apr_file_printf(out, " %s\n", + APR_ARRAY_IDX(pks->uris, + i, const char *)); + } + for (i = 0; (i < pks->cert_files->nelts) && APR_ARRAY_IDX(pks->cert_files, i, const char *); i++) { @@ -2356,6 +2528,10 @@ void ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s) SSLSrvConfigRec *sc = mySrvConfig(s); if (sc && sc->server) { + if (sc->server->auth.ca_cert_uri) { + apr_file_printf(out, " %s\n", + sc->server->auth.ca_cert_uri); + } if (sc->server->auth.ca_cert_path) { apr_file_printf(out, " %s\n", sc->server->auth.ca_cert_path); @@ -2623,6 +2799,7 @@ static void modssl_auth_ctx_dump(modssl_auth_ctx_t *auth, apr_pool_t *p, int pro #endif DMP_VERIFY(proxy? "SSLProxyVerify" : "SSLVerifyClient", auth->verify_mode); DMP_LONG( proxy? "SSLProxyVerify" : "SSLVerifyDepth", auth->verify_depth); + DMP_STRING(proxy? "SSLProxyCACertificateURI" : "SSLCACertificateURI", auth->ca_cert_uri); DMP_STRING(proxy? "SSLProxyCACertificateFile" : "SSLCACertificateFile", auth->ca_cert_file); DMP_STRING(proxy? "SSLProxyCACertificatePath" : "SSLCACertificatePath", auth->ca_cert_path); } @@ -2640,14 +2817,17 @@ static void modssl_ctx_dump(modssl_ctx_t *ctx, apr_pool_t *p, int proxy, modssl_auth_ctx_dump(&ctx->auth, p, proxy, out, indent, psep); + DMP_STRING(proxy? "SSLProxyCARevocationURI" : "SSLCARevocationURI", ctx->crl_uri); DMP_STRING(proxy? "SSLProxyCARevocationFile" : "SSLCARevocationFile", ctx->crl_file); DMP_STRING(proxy? "SSLProxyCARevocationPath" : "SSLCARevocationPath", ctx->crl_path); DMP_CRLCHK(proxy? "SSLProxyCARevocationCheck" : "SSLCARevocationCheck", ctx->crl_check_mask); if (!proxy) { DMP_PHRASE("SSLPassPhraseDialog", ctx->pphrase_dialog_type, ctx->pphrase_dialog_path); if (ctx->pks) { + DMP_STRING("SSLCADNRequestURI", ctx->pks->ca_name_uri); DMP_STRING("SSLCADNRequestFile", ctx->pks->ca_name_file); DMP_STRING("SSLCADNRequestPath", ctx->pks->ca_name_path); + DMP_STRARR("SSLCertificateURI", ctx->pks->uris); DMP_STRARR("SSLCertificateFile", ctx->pks->cert_files); DMP_STRARR("SSLCertificateKeyFile", ctx->pks->key_files); } @@ -2698,6 +2878,7 @@ static void modssl_ctx_dump(modssl_ctx_t *ctx, apr_pool_t *p, int proxy, } else { /* proxy */ if (ctx->pkp) { + DMP_STRARR("SSLProxyMachineCertificateURI", ctx->pkp->uris); DMP_STRING("SSLProxyMachineCertificateFile", ctx->pkp->cert_file); DMP_STRING("SSLProxyMachineCertificatePath", ctx->pkp->cert_path); DMP_STRING("SSLProxyMachineCertificateChainFile", ctx->pkp->ca_cert_file); diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c index a557e940dd4..95187ea9fbd 100644 --- a/modules/ssl/ssl_engine_init.c +++ b/modules/ssl/ssl_engine_init.c @@ -334,6 +334,7 @@ static void hash_sni_policy_pk(apr_pool_t *ptemp, apr_md5_ctx_t *hash, modssl_ct md5_ifstr_update(hash, "ciphers:", ctx->auth.cipher_suite); md5_ifstr_update(hash, "tls13_ciphers:", ctx->auth.tls13_ciphers); + md5_strarray_hash(ptemp, hash, "uris:", ctx->pks->uris); md5_strarray_hash(ptemp, hash, "cert_files:", ctx->pks->cert_files); md5_strarray_hash(ptemp, hash, "key_files:", ctx->pks->key_files); } @@ -346,10 +347,13 @@ static void hash_sni_policy_auth(apr_md5_ctx_t *hash, modssl_ctx_t *ctx) md5_fmt_update(hash, "verify_depth:%d", a->verify_depth); md5_fmt_update(hash, "verify_mode:%d", a->verify_mode); + md5_ifstr_update(hash, "ca_name_uri:", pks->ca_name_uri); md5_ifstr_update(hash, "ca_name_path:", pks->ca_name_path); md5_ifstr_update(hash, "ca_name_file:", pks->ca_name_file); + md5_ifstr_update(hash, "ca_cert_uri:", a->ca_cert_uri); md5_ifstr_update(hash, "ca_cert_path:", a->ca_cert_path); md5_ifstr_update(hash, "ca_cert_file:", a->ca_cert_file); + md5_ifstr_update(hash, "crl_uri:", ctx->crl_uri); md5_ifstr_update(hash, "crl_path:", ctx->crl_path); md5_ifstr_update(hash, "crl_file:", ctx->crl_file); md5_fmt_update(hash, "crl_check_mask:%d", ctx->crl_check_mask); @@ -848,7 +852,7 @@ static apr_status_t ssl_init_ctx_tls_extensions(server_rec *s, #endif #if OPENSSL_VERSION_NUMBER < 0x10100000L || \ - (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20800000L) + (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20800000L) /* * Enable/disable SSLProtocol. If the mod_ssl enables protocol * which is disabled by default by OpenSSL, show a warning. @@ -887,7 +891,7 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, int protocol = mctx->protocol; SSLSrvConfigRec *sc = mySrvConfig(s); #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \ - (!defined(LIBRESSL_VERSION_NUMBER) || LIBRESSL_VERSION_NUMBER >= 0x20800000L) + (!defined(LIBRESSL_VERSION_NUMBER) || LIBRESSL_VERSION_NUMBER >= 0x20800000L) /* default is highest supported version, will be overridden below */ #if SSL_HAVE_PROTOCOL_TLSV1_3 int prot = TLS1_3_VERSION; @@ -978,7 +982,7 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, SSL_CTX_set_options(ctx, SSL_OP_ALL); #if OPENSSL_VERSION_NUMBER < 0x10100000L || \ - (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20800000L) + (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20800000L) /* always disable SSLv2, as per RFC 6176 */ SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2); @@ -1222,6 +1226,92 @@ int modssl_CTX_load_verify_locations(SSL_CTX *ctx, return 1; } +/* + * OpenSSL has a SSL_CTX_load_verify_store() function, but + * this function loads both leaf certs and CA certs. + * + * An end user reasonably wants to configure a URI pointing at + * CA certs and not have any surprises if the scope of the URI + * included leaf certificates. + * + * As a result we consider CA certs exclusively below. + */ + +static APR_INLINE +apr_status_t modssl_CTX_load_verify_store(server_rec *s, + apr_pool_t *ptemp, + const char *uri, + int depth, + modssl_ctx_t *mctx) +{ +#if MODSSL_HAVE_OPENSSL_STORE + OSSL_STORE_CTX *sctx; + OSSL_STORE_INFO *info; + + apr_status_t status = APR_SUCCESS; + + X509_STORE *store = SSL_CTX_get_cert_store(mctx->ssl_ctx); + + ap_assert(store != NULL); /* safe to assume always non-NULL? */ + + if (!uri || + (!(sctx = OSSL_STORE_open_ex(uri, mctx->libctx, NULL, NULL, NULL, + NULL, NULL, NULL)))) { + return APR_EGENERAL; + } + + while (!OSSL_STORE_eof(sctx) && !OSSL_STORE_error(sctx)) { + + if (!(info = OSSL_STORE_load(sctx))) { + continue; + } + + switch(OSSL_STORE_INFO_get_type(info)) { + case OSSL_STORE_INFO_NAME: { + + if (depth > 0) { + status = modssl_CTX_load_verify_store(s, ptemp, + OSSL_STORE_INFO_get0_NAME(info), + depth - 1, mctx); + } + + break; + } + case OSSL_STORE_INFO_CERT: { + + X509 *cert; + const X509_NAME *name; + X509_NAME *xname; + + if (!(cert = OSSL_STORE_INFO_get0_CERT(info))) { + return APR_EGENERAL; + } + else if (!X509_check_ca(cert)) { + /* ignore leaf certificates */ + continue; + } + if (X509_STORE_add_cert(store, cert)) { + + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO() + "Host %s: Trusted certificate from URI: %s", + mctx->sc->vhost_id, + modssl_X509_NAME_to_string(ptemp, + X509_get_subject_name(cert), 0)); + + } + + break; + } + } + } + + return status; +#else + return APR_ENOTIMPL; +#endif +} + + static apr_status_t ssl_init_ctx_verify(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp, @@ -1258,10 +1348,20 @@ static apr_status_t ssl_init_ctx_verify(server_rec *s, /* * Configure Client Authentication details */ - if (mctx->auth.ca_cert_file || mctx->auth.ca_cert_path) { + + if (mctx->auth.ca_cert_file || mctx->auth.ca_cert_path || + mctx->auth.ca_cert_uri) { ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s, "Configuring client authentication"); + if (modssl_CTX_load_verify_store(s, ptemp, mctx->auth.ca_cert_uri, 1, mctx) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO() + "Unable to configure verify store " + "for client authentication"); + ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); + return ssl_die(s); + } + 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) @@ -1271,14 +1371,22 @@ static apr_status_t ssl_init_ctx_verify(server_rec *s, return ssl_die(s); } - if (mctx->pks && (mctx->pks->ca_name_file || mctx->pks->ca_name_path)) { + if (mctx->pks && (mctx->pks->ca_name_file || mctx->pks->ca_name_path || + mctx->pks->ca_name_uri)) { ca_list = ssl_init_FindCAList(s, ptemp, - mctx->pks->ca_name_file, - mctx->pks->ca_name_path); - } else + mctx->pks->ca_name_file, + mctx->pks->ca_name_path, + mctx->pks->ca_name_uri, + mctx); + + } else { ca_list = ssl_init_FindCAList(s, ptemp, - mctx->auth.ca_cert_file, - mctx->auth.ca_cert_path); + mctx->auth.ca_cert_file, + mctx->auth.ca_cert_path, + mctx->auth.ca_cert_uri, + mctx); + } + if (sk_X509_NAME_num(ca_list) <= 0) { ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01896) "Unable to determine list of acceptable " @@ -1287,6 +1395,7 @@ static apr_status_t ssl_init_ctx_verify(server_rec *s, } SSL_CTX_set_client_CA_list(ctx, ca_list); + } /* @@ -1354,17 +1463,100 @@ int modssl_X509_STORE_load_locations(X509_STORE *store, const char *path) { #if OPENSSL_VERSION_NUMBER < 0x30000000L - if (!X509_STORE_load_locations(store, file, path)) + if (!X509_STORE_load_locations(store, file, path)) { return 0; + } #else - if (file && !X509_STORE_load_file(store, file)) + if (file && !X509_STORE_load_file(store, file)) { return 0; - if (path && !X509_STORE_load_path(store, path)) + } + if (path && !X509_STORE_load_path(store, path)) { return 0; + } #endif return 1; } +/* + * OpenSSL has a X509_STORE_load_store() function, but this + * function has side effects - it loads both CRLs and trusted + * CA certificates. + * + * An end user reasonably wants to configure a URI pointing at + * CRLs and not have any surprises if the scope of the URI + * included trusted CA certificates for whatever reason. + * + * As a result we consider CRLs exclusively below. + */ + +static APR_INLINE +apr_status_t modssl_X509_STORE_load_crl(server_rec *s, + apr_pool_t *ptemp, + const char *uri, + int depth, + modssl_ctx_t *mctx) +{ +#if MODSSL_HAVE_OPENSSL_STORE + OSSL_STORE_CTX *sctx; + OSSL_STORE_INFO *info; + + apr_status_t status = APR_SUCCESS; + + X509_STORE *store = SSL_CTX_get_cert_store(mctx->ssl_ctx); + + ap_assert(store != NULL); /* safe to assume always non-NULL? */ + + if (!uri || + (!(sctx = OSSL_STORE_open_ex(uri, mctx->libctx, NULL, NULL, NULL, + NULL, NULL, NULL)))) { + return APR_EGENERAL; + } + + while (!OSSL_STORE_eof(sctx) && !OSSL_STORE_error(sctx)) { + + if (!(info = OSSL_STORE_load(sctx))) { + continue; + } + + switch(OSSL_STORE_INFO_get_type(info)) { + case OSSL_STORE_INFO_NAME: { + + if (depth > 0) { + status = modssl_X509_STORE_load_crl(s, ptemp, + OSSL_STORE_INFO_get0_NAME(info), + depth - 1, mctx); + } + + break; + } + case OSSL_STORE_INFO_CRL: { + + X509_CRL *crl; + + if (!(crl = OSSL_STORE_INFO_get0_CRL(info))) { + return APR_EGENERAL; + } + if (X509_STORE_add_crl(store, crl)) { + + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO() + "Host %s: Certificate revocation list from URI: %s", + mctx->sc->vhost_id, + modssl_X509_NAME_to_string(ptemp, + X509_CRL_get_issuer(crl), 0)); + + } + + break; + } + } + } + + return status; +#else + return APR_ENOTIMPL; +#endif +} + static apr_status_t ssl_init_ctx_crl(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp, @@ -1375,6 +1567,8 @@ static apr_status_t ssl_init_ctx_crl(server_rec *s, char *cfgp = mctx->pkp ? "SSLProxy" : "SSL"; int crl_check_mode; + ap_assert(store != NULL); /* safe to assume always non-NULL? */ + if (mctx->ocsp_mask == UNSET) { mctx->ocsp_mask = SSL_OCSPCHECK_NONE; } @@ -1388,13 +1582,13 @@ static apr_status_t ssl_init_ctx_crl(server_rec *s, * Configure Certificate Revocation List (CRL) Details */ - if (!(mctx->crl_file || mctx->crl_path)) { + if (!(mctx->crl_uri || mctx->crl_file || mctx->crl_path)) { if (crl_check_mode == SSL_CRLCHECK_LEAF || crl_check_mode == SSL_CRLCHECK_CHAIN) { ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01899) "Host %s: CRL checking has been enabled, but " - "neither %sCARevocationFile nor %sCARevocationPath " - "is configured", mctx->sc->vhost_id, cfgp, cfgp); + "neither %sCARevocationURI, %sCARevocationFile nor %sCARevocationPath " + "is configured", mctx->sc->vhost_id, cfgp, cfgp, cfgp); return ssl_die(s); } return APR_SUCCESS; @@ -1403,8 +1597,16 @@ 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 || !modssl_X509_STORE_load_locations(store, mctx->crl_file, - mctx->crl_path)) { + if (!modssl_X509_STORE_load_crl(s, ptemp, mctx->crl_uri, 1, mctx)) { + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO() + "Host %s: unable to configure X.509 CRL uri " + "for certificate revocation", mctx->sc->vhost_id); + ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); + return ssl_die(s); + } + + if (!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); @@ -1630,11 +1832,380 @@ static void ssl_check_public_cert(server_rec *s, } } -/* prevent OpenSSL from showing its "Enter PEM pass phrase:" prompt */ -static int ssl_no_passwd_prompt_cb(char *buf, int size, int rwflag, - void *userdata) { - return 0; +/* prevent OpenSSL from showing its "Enter PEM pass phrase:" prompt */ +static int ssl_no_passwd_prompt_cb(char *buf, int size, int rwflag, + void *userdata) { + return 0; +} + + +#ifndef DEFINE_STACK_OF_EVP_PKEY +DEFINE_STACK_OF(EVP_PKEY) +#endif + +#if MODSSL_HAVE_OPENSSL_STORE + +apr_status_t ssl_init_uri_cleanup(void *data) +{ + modssl_ctx_uri_t *uctx = (modssl_ctx_uri_t *)data; + + sk_X509_pop_free(uctx->cert_list, X509_free); + sk_EVP_PKEY_pop_free(uctx->key_list, EVP_PKEY_free); + sk_X509_pop_free(uctx->ca_list, X509_free); + + return APR_SUCCESS; +} + +/* + * Sort certificates oldest to newest (last one wins). + */ +static int compare_certs_asc(const X509 *const *a, const X509 *const *b) +{ + const ASN1_TIME *time_a = X509_get0_notBefore(*a); + const ASN1_TIME *time_b = X509_get0_notBefore(*b); + + // ASN1_TIME_compare returns: + // -1 if time_a is earlier than time_b + // 0 if they are identical + // 1 if time_a is later than time_b + return ASN1_TIME_compare(time_a, time_b); +} + +static int cert_match(apr_pool_t *p, X509 *cert, const char *id) +{ + if (id[0] == '[') { + const char *end = strchr(id, ']'); + if (end && X509_check_ip_asc(cert, + apr_pstrndup(p, id + 1, end - id - 1), 0) == 1) { + return 1; + } + return 0; + } + if (X509_check_ip_asc(cert, id, 0) == 1) { + return 1; + } + if (X509_check_host(cert, id, 0, 0, NULL) == 1) { + return 1; + } + return 0; +} + +static apr_status_t ssl_init_uri(server_rec *s, + apr_pool_t *ptemp, + const char *uri, + int depth, + modssl_ctx_uri_t *uctx) +{ + OSSL_STORE_CTX *sctx; + OSSL_STORE_INFO *info; + + apr_status_t status = APR_SUCCESS; + + if (!uri || + (!(sctx = OSSL_STORE_open_ex(uri, uctx->mctx->libctx, NULL, + modssl_get_passphrase_ui(ptemp), + modssl_get_passphrase_cb(s, ptemp, + uctx->mctx->sc->vhost_id, uri), + NULL, NULL, NULL)))) { + return APR_EGENERAL; + } + + while (!OSSL_STORE_eof(sctx) && !OSSL_STORE_error(sctx)) { + + if (!(info = OSSL_STORE_load(sctx))) { + continue; + } + + switch(OSSL_STORE_INFO_get_type(info)) { + case OSSL_STORE_INFO_NAME: { + + if (depth > 0) { + status = ssl_init_uri(s, ptemp, + OSSL_STORE_INFO_get0_NAME(info), + depth - 1, uctx); + } + + break; + } + case OSSL_STORE_INFO_CERT: { + + X509 *cert; + const X509_NAME *name; + X509_NAME *xname; + + if (!(cert = OSSL_STORE_INFO_get1_CERT(info))) { + return APR_EGENERAL; + } + else if (X509_check_ca(cert)) { + + if (X509_self_signed(cert, 1)) { + + uctx->num_ca_certs++; + + /* ignore root certificates */ + X509_free(cert); + continue; + } + + if (sk_X509_push(uctx->ca_list, cert) <= 0) { + X509_free(cert); + return APR_EGENERAL; + } + + uctx->num_intermediate_certs++; + + } + else { + + uctx->num_leaf_certs++; + + if (!X509_check_purpose(cert, X509_PURPOSE_SSL_SERVER, 0)) { + /* ignore non server certs */ + X509_free(cert); + continue; + } + + /* check for a match on server name */ + if (s->server_hostname) { + if (!cert_match(ptemp, cert, s->server_hostname)) { + X509_free(cert); + continue; + } + } + + /* check for a match on all server aliases */ + if (s->names && !apr_is_empty_array(s->names)) { + const char **aliases = (const char **)s->names->elts; + int i; + for (i = 0; i < s->names->nelts; i++) { + if (!cert_match(ptemp, cert, aliases[i])) { + X509_free(cert); + continue; + } + } + } + + /* If we get here and a server name or server alias was + * not specified, we use the most recently issued leaf + * certificate in scope and assume the admin knows what + * they are doing. + */ + + if (sk_X509_push(uctx->cert_list, cert) <= 0) { + X509_free(cert); + return APR_EGENERAL; + } + + uctx->num_server_certs++; + + } + + uctx->num_certs++; + + break; + } + case OSSL_STORE_INFO_PKEY: { + + EVP_PKEY *key; + + if (!(key = OSSL_STORE_INFO_get1_PKEY(info))) { + return APR_EGENERAL; + } + if (sk_EVP_PKEY_push(uctx->key_list, key) <= 0) { + EVP_PKEY_free(key); + return APR_EGENERAL; + } + + uctx->num_keys++; + + break; + } + } + } + + return status; +} + + +/* + * Load certs from all URIs. + * + * The end user might point their URI at a single set of + * PEM encoded certs using the file: scheme, or might point + * the URI at pkcs11: or the whole MacOS keychain and + * expect us to figure it out for them. Lets help as much + * as possible. + * + * - Load all certs across all uris. + * - Consider intermediate certs, add them to the store + * - Consider leaf certs that match the ServerName and + * ServerAliases and drop if no match. + * - Sort certs by start date, oldest to newest + * - Load all keys across all uris. + * - Consider certs with a private key, drop the rest. + * - Pass each cert and key, in order, using + * SSL_CTX_use_certificate and SSL_CTX_use_PrivateKey. + * - End result, the most recent cert for each type (RSA, + * ECDSA, etc) wins. + * + */ + +static apr_status_t ssl_init_server_uris(server_rec *s, + apr_pool_t *p, + apr_pool_t *ptemp, + modssl_ctx_t *mctx, + apr_array_header_t *pphrases) +{ + SSLModConfigRec *mc = myModConfig(s); + const char *vhost_id = mctx->sc->vhost_id, *uri; + int i, k; + int found = 0; + apr_status_t status = APR_SUCCESS; + + modssl_ctx_uri_t *uctx = apr_pcalloc(ptemp, sizeof(modssl_ctx_uri_t)); + + uctx->mctx = mctx; + + uctx->cert_list = sk_X509_new_null(); + uctx->key_list = sk_EVP_PKEY_new_null(); + uctx->ca_list = sk_X509_new_null(); + + apr_pool_cleanup_register(ptemp, uctx, + ssl_init_uri_cleanup, + apr_pool_cleanup_null); + + sk_X509_set_cmp_func(uctx->cert_list, compare_certs_asc); + + /* no OpenSSL default prompts for any of the SSL_CTX_use_* calls, please */ + SSL_CTX_set_default_passwd_cb(mctx->ssl_ctx, ssl_no_passwd_prompt_cb); + + /* Iterate over the SSLCertificateURI array */ + for (i = 0; (i < mctx->pks->uris->nelts) && + (uri = APR_ARRAY_IDX(mctx->pks->uris, i, + const char *)); + i++) { + + if (uri && + ssl_init_uri(s, ptemp, uri, 1, uctx) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO() + "Host %s: Failed to open URI `%s'", + mctx->sc->vhost_id, uri); + return APR_EGENERAL; + } + + } + + /* oldest to newest, last one wins */ + sk_X509_sort(uctx->cert_list); + + /* Match certs to keys */ + for (i = sk_X509_num(uctx->cert_list) - 1; i >= 0; i--) { + X509 *cert = sk_X509_value(uctx->cert_list, i); + + for (k = 0; k < sk_EVP_PKEY_num(uctx->key_list); k++) { + EVP_PKEY *pkey = sk_EVP_PKEY_value(uctx->key_list, k); + + if (X509_check_private_key(cert, pkey) == 1) { + + if (SSL_CTX_use_certificate(mctx->ssl_ctx, cert) < 1) { + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO() + "Host %s: Failed to use certificate: %s", + mctx->sc->vhost_id, + modssl_X509_NAME_to_string(ptemp, + X509_get_subject_name(cert), 0)); + ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); + return APR_EGENERAL; + } + + if (SSL_CTX_use_PrivateKey(mctx->ssl_ctx, pkey) < 1) { + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO() + "Host %s: Failed to use private key: %s", + mctx->sc->vhost_id, + modssl_X509_NAME_to_string(ptemp, + X509_get_subject_name(cert), 0)); + ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); + return APR_EGENERAL; + } + + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO() + "Host %s: Server certificate from URI: %s", + mctx->sc->vhost_id, + modssl_X509_NAME_to_string(ptemp, + X509_get_subject_name(cert), 0)); + + found = 1; + break; + } + + } + } + + if (!found) { + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO() + "Host %s: No matching certificate/key pairs found among " + "%d certs, %d CA certs, %d intermediate certs, " + "%d leaf certs, %d server certs, %d keys.", + mctx->sc->vhost_id, + uctx->num_certs, uctx->num_ca_certs, uctx->num_intermediate_certs, + uctx->num_leaf_certs, + uctx->num_server_certs, uctx->num_keys); + ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); + return APR_EGENERAL; + } + + /* Handle intermediates, must happen after cert handling */ + for (i = sk_X509_num(uctx->ca_list) - 1; i >= 0; i--) { + X509 *cert = sk_X509_value(uctx->ca_list, i); + if (!SSL_CTX_add1_chain_cert(mctx->ssl_ctx, cert)) { + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO() + "Host %s: Failed to add intermediate certificate: %s", + mctx->sc->vhost_id, + modssl_X509_NAME_to_string(ptemp, + X509_get_subject_name(cert), 0)); + ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); + return APR_EGENERAL; + } + } + + /* + * Do our best to build as much of the chain as possible with + * the certs we were provided. + */ + + if (!SSL_CTX_build_cert_chain(mctx->ssl_ctx, SSL_BUILD_CHAIN_FLAG_NO_ROOT | + SSL_BUILD_CHAIN_FLAG_UNTRUSTED | + SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR | + SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR)) { + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO() + "Host %s: Could not build the certificate chain from " + "%d certs, %d CA certs, %d intermediate certs, " + "%d leaf certs, %d server certs, %d keys.", + mctx->sc->vhost_id, + uctx->num_certs, uctx->num_ca_certs, uctx->num_intermediate_certs, + uctx->num_leaf_certs, + uctx->num_server_certs, uctx->num_keys); + ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); + return APR_EGENERAL; + } + + return status; +} +#else +static apr_status_t ssl_init_server_uris(server_rec *s, + apr_pool_t *p, + apr_pool_t *ptemp, + modssl_ctx_t *mctx, + apr_array_header_t *pphrases) +{ + const char *vhost_id = mctx->sc->vhost_id; + + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO() + "Host %s: Server certificate URIs are not supported on this platform.", + mctx->sc->vhost_id); + + return APR_ENOTIMPL; } +#endif /* SSL_CTX_use_PrivateKey_file() can fail either because the private * key was encrypted, or due to a mismatch between an already-loaded @@ -2001,6 +2572,284 @@ static apr_status_t ssl_init_ticket_key(server_rec *s, } #endif +#if MODSSL_HAVE_OPENSSL_STORE + +/* + * Sort certificates newest to oldest (first one wins). + */ +static int compare_certs_desc(const X509 *const *a, const X509 *const *b) +{ + const ASN1_TIME *time_a = X509_get0_notBefore(*a); + const ASN1_TIME *time_b = X509_get0_notBefore(*b); + + // ASN1_TIME_compare returns: + // -1 if time_a is earlier than time_b + // 0 if they are identical + // 1 if time_a is later than time_b + return -ASN1_TIME_compare(time_a, time_b); +} + +static apr_status_t ssl_init_proxy_uri(server_rec *s, + apr_pool_t *ptemp, + const char *uri, + int depth, + modssl_ctx_uri_t *uctx) +{ + OSSL_STORE_CTX *sctx; + OSSL_STORE_INFO *info; + + apr_status_t status = APR_SUCCESS; + + if (!uri || + (!(sctx = OSSL_STORE_open_ex(uri, uctx->mctx->libctx, NULL, + modssl_get_passphrase_ui(ptemp), + modssl_get_passphrase_cb(s, ptemp, + uctx->mctx->sc->vhost_id, uri), + NULL, NULL, NULL)))) { + return APR_EGENERAL; + } + + while (!OSSL_STORE_eof(sctx) && !OSSL_STORE_error(sctx)) { + + if (!(info = OSSL_STORE_load(sctx))) { + continue; + } + + switch(OSSL_STORE_INFO_get_type(info)) { + case OSSL_STORE_INFO_NAME: { + + if (depth > 0) { + status = ssl_init_uri(s, ptemp, + OSSL_STORE_INFO_get0_NAME(info), + depth - 1, uctx); + } + + break; + } + case OSSL_STORE_INFO_CERT: { + + X509 *cert; + const X509_NAME *name; + X509_NAME *xname; + + if (!(cert = OSSL_STORE_INFO_get1_CERT(info))) { + return APR_EGENERAL; + } + else if (X509_check_ca(cert)) { + + if (X509_self_signed(cert, 1)) { + + uctx->num_ca_certs++; + + /* ignore root certificates */ + X509_free(cert); + break; + } + + if (sk_X509_push(uctx->ca_list, cert) <= 0) { + X509_free(cert); + return APR_EGENERAL; + } + + uctx->num_intermediate_certs++; + + } + else { + + uctx->num_leaf_certs++; + + if (!X509_check_purpose(cert, X509_PURPOSE_SSL_CLIENT, 0)) { + /* ignore non client certs */ + X509_free(cert); + break; + } + + if (sk_X509_push(uctx->cert_list, cert) <= 0) { + X509_free(cert); + return APR_EGENERAL; + } + + uctx->num_client_certs++; + + } + + uctx->num_certs++; + + break; + } + case OSSL_STORE_INFO_PKEY: { + + EVP_PKEY *key; + + if (!(key = OSSL_STORE_INFO_get1_PKEY(info))) { + return APR_EGENERAL; + } + if (sk_EVP_PKEY_push(uctx->key_list, key) <= 0) { + EVP_PKEY_free(key); + return APR_EGENERAL; + } + + uctx->num_keys++; + + break; + } + } + } + + return status; +} + +static apr_status_t ssl_init_proxy_uris(server_rec *s, + apr_pool_t *p, + apr_pool_t *ptemp, + modssl_ctx_t *mctx) +{ + SSLModConfigRec *mc = myModConfig(s); + const char *vhost_id = mctx->sc->vhost_id, *uri; + modssl_pk_proxy_t *pkp = mctx->pkp; + modssl_ctx_uri_t *uctx; + STACK_OF(X509_INFO) *sk; + + int i, k; + int found = 0; + apr_status_t status = APR_SUCCESS; + + X509_STORE *store = SSL_CTX_get_cert_store(mctx->ssl_ctx); + + ap_assert(store != NULL); /* safe to assume always non-NULL? */ + + if (!pkp->uris->nelts) { + return APR_SUCCESS; + } + + SSL_CTX_set_post_handshake_auth(mctx->ssl_ctx, 1); + + SSL_CTX_set_client_cert_cb(mctx->ssl_ctx, + ssl_callback_proxy_cert); + + sk = pkp->certs; + if (!sk) { + pkp->certs = sk = sk_X509_INFO_new_null(); + } + + uctx = apr_pcalloc(ptemp, sizeof(modssl_ctx_uri_t)); + + uctx->mctx = mctx; + + uctx->cert_list = sk_X509_new_null(); + uctx->key_list = sk_EVP_PKEY_new_null(); + uctx->ca_list = sk_X509_new_null(); + + apr_pool_cleanup_register(ptemp, uctx, + ssl_init_uri_cleanup, + apr_pool_cleanup_null); + + sk_X509_set_cmp_func(uctx->cert_list, compare_certs_desc); + + /* Iterate over the SSLProxyCertificateURI array */ + for (i = 0; (i < mctx->pkp->uris->nelts) && + (uri = APR_ARRAY_IDX(mctx->pkp->uris, i, + const char *)); + i++) { + + if (uri && + ssl_init_proxy_uri(s, ptemp, uri, 1, uctx) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO() + "Host %s: Failed to open proxy URI `%s'", + mctx->sc->vhost_id, uri); + return APR_EGENERAL; + } + + } + + /* newest to oldest, first one wins */ + sk_X509_sort(uctx->cert_list); + + /* Match certs to keys */ + for (i = sk_X509_num(uctx->cert_list) - 1; i >= 0; i--) { + X509 *cert = sk_X509_value(uctx->cert_list, i); + + for (k = 0; k < sk_EVP_PKEY_num(uctx->key_list); k++) { + EVP_PKEY *pkey = sk_EVP_PKEY_value(uctx->key_list, k); + + if (X509_check_private_key(cert, pkey) == 1) { + + X509_INFO *info = X509_INFO_new(); + info->x_pkey = X509_PKEY_new(); + + X509_up_ref(cert); + info->x509 = cert; + + EVP_PKEY_up_ref(pkey); + info->x_pkey->dec_pkey = pkey; + + sk_X509_INFO_push(sk, info); + + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO() + "Host %s: Proxy certificate from URI: %s", + mctx->sc->vhost_id, + modssl_X509_NAME_to_string(ptemp, + X509_get_subject_name(cert), 0)); + + found = 1; + break; + } + + } + } + + if (!found) { + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO() + "Host %s: No matching proxy certificate/key pairs found among " + "%d certs, %d CA certs, %d intermediate certs, " + "%d leaf certs, %d client certs, %d keys.", + mctx->sc->vhost_id, + uctx->num_certs, uctx->num_ca_certs, uctx->num_intermediate_certs, + uctx->num_leaf_certs, + uctx->num_client_certs, uctx->num_keys); + ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); + sk_X509_INFO_free(sk); + return APR_EGENERAL; + } + + /* Handle intermediates, must happen after cert handling */ + for (i = sk_X509_num(uctx->ca_list) - 1; i >= 0; i--) { + X509 *cert = sk_X509_value(uctx->ca_list, i); + X509_STORE_add_cert(store, cert); /* increments cert */ + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO() + "Host %s: loaded %d client certs for SSL proxy among " + "%d certs, %d CA certs, %d intermediate certs, " + "%d leaf certs, %d client certs, %d keys.", + mctx->sc->vhost_id, + sk_X509_INFO_num(sk), + uctx->num_certs, uctx->num_ca_certs, uctx->num_intermediate_certs, + uctx->num_leaf_certs, + uctx->num_client_certs, uctx->num_keys); + + return status; +} +#else +static apr_status_t ssl_init_proxy_uris(server_rec *s, + apr_pool_t *p, + apr_pool_t *ptemp, + modssl_ctx_t *mctx) +{ + if (pkp->uris->nelts) { + const char *vhost_id = mctx->sc->vhost_id; + + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO() + "Host %s: Proxy certificate URIs are not supported on this platform.", + mctx->sc->vhost_id); + + return APR_ENOTIMPL; + } + + return APR_SUCCESS; +} +#endif + static BOOL load_x509_info(apr_pool_t *ptemp, STACK_OF(X509_INFO) *sk, const char *filename) @@ -2030,14 +2879,10 @@ static apr_status_t ssl_init_proxy_certs(server_rec *s, apr_pool_t *ptemp, modssl_ctx_t *mctx) { - int n, ncerts = 0; STACK_OF(X509_INFO) *sk; modssl_pk_proxy_t *pkp = mctx->pkp; - 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 */ + int n, ncerts = 0; ap_assert(store != NULL); /* safe to assume always non-NULL? */ @@ -2047,7 +2892,7 @@ static apr_status_t ssl_init_proxy_certs(server_rec *s, * https://github.com/openssl/openssl/issues/6933 */ SSL_CTX_set_post_handshake_auth(mctx->ssl_ctx, 1); #endif - + SSL_CTX_set_client_cert_cb(mctx->ssl_ctx, ssl_callback_proxy_cert); @@ -2082,7 +2927,6 @@ static apr_status_t ssl_init_proxy_certs(server_rec *s, X509_INFO_free(inf); sk_X509_INFO_delete(sk, n); n--; - addl_chain = 1; continue; } @@ -2093,7 +2937,7 @@ static apr_status_t ssl_init_proxy_certs(server_rec *s, "(missing or encrypted private key?)"); return ssl_die(s); } - + if (X509_check_private_key(inf->x509, inf->x_pkey->dec_pkey) != 1) { ssl_log_xerror(SSLLOG_MARK, APLOG_STARTUP, 0, ptemp, s, inf->x509, APLOGNO(02326) "proxy client certificate and " @@ -2115,36 +2959,51 @@ static apr_status_t ssl_init_proxy_certs(server_rec *s, ncerts); pkp->certs = sk; - /* 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; + if (pkp->ca_cert_file) { + modssl_X509_STORE_load_locations(store, pkp->ca_cert_file, NULL); } - /* If SSLProxyMachineCertificateChainFile is configured, load all - * the CA certs and have OpenSSL attempt to construct a full chain - * from each configured end-entity cert up to a root. This will - * allow selection of the correct cert given a list of root CA + return APR_SUCCESS; +} + +static apr_status_t ssl_init_proxy_ca_certs(server_rec *s, + apr_pool_t *p, + apr_pool_t *ptemp, + modssl_ctx_t *mctx) +{ + modssl_pk_proxy_t *pkp = mctx->pkp; + + X509_STORE_CTX *sctx; + X509_STORE *store = SSL_CTX_get_cert_store(mctx->ssl_ctx); + STACK_OF(X509) *chain; + + int n, ncerts = 0; + + ap_assert(store != NULL); /* safe to assume always non-NULL? */ + + ncerts = sk_X509_INFO_num(pkp->certs); + + /* If intermediate certificates have been configured, have + * OpenSSL attempt to construct a full chain from each + * configured end-entity cert up to a root. This will allow + * selection of the correct cert given a list of root CA * names in the certificate request from the server. */ - pkp->ca_certs = (STACK_OF(X509) **) apr_pcalloc(p, ncerts * sizeof(sk)); + + pkp->ca_certs = (STACK_OF(X509) **) apr_pcalloc(p, ncerts * sizeof(STACK_OF(X509_INFO) *)); sctx = X509_STORE_CTX_new(); if (!sctx) { 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); } - modssl_X509_STORE_load_locations(store, pkp->ca_cert_file, NULL); - for (n = 0; n < ncerts; n++) { int i; X509_INFO *inf = sk_X509_INFO_value(pkp->certs, n); if (!X509_STORE_CTX_init(sctx, store, inf->x509, NULL)) { - sk_X509_INFO_free(sk); X509_STORE_CTX_free(sctx); return ssl_die(s); } @@ -2268,6 +3127,14 @@ static apr_status_t ssl_init_proxy_ctx(server_rec *s, return rv; } + if ((rv = ssl_init_proxy_uris(s, p, ptemp, proxy)) != APR_SUCCESS) { + return rv; + } + + if ((rv = ssl_init_proxy_ca_certs(s, p, ptemp, proxy)) != APR_SUCCESS) { + return rv; + } + return APR_SUCCESS; } @@ -2319,16 +3186,30 @@ static apr_status_t ssl_init_server_ctx(server_rec *s, /* additionally installed certs overrides any old chain configuration */ sc->server->cert_chain = NULL; } - + if ((rv = ssl_init_ctx(s, p, ptemp, sc->server)) != APR_SUCCESS) { return rv; } - if ((rv = ssl_init_server_certs(s, p, ptemp, sc->server, pphrases)) - != APR_SUCCESS) { - return rv; + if (pks->cert_files->nelts) { + + if ((rv = ssl_init_server_certs(s, p, ptemp, sc->server, pphrases)) + != APR_SUCCESS) { + return rv; + } + + } + + if (pks->uris->nelts) { + + if ((rv = ssl_init_server_uris(s, p, ptemp, sc->server, pphrases)) + != APR_SUCCESS) { + return rv; + } + } + #ifdef HAVE_SSL_CONF_CMD SSL_CONF_CTX_set_ssl_ctx(cctx, sc->server->ssl_ctx); for (i = 0; i < sc->server->ssl_ctx_param->nelts; i++, param++) { @@ -2425,10 +3306,10 @@ apr_status_t ssl_init_ConfigureServer(server_rec *s, return rv; } - /* Initialize OCSP Responder certificate if OCSP enabled */ - #ifndef OPENSSL_NO_OCSP - ssl_init_ocsp_certificates(s, sc->server); - #endif + /* Initialize OCSP Responder certificate if OCSP enabled */ + #ifndef OPENSSL_NO_OCSP + ssl_init_ocsp_certificates(s, sc->server); + #endif } @@ -2566,6 +3447,86 @@ int ssl_proxy_section_post_config(apr_pool_t *p, apr_pool_t *plog, return OK; } +static int ssl_init_x509_name_cmp(const X509_NAME *const *a, const X509_NAME *const *b) +{ + return X509_NAME_cmp(*a, *b); +} + +static apr_status_t ssl_init_ca_cert_uri(server_rec *s, + apr_pool_t *ptemp, + const char *uri, + STACK_OF(X509_NAME) *ca_list, + int depth, + modssl_ctx_t *mctx) +{ +#if MODSSL_HAVE_OPENSSL_STORE + OSSL_STORE_CTX *sctx; + OSSL_STORE_INFO *info; + + apr_status_t status = APR_SUCCESS; + + sk_X509_NAME_set_cmp_func(ca_list, ssl_init_x509_name_cmp); + + if (!uri || (!ca_list) || + (!(sctx = OSSL_STORE_open_ex(uri, mctx->libctx, NULL, NULL, NULL, + NULL, NULL, NULL)))) { + return APR_EGENERAL; + } + + while (!OSSL_STORE_eof(sctx) && !OSSL_STORE_error(sctx)) { + + if (!(info = OSSL_STORE_load(sctx))) { + continue; + } + + switch(OSSL_STORE_INFO_get_type(info)) { + case OSSL_STORE_INFO_NAME: { + + if (depth > 0) { + status = ssl_init_ca_cert_uri(s, ptemp, + OSSL_STORE_INFO_get0_NAME(info), + ca_list, depth - 1, mctx); + } + + break; + } + case OSSL_STORE_INFO_CERT: { + + X509 *cert; + const X509_NAME *name; + X509_NAME *xname; + + if (!(cert = OSSL_STORE_INFO_get0_CERT(info))) { + return APR_EGENERAL; + } + else if (!X509_check_ca(cert)) { + /* ignore leaf certificates */ + continue; + } + else if (!(name = X509_get_subject_name(cert)) || + !(xname = X509_NAME_dup(name))) { + return APR_EGENERAL; + } + if (sk_X509_NAME_find(ca_list, xname) >= 0) { + /* duplicate */ + X509_NAME_free(xname); + } + else if (!sk_X509_NAME_push(ca_list, xname)) { + X509_NAME_free(xname); + return APR_EGENERAL; + } + + break; + } + } + } + + return status; +#else + return APR_ENOTIMPL; +#endif +} + static apr_status_t ssl_init_ca_cert_path(server_rec *s, apr_pool_t *ptemp, const char *path, @@ -2603,24 +3564,33 @@ static apr_status_t ssl_init_ca_cert_path(server_rec *s, STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s, apr_pool_t *ptemp, const char *ca_file, - const char *ca_path) + const char *ca_path, + const char *ca_uri, + modssl_ctx_t *mctx) { STACK_OF(X509_NAME) *ca_list = sk_X509_NAME_new_null();; + /* + * Process CA certificate store uri + */ + if (ca_uri && + ssl_init_ca_cert_uri(s, ptemp, + ca_uri, ca_list, 1, mctx) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO() + "Failed to open Certificate URI `%s'", ca_uri); + sk_X509_NAME_pop_free(ca_list, X509_NAME_free); + return NULL; + } + /* * Process CA certificate bundle file */ - if (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. - */ - if (sk_X509_NAME_num(ca_list) == 0) { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02210) + if (ca_file && SSL_add_file_cert_subjects_to_stack(ca_list, ca_file)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02210) "Failed to load SSLCACertificateFile: %s", ca_file); - ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s); - } + ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s); + sk_X509_NAME_pop_free(ca_list, X509_NAME_free); + return NULL; } /* @@ -2675,10 +3645,10 @@ apr_status_t ssl_init_ModuleKill(void *data) ssl_init_ctx_cleanup(sc->server); - /* Not Sure but possibly clear X509 trusted cert file */ - #ifndef OPENSSL_NO_OCSP - sk_X509_pop_free(sc->server->ocsp_certs, X509_free); - #endif + /* Not Sure but possibly clear X509 trusted cert file */ + #ifndef OPENSSL_NO_OCSP + sk_X509_pop_free(sc->server->ocsp_certs, X509_free); + #endif } diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c index 3e96f9efdac..85118b7a9d0 100644 --- a/modules/ssl/ssl_engine_kernel.c +++ b/modules/ssl/ssl_engine_kernel.c @@ -29,6 +29,7 @@ time I was too famous.'' -- Unknown */ #include "ssl_private.h" +#include "httpd.h" #include "mod_ssl.h" #include "util_md5.h" #include "scoreboard.h" diff --git a/modules/ssl/ssl_engine_pphrase.c b/modules/ssl/ssl_engine_pphrase.c index 773c4660eb8..900b91a472a 100644 --- a/modules/ssl/ssl_engine_pphrase.c +++ b/modules/ssl/ssl_engine_pphrase.c @@ -780,7 +780,7 @@ static apr_status_t pp_ui_method_cleanup(void *uip) return APR_SUCCESS; } -static UI_METHOD *get_passphrase_ui(apr_pool_t *p) +UI_METHOD *modssl_get_passphrase_ui(apr_pool_t *p) { UI_METHOD *ui_method = UI_create_method("Passphrase UI"); @@ -794,6 +794,21 @@ static UI_METHOD *get_passphrase_ui(apr_pool_t *p) return ui_method; } + +void *modssl_get_passphrase_cb(server_rec *s, apr_pool_t *p, + const char *vhostid, + const char *uri) +{ + pphrase_cb_arg_t *ppcb = apr_pcalloc(p, sizeof(pphrase_cb_arg_t)); + + ppcb->s = s; + ppcb->p = p; + ppcb->bPassPhraseDialogOnce = TRUE; + ppcb->key_id = vhostid; + ppcb->pkey_file = uri; + + return ppcb; +} #endif #if MODSSL_HAVE_ENGINE_API @@ -819,7 +834,7 @@ static apr_status_t modssl_load_keypair_engine(server_rec *s, apr_pool_t *pconf, { const char *c, *scheme; ENGINE *e; - UI_METHOD *ui_method = get_passphrase_ui(ptemp); + UI_METHOD *ui_method = modssl_get_passphrase_ui(ptemp); pphrase_cb_arg_t ppcb; memset(&ppcb, 0, sizeof ppcb); @@ -904,7 +919,7 @@ static OSSL_STORE_INFO *modssl_load_store_uri(server_rec *s, apr_pool_t *p, const char *uri, int info_type) { OSSL_STORE_CTX *sctx; - UI_METHOD *ui_method = get_passphrase_ui(p); + UI_METHOD *ui_method = modssl_get_passphrase_ui(p); pphrase_cb_arg_t ppcb; OSSL_STORE_INFO *info = NULL; diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h index a34b034f265..8814f276e05 100644 --- a/modules/ssl/ssl_private.h +++ b/modules/ssl/ssl_private.h @@ -755,19 +755,23 @@ typedef struct { * a given vhost */ typedef struct { /* Lists of configured certs and keys for this server */ + apr_array_header_t *uris; apr_array_header_t *cert_files; apr_array_header_t *key_files; /** Certificates which specify the set of CA names which should be * sent in the CertificateRequest message: */ + const char *ca_name_uri; const char *ca_name_path; const char *ca_name_file; - + /* TLS service for this server is suspended */ int service_unavailable; } modssl_pk_server_t; typedef struct { + /* Lists of configured certs and keys for this proxy */ + apr_array_header_t *uris; /** proxy can have any number of cert/key pairs */ const char *cert_file; const char *cert_path; @@ -784,6 +788,7 @@ typedef struct { /** stuff related to authentication that can also be per-dir */ typedef struct { /** known/trusted CAs */ + const char *ca_cert_uri; const char *ca_cert_path; const char *ca_cert_file; @@ -822,6 +827,9 @@ typedef struct { typedef struct { SSLSrvConfigRec *sc; /** pointer back to server config */ SSL_CTX *ssl_ctx; +#if MODSSL_HAVE_OPENSSL_STORE + OSSL_LIB_CTX *libctx; +#endif /** we are one or the other */ modssl_pk_server_t *pks; @@ -841,6 +849,7 @@ typedef struct { const char *cert_chain; /** certificate revocation list */ + const char *crl_uri; const char *crl_path; const char *crl_file; int crl_check_mask; @@ -892,6 +901,24 @@ typedef struct { BOOL ssl_check_peer_expire; } modssl_ctx_t; + +typedef struct { + modssl_ctx_t* mctx; + + STACK_OF(X509) *cert_list; + STACK_OF(EVP_PKEY) *key_list; + STACK_OF(X509) *ca_list; + + int num_certs; + int num_ca_certs; + int num_intermediate_certs; + int num_leaf_certs; + int num_server_certs; + int num_client_certs; + int num_keys; + +} modssl_ctx_uri_t; + struct SSLSrvConfigRec { SSLModConfigRec *mc; ssl_enabled_t enabled; @@ -963,13 +990,17 @@ const char *ssl_cmd_SSLEngine(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLECHKeyDir(cmd_parms *cmd, void *dcfg, const char *arg); #endif const char *ssl_cmd_SSLCipherSuite(cmd_parms *, void *, const char *, const char *); +const char *ssl_cmd_SSLCertificateURI(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLCertificateFile(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLCertificateKeyFile(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLCertificateChainFile(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLCACertificateURI(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLCACertificatePath(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLCACertificateFile(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLCADNRequestURI(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLCADNRequestPath(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLCADNRequestFile(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLCARevocationURI(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLCARevocationPath(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLCARevocationFile(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLCARevocationCheck(cmd_parms *, void *, const char *); @@ -996,11 +1027,14 @@ const char *ssl_cmd_SSLProxyProtocol(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLProxyCipherSuite(cmd_parms *, void *, const char *, const char *); const char *ssl_cmd_SSLProxyVerify(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLProxyVerifyDepth(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLProxyCACertificateURI(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLProxyCACertificatePath(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLProxyCACertificateFile(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLProxyCARevocationURI(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLProxyCARevocationPath(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLProxyCARevocationFile(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLProxyCARevocationCheck(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLProxyMachineCertificateURI(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLProxyMachineCertificatePath(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLProxyMachineCertificateFile(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLProxyMachineCertificateChainFile(cmd_parms *, void *, const char *); @@ -1046,7 +1080,7 @@ int ssl_proxy_section_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s, ap_conf_vector_t *section_config); STACK_OF(X509_NAME) - *ssl_init_FindCAList(server_rec *, apr_pool_t *, const char *, const char *); + *ssl_init_FindCAList(server_rec *, apr_pool_t *, const char *, const char *, const char *, modssl_ctx_t *); void ssl_init_Child(apr_pool_t *, server_rec *); apr_status_t ssl_init_ModuleKill(void *data); @@ -1181,6 +1215,12 @@ apr_status_t modssl_load_engine_keypair(server_rec *s, const char *certid, const char *keyid, X509 **pubkey, EVP_PKEY **privkey); +UI_METHOD *modssl_get_passphrase_ui(apr_pool_t *p); +void *modssl_get_passphrase_cb(server_rec *s, apr_pool_t *p, + const char *vhostid, + const char *uri); + + /** Diffie-Hellman Parameter Support */ #if OPENSSL_VERSION_NUMBER < 0x30000000L DH *modssl_dh_from_file(const char *); From 299099c240e1ae679864c1bb0c9321854fb87c4f Mon Sep 17 00:00:00 2001 From: Graham Leggett Date: Wed, 29 Jul 2026 11:23:53 +0100 Subject: [PATCH 2/3] Overhaul error handling paths. --- modules/ssl/ssl_engine_init.c | 148 +++++++++++++++++++++++++--------- 1 file changed, 111 insertions(+), 37 deletions(-) diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c index 95187ea9fbd..7330b7afea8 100644 --- a/modules/ssl/ssl_engine_init.c +++ b/modules/ssl/ssl_engine_init.c @@ -1248,14 +1248,17 @@ apr_status_t modssl_CTX_load_verify_store(server_rec *s, OSSL_STORE_CTX *sctx; OSSL_STORE_INFO *info; - apr_status_t status = APR_SUCCESS; + apr_status_t rv = APR_SUCCESS; X509_STORE *store = SSL_CTX_get_cert_store(mctx->ssl_ctx); ap_assert(store != NULL); /* safe to assume always non-NULL? */ - if (!uri || - (!(sctx = OSSL_STORE_open_ex(uri, mctx->libctx, NULL, NULL, NULL, + if (!uri) { + return APR_SUCCESS; + } + + if ((!(sctx = OSSL_STORE_open_ex(uri, mctx->libctx, NULL, NULL, NULL, NULL, NULL, NULL)))) { return APR_EGENERAL; } @@ -1270,9 +1273,13 @@ apr_status_t modssl_CTX_load_verify_store(server_rec *s, case OSSL_STORE_INFO_NAME: { if (depth > 0) { - status = modssl_CTX_load_verify_store(s, ptemp, + rv = modssl_CTX_load_verify_store(s, ptemp, OSSL_STORE_INFO_get0_NAME(info), depth - 1, mctx); + if (APR_SUCCESS != rv) { + OSSL_STORE_close(sctx); + return rv; + } } break; @@ -1305,8 +1312,14 @@ apr_status_t modssl_CTX_load_verify_store(server_rec *s, } } - return status; + OSSL_STORE_close(sctx); + + return rv; #else + if (!uri) { + return APR_SUCCESS; + } + return APR_ENOTIMPL; #endif } @@ -1351,11 +1364,15 @@ static apr_status_t ssl_init_ctx_verify(server_rec *s, if (mctx->auth.ca_cert_file || mctx->auth.ca_cert_path || mctx->auth.ca_cert_uri) { + + apr_status_t rv; + ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s, "Configuring client authentication"); - if (modssl_CTX_load_verify_store(s, ptemp, mctx->auth.ca_cert_uri, 1, mctx) != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO() + if ((rv = modssl_CTX_load_verify_store(s, ptemp, + mctx->auth.ca_cert_uri, 1, mctx)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO() "Unable to configure verify store " "for client authentication"); ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); @@ -1391,6 +1408,7 @@ static apr_status_t ssl_init_ctx_verify(server_rec *s, ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01896) "Unable to determine list of acceptable " "CA certificates for client authentication"); + ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); return ssl_die(s); } @@ -1500,14 +1518,17 @@ apr_status_t modssl_X509_STORE_load_crl(server_rec *s, OSSL_STORE_CTX *sctx; OSSL_STORE_INFO *info; - apr_status_t status = APR_SUCCESS; + apr_status_t rv = APR_SUCCESS; X509_STORE *store = SSL_CTX_get_cert_store(mctx->ssl_ctx); ap_assert(store != NULL); /* safe to assume always non-NULL? */ - if (!uri || - (!(sctx = OSSL_STORE_open_ex(uri, mctx->libctx, NULL, NULL, NULL, + if (!uri) { + return APR_SUCCESS; + } + + if ((!(sctx = OSSL_STORE_open_ex(uri, mctx->libctx, NULL, NULL, NULL, NULL, NULL, NULL)))) { return APR_EGENERAL; } @@ -1522,9 +1543,13 @@ apr_status_t modssl_X509_STORE_load_crl(server_rec *s, case OSSL_STORE_INFO_NAME: { if (depth > 0) { - status = modssl_X509_STORE_load_crl(s, ptemp, + rv = modssl_X509_STORE_load_crl(s, ptemp, OSSL_STORE_INFO_get0_NAME(info), depth - 1, mctx); + if (APR_SUCCESS != rv) { + OSSL_STORE_close(sctx); + return rv; + } } break; @@ -1551,8 +1576,14 @@ apr_status_t modssl_X509_STORE_load_crl(server_rec *s, } } - return status; + OSSL_STORE_close(sctx); + + return rv; #else + if (!uri) { + return APR_SUCCESS; + } + return APR_ENOTIMPL; #endif } @@ -1566,6 +1597,7 @@ static apr_status_t ssl_init_ctx_crl(server_rec *s, unsigned long crlflags = 0; char *cfgp = mctx->pkp ? "SSLProxy" : "SSL"; int crl_check_mode; + apr_status_t rv; ap_assert(store != NULL); /* safe to assume always non-NULL? */ @@ -1597,8 +1629,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 (!modssl_X509_STORE_load_crl(s, ptemp, mctx->crl_uri, 1, mctx)) { - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO() + if ((rv = modssl_X509_STORE_load_crl(s, ptemp, mctx->crl_uri, 1, mctx)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO() "Host %s: unable to configure X.509 CRL uri " "for certificate revocation", mctx->sc->vhost_id); ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); @@ -1899,10 +1931,13 @@ static apr_status_t ssl_init_uri(server_rec *s, OSSL_STORE_CTX *sctx; OSSL_STORE_INFO *info; - apr_status_t status = APR_SUCCESS; + apr_status_t rv = APR_SUCCESS; - if (!uri || - (!(sctx = OSSL_STORE_open_ex(uri, uctx->mctx->libctx, NULL, + if (!uri) { + return rv; + } + + if ((!(sctx = OSSL_STORE_open_ex(uri, uctx->mctx->libctx, NULL, modssl_get_passphrase_ui(ptemp), modssl_get_passphrase_cb(s, ptemp, uctx->mctx->sc->vhost_id, uri), @@ -1920,9 +1955,13 @@ static apr_status_t ssl_init_uri(server_rec *s, case OSSL_STORE_INFO_NAME: { if (depth > 0) { - status = ssl_init_uri(s, ptemp, + rv = ssl_init_uri(s, ptemp, OSSL_STORE_INFO_get0_NAME(info), depth - 1, uctx); + if (APR_SUCCESS != rv) { + OSSL_STORE_close(sctx); + return rv; + } } break; @@ -1949,6 +1988,7 @@ static apr_status_t ssl_init_uri(server_rec *s, if (sk_X509_push(uctx->ca_list, cert) <= 0) { X509_free(cert); + OSSL_STORE_close(sctx); return APR_EGENERAL; } @@ -1993,6 +2033,7 @@ static apr_status_t ssl_init_uri(server_rec *s, if (sk_X509_push(uctx->cert_list, cert) <= 0) { X509_free(cert); + OSSL_STORE_close(sctx); return APR_EGENERAL; } @@ -2009,10 +2050,12 @@ static apr_status_t ssl_init_uri(server_rec *s, EVP_PKEY *key; if (!(key = OSSL_STORE_INFO_get1_PKEY(info))) { + OSSL_STORE_close(sctx); return APR_EGENERAL; } if (sk_EVP_PKEY_push(uctx->key_list, key) <= 0) { EVP_PKEY_free(key); + OSSL_STORE_close(sctx); return APR_EGENERAL; } @@ -2023,7 +2066,9 @@ static apr_status_t ssl_init_uri(server_rec *s, } } - return status; + OSSL_STORE_close(sctx); + + return rv; } @@ -2060,7 +2105,7 @@ static apr_status_t ssl_init_server_uris(server_rec *s, const char *vhost_id = mctx->sc->vhost_id, *uri; int i, k; int found = 0; - apr_status_t status = APR_SUCCESS; + apr_status_t rv = APR_SUCCESS; modssl_ctx_uri_t *uctx = apr_pcalloc(ptemp, sizeof(modssl_ctx_uri_t)); @@ -2085,11 +2130,11 @@ static apr_status_t ssl_init_server_uris(server_rec *s, const char *)); i++) { - if (uri && - ssl_init_uri(s, ptemp, uri, 1, uctx) != APR_SUCCESS) { + if (ssl_init_uri(s, ptemp, uri, 1, uctx) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO() "Host %s: Failed to open URI `%s'", mctx->sc->vhost_id, uri); + ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); return APR_EGENERAL; } @@ -2188,7 +2233,7 @@ static apr_status_t ssl_init_server_uris(server_rec *s, return APR_EGENERAL; } - return status; + return rv; } #else static apr_status_t ssl_init_server_uris(server_rec *s, @@ -2598,10 +2643,13 @@ static apr_status_t ssl_init_proxy_uri(server_rec *s, OSSL_STORE_CTX *sctx; OSSL_STORE_INFO *info; - apr_status_t status = APR_SUCCESS; + apr_status_t rv = APR_SUCCESS; + + if (!uri) { + return rv; + } - if (!uri || - (!(sctx = OSSL_STORE_open_ex(uri, uctx->mctx->libctx, NULL, + if ((!(sctx = OSSL_STORE_open_ex(uri, uctx->mctx->libctx, NULL, modssl_get_passphrase_ui(ptemp), modssl_get_passphrase_cb(s, ptemp, uctx->mctx->sc->vhost_id, uri), @@ -2619,9 +2667,13 @@ static apr_status_t ssl_init_proxy_uri(server_rec *s, case OSSL_STORE_INFO_NAME: { if (depth > 0) { - status = ssl_init_uri(s, ptemp, + rv = ssl_init_uri(s, ptemp, OSSL_STORE_INFO_get0_NAME(info), depth - 1, uctx); + if (APR_SUCCESS != rv) { + OSSL_STORE_close(sctx); + return rv; + } } break; @@ -2633,6 +2685,7 @@ static apr_status_t ssl_init_proxy_uri(server_rec *s, X509_NAME *xname; if (!(cert = OSSL_STORE_INFO_get1_CERT(info))) { + OSSL_STORE_close(sctx); return APR_EGENERAL; } else if (X509_check_ca(cert)) { @@ -2666,6 +2719,7 @@ static apr_status_t ssl_init_proxy_uri(server_rec *s, if (sk_X509_push(uctx->cert_list, cert) <= 0) { X509_free(cert); + OSSL_STORE_close(sctx); return APR_EGENERAL; } @@ -2682,10 +2736,12 @@ static apr_status_t ssl_init_proxy_uri(server_rec *s, EVP_PKEY *key; if (!(key = OSSL_STORE_INFO_get1_PKEY(info))) { + OSSL_STORE_close(sctx); return APR_EGENERAL; } if (sk_EVP_PKEY_push(uctx->key_list, key) <= 0) { EVP_PKEY_free(key); + OSSL_STORE_close(sctx); return APR_EGENERAL; } @@ -2696,7 +2752,9 @@ static apr_status_t ssl_init_proxy_uri(server_rec *s, } } - return status; + OSSL_STORE_close(sctx); + + return rv; } static apr_status_t ssl_init_proxy_uris(server_rec *s, @@ -2712,7 +2770,7 @@ static apr_status_t ssl_init_proxy_uris(server_rec *s, int i, k; int found = 0; - apr_status_t status = APR_SUCCESS; + apr_status_t rv = APR_SUCCESS; X509_STORE *store = SSL_CTX_get_cert_store(mctx->ssl_ctx); @@ -2828,7 +2886,7 @@ static apr_status_t ssl_init_proxy_uris(server_rec *s, uctx->num_leaf_certs, uctx->num_client_certs, uctx->num_keys); - return status; + return rv; } #else static apr_status_t ssl_init_proxy_uris(server_rec *s, @@ -2981,7 +3039,7 @@ static apr_status_t ssl_init_proxy_ca_certs(server_rec *s, ap_assert(store != NULL); /* safe to assume always non-NULL? */ - ncerts = sk_X509_INFO_num(pkp->certs); + ncerts = pkp->certs ? sk_X509_INFO_num(pkp->certs) : 0; /* If intermediate certificates have been configured, have * OpenSSL attempt to construct a full chain from each @@ -3463,12 +3521,15 @@ static apr_status_t ssl_init_ca_cert_uri(server_rec *s, OSSL_STORE_CTX *sctx; OSSL_STORE_INFO *info; - apr_status_t status = APR_SUCCESS; + apr_status_t rv = APR_SUCCESS; sk_X509_NAME_set_cmp_func(ca_list, ssl_init_x509_name_cmp); - if (!uri || (!ca_list) || - (!(sctx = OSSL_STORE_open_ex(uri, mctx->libctx, NULL, NULL, NULL, + if (!uri) { + return rv; + } + + if ((!(sctx = OSSL_STORE_open_ex(uri, mctx->libctx, NULL, NULL, NULL, NULL, NULL, NULL)))) { return APR_EGENERAL; } @@ -3483,9 +3544,13 @@ static apr_status_t ssl_init_ca_cert_uri(server_rec *s, case OSSL_STORE_INFO_NAME: { if (depth > 0) { - status = ssl_init_ca_cert_uri(s, ptemp, + rv = ssl_init_ca_cert_uri(s, ptemp, OSSL_STORE_INFO_get0_NAME(info), ca_list, depth - 1, mctx); + if (APR_SUCCESS != rv) { + OSSL_STORE_close(sctx); + return rv; + } } break; @@ -3497,6 +3562,7 @@ static apr_status_t ssl_init_ca_cert_uri(server_rec *s, X509_NAME *xname; if (!(cert = OSSL_STORE_INFO_get0_CERT(info))) { + OSSL_STORE_close(sctx); return APR_EGENERAL; } else if (!X509_check_ca(cert)) { @@ -3513,6 +3579,7 @@ static apr_status_t ssl_init_ca_cert_uri(server_rec *s, } else if (!sk_X509_NAME_push(ca_list, xname)) { X509_NAME_free(xname); + OSSL_STORE_close(sctx); return APR_EGENERAL; } @@ -3521,8 +3588,14 @@ static apr_status_t ssl_init_ca_cert_uri(server_rec *s, } } - return status; + OSSL_STORE_close(sctx); + + return rv; #else + if (!uri) { + return APR_SUCCESS; + } + return APR_ENOTIMPL; #endif } @@ -3585,7 +3658,8 @@ STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s, /* * Process CA certificate bundle file */ - if (ca_file && SSL_add_file_cert_subjects_to_stack(ca_list, ca_file)) { + if (ca_file && + !SSL_add_file_cert_subjects_to_stack(ca_list, ca_file)) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02210) "Failed to load SSLCACertificateFile: %s", ca_file); ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s); From 7e9900b7fc74d62c167eb60040583330791ec73b Mon Sep 17 00:00:00 2001 From: Graham Leggett Date: Wed, 29 Jul 2026 12:53:24 +0100 Subject: [PATCH 3/3] Remove warnings, update log message tags. --- docs/log-message-tags/next-number | 2 +- modules/ssl/ssl_engine_init.c | 72 ++++++++++++++----------------- 2 files changed, 34 insertions(+), 40 deletions(-) diff --git a/docs/log-message-tags/next-number b/docs/log-message-tags/next-number index f847eee1e1f..77ed9b0d16d 100644 --- a/docs/log-message-tags/next-number +++ b/docs/log-message-tags/next-number @@ -1 +1 @@ -10599 +10617 diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c index 7330b7afea8..3fb308e234b 100644 --- a/modules/ssl/ssl_engine_init.c +++ b/modules/ssl/ssl_engine_init.c @@ -1287,8 +1287,6 @@ apr_status_t modssl_CTX_load_verify_store(server_rec *s, case OSSL_STORE_INFO_CERT: { X509 *cert; - const X509_NAME *name; - X509_NAME *xname; if (!(cert = OSSL_STORE_INFO_get0_CERT(info))) { return APR_EGENERAL; @@ -1299,7 +1297,7 @@ apr_status_t modssl_CTX_load_verify_store(server_rec *s, } if (X509_STORE_add_cert(store, cert)) { - ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO() + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(10599) "Host %s: Trusted certificate from URI: %s", mctx->sc->vhost_id, modssl_X509_NAME_to_string(ptemp, @@ -1372,7 +1370,7 @@ static apr_status_t ssl_init_ctx_verify(server_rec *s, if ((rv = modssl_CTX_load_verify_store(s, ptemp, mctx->auth.ca_cert_uri, 1, mctx)) != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO() + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(10600) "Unable to configure verify store " "for client authentication"); ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); @@ -1563,7 +1561,7 @@ apr_status_t modssl_X509_STORE_load_crl(server_rec *s, } if (X509_STORE_add_crl(store, crl)) { - ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO() + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(10601) "Host %s: Certificate revocation list from URI: %s", mctx->sc->vhost_id, modssl_X509_NAME_to_string(ptemp, @@ -1630,7 +1628,7 @@ static apr_status_t ssl_init_ctx_crl(server_rec *s, "Configuring certificate revocation facility"); if ((rv = modssl_X509_STORE_load_crl(s, ptemp, mctx->crl_uri, 1, mctx)) != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO() + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(10602) "Host %s: unable to configure X.509 CRL uri " "for certificate revocation", mctx->sc->vhost_id); ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); @@ -1877,7 +1875,7 @@ DEFINE_STACK_OF(EVP_PKEY) #if MODSSL_HAVE_OPENSSL_STORE -apr_status_t ssl_init_uri_cleanup(void *data) +static apr_status_t ssl_init_uri_cleanup(void *data) { modssl_ctx_uri_t *uctx = (modssl_ctx_uri_t *)data; @@ -1896,14 +1894,15 @@ static int compare_certs_asc(const X509 *const *a, const X509 *const *b) const ASN1_TIME *time_a = X509_get0_notBefore(*a); const ASN1_TIME *time_b = X509_get0_notBefore(*b); - // ASN1_TIME_compare returns: - // -1 if time_a is earlier than time_b - // 0 if they are identical - // 1 if time_a is later than time_b + /* ASN1_TIME_compare returns: + * -1 if time_a is earlier than time_b + * 0 if they are identical + * 1 if time_a is later than time_b + */ return ASN1_TIME_compare(time_a, time_b); } -static int cert_match(apr_pool_t *p, X509 *cert, const char *id) +static int cert_match(apr_pool_t *p, X509 *cert, char *id) { if (id[0] == '[') { const char *end = strchr(id, ']'); @@ -1969,8 +1968,6 @@ static apr_status_t ssl_init_uri(server_rec *s, case OSSL_STORE_INFO_CERT: { X509 *cert; - const X509_NAME *name; - X509_NAME *xname; if (!(cert = OSSL_STORE_INFO_get1_CERT(info))) { return APR_EGENERAL; @@ -2015,7 +2012,7 @@ static apr_status_t ssl_init_uri(server_rec *s, /* check for a match on all server aliases */ if (s->names && !apr_is_empty_array(s->names)) { - const char **aliases = (const char **)s->names->elts; + char **aliases = (char **)s->names->elts; int i; for (i = 0; i < s->names->nelts; i++) { if (!cert_match(ptemp, cert, aliases[i])) { @@ -2101,8 +2098,7 @@ static apr_status_t ssl_init_server_uris(server_rec *s, modssl_ctx_t *mctx, apr_array_header_t *pphrases) { - SSLModConfigRec *mc = myModConfig(s); - const char *vhost_id = mctx->sc->vhost_id, *uri; + const char *uri; int i, k; int found = 0; apr_status_t rv = APR_SUCCESS; @@ -2131,7 +2127,7 @@ static apr_status_t ssl_init_server_uris(server_rec *s, i++) { if (ssl_init_uri(s, ptemp, uri, 1, uctx) != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO() + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10603) "Host %s: Failed to open URI `%s'", mctx->sc->vhost_id, uri); ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); @@ -2153,7 +2149,7 @@ static apr_status_t ssl_init_server_uris(server_rec *s, if (X509_check_private_key(cert, pkey) == 1) { if (SSL_CTX_use_certificate(mctx->ssl_ctx, cert) < 1) { - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO() + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10604) "Host %s: Failed to use certificate: %s", mctx->sc->vhost_id, modssl_X509_NAME_to_string(ptemp, @@ -2163,7 +2159,7 @@ static apr_status_t ssl_init_server_uris(server_rec *s, } if (SSL_CTX_use_PrivateKey(mctx->ssl_ctx, pkey) < 1) { - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO() + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10605) "Host %s: Failed to use private key: %s", mctx->sc->vhost_id, modssl_X509_NAME_to_string(ptemp, @@ -2172,7 +2168,7 @@ static apr_status_t ssl_init_server_uris(server_rec *s, return APR_EGENERAL; } - ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO() + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(10606) "Host %s: Server certificate from URI: %s", mctx->sc->vhost_id, modssl_X509_NAME_to_string(ptemp, @@ -2186,7 +2182,7 @@ static apr_status_t ssl_init_server_uris(server_rec *s, } if (!found) { - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO() + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10607) "Host %s: No matching certificate/key pairs found among " "%d certs, %d CA certs, %d intermediate certs, " "%d leaf certs, %d server certs, %d keys.", @@ -2202,7 +2198,7 @@ static apr_status_t ssl_init_server_uris(server_rec *s, for (i = sk_X509_num(uctx->ca_list) - 1; i >= 0; i--) { X509 *cert = sk_X509_value(uctx->ca_list, i); if (!SSL_CTX_add1_chain_cert(mctx->ssl_ctx, cert)) { - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO() + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10608) "Host %s: Failed to add intermediate certificate: %s", mctx->sc->vhost_id, modssl_X509_NAME_to_string(ptemp, @@ -2221,7 +2217,7 @@ static apr_status_t ssl_init_server_uris(server_rec *s, SSL_BUILD_CHAIN_FLAG_UNTRUSTED | SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR | SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR)) { - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO() + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10609) "Host %s: Could not build the certificate chain from " "%d certs, %d CA certs, %d intermediate certs, " "%d leaf certs, %d server certs, %d keys.", @@ -2244,7 +2240,7 @@ static apr_status_t ssl_init_server_uris(server_rec *s, { const char *vhost_id = mctx->sc->vhost_id; - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO() + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10610) "Host %s: Server certificate URIs are not supported on this platform.", mctx->sc->vhost_id); @@ -2627,10 +2623,11 @@ static int compare_certs_desc(const X509 *const *a, const X509 *const *b) const ASN1_TIME *time_a = X509_get0_notBefore(*a); const ASN1_TIME *time_b = X509_get0_notBefore(*b); - // ASN1_TIME_compare returns: - // -1 if time_a is earlier than time_b - // 0 if they are identical - // 1 if time_a is later than time_b + /* ASN1_TIME_compare returns: + * -1 if time_a is earlier than time_b + * 0 if they are identical + * 1 if time_a is later than time_b + */ return -ASN1_TIME_compare(time_a, time_b); } @@ -2681,8 +2678,6 @@ static apr_status_t ssl_init_proxy_uri(server_rec *s, case OSSL_STORE_INFO_CERT: { X509 *cert; - const X509_NAME *name; - X509_NAME *xname; if (!(cert = OSSL_STORE_INFO_get1_CERT(info))) { OSSL_STORE_close(sctx); @@ -2762,8 +2757,7 @@ static apr_status_t ssl_init_proxy_uris(server_rec *s, apr_pool_t *ptemp, modssl_ctx_t *mctx) { - SSLModConfigRec *mc = myModConfig(s); - const char *vhost_id = mctx->sc->vhost_id, *uri; + const char *uri; modssl_pk_proxy_t *pkp = mctx->pkp; modssl_ctx_uri_t *uctx; STACK_OF(X509_INFO) *sk; @@ -2812,7 +2806,7 @@ static apr_status_t ssl_init_proxy_uris(server_rec *s, if (uri && ssl_init_proxy_uri(s, ptemp, uri, 1, uctx) != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO() + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10611) "Host %s: Failed to open proxy URI `%s'", mctx->sc->vhost_id, uri); return APR_EGENERAL; @@ -2843,7 +2837,7 @@ static apr_status_t ssl_init_proxy_uris(server_rec *s, sk_X509_INFO_push(sk, info); - ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO() + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(10612) "Host %s: Proxy certificate from URI: %s", mctx->sc->vhost_id, modssl_X509_NAME_to_string(ptemp, @@ -2857,7 +2851,7 @@ static apr_status_t ssl_init_proxy_uris(server_rec *s, } if (!found) { - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO() + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10613) "Host %s: No matching proxy certificate/key pairs found among " "%d certs, %d CA certs, %d intermediate certs, " "%d leaf certs, %d client certs, %d keys.", @@ -2876,7 +2870,7 @@ static apr_status_t ssl_init_proxy_uris(server_rec *s, X509_STORE_add_cert(store, cert); /* increments cert */ } - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO() + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(10614) "Host %s: loaded %d client certs for SSL proxy among " "%d certs, %d CA certs, %d intermediate certs, " "%d leaf certs, %d client certs, %d keys.", @@ -2897,7 +2891,7 @@ static apr_status_t ssl_init_proxy_uris(server_rec *s, if (pkp->uris->nelts) { const char *vhost_id = mctx->sc->vhost_id; - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO() + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10615) "Host %s: Proxy certificate URIs are not supported on this platform.", mctx->sc->vhost_id); @@ -3649,7 +3643,7 @@ STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s, if (ca_uri && ssl_init_ca_cert_uri(s, ptemp, ca_uri, ca_list, 1, mctx) != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO() + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10616) "Failed to open Certificate URI `%s'", ca_uri); sk_X509_NAME_pop_free(ca_list, X509_NAME_free); return NULL;