.NET: Disabling SSL Certificate validation
Yesterday I wanted to download some content off a website with F#, however unfortunately the certificate of the website was expired.
let result =
try
let request =
"https://somewebsite/with/expired/ssl/certificate/data.json?paramx=1¶my=2"
|> WebRequest.Create
let response =
request.GetResponse ()
// parse data
let parsed = "..."
Ok parsed
with
| ex ->
Error ex
If we execute this, then result would be of Error with the following exception:
ex.Message
"The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel."
ex.InnerException.Message
"The remote certificate is invalid according to the validation procedure."
So how do we fix this?
The solution is to set the following code at startup of the application (or at least before the first call):
ServicePointManager.ServerCertificateValidationCallback <-
new RemoteCertificateValidationCallback(fun _ _ _ _ -> true)
Notice that you should not do this, because this does not validate the certificate at ALL! Also, this is for ALL calls, if you want to do it on a specific call you need to do make some changes.
First of all, it doesn’t work with WebRequest.Create
, you need to use WebRequest.CreateHttp
, or cast the WebRequest
to HttpWebRequest
, as the property we need, ServerCertificateValidationCallback
is not available on WebRequest
, only on HttpWebRequest
. The resulting code looks like this:
let request =
"https://somewebsite/with/expired/ssl/certificate/data.json?paramx=1¶my=2"
|> WebRequest.CreateHttp
request.ServerCertificateValidationCallback <- new RemoteCertificateValidationCallback(fun _ _ _ _ -> true)
let response =
request.GetResponse ()
Again, don’t do this in production!
If need be, do it on a single HttpWebRequest
, like the last example, and write some code so that you ignore the expiration part, but leave in place the validation part.
Code on Github!