Bug 32848 - No independent control of CertificateRequest handshake message
Summary: No independent control of CertificateRequest handshake message
Status: RESOLVED FIXED
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: mod_ssl (show other bugs)
Version: 2.0.52
Hardware: All All
: P2 normal (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
URL:
Keywords: PatchAvailable
Depends on:
Blocks:
 
Reported: 2004-12-27 16:57 UTC by Tim K. Taylor
Modified: 2005-02-02 13:31 UTC (History)
1 user (show)



Attachments
documentation patch to mod_ssl.xml (3.03 KB, patch)
2005-02-02 22:31 UTC, Tim K. Taylor
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Tim K. Taylor 2004-12-27 16:57:12 UTC
SSLv3 draft (5.6.4) and RFC2246 (7.4.4) describe the capability to provide a
list a CA distinguished names for defining a desired authorization space. This
is currently not possible with mod_ssl.

Even though OpenSSL SSL contexts have both a certificate store for client
authentication and a stack of CA names for the CertificateRequest handshake
message, they are both created from the same set of certificates. This is ok
when the list of trusted roots is also the issuer of the client certificates.

PROBLEM
=======
When the trusted roots issue subordinate (intermediate) CA certificates which in
turn issue end entity certificates, there is the possibility that some and not
all of the intermediate CA certificates are acceptable for the trusted root.
However, if the trusted root is used for the CertificateRequest handshake
message, all of its intermediate CA's are acceptable. Of course, if the trusted
root is left out, the certificate chain cannot be verified.

FIX
===
Separate and independent control of the CertificateRequest handshake message.
Currently, the SSLCACertificateFile and SSLCACertificatePath are used to both
define the trust list for client authentication and create the list of CA
distinguished names for the CertificateRequest message. By adding a new
directive to mod_ssl (SSLCADNRequestPath, SSLCADNRequestFile) that, only when
present, will specifically define the set of certificates to derive the
client_CA distinguished names in the exact same way as SSLCACertificate*. In
this case SSLCACertificate* will only define the trust list. When not present,
SSLCACertificate* does double duty as normal. This makes the fix downwardly
compatible with existing SSL configurations.

PATCH
=====
diff -ru httpd-2.0.52-pristine/modules/ssl/mod_ssl.c
httpd-2.0.52-patch3/modules/ssl/mod_ssl.c
--- httpd-2.0.52-pristine/modules/ssl/mod_ssl.c	Mon Aug 23 10:18:54 2004
+++ httpd-2.0.52-patch3/modules/ssl/mod_ssl.c	Tue Dec 14 11:27:21 2004
@@ -111,10 +111,16 @@
                 "(`/path/to/file' - PEM encoded)")
     SSL_CMD_ALL(CACertificatePath, TAKE1,
                 "SSL CA Certificate path "
-                "(`/path/to/dir' - contains PEM encoded files)")
+                "(`/path/to/dir' - contains PEM encoded files for client
authentication)")
     SSL_CMD_ALL(CACertificateFile, TAKE1,
                 "SSL CA Certificate file "
-                "(`/path/to/file' - PEM encoded)")
+                "(`/path/to/file' - PEM encoded for client authentication)")
+    SSL_CMD_ALL(CADNRequestPath, TAKE1,
+                "SSL CA Distinguished Name path "
+                "(`/path/to/dir' - symlink hashes to PEM of acceptable CA names
to request)")
+    SSL_CMD_ALL(CADNRequestFile, TAKE1,
+                "SSL CA Distinguished Name file "
+                "(`/path/to/file' - PEM encoded to derive acceptable CA names
to request)")
     SSL_CMD_SRV(CARevocationPath, TAKE1,
                 "SSL CA Certificate Revocation List (CRL) path "
                 "(`/path/to/dir' - contains PEM encoded files)")
================================================================================================
diff -ru httpd-2.0.52-pristine/modules/ssl/mod_ssl.h
httpd-2.0.52-patch3/modules/ssl/mod_ssl.h
--- httpd-2.0.52-pristine/modules/ssl/mod_ssl.h	Fri Aug 27 04:03:24 2004
+++ httpd-2.0.52-patch3/modules/ssl/mod_ssl.h	Tue Dec 14 11:27:26 2004
@@ -442,6 +442,20 @@
     const char  *ca_cert_path;
     const char  *ca_cert_file;
 
+    /*
+     * Acceptable CA names for certificateRequest message. (RFC2246) 
+     * These two were added to support specifying a CA name
+     * list that may or may not include a self-signed root CA.
+     * This allows the ability to create a limited authorization
+     * space given the (possible) growth of complex trust hierarchies.
+     *
+     * For backward compatibility, if SSLCADNRequest* is not specified
+     * the default behavior of using SSLCACertificate* for both trust
+     * and certificateRequest (client_CA list) will occur.
+     */
+    const char  *ca_name_path;
+    const char  *ca_name_file;
+
     const char  *cipher_suite;
 
     /* for client or downstream server authentication */
@@ -502,6 +516,8 @@
     int           nVerifyDepth;
     const char   *szCACertificatePath;
     const char   *szCACertificateFile;
+    const char   *szCADNRequestPath;
+    const char   *szCADNRequestFile;
     const char   *szUserName;
 } SSLDirConfigRec;
 
@@ -534,6 +550,8 @@
 const char  *ssl_cmd_SSLCertificateChainFile(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_SSLCADNRequestPath(cmd_parms *, void *, const char *);
+const char  *ssl_cmd_SSLCADNRequestFile(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_SSLVerifyClient(cmd_parms *, void *, const char *);
================================================================================================
diff -ru httpd-2.0.52-pristine/modules/ssl/ssl_engine_config.c
httpd-2.0.52-patch3/modules/ssl/ssl_engine_config.c
--- httpd-2.0.52-pristine/modules/ssl/ssl_engine_config.c	Mon Aug 23 10:18:54 2004
+++ httpd-2.0.52-patch3/modules/ssl/ssl_engine_config.c	Tue Dec 14 11:27:47 2004
@@ -122,6 +122,8 @@
 
     mctx->auth.ca_cert_path   = NULL;
     mctx->auth.ca_cert_file   = NULL;
+    mctx->auth.ca_name_path   = NULL; /* added to support separate control */
+    mctx->auth.ca_name_file   = NULL; /* of certificate request message.   */
     mctx->auth.cipher_suite   = NULL;
     mctx->auth.verify_depth   = UNSET;
     mctx->auth.verify_mode    = SSL_CVERIFY_UNSET;
@@ -217,6 +219,8 @@
 
     cfgMergeString(auth.ca_cert_path);
     cfgMergeString(auth.ca_cert_file);
+    cfgMergeString(auth.ca_name_path);
+    cfgMergeString(auth.ca_name_file);
     cfgMergeString(auth.cipher_suite);
     cfgMergeInt(auth.verify_depth);
     cfgMerge(auth.verify_mode, SSL_CVERIFY_UNSET);
@@ -286,6 +290,8 @@
 
     dc->szCACertificatePath    = NULL;
     dc->szCACertificateFile    = NULL;
+    dc->szCADNRequestPath      = NULL;
+    dc->szCADNRequestFile      = NULL;
     dc->szUserName             = NULL;
 
     return dc;
@@ -323,6 +329,8 @@
 
     cfgMergeString(szCACertificatePath);
     cfgMergeString(szCACertificateFile);
+    cfgMergeString(szCADNRequestPath);
+    cfgMergeString(szCADNRequestFile);
     cfgMergeString(szUserName);
 
     return mrg;
@@ -825,6 +833,32 @@
     sc->server->auth.ca_cert_file = arg;
 
     return NULL;
+}
+
+const char *ssl_cmd_SSLCADNRequestPath(cmd_parms *cmd, void *dcfg, const char
*arg) {
+    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+    const char *err;
+
+    if ((err = ssl_cmd_check_dir(cmd, &arg))) {
+        return err;
+    }
+
+    sc->server->auth.ca_name_path = arg;
+
+    return NULL;
+}
+
+const char *ssl_cmd_SSLCADNRequestFile(cmd_parms *cmd, void *dcfg, const char
*arg) {
+    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+    const char *err;
+
+    if ((err = ssl_cmd_check_file(cmd, &arg))) {
+        return err;
+    }
+
+    sc->server->auth.ca_name_file = arg;
+
+    return NULL;
 }
 
 const char *ssl_cmd_SSLCARevocationPath(cmd_parms *cmd,
================================================================================================
diff -ru httpd-2.0.52-pristine/modules/ssl/ssl_engine_init.c
httpd-2.0.52-patch3/modules/ssl/ssl_engine_init.c
--- httpd-2.0.52-pristine/modules/ssl/ssl_engine_init.c	Mon Jun  7 05:18:37 2004
+++ httpd-2.0.52-patch3/modules/ssl/ssl_engine_init.c	Thu Dec  9 19:04:04 2004
@@ -532,12 +532,20 @@
             ssl_die();
         }
 
-        ca_list = ssl_init_FindCAList(s, ptemp,
+	if (mctx->auth.ca_name_file || mctx->auth.ca_name_path) {
+	    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+		      "Configuring certificateRequest message");
+
+            ca_list = ssl_init_FindCAList(s, ptemp,
+                                      mctx->auth.ca_name_file,
+                                      mctx->auth.ca_name_path);
+	} else
+            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,
-                    "Unable to determine list of available "
+                    "Unable to determine list of acceptable "
                     "CA certificates for client authentication");
             ssl_die();
         }
@@ -556,7 +564,7 @@
             ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
                          "Init: Oops, you want to request client "
                          "authentication, but no CAs are known for "
-                         "verification!?  [Hint: SSLCACertificate*]");
+                         "verification!?  [Hint: SSLCACertificate*,
SSLCADNRequest*]");
         }
     }
 }
@@ -1123,7 +1131,7 @@
 
         if ((rv = apr_dir_open(&dir, ca_path, ptemp)) != APR_SUCCESS) {
             ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
-                    "Failed to open SSLCACertificatePath `%s'",
+                    "Failed to open Certificate Path `%s'",
                     ca_path);
             ssl_die();
         }
================================================================================================
diff -ru httpd-2.0.52-pristine/modules/ssl/ssl_engine_kernel.c
httpd-2.0.52-patch3/modules/ssl/ssl_engine_kernel.c
--- httpd-2.0.52-pristine/modules/ssl/ssl_engine_kernel.c	Mon Aug 23 10:18:55 2004
+++ httpd-2.0.52-patch3/modules/ssl/ssl_engine_kernel.c	Thu Dec  9 19:04:04 2004
@@ -470,11 +470,22 @@
         /* 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)))
+	/*
+	 * If no per-dir CADNRequest* is defined, the per-dir
+	 * CACertificate* takes on its default double-duty.
+	 */
+        if (MODSSL_CFG_NE(szCADNRequestFile) ||
+            MODSSL_CFG_NE(szCADNRequestPath))
         {
+            ca_file = MODSSL_CFG_CA(szCADNRequestFile);
+            ca_path = MODSSL_CFG_CA(szCADNRequestPath);
+	}
+
+        if (!(ca_list = ssl_init_FindCAList(r->server, r->pool, 
+                                           ca_file, ca_path)))
+        {
             ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
-                         "Unable to determine list of available "
+                         "Unable to determine list of acceptable "
                          "CA certificates for client authentication");
 
             return HTTP_FORBIDDEN;
Comment 1 Joe Orton 2005-01-14 15:02:39 UTC
Thanks for the submission. A trimmed-down version of this patch has been
committed to the trunk for future httpd 2.1/2.2 releases.

http://svn.apache.org/viewcvs?view=rev&rev=125165 [viewcvs currently accessible]

Did you have a docs update for this too, BTW?
Comment 2 Tim K. Taylor 2005-01-18 16:31:56 UTC
I had not done the doc but I can certainly do so. I assume that when I am done,
that I should attach here as was done with the code.
Comment 3 Joe Orton 2005-01-18 16:43:22 UTC
That or just send it to docs@httpd.apache.org; ideally as a diff against the XML
source.  If it's hassle then just sending in some unformatted text would be great.
Comment 4 Tim K. Taylor 2005-02-02 22:31:33 UTC
Created attachment 14160 [details]
documentation patch to mod_ssl.xml