4

So I have been following instructions on setting up Client Certificate Authentication in Apache2 w/ mod_ssl. This is solely for the purpose of testing an application against CAA, not for any sort of production use.

So far I've followed http://www.impetus.us/~rjmooney/projects/misc/clientcertauth.html for advice on generating my CA, server, and client encryption information. I've put all three of them into /etc/ssl/ca/private. I've setup the following additional directives in my default_ssl site file:

<IfModule mod_ssl.c>
<VirtualHost _default_:443>
...
    SSLEngine on
    SSLCertificateFile    /etc/ssl/ca/private/server.crt
    SSLCertificateKeyFile /etc/ssl/ca/private/server.key
    SSLVerifyClient require
    SSLVerifyDepth 2

    SSLCACertificatePath /etc/ssl/ca/private
    SSLCACertificateFile /etc/ssl/ca/private/ca.crt
    <Location />
            SSLRequireSSL
            SSLVerifyClient require
            SSLVerifyDepth 2
    </Location>
    <FilesMatch "\.(cgi|shtml|phtml|php)$">
            SSLOptions +StdEnvVars
    </FilesMatch>
    <Directory /usr/lib/cgi-bin>
            SSLOptions +StdEnvVars
    </Directory>
...
</VirtualHost>
</IfModule>

I've install the p12 file into Chrome, but when I go to visit https://localhost, I get the following errors

Chrome: Error 107 (net::ERR_SSL_PROTOCOL_ERROR): SSL protocol error.

Apache: Certificate Verification: Error (18): self signed certificate

If I had to guess, one of my directives is not setup right to load and verify the p12 w/ my self created CA. But I can't for the life of me figure out what it is. Would anyone have more experience here who could point me in the right direction?

decoy
  • 393
  • 2
  • 3
  • 6

3 Answers3

4

Firstly, I would suggest to avoid to use both SSLCACertificatePath and SSLCACertificateFile at the same time. SSLCACertificatePath is used to point to a directory containing multiple files, one for each CA certificate you trust. SSLCACertificateFile is used to point to a single file, being the concatenation of all the CA certificates you trust. It doesn't really make sense to point SSLCACertificatePath to a directory that also holds private keys (although I'm not sure it would cause problems anyway).

What matters is that the client certificate you're using is issued by one of the CA certificates (pointed to either by whichever of SSLCACertificatePath or SSLCACertificateFile you'll be using): the issuer DN of your client certificate must be the subject DN of one of the CA certificates you've configured this way in Apache Httpd (in addition, it must really be issued by that CA, so your client certificate's signature must be verifiable by the CA certificate's public key, but I'm assuming you've created your CA and issued certificates properly: you may want to check this, just in case).

You can check the content of a certificate (CA or not) in PEM form (often .pem or .crt) using:

openssl x509 -text -noout -in filename.pem

(This should display enough information about the certificate.)

EDIT:

Just in case there might be an issue with your certificates, you could try these test certificates:

http://jsslutils.googlecode.com/svn/tags/jsslutils-root-1.0.7/certificates/src/main/resources/org/jsslutils/certificates/local/

(All the passwords are testtest.)

You can import testclient.p12 into your browser. cacert.pem is the CA certificate in PEM format, and localhost-cert.pem is a server certificate for localhost (so it's intended for testing from the machine itself). localhost-key.pem is the private key for the server certificate. You can unprotect it using:

openssl rsa -in localhost-key.pem -out localhost-key-unprotected.pem

You might need to trust cacert.pem temporarily in your browser, but remove it after the tests (because obviously testtest is not much of a secret, so anyone could use this CA).

Bruno
  • 4,099
  • 1
  • 21
  • 37
  • Reduced it down to just SSLCACertificateFile. Re-ran the instructions from above link, placing them carefully into 3 bash scripts (ca, server, and client). Reloaded all certs. No luck. Gonna have to look for another walkthrough, maybe something more recent. – decoy Dec 21 '11 at 15:56
  • @decoy, Just in case there's a problem with your certificates, you could try the test certificates I've just mentioned. – Bruno Dec 23 '11 at 14:22
  • 1
    The problem was with my certificates. I had to ensure the Common Name was different between Client and Server. Otherwise it got angry and threw the above error. I gave you the check for leading me to the answer. Testing using your certs helped me cross off a lot of possible problems. Thanks again! – decoy Jan 04 '12 at 14:18
2

I had the same problem (under Nginx). Solution was to make my client common name something other than the server's certs common name. Originally I thought that my cert CN had to match the FQDN of the server cert..

EX:

Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:Minnesota
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:MyCo
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:Ryan Pendergast
Email Address []:me@gmail.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Signature ok
subject=/C=US/ST=Minnesota/O=MyCo/CN=Ryan Pendergast/emailAddress=me@gmail.com
rynop
  • 239
  • 4
  • 16
1

I too had this problem with nginx, similar to @rynop the solution turned out to be getting the naming right.

In my case, ensuring the organisation / common names for client CA and client cert were different got this resolved.

If the names are the same, nginx / openssl sees a self-signed cert, instead of one signed by a CA.

The following guide was helpful in setting up client cert authentication with nginx, and guides one toward using different names for CA and cert:

https://gist.github.com/mtigas/952344#convert-client-key-to-combined-pem

u-phoria
  • 111
  • 2