Bug 21371 - apache not passing certificate chain to servlet or CGI
Summary: apache not passing certificate chain to servlet or CGI
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: mod_ssl (show other bugs)
Version: 2.0.46
Hardware: Other Linux
: P3 major (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
Keywords: PatchAvailable
Depends on:
Reported: 2003-07-07 13:28 UTC by Mark Webb
Modified: 2004-11-16 19:05 UTC (History)
1 user (show)

proposed fix for cert chain variable problem (751 bytes, patch)
2003-07-10 20:40 UTC, Jeff Trawick
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Mark Webb 2003-07-07 13:28:15 UTC
I have been working on a site that enforces mutually authenticated SSL
using apache 2.0.46. I have compiled it from source using the following
commands passed to the ./configure script:

./configure --enable-so --enable-ssl --with-ssl=/usr/local/ssl

/usr/local/ssl contains openssl version 0.9.7b which I compiled from
source using the default build configuration.
I have tried both servlets and cgi and all I can get is the user
certificate, not the certificate chain.  I have tried looking at the
mod_ssl code, and cannot figure out why the +ExportCertData directive
will only tell apache to forward on the user certificate, not the chain.
Comment 1 Jeff Trawick 2003-07-10 20:39:21 UTC
This is all Greek to me (i.e., it would take me a long time to figure out how to
test), but it looks like there is an off-by-one error in ssl_engine_vars.c that
messes up
the lookup of the cert chain info.  I'll attach a patch to test in just a sec.

The latest mod_ssl for Apache 1.3 has this change too.  I'd wager that
backtracking that line of code in prior releases of the original mod_ssl
would show that it got fixed after we imported it into Apache 2.0.
Comment 2 Jeff Trawick 2003-07-10 20:40:35 UTC
Created attachment 7231 [details]
proposed fix for cert chain variable problem
Comment 3 Jeff Trawick 2003-07-14 17:34:24 UTC
The patch posted previously has been committed to Apache 2.1-dev and proposed
for merge to 2.0.48-dev.
Comment 4 Mark Webb 2003-07-15 20:32:34 UTC
I tried the patch and got the same results.  I do not think that the patch fixed
the problem.
Comment 5 Jeff Trawick 2003-07-16 11:11:34 UTC
Then I suppose more changes are required :(  The change in the patch corrected a
blatant error which has also been fixed in the mod_ssl project for 1.3.

Do you have any setup hints for testing this scenario?  Perhaps you can point to
some documentation?
Comment 6 Mark Webb 2003-07-16 12:23:16 UTC
This is what I do...

to compile apache(2.0.47).  I am using openSSL 0.9.7b, compiled from source, and
installed in /usr/local/ssl.
./configure --enable-so --enable-ssl --with-ssl=/usr/local/ssl
gmake install

to configure apache
create a test cert for apache, set up ssl.conf properly.
open browser, point to test-cgi.
observe that certificate chain is not listed in the output.

This proves to me that the certificate chain is not being passed to the CGI, and
therefore would not be passed to a servlet either.  I am most interested in
getting apache to pass the entire certificate chain to a servlet, but am using
cgi's to test with right now.  This is because it is easier to test, and takes
the tomcat connector stuff out of the equation.

Please let me know what more help I may be.
Comment 7 Jeff Trawick 2003-07-16 17:50:48 UTC
I'm stuck at the point of getting a certificate chain passed from the client. 
(No idea how to do that yet :) ).  I see SSL_CLIENT_CERT being set but with the
following patch to one of the mod_ssl files I see that OpenSSL is telling
mod_ssl that there are zero certificates in the chain.

Try testing with this patch to see if OpenSSL has provided mod_ssl with a chain.
If it hasn't, you'll see something like I did:

[debug] ssl_engine_kernel.c(1064): [client] got peer certificate
chain (0/8245458/8252f50)

where the 0 after "chain (" is the number of certificates in the chain returned
by OpenSSL...

Index: modules/ssl/ssl_engine_kernel.c
RCS file: /home/cvs/httpd-2.0/modules/ssl/ssl_engine_kernel.c,v
retrieving revision
diff -u -r1.82.2.6 ssl_engine_kernel.c
--- modules/ssl/ssl_engine_kernel.c     16 May 2003 18:12:18 -0000
+++ modules/ssl/ssl_engine_kernel.c     16 Jul 2003 17:28:03 -0000
@@ -1059,6 +1061,9 @@
         apr_table_setn(env, "SSL_CLIENT_CERT", val);

         if ((peer_certs = (STACK_OF(X509) *)SSL_get_peer_cert_chain(ssl))) {
+            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+                          "got peer certificate chain (%d/%pp/%pp)",
+                          sk_X509_num(peer_certs), peer_certs, ssl);
             for (i = 0; i < sk_X509_num(peer_certs); i++) {
                 var = apr_psprintf(r->pool, "SSL_CLIENT_CERT_CHAIN_%d", i);
                 val = ssl_var_lookup(r->pool, r->server, r->connection,
@@ -1067,6 +1072,10 @@
                     apr_table_setn(env, var, val);
+        }
+        else {
+            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+                          "SSL library returned no peer certificate chain");

Comment 8 Joe Orton 2003-09-16 12:43:49 UTC
Confirmed fixed in 2.0.46 + Jeff's off-by-one patch.

Mark, you did have "SSLOptions +ExportCertData" set in the right context?

(Mozilla doesn't seem to send the CA certs included in an imported PKCS#12 ccert
for me, neither will "openssl s_client"; maybe MSIE does it, I had to hack my
own code to reproduce this)