Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add a trusted CA certificate (NOT a client certificate) to HttpWebRequest?

I wrote a C# program that uses HttpWebRequest to connect to an HTTPS site. The GetResponse() method throws an exception:

SystemError: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.

I'm able to connect to the same website using curl.exe --cacert CAFile.pem. I'd like to be able use the same trusted CA certificates from the C# program.

How can I get HttpWebRequest to use this CA certificate file (or an X509CertificateCollection containing certificates parsed from it)?

like image 240
dan04 Avatar asked Feb 29 '12 23:02

dan04


People also ask

How do I manually add a trust certificate?

Expand Policies > Windows Settings > Security Settings > Public Key Policies. Right-click Trusted Root Certification Authorities and select Import. Click Next and Browse to select the CA certificate you copied to the device. Click Finish and then OK.

How do I import a trusted certificate?

Expand the Computer Configuration section and open Windows Settings\Security Settings\Public Key. Right-click Trusted Root Certification Authorities and select Import. Follow the prompts in the wizard to import the root certificate (for example, rootCA. cer) and click OK.

How do I pass a certificate in HTTP request?

You need to send the client certificate during the TLS handshake before anything HTTP (methods, headers, URLs, request bodies) is available to be influenced. The server will not accept a client certificate sent later.


1 Answers

Try setting your ServerCertificateValidationCallback to use this:

public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
    if (sslPolicyErrors == SslPolicyErrors.None)
    return true;

    X509Chain privateChain = new X509Chain();
    privateChain.ChainPolicy.RevocationMode = X509RevocationMode.Offline;

    X509Certificate2 cert2 = new X509Certificate2(certificate);
    X509Certificate2 signerCert2 = new X509Certificate2(@"C:\MyCACert.PEM");

    privateChain.ChainPolicy.ExtraStore.Add(signerCert2);       
    privateChain.Build(cert2);

    bool isValid = true;

    foreach (X509ChainStatus chainStatus in privateChain.ChainStatus)
    {
        if (chainStatus.Status != X509ChainStatusFlags.NoError)
        {
            isValid = false;
            break;
        }
    }

    return isValid;
}

I have not had an opportunity to test this, so let me know if you encounter any errors and I'll modify the answer if needed.

like image 185
JamieSee Avatar answered Oct 05 '22 09:10

JamieSee