ASP.NET and The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel

certificatecocoahttpserverhttpsssl

I'm making an httpwebrequest using a public Root authority Certificat file X509. I only have the public key, not the private key. Everything works fine from a Console app but it does not work from an asp.net app. I get the error: "The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel."

The option to disable Validation is not an option.

Here is the code

HttpWebRequest req = (HttpWebRequest)WebRequest.Create("https://xxxxxxx/gateway.aspx");
string post = "abcdef";
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
req.ContentLength = post.Length;

var cert = System.Security.Cryptography.X509Certificates.X509Certificate.CreateFromCertFile(@"c:\temp\root.cer");

req.ClientCertificates.Add(cert);
StreamWriter stOut = new StreamWriter(req.GetRequestStream(), System.Text.Encoding.ASCII);
stOut.Write(post.ToString());
stOut.Close();

HttpWebResponse resp = (HttpWebResponse)req.GetResponse();

Here is the System Logs from System.Net and System.Net Sockets.

System.Net Information: 0 : [5928] SecureChannel#8106798 – A certificate chain could not be built to a trusted root authority.

System.Net Information: 0 : [5928] SecureChannel#8106798 – Remote certificate was verified as invalid by the user.

System.Net.Sockets Verbose: 0 : [5928] Socket#7486778::Dispose()

System.Net Error: 0 : [5928] Exception in the HttpWebRequest#51319244:: – The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.

System.Net Error: 0 : [5928] Exception in the HttpWebRequest#51319244::EndGetRequestStream – The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.

Further info

If I use this code (from CodeGuru)

  public static bool ValidateServerCertificate(object sender,
     X509Certificate certificate, X509Chain chain,
     SslPolicyErrors sslPolicyErrors)
  {
     if (sslPolicyErrors ==
        SslPolicyErrors.RemoteCertificateChainErrors) {
        return false;
     } else if (sslPolicyErrors ==
        SslPolicyErrors.RemoteCertificateNameMismatch) {
        System.Security.Policy.Zone z =
           System.Security.Policy.Zone.CreateFromUrl
           (((HttpWebRequest)sender).RequestUri.ToString());
        if (z.SecurityZone ==
           System.Security.SecurityZone.Intranet ||
           z.SecurityZone ==
           System.Security.SecurityZone.MyComputer) {
           return true;
        }
        return false;
     }
     return true;
  }

I ultimately get the error:

Remote Certificate Chain Error

Best Answer

This problem can be fixed with this added to Application_Start:

ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;

It basically allows for a mismatch between the server and its certificate.

Source:

http://www.ben-morris.com/asp-net-web-services-and-ssl-certificates-establishing-a-trust-relationship

Note: This workaround is not recommended for production