I'm tracking down the infamous "SSL exception" from a unit test - the same exception is generated running tests under ReSharper, the nunit from the console under my account, and on the build server integration tests. Locally, the code is running from a Windows 7 machine with .NET 4.5.1 installed.
System.Net.WebException : The request was aborted: Could not create SSL/TLS secure channel.
I am fairly certain it is not strictly related to certificates, although they have been recently updated. (The exact time of failure is close-ish, but not definite - on the other hand, this is the likeliest related change across the different environments.)
IIS is setup to require client certificates and the HTTPS connection to the same endpoint is "Green" in Chrome. If I choose an invalid client certificate in Chrome I get a 403 message from IIS served up over the successfully created HTTPS connection.
Questions:
Why does (how can) the secure SSL/TLS channel creation fail after the "handshake completed successfully"?
Is an HTTP 403 Forbidden status response, and possible WebClient processing of such, a factor at all? If not, this inquiry path can be abandoned.
What is a good next step in debugging the issue? Is there a certain monitorable event to indicate success (or failure) after the initial negotiation?
Here is what has been gathered while eliminating issues identified in other posts:
This is the end of the exception tree; there is no inner "The remote certificate is invalid according to the validation procedure" exception, which is what I would expect on a certificate error.
With 'all logging' for SCHANNEL enabled the server shows
An SSL server handshake completed successfully. The negotiated cryptographic parameters are as follows.
Protocol: TLS 1.0 / CipherSuite: 0x5 / Exchange strength: 2048
The SSL handshake/negotiation from the failing unit test 'looks successful' on Wireshark. (It's not identical to the Chrome request and has a different negotiated CipherSuite.)
The HTTP Client timeout is 100 seconds, which should be the default.
Slightly amusing, the first failing test is ShouldCompleteSslHandshakeFor[InvalidClientCert]
.
UPDATE: After looking at the local machine's event viewer (don't ask why this just occurred to me) there are corresponding entries for the failing connections:
(SCHANNEL) 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.
This would definitely be a valid reason for why the encrypted channel after the handshake fails.
Make sure the process accessing the client certificate has access to the certificate's private key.
MMC Console with the Certificate Plugin -> Right Click the specified certificate -> All Tasks -> Manage Private Keys.
Answers to my questions:
Why does (how can) the secure SSL/TLS channel creation fail after the "handshake completed successfully"?
The secure channel encryption can still fail after the handshake/negotiation phase, which only decides on what certs/crypto to use. In this case it was because the private key (on the client certificate) was not available due to a security restriction.
Is an HTTP 403 Forbidden status response, and possible WebClient processing of such, a factor at all? If not, this inquiry path can be abandoned.
No. The error is caused by failing SSL/TLS encryption, before the server handler is even invoked. It was a misguided question grasping at straws.
What is a good next step in debugging the issue? Is there a certain monitorable event to indicate success (or failure) after the initial negotiation?
Look in the relevant event logs - in this case that was the schannel logs for the local machine, where an critical error message was being reported. It is likely that the error would also have been found if enabling tracing as discussed here.
I tried everything here for that same message, and it turned out to be the security permissions on the MachineKeys folder (C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys) needed to be given to the users on the server. MSDN article with common solutions to this problem
User contributions licensed under CC BY-SA 3.0