SSLVerifyDepth explaination
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.
David Balažic
Updated on September 18, 2022Comments
-
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 almost 5 yearsRFC 5280 Section 6 covers the certificate chain verification procedure.
-
David Balažic almost 5 years@garethTheRed I see no mention of verification depth there.
-
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 almost 5 yearsIf 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 almost 5 yearsApache 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 almost 5 yearsI 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.