]> granicus.if.org Git - apache/commitdiff
per-dir SSLCACertificate{File,Path} cannot use SSL_CTX_set_cert_store
authorDoug MacEachern <dougm@apache.org>
Tue, 26 Mar 2002 16:57:49 +0000 (16:57 +0000)
committerDoug MacEachern <dougm@apache.org>
Tue, 26 Mar 2002 16:57:49 +0000 (16:57 +0000)
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
modules/ssl/mod_ssl.h
modules/ssl/ssl_engine_config.c
modules/ssl/ssl_engine_kernel.c

index 45f72bb10cf72d62d57dd09b5eef37506697d96f..a2032f2c993e609961cff54827d3dc083d609dd1 100644 (file)
@@ -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)")
index be1e2a36c5921ab0acc5b7f805330f189b7a065d..9e439ca5ab8110140dd0b0845617d237da9f1268 100644 (file)
@@ -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
 #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;
 
 /*
index 61bfc8b8d4cbb80bd3cca99aa13c20b2833a94cb..ef8ecd86a83667a39605de6150b90f253d8476e7 100644 (file)
@@ -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;
 }
index 0d019906a4f650949c4474d1c4dde56bdebc0dad..57f91dd3185f542bd064171b9664e1502f0a1c33 100644 (file)
@@ -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
      */