Ssl – How to get a client certificate chain during a certificate auth with Apache

apache-2.4authenticationcertificatessl

I'm trying to configure an Apache 2.4.29 server as an SSL terminating reverse proxy for my app. The proxy should request a client certificate during the SSL handshake and pass it to the app for validation. I use the next virtual host configuration:

<VirtualHost *:443>
# Default settings
    DefaultType none

    RewriteEngine on
    AllowEncodedSlashes on

    RewriteCond %{QUERY_STRING} transport=polling
    RewriteRule /(.*)$ http://127.0.0.1:8088/$1 [P]

    ProxyRequests off

    ProxyPass "/" "http://127.0.0.1:8088/"
    ProxyPassReverse "/" "http://127.0.0.1:8088/"

    RequestHeader set X-Forwarded-Proto "https"
# Default settings

# SSL settings
    SSLEngine On
    # A file with certificate data in PEM format
    # https://httpd.apache.org/docs/2.4/mod/mod_ssl.html#sslcertificatefile
    SSLCertificateFile "/path/to/server-chain.cert.pem"
    # The PEM-encoded private key file for the server
    # https://httpd.apache.org/docs/2.4/mod/mod_ssl.html#sslcertificatekeyfile
    SSLCertificateKeyFile "/path/to/server.key.pem"
# SSL Settings

# Client certificate auth settings
    SSLOptions +ExportCertData
    SSLCACertificateFile "/path/to/ca.cert.pem"
    # Enable client certificate authentication
    SSLVerifyClient optional_no_ca
    # Specify the max depth of the certificate chain
    SSLVerifyDepth 3

    # Add the client certificate to the request header
    #RequestHeader set SSL_CLIENT_CERT "%{SSL_CLIENT_CERT_CHAIN_3}s"
    RequestHeader set SSL_CLIENT_CERT "%{SSL_CLIENT_CERT}s"


# Client certificate auth settings

</VirtualHost>

Bits of clarification:

  • the server certificate is issued by an intermediate CA
  • I composed the server-chain.cert.pem to contain the whole chain from the server certificate to the CA certificate
  • client certificates are issued by a nested intermediate CA

CA
intermediate CA 1
server certificate
intermediate CA 2
client certificate A
client certificate B

The config works fine and I'm able to get the client certificate from the SSL_CLIENT_CERT header of an incoming request to my app.

The next step is a validation of the client certificate. I suppose I need the whole client certificate chain for that. But I get only the leaf client certificate in the header. When I try to use SSL_CLIENT_CERT_CHAIN_n variable to set the header in my Apache configuration I get (null) as the header's value no matter what n I use.

Please suggest a way to get the whole client certificate chain from the leaf client certificate to a parent certificate specified in the SSLCACertificateFile directive.

Best Answer

In order to verify the client certificate the server needs the full certificate chain, since it. If you set SSLCACertificateFile then these are the CA certs that are sent to the client, but they should not contain the intermediate cert. You will need to use the more cumbersome SSLCACertificatePath as well, to set the intermediate CA certs.