Our team regularly handles incidents dealing with SSL certificates. During the verification process for client (or server) SSL certificates, we tend to rely on the certificate UI to check if a given certificate has a valid private key. While doing some recent testing with the findprivatekey utility (http://msdn.microsoft.com/en-us/library/aa717039(v=vs.90).aspx ), I realized that trusting the UI was in fact a bad idea. Let's take a simple example of a client certificate used for SSL client authentication:
Given the certificate's thumbprint above, the findprivatekey utility allows us to display the private key location:
findprivatekey My CurrentUser -t "e3 bd c8 d3 0c c0 63 c6 89 68 3f 84 d0 dc af 62 41 0c 8c 53"
Private key directory:
C:\Users\emmanubo\AppData\Roaming\Microsoft\Crypto\RSA\S-1-5-21-1721254763-462695806-1538882281-36999
Private key file name:
7f00fa7302a28c328d1c0e78d51b744d_73d0bc64-45a4-4161-9a00-d6ffb76163e3
As an "experiment", let's rename the private key file:
Cd C:\Users\emmanubo\AppData\Roaming\Microsoft\Crypto\RSA\S-1-5-21-1721254763-462695806-1538882281-36999
C:\Users\emmanubo\AppData\Roaming\Microsoft\Crypto\RSA\S-1-5-21-1721254763-462695806-1538882281-36999>attrib 7f00fa7302a 28c328d1c0e78d51b744d_73d0bc64-45a4-4161-9a00-d6ffb76163e3 –s
C:\Users\emmanubo\AppData\Roaming\Microsoft\Crypto\RSA\S-1-5-21-1721254763-462695806-1538882281-36999>ren 7f00fa7302a 28c328d1c0e78d51b744d_73d0bc64-45a4-4161-9a00-d6ffb76163e3 *.sau
Surprisingly, the certificate's UI still shows that "You have a private key that corresponds to this certificate"!
And if we try to use the above client certificate in Internet Explorer for SSL client authentication, we'll just get a generic failure after selecting the client certificate:
A network trace shows that client resets the TCP connection during the SSL handshake (instead of passing the client certificate to the server).
If you open a support incident with Microsoft, the support team will likely ask you to gather an ETL trace for schannel:
logman -start schannel -p {37D2C3CD-C5D4-4587-8531-4696C44244C8} 255 3 –ets
<reproduce the problem>
logman -stop schannel -ets
And the etl produced will point that the private key is missing:
[abstract of parsed schannel.etl]
…
[4] 02BC.0308::06/14/2012-14:06:28.314 A fatal error occurred when attempting to access the SSL client credential private key. The error code returned from the cryptographic module is 0x8009030D. The internal error state is 10003.
[4] 02BC.0308::06/14/2012-14:06:28.314 [sslproto] Credential_cpp191 CSslCredential::CreateCredential() - GetPrivateFromCert() FAILED: 0x8009030d
…
Conclusion: for basic SSL troubleshooting, consider using findprivatekey or certutil to check that certificate's private key exists:
findprivatekey My CurrentUser -t "e3 bd c8 d3 0c c0 63 c6 89 68 3f 84 d0 dc af 62 41 0c 8c 53"
FindPrivateKey failed for the following reason:
Unable to obtain private key file name
certutil -v -user -store My "e3 bd c8 d3 0c c0 63 c6 89 68 3f 84 d0 dc af 62 41 0c 8c 53"
My
================ Certificate 1 ================
X509 Certificate:
Version: 3
Serial Number: 61580f4d000000000006
…
Missing stored keyset
We hope the above tricks will save you precious time!
Emmanuel