SSLVerifyDepth explaination

7,549

Solution 1

As per my tests (see this comment) and this answer, the certificate chain verification in apache works like this:

current_certificate := client_certificate_from_request
current_depth := 0
LOOP
  if current_certificate IS self-signed (ie. root)
    if current_certificate IS IN SSLCACertificateFile
      THEN RETURN true // cert is accepted as valid
      ELSE RETURN false // validation failed
    end if
  end if

  current_certificate := current_certificate.getIssuer()
  current_depth += 1
  if current_depth > SSLVerifyDepth
    THEN RETURN false // validation failed
END LOOP // repeat

In words:

The final root certificate must be in the SSLCACertificateFile (or alternatively in SSLCACertificatePath) otherwise the client certificate is not accepted valid. The SSLVerifyDepth parameter limits how far the chain will apache look. If the limit is reached, the certificate is rejected.

The intermediate certificates listed in SSLCACertificateFile only affect building the chain (for example when the client does not send the full chain, so without those listed on the SSLCACertificateFile apache httpd would not have a way to reach the root certificate), but the validity depends only on the presence of the root certificate in SSLCACertificateFile.

Solution 2

https://httpd.apache.org/docs/2.4/mod/mod_ssl.html#sslverifydepth

... The depth actually is the maximum number of intermediate certificate issuers, i.e. the number of CA certificates which are max allowed to be followed while verifying the client certificate.
A depth of 0 means that self-signed client certificates are accepted only,
the default depth of 1 means the client certificate can be self-signed or has to be signed by a CA which is directly known to the server (i.e. the CA's certificate is under SSLCACertificatePath), etc.

A depth of 2 means that certificates signed by a (single level of) intermediate CA are accepted i.e. by an intermediate CA, whose CA certificate is signed by a CA directly known to the server.

Share:
7,549
David Balažic
Author by

David Balažic

Updated on September 18, 2022

Comments

  • David Balažic
    David Balažic almost 2 years

    Is there a comprehensive explanation how exactly does certificate chain verification work in apache httpd and how exactly does the SSLVerifyDepth parameter affect it? Possibly as pseudo-code.

    Most references just casually mention it.

    • garethTheRed
      garethTheRed almost 5 years
      RFC 5280 Section 6 covers the certificate chain verification procedure.
    • David Balažic
      David Balažic almost 5 years
      @garethTheRed I see no mention of verification depth there.
    • Steffen Ullrich
      Steffen Ullrich almost 5 years
      @DavidBalažic: just search for 'depth' in this section 6 and you'll find some. But the documentation clearly says: "The depth actually is the maximum number of intermediate certificate issuers, i.e. the number of CA certificates which are max allowed to be followed while verifying the client certificate....". If you don't understand this you likely don't understand how certificate validation works in general, i.e. the problem is not this parameter only.
  • David Balažic
    David Balažic almost 5 years
    If the client certificate is signed by an intermediate CA which is signed by a root (self-signed) CA, and apache has that intermediate CA in the SSLCACertificateFile, is the client certificate accepted as valid? At which values of SSLVerifyDepth?
  • HBruijn
    HBruijn almost 5 years
    Apache still only needs to follow 1 level when the certificate that signed a certificate is know to the server, regardless of whether the certificate known to Apache is an intermediate certificate, or not
  • David Balažic
    David Balažic almost 5 years
    I just tested with SSLVerifyDepth 1 and the intermediate certificate in SSLCACertificateFile and it does not accept the client certificate. apache version 2.2.10. It only accepts it if I also put the root CA into SSLCACertificateFile and set SSLVerifyDepth to 2 or more. So your claim is not true.