SSL Client certificate issues may be hard to troubleshoot. A list of common issues and troubleshooting methods is available in this (excellent) blog : Client Certificate revisited....How to troubleshoot client certificate related issues. In this article, we'll focus on the 403.7 error and more generally on troubleshooting tips in order to force a client certificate(s) to be displayed and understand what may cause client certificate(s) not to be displayed.
From my experience, there are 3 main reasons which may prevent client certificate(s) from being displayed :
- Default Internet Explorer configuration
- Invalid Key Usage (KU) or Enhanced Key Usage (EKU) in client certificate, missing private key or untrusted certificate
- Wrong IIS configuration (CTL)
Let's visit the above in details …
I – Default Internet Explorer configuration
By default, Internet Explorer doesn't display client certificates when only one certificate exists. In this scenario, the "unique" client certificate – when found - is silently sent to the web server. For troubleshooting purpose, I always disable this setting:
Note that the behavior of the above setting may vary depending on the Internet Explorer version used. Specifically, starting with Internet Explorer 8, If the user has no suitable client certificates, no prompt is shown, and no certificate is sent to the server (see the following blog for more details : Client Certificate Selection Prompt).
II - Invalid Key Usage (KU) or Enhanced Key Usage (EKU) in client certificate, missing private key or untrusted certificate
In order to be selected by Internet Explorer for client authentication, a client certificate needs to meet a couple of requirements
- Key Usage (KU), if present, must be "Digital Signed"
- Enhance Key Usage (KU), if present, must have OID "18.104.22.168.22.214.171.124.2"
- Client Certificate must be trusted and have a private key
Here an example of a certificate that will *not* be selected by Internet Explorer for client authentication:
In order to generate the above certificate, I've used the following (default) Certificate Server enrollment page :
Despite the fact that the "Type of Certificate Needed" is "Client Authentication Certificate", the CSP selected doesn't provide the ability to generate Key that can be used for "Digital Signature" (only "Key Exchange" can be chosen). Using another CSP allows to get the Signature Key Usage :
Here's a certificate generated using above form once installed on the client machine :
Further details on "interpretation" of Key Usage (KU) and Enhanced Key Usage (EKU) extensions can be found in the following KB article : Client certificates that contain the Key Usage (KU) extension may not be displayed or may be incorrectly displayed when you connect to a secure Web site in Internet Explorer 6 Service Pack 1. This article describes Internet Explorer's behavior when KU and/or EKU extensions are not present. The default behavior is the following : "A certificate is considered valid for SSL client authentication if no Key Usage extension is present, or is present and contains the Digital Signature bit. No Extended Key Usage extension is present, or is present and contains the Client Auth object identifier". This behavior may be changed using the FEATURE_CLIENTAUTHCERTFILTER registry key which still exists in Internet Explorer 9 but is only valid when running on pre-Windows7/R2 OS.
Back to our client certificate, It must obviously be trusted and to have a private key in order to be considered valid for client authentication:
So, the above client certificate should be selected by Internet Explorer unless the IIS/CTL configuration is wrong…
III - Wrong IIS/CTL configuration
Wrong IIS configuration is probably the most common cause for the 403.7 error. When SSL client authentication is configured, IIS sends a list of known Certificate Authorities (AKA Certificate Trust List, CTL, Issuer List…). This list is used by Internet Explorer to filter out client certificates that are "unknown" to the web server. For this reason, if you want a client certificate to be selected, you need to make sure that the Root Certificate used to sign the client certificate has been installed in the "Trusted Root" store for the Computer account on the IIS server :
If you don't have access to the server's configuration, it is possible to list the CTL using OpenSSL by typing the following command (commands to type are in bold, /samples/ssl/client is the directory I've configured for SSL client authentication) :
openssl s_client -connect yourservername:443 –prexit
Acceptable client certificate CA names
/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2006 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification
Starting with IE9 running on Windows 7 or Windows 2008 R2, STRACE also provide a way to dump the CTL/Issuer List . All you need to do is to download and install the STRACE tool from HERE, run STRACE.CMD and access your webserver configured for SSL Client authentication. Then, open the STRACE log on the desktop with notepad and search for "CertSelectCertificateChains" (if multiple STRACE logs are created, just open the last one). You should see tracing similar to this :
STRACE_IEXPLORE.LOG sample output
dwFlags : 00000088
cCriteria : 3
OID : 126.96.36.199.188.8.131.52.2
===== CERT_SELECT_BY_ISSUER_NAME <- this section will dump the CTL/issuer list as sent by the web server
Number of issuer(s) : 22
C=US, O="VeriSign, Inc.", OU=VeriSign Trust Network, OU="(c) 2006 VeriSign, Inc. - For authorized use only", CN=VeriSign Class 3 Public Primary Certification Authority - G5
C=US, O="VeriSign, Inc.", OU=Class 3 Public Primary Certification Authority
O=Entrust.net, OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.), OU=(c) 1999 Entrust.net Limited, CN=Entrust.net Certification Authority (2048)
O=Microsoft Corporation, CN=Microsoft Corporate Root CA
fCritical : FALSE
pszObjId : (null)
Value : 00000080
Number of certificates matching criteria(s) : 2
CertSelectCertificateChains exited with value : TRUE
The tracing above provides detailed information on Internet Explorer's client certificate selection process which is relying on the CertSelectCertificateChains API (starting with IE9 on Windows7/R2). In the above trace example, we can see the selection criteria required by Internet Explorer. Selected client certificate(s) must :
- have a private key (CERT_SELECT_HAS_PRIVATE_KEY flag is set)
- be issued by one of the 22 CAs listed in the CTL
- have the "Digital Signature" Key Usage (CERT_DIGITAL_SIGNATURE_KEY_USAGE flag set)
We can also notice that the CERT_SELECT_ALLOW_EXPIRED flag is not passed to the API which is the reason why no expired certificate is displayed. In the end 2 matching certificates were found and displayed by Internet Explorer.
Back to the CTL configuration, you may be aware that it is possible to create your own CTL and bind it to a web site. Doing this may be tricky (because MAKECTL doesn't work anymore on Windows 2008 R2 so you need to use it on a Windows 2003 server). Even if you succeed in constructing and binding a custom CTL to a web site, you'll have the terrible feeling that "it doesn't work". The reason for this is that the CTL is just added to the list of Root CAs sent by IIS. This behavior prevents using the CTL as a way to restrict client certificates to be displayed on the client. This problem is also detailed here: Certificate Trust List not being honored by IIS 5.0/6.0/7.0? As a workaround, it's possible to limit the CTL by changing the "Certificate Purpose" of the Root certificate(s) that you want to exclude (Limit the List of Certification Authorities allowed for Client Authentication). This has to be done in the Certificates MMC for the local computer account by unchecking the "Client Authentication" purpose for the CA that you want to exclude from the CTL:
The last "trick" I want to share is the SendTrustedIssuerList registry key. This registry key is documented here : Clients cannot make connections if you require client certificates on a Web site or if you use IAS in Windows Server 2003). It can be used to prevent IIS from sending a CTL which will cause Internet Explorer to display "unfiltered" list of client certificate. This can be useful to confirm/exclude assumptions regarding CTL content.
I hope I've covered most of the issues preventing a client certificate to be displayed. Hopefully, this blog – and the new STRACE tool feature - will save you some time when troubleshooting client certificate related issues!