Hi all --

I'm having some trouble configuring Apache/mod_ssl to do what I want. 
Perhaps I have some misconceptions that need dispelled.  Any help would be
grealy appreciated.

OVERVIEW/GOAL:
I'm retrofitting some Apache servers to require client certificates.  Note
that these servers have certificates that are (temporarily) self-signed. 
Our organization already has a PKI consisting of a self-signed RootCA and
two IssuingCAs.  My goal here is to configure my Apache server to require
user certificates issued by IssuingCA2, and to refuse access to all
others.

Server version: Apache/2.2.3
Server built:   Aug 10 2006 17:29:16
OpenSSL 0.9.8b 04 May 2006

THE PROBLEM:
The problem is that I've found only one configuration that will allow a
client to successfully load a page, and in this case, it will also allow
the use of user certificates issued by the other IssuingCA.  I find this
baffling, since I haven't told Apache anything about this particular
IssuingCA.

I believe that my problems are centering around the SSLCACertificateFile
directive.  See below for my SSL (scrubbed) conf file.

CASE 1:
If I use this invocation, Apache allows certificates from any issuing CA
that has been signed by our Root CA.  Note that certchain.cer is a
concatenation of the PEM-encoded certificates for IssuingCA2 and the
RootCA (specifically, of IssuingCA2.cer and RootCA.cer mentioned in the
next two cases).
  SSLCACertificateFile conf/ssl/certchain.cer

Here is the logfile exerpt for this case:

[Mon Apr 23 22:26:14 2007] [debug] ssl_engine_kernel.c(1190): Certificate
Verification: depth: 2, subject: [SNIP]Root CA, issuer: [SNIP]Root CA
[Mon Apr 23 22:26:14 2007] [debug] ssl_engine_kernel.c(1190): Certificate
Verification: depth: 1, subject: [SNIP]Issuing CA 1, issuer: [SNIP]Root CA
[Mon Apr 23 22:26:14 2007] [debug] ssl_engine_kernel.c(1190): Certificate
Verification: depth: 0, subject: /CN=[SNIP], issuer: [SNIP]Issuing CA 1

CASE 2:
If I use this invocation, Apache will run but will complain (whenever the
protected page is loaded) that it can't find the local issuer certificate.
 I've tried setting SSLVerifyDepth to 1, but this didn't help anything. 
The only good thing about this case is that the list of certificates
presented by the remote browser to the user only includes those directly
issued by IssuingCA2.
   SSLCACertificateFile conf/ssl/IssuingCA2.cer

Here is the logfile exerpt for this case:

[Mon Apr 23 22:31:18 2007] [debug] ssl_engine_kernel.c(1190): Certificate
Verification: depth: 1, subject: [SNIP]Issuing CA 2, issuer: [SNIP]Root CA
[Mon Apr 23 22:31:18 2007] [error] Certificate Verification: Error (20):
unable to get local issuer certificate

CASE 3:
If I use this invocation, Apache won't even run.  Note that the content of
RootCA.cer is exactly the same content that makes up an essential part of
certchain.cer (see above).  AFAIK, this certificate should have format and
content readily useable by Apache.  The only special thing about it, is
that it is a self-signed certificate (does that make a difference?)
   SSLCACertificateFile conf/ssl/RootCA.cer

Here is the logfile exerpt for this case:

[Mon Apr 23 22:02:13 2007] [info] Loading certificate & private key of
SSL-aware server
[Mon Apr 23 22:02:13 2007] [debug] ssl_engine_pphrase.c(469): unencrypted
RSA private key - pass phrase not required
[Mon Apr 23 22:02:13 2007] [info] Configuring server for SSL protocol
[Mon Apr 23 22:02:13 2007] [debug] ssl_engine_init.c(405): Creating new
SSL context (protocols: SSLv2, TLSv1)
[Mon Apr 23 22:02:13 2007] [debug] ssl_engine_init.c(538): Configuring
client authentication
[Mon Apr 23 22:02:13 2007] [error] Unable to configure verify locations
for client authentication
[Mon Apr 23 22:02:13 2007] [error] SSL Library Error: 33558533
error:02001005:system library:fopen:Input/output error
[Mon Apr 23 22:02:13 2007] [error] SSL Library Error: 537317378
error:2006D002:BIO routines:BIO_new_file:system lib
[Mon Apr 23 22:02:13 2007] [error] SSL Library Error: 185090050
error:0B084002:x509 certificate routines:X509_load_cert_crl_file:system
lib

HELP:
My expectation here was that I would need to provide the certificate chain
(issuing and root CA) required to authenticate the user certificate, and
that a user certificate issued by any other IssuingCA would fail because I
haven't given Apache the IssuingCA's certificate.

Instead, it seems like the server has gained access to the IssuingCA1
certificate (does it do this directly, or does the client send it?), and
is validating that certificate against the RootCA.  This seems to happen
when I provided the RootCA in the SSLCACertificateFile, which (as I
understand it) gets sent to the remote client so that it can filter its
list of applicable user certificates.

So, I'm looking for is a way to configure Apache to:
1.  Instruct the remote browser to limit the applicable user certificates
to only those issued by IssuingCA2,
2.  Avoid the "unable to get local issuer certificate" error
3.  Never accept a user certificate issued by IssuingCA1

Could someone please tell me where I've gone wrong, and/or how to achieve
these goals?



CONFIGURATION:
Here's my SSL conf file.  It's loaded from httpd.conf:

<VirtualHost _default_:443>
    DocumentRoot [SNIP]
    ServerName [SNIP]:443
    ServerAdmin [SNIP]
    CustomLog virtualhosts/secure/logs/access.log common
    ErrorLog virtualhosts/secure/logs/error.log
    TransferLog virtualhosts/secure/logs/access.log
    LogLevel debug

    <IfModule ssl_module>
        SSLEngine on
        SSLCipherSuite
ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
        SSLCertificateFile conf/ssl/[SNIP].crt
        SSLCertificateKeyFile conf/ssl/[SNIP].key
        SSLCACertificateFile conf/ssl/certchain.cer
        SSLVerifyDepth  10
        <Files ~ "\.(cgi|shtml|phtml|php3?)$">
            SSLOptions +StdEnvVars
        </Files>
        <Directory "cgi-bin">
            SSLOptions +StdEnvVars
        </Directory>
        SetEnvIf User-Agent ".*MSIE.*" \
                 nokeepalive ssl-unclean-shutdown \
                 downgrade-1.0 force-response-1.0
        CustomLog virtualhosts/secure/logs/ssl_request_log \
                  "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"

        # Prevent clients from using SSLv3
        SSLProtocol all -SSLv3
    </IfModule>

    DocumentRoot [SNIP]/virtualhosts/secure/htdocs
    <Directory [SNIP]/virtualhosts/secure/htdocs>
        Options Indexes FollowSymLinks
        AllowOverride None
        Order allow,deny
        Allow from all
    </Directory>

    <Location />
        Options FollowSymLinks
        AllowOverride None

        Order allow,deny
        Allow from all
    </Location>

    <Location /protected>
        # Per-directory configuration for SSL
        SSLRequireSSL
        SSLRequire %{SSL_CIPHER_USEKEYSIZE} >= 128
        SSLVerifyClient require
    </Location>

    <Directory "[SNIP]/virtualhosts/secure/cgi-bin">
        AllowOverride None
        Options None
        Order allow,deny
        Allow from all
    </Directory>

</VirtualHost>


______________________________________________________________________
Apache Interface to OpenSSL (mod_ssl)                   www.modssl.org
User Support Mailing List                      modssl-users@modssl.org
Automated List Manager                            [EMAIL PROTECTED]

Reply via email to