8

Currently I'm writing a utility application that will connect to a given IP and port and check the information in the SSL certificate using HttpWebRequest. When I try to extract the certificate I get an error that an exception was thrown. The exception seems to be because the act of coping the SSL certificate seems to trigger yet another validation check.

Here is the code, and maybe someone can either show me a better way to do this or if I am missing something. I don't care if the SSL Certificate is expired or doesn't match the URL. None of that is relevant for what I'm doing.

When I assign the X509Certificate in the delegate to a new variable, and look at the variable in the debugger, all the properties show SSLCert.Issuer threw an exception of type 'System.Security.Cryptography.CyrptographicException'

When I try to access a property of SSLCert, I get the following Exception thrown: m_safeCertContext is an invalid handle

I'be searched for that exception, but everything points to an invalid certificate, which might be true if the certificate is expired, and might be true for the IP and port combination I am connecting to. But since I am connecting to the IP using the IP and not anything that would match the common name, I expect that and could care less as I still need the information.

The code is below, I put some comments in as well for what doesn't work and what does work.

 // 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; 
6
  • There are a lot of questions and answers here about working with SSL and certificates in HttpWebRequest. Have you looked at the "Related" questions to the right, or done a search for [ssl certificate httpwebrequest]? Commented Mar 11, 2011 at 16:13
  • 1
    Yes, pretty much everyone is asking how to use client certificates, which I am not using, or is getting an error within HttpWebRequest because of an invalid certificate, which I am already handling that. Commented Mar 11, 2011 at 16:19
  • I should add, the big problem is that I want to copy the X509Certificate to another X509Certificate type variable and .NET appears to be validating the certificate again when I do "this.SSLCert = certificate;" Commented Mar 11, 2011 at 16:23
  • What is the detailed exception thrown where your example fails? Please add it to your OP if you can... Commented Mar 11, 2011 at 16:25
  • I added more information with the exception and errors thrown. Commented Mar 11, 2011 at 16:42

2 Answers 2

1

This is just a guess on my part. WHat I think is happening is that the certificate info coming through in the SSL handshake is used by .NET to create a cert object that is passed to you in the delegate. The delegate is only to be used for the purpose of validation. After the call completes, .NET closes the safe handle of the certificate. 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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, this helped me (only needed a certificate property, so I assigned it to a class scoped variable from the delegate).
0

(Edit from our comments below)

I suppose what you need to do is create a custom class and store the data you need in it inside the delegate code, rather than pass around the actual certificate reference.

6 Comments

Unfortunately the same problem. While the delegate takes in a type of X509Certificate, the type actually passed in is an X509Certificate2 so I'm just casting it to what it is. Though I did try it and recheck, same problem.
Maybe try making a memberwise clone instead?
That's a good attempt, but oddly, I see the method as being a protected method on the MSDN site, but yet, it doesn't appear to be available for some reason. VS is highlighting it as an error and it won't compile. Also intellisense doesn't show it as a valid method.
Here is something interesting. When I am in the delegate and do the assignment, it shows fine for SSLCert, however, it doesn't seem to internally throw exceptions until after I exit from the delegate.
Oversight on my part (that MemberwiseClone is protected). I guess what you need to do is create a custom class and store the data you need in it inside the delegate, rather than pass around the actual certificate reference.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.