Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Verify remote SSL certificate during HTTPS request

Tags:

c#

.net

https

ssl

When making HTTPS request to remote web server, I use WebRequest, which establishes secure connection with remote web server. During development, I use self-signed cert on server, and WebRequest fails to establish secure connection, since cert is not valid, which is expected behavior.

I have found this code that "remotes" cert check, activated by calling SetCertificatePolicy() method in following code.

public static void SetCertificatePolicy()
{
    ServicePointManager.ServerCertificateValidationCallback
                += RemoteCertificateValidate;
}

/// <summary>
/// Remotes the certificate validate.
/// </summary>
private static bool RemoteCertificateValidate(
    object sender, X509Certificate cert,
    X509Chain chain, SslPolicyErrors error)
{
    // trust any certificate!!!
    System.Console.WriteLine("Warning, trust any certificate");
    return true;
}

I am wondering, if it is possible to do special checks on remote SSL cert (using above code, for instance), so that I can verify that remote web server uses valid SSL cert, and not just any valid cert, but exactly the one I want? For instance, I want to make sure that I'm talking to www.someplace.com website, cert issued to ACME Inc, with fingerprint 00:11:22:.....

What is a "best practice" approach for this scenario?

Thanks!

like image 578
mr.b Avatar asked Jun 23 '10 12:06

mr.b


People also ask

Does curl check SSL certificate?

libcurl performs peer SSL certificate verification by default. This is done by using a CA certificate store that the SSL library can use to make sure the peer's server certificate is valid.

Which command line tools could you use to get the SSL certificate information from a remote HTTPS website?

Keytool. Keytool² is another excellent tool used to analyze and extract data from a remote SSL certificate.


1 Answers

If you really want to nail it down to one particular certificate, you can compare the certificate data (in DER format) to the byte[] in certificate.GetRawCertData().

You can also use GetCertHashString() and Subject on the certificate parameter in RemoteCertificateValidate to get the information you're after. The hostname ought to be in the subject alternative name of the certificate or, if there isn't a subject alternative name, in the CN of the subject (distinguished) name. Considering the way .NET formats the subject string, this ought to be the first CN= you find there.

You'll also get more data if certificate is an instance of X509Certificate2. You'll then be able to get SubjectName as an X500PrincipalName and also the Extensions (to check the subject alternative name extension). It might be useful to use tools such as BouncyCastle for parsing the subject name.

You're also likely to get more information about the hostname you're trying to contact in the sender, depending on its runtime type.

like image 197
Bruno Avatar answered Oct 23 '22 16:10

Bruno