From 18c5af85dca0656f764bf09374ed87bcc2556c2a Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Tue, 26 Mar 2002 16:57:49 +0000 Subject: [PATCH] per-dir SSLCACertificate{File,Path} cannot use SSL_CTX_set_cert_store as the 1.x based module does, since the function is not thread-safe. a patch has been submitted to OpenSSL to support SSL_set_cert_store which is thread safe. this feature is enabled by default in the current 1.x based module, we only enable it if the SSL_set_cert_store function is available. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@94179 13f79535-47bb-0310-9956-ffa450edef68 --- modules/ssl/mod_ssl.c | 9 ---- modules/ssl/mod_ssl.h | 10 ++-- modules/ssl/ssl_engine_config.c | 42 ++++++---------- modules/ssl/ssl_engine_kernel.c | 87 ++++++++++++--------------------- 4 files changed, 50 insertions(+), 98 deletions(-) diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c index 45f72bb10c..a2032f2c99 100644 --- a/modules/ssl/mod_ssl.c +++ b/modules/ssl/mod_ssl.c @@ -120,21 +120,12 @@ static const command_rec ssl_config_cmds[] = { SSL_CMD_SRV(CertificateChainFile, TAKE1, "SSL Server CA Certificate Chain file " "(`/path/to/file' - PEM encoded)") -#ifdef SSL_EXPERIMENTAL_PERDIRCA SSL_CMD_ALL(CACertificatePath, TAKE1, "SSL CA Certificate path " "(`/path/to/dir' - contains PEM encoded files)") SSL_CMD_ALL(CACertificateFile, TAKE1, "SSL CA Certificate file " "(`/path/to/file' - PEM encoded)") -#else - SSL_CMD_SRV(CACertificatePath, TAKE1, - "SSL CA Certificate path " - "(`/path/to/dir' - contains PEM encoded files)") - SSL_CMD_SRV(CACertificateFile, TAKE1, - "SSL CA Certificate file " - "(`/path/to/file' - PEM encoded)") -#endif SSL_CMD_SRV(CARevocationPath, TAKE1, "SSL CA Certificate Revocation List (CRL) path " "(`/path/to/dir' - contains PEM encoded files)") diff --git a/modules/ssl/mod_ssl.h b/modules/ssl/mod_ssl.h index be1e2a36c5..9e439ca5ab 100644 --- a/modules/ssl/mod_ssl.h +++ b/modules/ssl/mod_ssl.h @@ -70,9 +70,6 @@ * CFLAGS="-DSSL_EXPERIMENTAL_xxxx_IGNORE". */ #ifdef SSL_EXPERIMENTAL -#ifndef SSL_EXPERIMENTAL_PERDIRCA_IGNORE -#define SSL_EXPERIMENTAL_PERDIRCA -#endif #ifndef SSL_EXPERIMENTAL_PROXY_IGNORE #define SSL_EXPERIMENTAL_PROXY #endif @@ -83,6 +80,11 @@ #endif #endif /* SSL_EXPERIMENTAL */ +/* XXX: add configure check */ +#ifndef MODSSL_HAVE_SSL_SET_CERT_STORE +#define MODSSL_HAVE_SSL_SET_CERT_STORE 0 +#endif + /* * Power up our brain... */ @@ -567,10 +569,8 @@ typedef struct { const char *szCipherSuite; ssl_verify_t nVerifyClient; int nVerifyDepth; -#ifdef SSL_EXPERIMENTAL_PERDIRCA const char *szCACertificatePath; const char *szCACertificateFile; -#endif } SSLDirConfigRec; /* diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c index 61bfc8b8d4..ef8ecd86a8 100644 --- a/modules/ssl/ssl_engine_config.c +++ b/modules/ssl/ssl_engine_config.c @@ -252,10 +252,8 @@ void *ssl_config_perdir_create(apr_pool_t *p, char *dir) dc->nVerifyClient = SSL_CVERIFY_UNSET; dc->nVerifyDepth = UNSET; -#ifdef SSL_EXPERIMENTAL_PERDIRCA dc->szCACertificatePath = NULL; dc->szCACertificateFile = NULL; -#endif return dc; } @@ -290,10 +288,8 @@ void *ssl_config_perdir_merge(apr_pool_t *p, void *basev, void *addv) cfgMerge(nVerifyClient, SSL_CVERIFY_UNSET); cfgMergeInt(nVerifyDepth); -#ifdef SSL_EXPERIMENTAL_PERDIRCA cfgMergeString(szCACertificatePath); cfgMergeString(szCACertificateFile); -#endif return new; } @@ -662,12 +658,22 @@ const char *ssl_cmd_SSLCertificateChainFile(cmd_parms *cmd, void *ctx, return NULL; } +#define NO_PER_DIR_SSL_CA \ + "Your ssl library does not have support for per-directory CA" + +#define MODSSL_SET_CA(f) \ + if (cmd->path) \ + if (MODSSL_HAVE_SSL_SET_CERT_STORE) \ + dc->f = arg; \ + else \ + return NO_PER_DIR_SSL_CA; \ + else \ + sc->f = arg \ + const char *ssl_cmd_SSLCACertificatePath(cmd_parms *cmd, void *ctx, const char *arg) { -#ifdef SSL_EXPERIMENTAL_PERDIRCA SSLDirConfigRec *dc = (SSLDirConfigRec *)ctx; -#endif SSLSrvConfigRec *sc = mySrvConfig(cmd->server); const char *err; @@ -675,16 +681,7 @@ const char *ssl_cmd_SSLCACertificatePath(cmd_parms *cmd, void *ctx, return err; } -#ifdef SSL_EXPERIMENTAL_PERDIRCA - if (cmd->path) { - dc->szCACertificatePath = arg; - } - else { - sc->szCACertificatePath = arg; - } -#else - sc->szCACertificatePath = arg; -#endif + MODSSL_SET_CA(szCACertificatePath); return NULL; } @@ -692,9 +689,7 @@ const char *ssl_cmd_SSLCACertificatePath(cmd_parms *cmd, void *ctx, const char *ssl_cmd_SSLCACertificateFile(cmd_parms *cmd, void *ctx, const char *arg) { -#ifdef SSL_EXPERIMENTAL_PERDIRCA SSLDirConfigRec *dc = (SSLDirConfigRec *)ctx; -#endif SSLSrvConfigRec *sc = mySrvConfig(cmd->server); const char *err; @@ -702,16 +697,7 @@ const char *ssl_cmd_SSLCACertificateFile(cmd_parms *cmd, void *ctx, return err; } -#ifdef SSL_EXPERIMENTAL_PERDIRCA - if (cmd->path) { - dc->szCACertificateFile = arg; - } - else { - sc->szCACertificateFile = arg; - } -#else - sc->szCACertificateFile = arg; -#endif + MODSSL_SET_CA(szCACertificateFile); return NULL; } diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c index 0d019906a4..57f91dd318 100644 --- a/modules/ssl/ssl_engine_kernel.c +++ b/modules/ssl/ssl_engine_kernel.c @@ -322,16 +322,10 @@ int ssl_hook_Access(request_rec *r) char *cp; int ok, i; BOOL renegotiate = FALSE, renegotiate_quick = FALSE; -#ifdef SSL_EXPERIMENTAL_PERDIRCA - BOOL reconfigured_locations = FALSE; - STACK_OF(X509_NAME) *ca_list; - char *ca_path, *ca_file; -#endif X509 *cert; - STACK_OF(X509) *cert_stack; - X509_STORE *cert_store; + X509_STORE *cert_store = NULL; X509_STORE_CTX cert_store_ctx; - STACK_OF(SSL_CIPHER) *cipher_list_old=NULL, *cipher_list = NULL; + STACK_OF(SSL_CIPHER) *cipher_list_old = NULL, *cipher_list = NULL; SSL_CIPHER *cipher = NULL; int depth, verify_old, verify, n; @@ -578,17 +572,13 @@ int ssl_hook_Access(request_rec *r) } /* - * override SSLCACertificateFile & SSLCACertificatePath - * This is tagged experimental because it has to use an ugly kludge: We - * have to change the locations inside the SSL_CTX* (per-server global) - * instead inside SSL* (per-connection local) and reconfigure it to the - * old values later. That's problematic at least for the threaded process - * model of Apache under Win32 or when an error occurs. But unless - * OpenSSL provides a SSL_load_verify_locations() function we've no other - * chance to provide this functionality... + * override SSLCACertificateFile & SSLCACertificatePath + * This is only enabled if the SSL_set_cert_store() function + * is available in the ssl library. the 1.x based mod_ssl + * used SSL_CTX_set_cert_store which is not thread safe. */ -#ifdef SSL_EXPERIMENTAL_PERDIRCA +#if MODSSL_HAVE_SSL_SET_CERT_STORE /* * check if per-dir and per-server config field are not the same. * if f is defined in per-dir and not defined in per-server @@ -597,28 +587,31 @@ int ssl_hook_Access(request_rec *r) #define MODSSL_CFG_NE(f) \ (dc->f && (!sc->f || (sc->f && strNE(dc->f, sc->f)))) +#define MODSSL_CFG_CA(f) \ + (dc->f ? dc->f : sc->f) + if (MODSSL_CFG_NE(szCACertificateFile) || MODSSL_CFG_NE(szCACertificatePath)) { - ca_file = dc->szCACertificateFile ? - dc->szCACertificateFile : sc->szCACertificateFile; + STACK_OF(X509_NAME) *ca_list; + const char *ca_file = MODSSL_CFG_CA(szCACertificateFile); + const char *ca_path = MODSSL_CFG_CA(szCACertificatePath); - ca_path = dc->szCACertificatePath ? - dc->szCACertificatePath : sc->szCACertificatePath; + cert_store = X509_STORE_new(); - /* - FIXME: This should be... - if (!SSL_load_verify_locations(ssl, ca_file, ca_path)) { - ...but OpenSSL still doesn't provide this! - */ - if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path)) { + if (!X509_STORE_load_locations(cert_store, ca_file, ca_path)) { ssl_log(r->server, SSL_LOG_ERROR|SSL_ADD_SSLERR, "Unable to reconfigure verify locations " "for client authentication"); + X509_STORE_free(cert_store); + return HTTP_FORBIDDEN; } + /* SSL_free will free cert_store */ + SSL_set_cert_store(ssl, cert_store); + if (!(ca_list = ssl_init_FindCAList(r->server, r->pool, ca_file, ca_path))) { @@ -631,13 +624,12 @@ int ssl_hook_Access(request_rec *r) SSL_set_client_CA_list(ssl, ca_list); renegotiate = TRUE; - reconfigured_locations = TRUE; ssl_log(r->server, SSL_LOG_TRACE, "Changed client verification locations " "will force renegotiation"); } -#endif /* SSL_EXPERIMENTAL_PERDIRCA */ +#endif /* MODSSL_HAVE_SSL_SET_CERT_STORE */ /* * SSL renegotiations in conjunction with HTTP @@ -726,23 +718,27 @@ int ssl_hook_Access(request_rec *r) "Requesting connection re-negotiation"); if (renegotiate_quick) { + STACK_OF(X509) *cert_stack; + /* perform just a manual re-verification of the peer */ ssl_log(r->server, SSL_LOG_TRACE, "Performing quick renegotiation: " "just re-verifying the peer"); - if (!(cert_store = SSL_CTX_get_cert_store(ctx))) { + cert_stack = (STACK_OF(X509) *)SSL_get_peer_cert_chain(ssl); + + if (!cert_stack || (sk_X509_num(cert_stack) == 0)) { ssl_log(r->server, SSL_LOG_ERROR, - "Cannot find certificate storage"); + "Cannot find peer certificate chain"); return HTTP_FORBIDDEN; } - cert_stack = (STACK_OF(X509) *)SSL_get_peer_cert_chain(ssl); - - if (!cert_stack || (sk_X509_num(cert_stack) == 0)) { + if (!(cert_store || + (cert_store = SSL_CTX_get_cert_store(ctx)))) + { ssl_log(r->server, SSL_LOG_ERROR, - "Cannot find peer certificate chain"); + "Cannot find certificate storage"); return HTTP_FORBIDDEN; } @@ -836,27 +832,6 @@ int ssl_hook_Access(request_rec *r) } } - /* - * Under old OpenSSL we had to change the X509_STORE inside the - * SSL_CTX instead inside the SSL structure, so we have to reconfigure it - * to the old values. This should be changed with forthcoming OpenSSL - * versions when better functionality is avaiable. - */ -#ifdef SSL_EXPERIMENTAL_PERDIRCA - if (renegotiate && reconfigured_locations) { - if (!SSL_CTX_load_verify_locations(ctx, - sc->szCACertificateFile, - sc->szCACertificatePath)) - { - ssl_log(r->server, SSL_LOG_ERROR|SSL_ADD_SSLERR, - "Unable to reconfigure verify locations " - "to per-server configuration parameters"); - - return HTTP_FORBIDDEN; - } - } -#endif /* SSL_EXPERIMENTAL_PERDIRCA */ - /* * Check SSLRequire boolean expressions */ -- 2.40.0