How to use SSL certificates with HttpWebRequest in C #?

I am currently writing a utility application that will connect to this IP port and verify the information in the SSL certificate using HttpWebRequest. When I try to extract the certificate, I get an error. The exception, apparently, is that the SSL certificate help action seems to trigger another validation check.

Here is the code, and maybe someone can show me the best way to do this or if I missed something. I don't care if the SSL certificate has expired or does not match the URL. None of this is relevant to what I am doing.

When I assign a new variable to X509Certificate and look at the variable in the debugger, all properties show SSLCert.Issuer throws an exception like "System.Security.Cryptography.CyrptographicException"

When I try to access the SSLCert property, I get the following exception: m_safeCertContext is an invalid handle

I searched for this exception, but everything points to an invalid certificate, which may be true if the certificate has expired, and may be true for the IP and port combination to which I connect. But since I am connecting to IP using an IP address, rather than matching a common name, I expect this to be less since I still need the information.

Below is the code, I also added some comments for what does not work and what works.

// To get around the SSL validation in the HttpWebRequest System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors) { // The below works but isn't what I want. CertName and ExpireDate are both Strings this.CertName = ProcessSubject(certificate.Subject); this.ExpireDate = certificate.GetExpirationDateString(); // The below works but the X509Certificate SSLCert shows exceptions in the debugger for most of the properties. this.SSLCert = certificate; return true; // **** Always accept }; HttpWebRequest myRequest = (HttpWebRequest)System.Net.WebRequest.Create("https://" + this.IP + ":" + this.Port + "/SSLCheck.html"); myRequest.KeepAlive = false; myRequest.Method = "GET"; try { HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse(); } catch (Exception e) { if (e.Message != "The remote server returned an error: (404) Not Found.") { throw Exception("Error"); } } // THE BELOW FAILS this.CertName = this.SSLCert.Subject; 
+8
c # ssl x509certificate x509
source share
2 answers

(Edit our comments below)

I believe that you need to create your own class and store the data that you need inside it in the delegate code, and not pass the actual certificate reference.

0
source

This is just a guess on my part. What I think is happening is that the certificate information passing through the SSL handshake is used by .NET to create a cert object that is passed to you in the delegate. The delegate should be used for verification purposes only. When the call completes, .NET closes the secure certificate descriptor. That is why the call fails when trying to access the certificate outside the callback.

To get around this, you can serialize the certificate inside the delegate and deserialize it outside the delegate.

+1
source

All Articles