codeape
codeape

Reputation: 100786

SSL certificate validation - is any caching involved?

The case:

The problem is now that we still get the same exception on the client: "The remote certificate is invalid according to the validation procedure".

My question:

Update: We restarted the client process, and then it works. To me this indicates that some SSL server certificate verification status is cached on the client, per process. I would still very much like to find out more about the details of this: On what level of the stack does this occur? WCF? .NET? Windows API? For how long is this cached? Is there any way to adjust the caching behavior? Can I manually empty the cache? Is this documented somewhere?

Full stack trace:

[E0]: The remote certificate is invalid according to the validation procedure. 
[T0]: System.Security.Authentication.AuthenticationException    at 
System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, 
AsyncProtocolRequest asyncRequest, Exception exception)     at 
System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] 
buffer, AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)  
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext 
executionContext, ContextCallback callback, Object state, Boolean 
preserveSyncCtx)     at System.Threading.ExecutionContext.Run(ExecutionContext 
executionContext, ContextCallback callback, Object state, Boolean 
preserveSyncCtx)     at System.Threading.ExecutionContext.Run(ExecutionContext 
executionContext, ContextCallback callback, Object state)     at 
System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result)     at 
System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size)     at 
System.Net.ConnectStream.WriteHeaders(Boolean async) [E1]: The underlying 
connection was closed: Could not establish trust relationship for the SSL/TLS 
secure channel. [T1]: System.Net.WebException    at 
System.Net.HttpWebRequest.GetResponse()     at 
System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannel
Request.WaitForReply(TimeSpan timeout) [E2]: Could not establish trust 
relationship for the SSL/TLS secure channel with authority 
'***removed***'. [T2]: 
System.ServiceModel.Security.SecurityNegotiationException 

Upvotes: 4

Views: 3221

Answers (1)

C B
C B

Reputation: 647

I ran into the same issue. I was validating TLS with a local Root CA cert. If I deleted the cert from the store, successive requests (using HttpWebRequest) continued to validate if made the call every few seconds. But if I waited a short time (30-60 seconds), the next call would fail because it couldn't find the root cert.

Set the HttpWebRequest.KeepAlive property to false to prevent the caching. To get any more control, it looks like you'd have to start reflecting down. See the question How to clear the client-side .Net SSL session cache.

Upvotes: 5

Related Questions