4

I have a CA hierarchy like this:

               Root-CA
          ________|_____________
         |                      |
      TEST-CA             PRODUCTION-CA
    _____|_____             ____|____
   |           |           |         |
TEST-SRV   TEST-CLI    PROD-SRV   PROD-CLI

From the perspective of the production server identified by the PROD-SRV server certificate, how would I setup Apache mod_ssl to require the PROD-CLI client certificate signed by the PRODUCTION-CA and not allow a client with the TEST-CLI certificate signed by the TEST-CA?


Currently I have:

SSLCertificateFile      prod_srv.crt
SSLCertificateKeyFile   prod_srv.pem
SSLCADNRequestFile      prod_ca.crt
SSLCACertificateFile    root_ca.crt

This looks like it is working because the server asks the browser for the PROD CLI certificate but if I provide TEST CLI certificate a valid certificate path is constructed and a test client is accepted onto the production system.

2

Look into the SSLRequire directive - the following rule should look at the Issuer field (i.e. the CA certificate) of the certificate presented, pick out the CN, and match it against the name of your PRODUCTION-CA certificate.

SSLRequire %{SSL_CLIENT_I_DN_CN} == "PRODUCTION-CA"
  • Thanks meulop! This solution works when SSLVerifyClient is set to optional. I was hoping there would be a way to implement this simply through defining trust, making the chain validation fail without explicitly checking parts of the certificates. If nobody provides such a solution I shall accept yours in a few days. I appreciate your help! – moosaka Mar 6 '12 at 12:24
  • Is this solution vulnerable to implicit trust attacks? (i.e. if someone manages to obtain a CA certificate you trust, with the name PRODUCTION-CA.) Can you check against a specific public key here, or maybe there is some other way to tell Apache "only trust certificates issued by this specific CA certificate"? – mpontillo Jun 12 '12 at 1:02
  • Never mind. Looks like you'd do it with SSLCACertificateFile set to PRODUCTION-CA. And in your case this might be fine because you have root_ca.crt (your own) specified in the configuration. I was worried about implicit trust from a public CA. I guess from a general security perspective it's better to trust less, so why not use the production CA and just exclude everything else? – mpontillo Jun 12 '12 at 1:07
0

I wanted to authenticate clients with certs issued by sub-CAs of an intermediate CA, i.e. like the following:

               Root-CA
                  |
            Intermediate-CA
          ________|_____________
         |                      |
      SUB-CA 1               SUB-CA 2
    _____|_____             ____|____
   |           |           |         |
TEST-SRV   TEST-CLI    PROD-SRV   PROD-CLI

You can use the SSL_CLIENT_CERT_CHAIN_n variable to inspect the chain, and e.g. do the following:

SSLRequireSSL
SSLVerifyClient require
SSLCACertificateFile ".../root-ca.cert.pem"
Require expr %{SSL_CLIENT_CERT_CHAIN_1} == file(".../intermediate.cert.pem")

or even multiple first-level intermediate CAs:

Require expr %{SSL_CLIENT_CERT_CHAIN_1} in { file(`".../intermediate.cert.pem"), file(".../intermediate2.cert.pem") }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.