summaryrefslogtreecommitdiff
path: root/modules/ssl/ssl_engine_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/ssl/ssl_engine_init.c')
-rw-r--r--modules/ssl/ssl_engine_init.c603
1 files changed, 455 insertions, 148 deletions
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
index 34535410..dc4269d8 100644
--- a/modules/ssl/ssl_engine_init.c
+++ b/modules/ssl/ssl_engine_init.c
@@ -27,6 +27,7 @@
see Recursive.''
-- Unknown */
#include "ssl_private.h"
+#include "mpm_common.h"
/* _________________________________________________________________
**
@@ -40,13 +41,12 @@ static void ssl_add_version_components(apr_pool_t *p,
{
char *modver = ssl_var_lookup(p, s, NULL, NULL, "SSL_VERSION_INTERFACE");
char *libver = ssl_var_lookup(p, s, NULL, NULL, "SSL_VERSION_LIBRARY");
- char *incver = ssl_var_lookup(p, s, NULL, NULL,
+ char *incver = ssl_var_lookup(p, s, NULL, NULL,
"SSL_VERSION_LIBRARY_INTERFACE");
- ap_add_version_component(p, modver);
ap_add_version_component(p, libver);
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01876)
"%s compiled against Server: %s, Library: %s",
modver, AP_SERVER_BASEVERSION, incver);
}
@@ -83,23 +83,42 @@ static int ssl_tmp_key_init_rsa(server_rec *s,
if (FIPS_mode() && bits < 1024) {
mc->pTmpKeys[idx] = NULL;
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01877)
"Init: Skipping generating temporary "
"%d bit RSA private key in FIPS mode", bits);
return OK;
}
#endif
-
+#ifdef HAVE_GENERATE_EX
+ {
+ RSA *tkey;
+ BIGNUM *bn_f4;
+ if (!(tkey = RSA_new())
+ || !(bn_f4 = BN_new())
+ || !BN_set_word(bn_f4, RSA_F4)
+ || !RSA_generate_key_ex(tkey, bits, bn_f4, NULL))
+ {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01878)
+ "Init: Failed to generate temporary "
+ "%d bit RSA private key", bits);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s);
+ return !OK;
+ }
+ BN_free(bn_f4);
+ mc->pTmpKeys[idx] = tkey;
+ }
+#else
if (!(mc->pTmpKeys[idx] =
RSA_generate_key(bits, RSA_F4, NULL, NULL)))
{
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01879)
"Init: Failed to generate temporary "
"%d bit RSA private key", bits);
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s);
return !OK;
}
+#endif
return OK;
}
@@ -113,7 +132,7 @@ static int ssl_tmp_key_init_dh(server_rec *s,
if (FIPS_mode() && bits < 1024) {
mc->pTmpKeys[idx] = NULL;
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01880)
"Init: Skipping generating temporary "
"%d bit DH parameters in FIPS mode", bits);
return OK;
@@ -124,7 +143,7 @@ static int ssl_tmp_key_init_dh(server_rec *s,
if (!(mc->pTmpKeys[idx] =
ssl_dh_GetTmpParam(bits)))
{
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01881)
"Init: Failed to generate temporary "
"%d bit DH parameters", bits);
return !OK;
@@ -141,7 +160,7 @@ static int ssl_tmp_key_init_dh(server_rec *s,
static int ssl_tmp_keys_init(server_rec *s)
{
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s,
"Init: Generating temporary RSA private keys (512/1024 bits)");
if (MODSSL_TMP_KEY_INIT_RSA(s, 512) ||
@@ -149,7 +168,7 @@ static int ssl_tmp_keys_init(server_rec *s)
return !OK;
}
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s,
"Init: Generating temporary DH parameters (512/1024 bits)");
if (MODSSL_TMP_KEY_INIT_DH(s, 512) ||
@@ -171,6 +190,14 @@ int ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
SSLSrvConfigRec *sc;
server_rec *s;
+ if (SSLeay() < SSL_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)"
+ " - may result in undefined or erroneous behavior",
+ SSL_LIBRARY_TEXT, SSLeay_version(SSLEAY_VERSION));
+ }
+
/* We initialize mc->pid per-process in the child init,
* but it should be initialized for startup before we
* call ssl_rand_seed() below.
@@ -178,7 +205,7 @@ int ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
mc->pid = getpid();
/*
- * Let us cleanup on restarts and exists
+ * Let us cleanup on restarts and exits
*/
apr_pool_cleanup_register(p, base_server,
ssl_init_ModuleKill,
@@ -229,7 +256,7 @@ int ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
sc->session_cache_timeout = SSL_SESSION_CACHE_TIMEOUT;
}
- if (sc->server->pphrase_dialog_type == SSL_PPTYPE_UNSET) {
+ if (sc->server && sc->server->pphrase_dialog_type == SSL_PPTYPE_UNSET) {
sc->server->pphrase_dialog_type = SSL_PPTYPE_BUILTIN;
}
@@ -251,7 +278,7 @@ int ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
ssl_init_Engine(base_server, p);
#endif
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01883)
"Init: Initialized %s library", SSL_LIBRARY_NAME);
/*
@@ -265,18 +292,18 @@ int ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
if(sc->fips) {
if (!FIPS_mode()) {
if (FIPS_mode_set(1)) {
- ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, APLOGNO(01884)
"Operating in SSL FIPS mode");
}
else {
- ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, "FIPS mode failed");
- ssl_log_ssl_error(APLOG_MARK, APLOG_EMERG, s);
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01885) "FIPS mode failed");
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
ssl_die();
}
}
}
else {
- ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, APLOGNO(01886)
"SSL FIPS mode disabled");
}
#endif
@@ -299,6 +326,9 @@ int ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
if (!ssl_mutex_init(base_server, p)) {
return HTTP_INTERNAL_SERVER_ERROR;
}
+#ifdef HAVE_OCSP_STAPLING
+ ssl_stapling_ex_init();
+#endif
/*
* initialize session caching
@@ -308,7 +338,7 @@ int ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
/*
* initialize servers
*/
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, base_server,
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, base_server, APLOGNO(01887)
"Init: Initializing (virtual) servers for SSL");
for (s = base_server; s; s = s->next) {
@@ -353,10 +383,10 @@ void ssl_init_Engine(server_rec *s, apr_pool_t *p)
if (mc->szCryptoDevice) {
if (!(e = ENGINE_by_id(mc->szCryptoDevice))) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01888)
"Init: Failed to load Crypto Device API `%s'",
mc->szCryptoDevice);
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
ssl_die();
}
@@ -365,14 +395,14 @@ void ssl_init_Engine(server_rec *s, apr_pool_t *p)
}
if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01889)
"Init: Failed to enable Crypto Device API `%s'",
mc->szCryptoDevice);
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
ssl_die();
}
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
- "Init: loaded Crypto Device API `%s'",
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01890)
+ "Init: loaded Crypto Device API `%s'",
mc->szCryptoDevice);
ENGINE_free(e);
@@ -389,8 +419,8 @@ static void ssl_init_server_check(server_rec *s,
* check for important parameters and the
* possibility that the user forgot to set them.
*/
- if (!mctx->pks->cert_files[0]) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ if (!mctx->pks->cert_files[0] && !mctx->pkcs7) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01891)
"No SSL Certificate set [hint: SSLCertificateFile]");
ssl_die();
}
@@ -399,9 +429,13 @@ static void ssl_init_server_check(server_rec *s,
* Check for problematic re-initializations
*/
if (mctx->pks->certs[SSL_AIDX_RSA] ||
- mctx->pks->certs[SSL_AIDX_DSA])
+ mctx->pks->certs[SSL_AIDX_DSA]
+#ifndef OPENSSL_NO_EC
+ || mctx->pks->certs[SSL_AIDX_ECC]
+#endif
+ )
{
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01892)
"Illegal attempt to re-initialise SSL for server "
"(SSLEngine On should go in the VirtualHost, not in global scope.)");
ssl_die();
@@ -417,7 +451,7 @@ static void ssl_init_ctx_tls_extensions(server_rec *s,
/*
* Configure TLS extensions support
*/
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01893)
"Configuring TLS extension handling");
/*
@@ -426,12 +460,21 @@ static void ssl_init_ctx_tls_extensions(server_rec *s,
if (!SSL_CTX_set_tlsext_servername_callback(mctx->ssl_ctx,
ssl_callback_ServerNameIndication) ||
!SSL_CTX_set_tlsext_servername_arg(mctx->ssl_ctx, mctx)) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01894)
"Unable to initialize TLS servername extension "
"callback (incompatible OpenSSL version?)");
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
ssl_die();
}
+
+#ifdef HAVE_OCSP_STAPLING
+ /*
+ * OCSP Stapling support, status_request extension
+ */
+ if ((mctx->pkp == FALSE) && (mctx->stapling_enabled == TRUE)) {
+ modssl_init_stapling(s, p, ptemp, mctx);
+ }
+#endif
}
#endif
@@ -450,44 +493,43 @@ static void ssl_init_ctx_protocol(server_rec *s,
* Create the new per-server SSL context
*/
if (protocol == SSL_PROTOCOL_NONE) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02231)
"No SSL protocols available [hint: SSLProtocol]");
ssl_die();
}
cp = apr_pstrcat(p,
- (protocol & SSL_PROTOCOL_SSLV2 ? "SSLv2, " : ""),
(protocol & SSL_PROTOCOL_SSLV3 ? "SSLv3, " : ""),
(protocol & SSL_PROTOCOL_TLSV1 ? "TLSv1, " : ""),
NULL);
cp[strlen(cp)-2] = NUL;
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, s,
"Creating new SSL context (protocols: %s)", cp);
-#ifndef OPENSSL_NO_SSL2
- if (protocol == SSL_PROTOCOL_SSLV2) {
+ if (protocol == SSL_PROTOCOL_SSLV3) {
method = mctx->pkp ?
- SSLv2_client_method() : /* proxy */
- SSLv2_server_method(); /* server */
- ctx = SSL_CTX_new(method); /* only SSLv2 is left */
+ SSLv3_client_method() : /* proxy */
+ SSLv3_server_method(); /* server */
}
- else
-#endif
- {
+ else if (protocol == SSL_PROTOCOL_TLSV1) {
+ method = mctx->pkp ?
+ TLSv1_client_method() : /* proxy */
+ TLSv1_server_method(); /* server */
+ }
+ else { /* For multiple protocols, we need a flexible method */
method = mctx->pkp ?
SSLv23_client_method() : /* proxy */
SSLv23_server_method(); /* server */
- ctx = SSL_CTX_new(method); /* be more flexible */
}
+ ctx = SSL_CTX_new(method);
mctx->ssl_ctx = ctx;
SSL_CTX_set_options(ctx, SSL_OP_ALL);
- if (!(protocol & SSL_PROTOCOL_SSLV2)) {
- SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
- }
+ /* always disable SSLv2, as per RFC 6176 */
+ SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
if (!(protocol & SSL_PROTOCOL_SSLV3)) {
SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3);
@@ -523,6 +565,12 @@ static void ssl_init_ctx_protocol(server_rec *s,
*/
SSL_CTX_set_options(ctx, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
#endif
+
+#ifdef SSL_MODE_RELEASE_BUFFERS
+ /* If httpd is configured to reduce mem usage, ask openssl to do so, too */
+ if (ap_max_mem_free != APR_ALLOCATOR_MAX_FREE_UNLIMITED)
+ SSL_CTX_set_mode(ctx, SSL_MODE_RELEASE_BUFFERS);
+#endif
}
static void ssl_init_ctx_session_cache(server_rec *s,
@@ -532,20 +580,14 @@ static void ssl_init_ctx_session_cache(server_rec *s,
{
SSL_CTX *ctx = mctx->ssl_ctx;
SSLModConfigRec *mc = myModConfig(s);
- long cache_mode = SSL_SESS_CACHE_OFF;
- if (mc->nSessionCacheMode != SSL_SCMODE_NONE) {
- /* SSL_SESS_CACHE_NO_INTERNAL will force OpenSSL
- * to ignore process local-caching and
- * to always get/set/delete sessions using mod_ssl's callbacks.
- */
- cache_mode = SSL_SESS_CACHE_SERVER|SSL_SESS_CACHE_NO_INTERNAL;
- }
- SSL_CTX_set_session_cache_mode(ctx, cache_mode);
+ SSL_CTX_set_session_cache_mode(ctx, mc->sesscache_mode);
- SSL_CTX_sess_set_new_cb(ctx, ssl_callback_NewSessionCacheEntry);
- SSL_CTX_sess_set_get_cb(ctx, ssl_callback_GetSessionCacheEntry);
- SSL_CTX_sess_set_remove_cb(ctx, ssl_callback_DelSessionCacheEntry);
+ if (mc->sesscache) {
+ SSL_CTX_sess_set_new_cb(ctx, ssl_callback_NewSessionCacheEntry);
+ SSL_CTX_sess_set_get_cb(ctx, ssl_callback_GetSessionCacheEntry);
+ SSL_CTX_sess_set_remove_cb(ctx, ssl_callback_DelSessionCacheEntry);
+ }
}
static void ssl_init_ctx_callbacks(server_rec *s,
@@ -557,6 +599,9 @@ static void ssl_init_ctx_callbacks(server_rec *s,
SSL_CTX_set_tmp_rsa_callback(ctx, ssl_callback_TmpRSA);
SSL_CTX_set_tmp_dh_callback(ctx, ssl_callback_TmpDH);
+#ifndef OPENSSL_NO_EC
+ SSL_CTX_set_tmp_ecdh_callback(ctx,ssl_callback_TmpECDH);
+#endif
SSL_CTX_set_info_callback(ctx, ssl_callback_Info);
}
@@ -598,17 +643,17 @@ static void ssl_init_ctx_verify(server_rec *s,
* Configure Client Authentication details
*/
if (mctx->auth.ca_cert_file || mctx->auth.ca_cert_path) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s,
"Configuring client authentication");
if (!SSL_CTX_load_verify_locations(ctx,
- MODSSL_PCHAR_CAST mctx->auth.ca_cert_file,
- MODSSL_PCHAR_CAST mctx->auth.ca_cert_path))
+ mctx->auth.ca_cert_file,
+ mctx->auth.ca_cert_path))
{
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01895)
"Unable to configure verify locations "
"for client authentication");
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
ssl_die();
}
@@ -620,8 +665,8 @@ static void ssl_init_ctx_verify(server_rec *s,
ca_list = ssl_init_FindCAList(s, ptemp,
mctx->auth.ca_cert_file,
mctx->auth.ca_cert_path);
- if (!ca_list) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ 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 "
"CA certificates for client authentication");
ssl_die();
@@ -638,7 +683,7 @@ static void ssl_init_ctx_verify(server_rec *s,
ca_list = SSL_CTX_get_client_CA_list(ctx);
if (sk_X509_NAME_num(ca_list) == 0) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(01897)
"Init: Oops, you want to request client "
"authentication, but no CAs are known for "
"verification!? [Hint: SSLCACertificate*]");
@@ -661,14 +706,14 @@ static void ssl_init_ctx_cipher_suite(server_rec *s,
return;
}
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s,
"Configuring permitted SSL ciphers [%s]",
suite);
- if (!SSL_CTX_set_cipher_list(ctx, MODSSL_PCHAR_CAST suite)) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ if (!SSL_CTX_set_cipher_list(ctx, suite)) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01898)
"Unable to configure permitted SSL ciphers");
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
ssl_die();
}
}
@@ -678,28 +723,67 @@ static void ssl_init_ctx_crl(server_rec *s,
apr_pool_t *ptemp,
modssl_ctx_t *mctx)
{
+ X509_STORE *store = SSL_CTX_get_cert_store(mctx->ssl_ctx);
+ unsigned long crlflags = 0;
+ char *cfgp = mctx->pkp ? "SSLProxy" : "SSL";
+
/*
* Configure Certificate Revocation List (CRL) Details
*/
if (!(mctx->crl_file || mctx->crl_path)) {
+ if (mctx->crl_check_mode == SSL_CRLCHECK_LEAF ||
+ mctx->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);
+ ssl_die();
+ }
return;
}
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01900)
"Configuring certificate revocation facility");
- mctx->crl =
- SSL_X509_STORE_create((char *)mctx->crl_file,
- (char *)mctx->crl_path);
-
- if (!mctx->crl) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
- "Unable to configure X.509 CRL storage "
- "for certificate revocation");
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
+ if (!store || !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);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
ssl_die();
}
+
+ switch (mctx->crl_check_mode) {
+ case SSL_CRLCHECK_LEAF:
+ crlflags = X509_V_FLAG_CRL_CHECK;
+ break;
+ case SSL_CRLCHECK_CHAIN:
+ crlflags = X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL;
+ break;
+ default:
+ crlflags = 0;
+ }
+
+ if (crlflags) {
+ X509_STORE_set_flags(store, crlflags);
+ } else {
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(01902)
+ "Host %s: X.509 CRL storage locations configured, "
+ "but CRL checking (%sCARevocationCheck) is not "
+ "enabled", mctx->sc->vhost_id, cfgp);
+ }
+}
+
+static void ssl_init_ctx_pkcs7_cert_chain(server_rec *s, modssl_ctx_t *mctx)
+{
+ STACK_OF(X509) *certs = ssl_read_pkcs7(s, mctx->pkcs7);
+ int n;
+
+ if (!mctx->ssl_ctx->extra_certs)
+ for (n = 1; n < sk_X509_num(certs); ++n)
+ SSL_CTX_add_extra_chain_cert(mctx->ssl_ctx, sk_X509_value(certs, n));
}
static void ssl_init_ctx_cert_chain(server_rec *s,
@@ -711,6 +795,11 @@ static void ssl_init_ctx_cert_chain(server_rec *s,
int i, n;
const char *chain = mctx->cert_chain;
+ if (mctx->pkcs7) {
+ ssl_init_ctx_pkcs7_cert_chain(s, mctx);
+ return;
+ }
+
/*
* Optionally configure extra server certificate chain certificates.
* This is usually done by OpenSSL automatically when one of the
@@ -740,12 +829,12 @@ static void ssl_init_ctx_cert_chain(server_rec *s,
(char *)chain,
skip_first, NULL);
if (n < 0) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01903)
"Failed to configure CA certificate chain!");
ssl_die();
}
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01904)
"Configuring server certificate chain "
"(%d CA certificate%s)",
n, n == 1 ? "" : "s");
@@ -792,24 +881,33 @@ static int ssl_server_import_cert(server_rec *s,
return FALSE;
}
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02232)
"Configuring %s server certificate", type);
ptr = asn1->cpData;
if (!(cert = d2i_X509(NULL, &ptr, asn1->nData))) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02233)
"Unable to import %s server certificate", type);
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
ssl_die();
}
if (SSL_CTX_use_certificate(mctx->ssl_ctx, cert) <= 0) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02234)
"Unable to configure %s server certificate", type);
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
ssl_die();
}
+#ifdef HAVE_OCSP_STAPLING
+ if ((mctx->pkp == FALSE) && (mctx->stapling_enabled == TRUE)) {
+ if (!ssl_stapling_init_cert(s, mctx, cert)) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02235)
+ "Unable to configure server certificate for stapling");
+ }
+ }
+#endif
+
mctx->pks->certs[idx] = cert;
return TRUE;
@@ -824,29 +922,36 @@ static int ssl_server_import_key(server_rec *s,
ssl_asn1_t *asn1;
MODSSL_D2I_PrivateKey_CONST unsigned char *ptr;
const char *type = ssl_asn1_keystr(idx);
- int pkey_type = (idx == SSL_AIDX_RSA) ? EVP_PKEY_RSA : EVP_PKEY_DSA;
+ int pkey_type;
EVP_PKEY *pkey;
+#ifndef OPENSSL_NO_EC
+ if (idx == SSL_AIDX_ECC)
+ pkey_type = EVP_PKEY_EC;
+ else
+#endif
+ pkey_type = (idx == SSL_AIDX_RSA) ? EVP_PKEY_RSA : EVP_PKEY_DSA;
+
if (!(asn1 = ssl_asn1_table_get(mc->tPrivateKey, id))) {
return FALSE;
}
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02236)
"Configuring %s server private key", type);
ptr = asn1->cpData;
if (!(pkey = d2i_PrivateKey(pkey_type, NULL, &ptr, asn1->nData)))
{
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02237)
"Unable to import %s server private key", type);
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
ssl_die();
}
if (SSL_CTX_use_PrivateKey(mctx->ssl_ctx, pkey) <= 0) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02238)
"Unable to configure %s server private key", type);
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
ssl_die();
}
@@ -859,9 +964,9 @@ static int ssl_server_import_key(server_rec *s,
if (pubkey && EVP_PKEY_missing_parameters(pubkey)) {
EVP_PKEY_copy_parameters(pubkey, pkey);
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02239)
"Copying DSA parameters from private key to certificate");
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s);
EVP_PKEY_free(pubkey);
}
}
@@ -877,7 +982,7 @@ static void ssl_check_public_cert(server_rec *s,
int type)
{
int is_ca, pathlen;
- char *cn;
+ apr_array_header_t *ids;
if (!cert) {
return;
@@ -888,7 +993,7 @@ static void ssl_check_public_cert(server_rec *s,
*/
if (SSL_X509_isSGC(cert)) {
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01905)
"%s server certificate enables "
"Server Gated Cryptography (SGC)",
ssl_asn1_keystr(type));
@@ -896,37 +1001,69 @@ static void ssl_check_public_cert(server_rec *s,
if (SSL_X509_getBC(cert, &is_ca, &pathlen)) {
if (is_ca) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(01906)
"%s server certificate is a CA certificate "
"(BasicConstraints: CA == TRUE !?)",
ssl_asn1_keystr(type));
}
if (pathlen > 0) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(01907)
"%s server certificate is not a leaf certificate "
"(BasicConstraints: pathlen == %d > 0 !?)",
ssl_asn1_keystr(type), pathlen);
}
}
- if (SSL_X509_getCN(ptemp, cert, &cn)) {
- int fnm_flags = APR_FNM_PERIOD|APR_FNM_CASE_BLIND;
-
- if (apr_fnmatch_test(cn)) {
- if (apr_fnmatch(cn, s->server_hostname,
- fnm_flags) == APR_FNM_NOMATCH) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
- "%s server certificate wildcard CommonName "
- "(CN) `%s' does NOT match server name!?",
- ssl_asn1_keystr(type), cn);
+ /*
+ * Check if the server name is covered by the certificate.
+ * Consider both dNSName entries in the subjectAltName extension
+ * and, as a fallback, commonName attributes in the subject DN.
+ * (DNS-IDs and CN-IDs as defined in RFC 6125).
+ */
+ if (SSL_X509_getIDs(ptemp, cert, &ids)) {
+ char *cp;
+ int i;
+ char **id = (char **)ids->elts;
+ BOOL is_wildcard, matched = FALSE;
+
+ for (i = 0; i < ids->nelts; i++) {
+ if (!id[i])
+ continue;
+
+ /*
+ * Determine if it is a wildcard ID - we're restrictive
+ * in the sense that we require the wildcard character to be
+ * THE left-most label (i.e., the ID must start with "*.")
+ */
+ is_wildcard = (*id[i] == '*' && *(id[i]+1) == '.') ? TRUE : FALSE;
+
+ /*
+ * If the ID includes a wildcard character, check if it matches
+ * for the left-most DNS label (i.e., the wildcard character
+ * is not allowed to match a dot). Otherwise, try a simple
+ * string compare, case insensitively.
+ */
+ if ((is_wildcard == TRUE &&
+ (cp = strchr(s->server_hostname, '.')) &&
+ !strcasecmp(id[i]+1, cp)) ||
+ !strcasecmp(id[i], s->server_hostname)) {
+ matched = TRUE;
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01908)
+ "%sID '%s' in %s certificate configured "
+ "for %s matches server name",
+ is_wildcard ? "Wildcard " : "",
+ id[i], ssl_asn1_keystr(type),
+ (mySrvConfig(s))->vhost_id);
+ break;
}
}
- else if (strNE(s->server_hostname, cn)) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
- "%s server certificate CommonName (CN) `%s' "
- "does NOT match server name!?",
- ssl_asn1_keystr(type), cn);
+
+ if (matched == FALSE) {
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(01909)
+ "%s certificate configured for %s does NOT include "
+ "an ID which matches the server name",
+ ssl_asn1_keystr(type), (mySrvConfig(s))->vhost_id);
}
}
}
@@ -937,19 +1074,39 @@ static void ssl_init_server_certs(server_rec *s,
modssl_ctx_t *mctx)
{
const char *rsa_id, *dsa_id;
+#ifndef OPENSSL_NO_EC
+ const char *ecc_id;
+#endif
const char *vhost_id = mctx->sc->vhost_id;
int i;
int have_rsa, have_dsa;
+#ifndef OPENSSL_NO_EC
+ int have_ecc;
+#endif
rsa_id = ssl_asn1_table_keyfmt(ptemp, vhost_id, SSL_AIDX_RSA);
dsa_id = ssl_asn1_table_keyfmt(ptemp, vhost_id, SSL_AIDX_DSA);
+#ifndef OPENSSL_NO_EC
+ ecc_id = ssl_asn1_table_keyfmt(ptemp, vhost_id, SSL_AIDX_ECC);
+#endif
have_rsa = ssl_server_import_cert(s, mctx, rsa_id, SSL_AIDX_RSA);
have_dsa = ssl_server_import_cert(s, mctx, dsa_id, SSL_AIDX_DSA);
+#ifndef OPENSSL_NO_EC
+ have_ecc = ssl_server_import_cert(s, mctx, ecc_id, SSL_AIDX_ECC);
+#endif
- if (!(have_rsa || have_dsa)) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ if (!(have_rsa || have_dsa
+#ifndef OPENSSL_NO_EC
+ || have_ecc
+#endif
+)) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01910)
+#ifndef OPENSSL_NO_EC
+ "Oops, no RSA, DSA or ECC server certificate found "
+#else
"Oops, no RSA or DSA server certificate found "
+#endif
"for '%s:%d'?!", s->server_hostname, s->port);
ssl_die();
}
@@ -960,13 +1117,81 @@ static void ssl_init_server_certs(server_rec *s,
have_rsa = ssl_server_import_key(s, mctx, rsa_id, SSL_AIDX_RSA);
have_dsa = ssl_server_import_key(s, mctx, dsa_id, SSL_AIDX_DSA);
+#ifndef OPENSSL_NO_EC
+ have_ecc = ssl_server_import_key(s, mctx, ecc_id, SSL_AIDX_ECC);
+#endif
- if (!(have_rsa || have_dsa)) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ if (!(have_rsa || have_dsa
+#ifndef OPENSSL_NO_EC
+ || have_ecc
+#endif
+ )) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01911)
+#ifndef OPENSSL_NO_EC
+ "Oops, no RSA, DSA or ECC server private key found?!");
+#else
"Oops, no RSA or DSA server private key found?!");
+#endif
+ ssl_die();
+ }
+}
+
+#ifdef HAVE_TLS_SESSION_TICKETS
+static void ssl_init_ticket_key(server_rec *s,
+ apr_pool_t *p,
+ apr_pool_t *ptemp,
+ modssl_ctx_t *mctx)
+{
+ apr_status_t rv;
+ apr_file_t *fp;
+ apr_size_t len;
+ char buf[TLSEXT_TICKET_KEY_LEN];
+ char *path;
+ modssl_ticket_key_t *ticket_key = mctx->ticket_key;
+
+ if (!ticket_key->file_path) {
+ return;
+ }
+
+ path = ap_server_root_relative(p, ticket_key->file_path);
+
+ rv = apr_file_open(&fp, path, APR_READ|APR_BINARY,
+ APR_OS_DEFAULT, ptemp);
+
+ if (rv != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02286)
+ "Failed to open ticket key file %s: (%d) %pm",
+ path, rv, &rv);
+ ssl_die();
+ }
+
+ rv = apr_file_read_full(fp, &buf[0], TLSEXT_TICKET_KEY_LEN, &len);
+
+ if (rv != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02287)
+ "Failed to read %d bytes from %s: (%d) %pm",
+ TLSEXT_TICKET_KEY_LEN, path, rv, &rv);
+ ssl_die();
+ }
+
+ memcpy(ticket_key->key_name, buf, 16);
+ memcpy(ticket_key->hmac_secret, buf + 16, 16);
+ memcpy(ticket_key->aes_key, buf + 32, 16);
+
+ if (!SSL_CTX_set_tlsext_ticket_key_cb(mctx->ssl_ctx,
+ ssl_callback_SessionTicket)) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01913)
+ "Unable to initialize TLS session ticket key callback "
+ "(incompatible OpenSSL version?)");
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
ssl_die();
}
+
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(02288)
+ "TLS session ticket key for %s successfully loaded from %s",
+ (mySrvConfig(s))->vhost_id, path);
}
+#endif
static void ssl_init_proxy_certs(server_rec *s,
apr_pool_t *p,
@@ -976,6 +1201,9 @@ static void ssl_init_proxy_certs(server_rec *s,
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);
SSL_CTX_set_client_cert_cb(mctx->ssl_ctx,
ssl_callback_proxy_cert);
@@ -996,7 +1224,7 @@ static void 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,
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(02206)
"no client certs found for SSL proxy");
return;
}
@@ -1008,7 +1236,7 @@ static void ssl_init_proxy_certs(server_rec *s,
if (!inf->x509 || !inf->x_pkey) {
sk_X509_INFO_free(sk);
- ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, APLOGNO(02252)
"incomplete client cert configured for SSL proxy "
"(missing or encrypted private key?)");
ssl_die();
@@ -1016,10 +1244,82 @@ static void ssl_init_proxy_certs(server_rec *s,
}
}
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ 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) {
+ return;
+ }
+
+ /* Load all of the CA certs and construct a chain */
+ pkp->ca_certs = (STACK_OF(X509) **) apr_pcalloc(p, ncerts * sizeof(sk));
+ 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);
+ ssl_die();
+ }
+
+ 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);
+ X509_STORE_CTX_init(sctx, store, inf->x509, NULL);
+
+ /* Attempt to verify the client cert */
+ if (X509_verify_cert(sctx) != 1) {
+ int err = X509_STORE_CTX_get_error(sctx);
+ ssl_log_xerror(SSLLOG_MARK, APLOG_WARNING, 0, ptemp, s, inf->x509,
+ APLOGNO(02270) "SSL proxy client cert chain "
+ "verification failed: %s :",
+ X509_verify_cert_error_string(err));
+ }
+
+ /* Clear X509_verify_cert errors */
+ ERR_clear_error();
+
+ /* Obtain a copy of the verified chain */
+ chain = X509_STORE_CTX_get1_chain(sctx);
+
+ if (chain != NULL) {
+ /* Discard end entity cert from the chain */
+ X509_free(sk_X509_shift(chain));
+
+ if ((i = sk_X509_num(chain)) > 0) {
+ /* Store the chain for later use */
+ pkp->ca_certs[n] = chain;
+ }
+ else {
+ /* Discard empty chain */
+ sk_X509_pop_free(chain, X509_free);
+ pkp->ca_certs[n] = NULL;
+ }
+
+ ssl_log_xerror(SSLLOG_MARK, APLOG_DEBUG, 0, ptemp, s, inf->x509,
+ APLOGNO(02271)
+ "loaded %i intermediate CA%s for cert %i: ",
+ i, i == 1 ? "" : "s", n);
+ if (i > 0) {
+ int j;
+ for (j = 0; j < i; j++) {
+ ssl_log_xerror(SSLLOG_MARK, APLOG_DEBUG, 0, ptemp, s,
+ sk_X509_value(chain, j), "%i:", j);
+ }
+ }
+ }
+
+ /* get ready for next X509_STORE_CTX_init */
+ X509_STORE_CTX_cleanup(sctx);
+ }
+
+ X509_STORE_CTX_free(sctx);
}
static void ssl_init_proxy_ctx(server_rec *s,
@@ -1042,6 +1342,10 @@ static void ssl_init_server_ctx(server_rec *s,
ssl_init_ctx(s, p, ptemp, sc->server);
ssl_init_server_certs(s, p, ptemp, sc->server);
+
+#ifdef HAVE_TLS_SESSION_TICKETS
+ ssl_init_ticket_key(s, p, ptemp, sc->server);
+#endif
}
/*
@@ -1055,8 +1359,8 @@ void ssl_init_ConfigureServer(server_rec *s,
/* Initialize the server if SSL is enabled or optional.
*/
if ((sc->enabled == SSL_ENABLED_TRUE) || (sc->enabled == SSL_ENABLED_OPTIONAL)) {
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
- "Configuring server for SSL protocol");
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01914)
+ "Configuring server %s for SSL protocol", sc->vhost_id);
ssl_init_server_ctx(s, p, ptemp, sc);
}
@@ -1084,7 +1388,7 @@ void ssl_init_CheckServers(server_rec *base_server, apr_pool_t *p)
if ((sc->enabled == SSL_ENABLED_TRUE) && (s->port == DEFAULT_HTTP_PORT)) {
ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
- base_server,
+ base_server, APLOGNO(01915)
"Init: (%s) You configured HTTPS(%d) "
"on the standard HTTP(%d) port!",
ssl_util_vhostid(p, s),
@@ -1093,7 +1397,7 @@ void ssl_init_CheckServers(server_rec *base_server, apr_pool_t *p)
if ((sc->enabled == SSL_ENABLED_FALSE) && (s->port == DEFAULT_HTTPS_PORT)) {
ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
- base_server,
+ base_server, APLOGNO(01916)
"Init: (%s) You configured HTTP(%d) "
"on the standard HTTPS(%d) port!",
ssl_util_vhostid(p, s),
@@ -1123,11 +1427,11 @@ void ssl_init_CheckServers(server_rec *base_server, apr_pool_t *p)
klen = strlen(key);
if ((ps = (server_rec *)apr_hash_get(table, key, klen))) {
- ap_log_error(APLOG_MARK,
+ ap_log_error(APLOG_MARK,
#ifdef OPENSSL_NO_TLSEXT
- APLOG_WARNING,
+ APLOG_WARNING,
#else
- APLOG_DEBUG,
+ APLOG_DEBUG,
#endif
0,
base_server,
@@ -1151,7 +1455,7 @@ void ssl_init_CheckServers(server_rec *base_server, apr_pool_t *p)
}
if (conflict) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, 0, base_server,
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, base_server, APLOGNO(01917)
#ifdef OPENSSL_NO_TLSEXT
"Init: You should not use name-based "
"virtual hosts in conjunction with SSL!!");
@@ -1163,39 +1467,32 @@ void ssl_init_CheckServers(server_rec *base_server, apr_pool_t *p)
}
}
-#ifdef SSLC_VERSION_NUMBER
-static int ssl_init_FindCAList_X509NameCmp(char **a, char **b)
-{
- return(X509_NAME_cmp((void*)*a, (void*)*b));
-}
-#else
-static int ssl_init_FindCAList_X509NameCmp(const X509_NAME * const *a,
+static int ssl_init_FindCAList_X509NameCmp(const X509_NAME * const *a,
const X509_NAME * const *b)
{
return(X509_NAME_cmp(*a, *b));
}
-#endif
static void ssl_init_PushCAList(STACK_OF(X509_NAME) *ca_list,
- server_rec *s, const char *file)
+ 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(MODSSL_PCHAR_CAST file);
+ SSL_load_client_CA_file(file);
if (!sk) {
return;
}
for (n = 0; n < sk_X509_NAME_num(sk); n++) {
- char name_buf[256];
X509_NAME *name = sk_X509_NAME_value(sk, n);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02209)
"CA certificate: %s",
- X509_NAME_oneline(name, name_buf, sizeof(name_buf)));
+ SSL_X509_NAME_to_string(ptemp, name, 0));
/*
* note that SSL_load_client_CA_file() checks for duplicates,
@@ -1233,7 +1530,16 @@ STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s,
* Process CA certificate bundle file
*/
if (ca_file) {
- ssl_init_PushCAList(ca_list, s, ca_file);
+ ssl_init_PushCAList(ca_list, s, ptemp, 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)
+ "Failed to load SSLCACertificateFile: %s", ca_file);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s);
+ }
}
/*
@@ -1246,7 +1552,7 @@ STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s,
apr_status_t rv;
if ((rv = apr_dir_open(&dir, ca_path, ptemp)) != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
+ ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(02211)
"Failed to open Certificate Path `%s'",
ca_path);
ssl_die();
@@ -1258,7 +1564,7 @@ STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s,
continue; /* don't try to load directories */
}
file = apr_pstrcat(ptemp, ca_path, "/", direntry.name, NULL);
- ssl_init_PushCAList(ca_list, s, file);
+ ssl_init_PushCAList(ca_list, s, ptemp, file);
}
apr_dir_close(dir);
@@ -1282,6 +1588,9 @@ void ssl_init_Child(apr_pool_t *p, server_rec *s)
/* open the mutex lockfile */
ssl_mutex_reinit(s, p);
+#ifdef HAVE_OCSP_STAPLING
+ ssl_stapling_mutex_reinit(s, p);
+#endif
}
#define MODSSL_CFG_ITEM_FREE(func, item) \
@@ -1292,8 +1601,6 @@ void ssl_init_Child(apr_pool_t *p, server_rec *s)
static void ssl_init_ctx_cleanup(modssl_ctx_t *mctx)
{
- MODSSL_CFG_ITEM_FREE(X509_STORE_free, mctx->crl);
-
MODSSL_CFG_ITEM_FREE(SSL_CTX_free, mctx->ssl_ctx);
}