title: HTTPs Client to connect to server without trusted chain (non trusted CA) on Azure Web App
body: <p>I have been stuck for around 3 days trying to connect to a server that has a certificate which hasn't been signed by a trusted CA - you can add the CA's certificate through Azure Portal - but to no affect.</p>
  
  <p>apparently everything HTTP uses a kernel module (!) HTTP.SYS.</p>
  
  <p>All of the suggestions I have seen to override this either use:</p>
  
  <p><code>ServicePointManager.ServerCertificateValidationCallback = Communicator.CustomServiceCertificateValidation;
  </code></p>
  
  <p>(or its less global counterpart on the request itself)</p>
  
  <p>or something like this:</p>
  
  <pre><code> client.ClientCredentials.ServiceCertificate.SslCertificateAuthentication =
                   new X509ServiceCertificateAuthentication()
                   {
                       CertificateValidationMode = X509CertificateValidationMode.Custom,
                       RevocationMode = X509RevocationMode.NoCheck,
  
                       //TrustedStoreLocation = StoreLocation.CurrentUser,
                       CustomCertificateValidator = new PermissiveCertificateValidator()
  
                   };
  </code></pre>
  
  <p>yet, neither gets invoked!!</p>
  
  <p>Some more important details:</p>
  
  <p>This works:</p>
  
  <pre><code>  try
          {
              ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) =&gt; true;
              using (var wc = new WebClient())
              {
                  var res = wc.DownloadString("https://untrusted-root.badssl.com/");
                  return Content(res);
              }
          }
          catch (Exception ex)
          {
              return Content(ex.ToString());
          }
  </code></pre>
  
  <p>Yet, I need to authenticate myself with a client certificate - so, following the instructions found here:
  <a href="https://stackoverflow.com/questions/2066489/how-can-you-add-a-certificate-to-webclient-c?utm_medium=organic&amp;utm_source=google_rich_qa&amp;utm_campaign=google_rich_qa">How can you add a Certificate to WebClient (C#)?</a></p>
  
  <p>I end up with the following code:</p>
  
  <pre><code>class ATWebClient : WebClient
  {
      protected override WebRequest GetWebRequest(Uri address)
      {
          HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address);
          request.Headers.Add("SOAPAction", "https://servicos.portaldasfinancas.gov.pt/sgdtws/documentosTransporte/");
          X509Certificate2 cert = new X509Certificate2();
          //From user installed Certificates
          //cert.Import(_pathCertificate, _passwordCertificate, X509KeyStorageFlags.DefaultKeySet);
          //From FileSystem "Resources\Certificates"
          cert.Import(Common.Properties.Resources.testewebservices_novo, "TESTEwebservice", X509KeyStorageFlags.Exportable);
  
          // Output Certificate 
          //Utils.Log(string.Format("Cert Subject: [{0}], NotBefore: [{1}], NotAfter: [{2}]", cert.Subject, cert.NotBefore, cert.NotAfter));
  
          request.ClientCertificates.Add(cert);
          request.Method = "POST";
          request.ContentType = "text/xml; charset=utf-8";
          request.Accept = "text/xml";
  
  
          return request;
      }
  </code></pre>
  
  <p>And now I invoke the service with:</p>
  
  <pre><code>   try
      {
  
          ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) =&gt; true;
          ServicePointManager.CheckCertificateRevocationList = false;
          ServicePointManager.UseNagleAlgorithm = false;
          using (var wc = new ATWebClient())
          {
              //var res = wc.DownloadString("https://servicos.portaldasfinancas.gov.pt:701/sgdtws/documentosTransporte");
              var res = wc.UploadString("https://servicos.portaldasfinancas.gov.pt:701/sgdtws/documentosTransporte", "Test of content");
              return Content(res);
          }
  
  
      }
      catch (Exception ex)
      {
          return Json(ex);
      }
  </code></pre>
  
  <p>Note, yes, this is a SOAP endpoint - I tried sending valid SOAP content, yet the result is in both cases the same, I get the following exception:</p>
  
  <p><code>The underlying connection was closed: An unexpected error occurred on a send.</code></p>
  
  <p>Stacktrace:</p>
  
  <pre><code>   at System.Net.WebClient.UploadDataInternal(Uri address, String method, Byte[] data, WebRequest&amp; request)
     at System.Net.WebClient.UploadString(Uri address, String method, String data)
     at System.Net.WebClient.UploadString(String address, String data)
     at MagniWebApp.Controllers.HomeController.NonTrustedCATestEndpoint() in C:\Users\joao.antunes.Office2\source\repos\07. Platform\WebApp\MagniWebApp\Controllers\HomeController.cs:line 1154
  </code></pre>
  
  <p>Inner exception's message:</p>
  
  <p><code>
  Authentication failed because the remote party has closed the transport stream.
  </code></p>
  
  <p>Any ideas?!
  Halp!</p>