tags:

views:

46

answers:

1

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!

+1  A: 

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.

Bruno
Thanks, that was what I was sort of info I looking for. Just a quick Q, about first hint (comparing cert data to byte[]) - do I need to compare known valid cert's byte array to the one I'm verifying?
mr.b
I think the byte array is going to be the certificate in DER encoding, so you should probably compare that to your reference certificate in DER format (many tools, including the Windows certificate tool can export to that format). You might even be able to load this from the certificate store directly (not sure how).
Bruno