Oct 21, 2011

SSL certificate handshake and web service error: The Underlying Connection Was Closed. Could Not Establish Trust Relationship with Remote Server

In SSL, Client and Server authenticate each other's certificate. The handshake process is illustrated as follows:
Note: It is optional for Server to authenticate Client's certificate. It is configurable in IIS site->SSL Settings. By default it is "ignore". In a rare occasion client certificate is "required", the handshake will fail if  client certificate is not present and you will get "403.7 Forbidden " error in browser. In ASP .Net Web code, some people suggest getting around this by sending client certificate to server, but I have not tried it.

On the other side, Client is always required to authenticate server's certificate. Browser will popup a security alert when  server certificate is not valid/trusted. you can depress the alert by installing the certificate into both "Personal" and "Trusted Root Certificate Authority" locations in client machine's certificate store.

you can check the store by MMC->Add Snap-in->Certificate-> My User(Computer) Account.


Things are different if you call SSL web service from .Net ASP Web. you often get this error:
The Underlying Connection Was Closed. Could Not Establish Trust Relationship with Remote Server

The reason is the computer maintains two different certificate stores:
  • The local machine store: An ASP.NET Web application looks in this store to locate client certificates.
  • The local user store: An interactive user application looks in this store to locate client certificates.
So, in order to solve above error in .Net code, you will need to import the same server certificate into Local Machine Store on both "Personal" and "Trusted Root Certificate Authority" location. Also you need to grant  the service account running ASP .Net Web has sufficient right to access the Local Machine Store. ( using local admin right is not good idea, but good enough to run a test). See here for details.


Another workaround  which are quite "popular", but bad, is to bypass security handshake totally. See here for details. the killer is System.Net.ServicePointManager.ServerCertificateValidationCallback += delegate { return true; };