Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

verify server certificate against self-signed certificate authority

I have custom server/client applications that communicate to each other using an SSL-encrypted TCP connection (custom protocol). To setup the server certificate, I have created a self-signed certificate authority and used that to sign a certificate for the server to use. On the client side, I would like to verify that the certificate of the server I am connecting to was signed by my self-signed CA.

I was able to get this working in C++ with boost by giving the ssl::context the self-signed CA certificate using the load_verify_file() function. I would like to implement the same functionality in a C# client, but the .NET SSL stuff seems to be much more stringent about trusting certificates that are not in the Windows trust store.

I have found several partial solutions in my searching around so far. Apparently X509Chain is the class to use to verify SSL certificates. I have tried code like this but the manually created chain still complains that the root certificate is untrusted, just like the original chain that gets passed into the verification function. There is an option to ignore unknown certificate authorities, but that seems to mean that it will accept any self-signed certificate, which is definitely not what I want.

This is the code that seems to come closest to what I want, but as stated above, I have the problem that it still complains about the certificate I add to the ExtraStore being self-signed. Is there any way to convince X509Chain to trust the certificate I am giving it?

bool remoteCertificateValidationCallback(
    object sender, X509Certificate certificate, X509Chain chain,
    SslPolicyErrors sslPolicyErrors)
{
    // make sure certificate was signed by our CA cert
    X509Chain verify = new X509Chain();
    verify.ChainPolicy.ExtraStore.Add(secureClient.CertificateAuthority); // add CA cert for verification
    //verify.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority; // this accepts too many certificates
    verify.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; // no revocation checking
    verify.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
    if (verify.Build(new X509Certificate2(certificate)))
    {
        return true; // success?
    }
    return false;
}
like image 238
plasmoidia Avatar asked Dec 05 '14 01:12

plasmoidia


People also ask

How are certificates used to validate the authenticity of a server?

The web server sends a copy of the SSL certificate to the browser. The browser checks the authenticity of the certificate and sends a message to the webserver. In return, the webserver/website sends a digitally signed acceptance for initiating an SSL encrypted session.

How do you check if a certificate is a CA?

A Root CA will be a self signed certificate with the keyCertSign flag enabled. In most scenarios the common name may include the word CA for convenience. An intermediate CA certificate may be signed by a Root CA (or another Intermediate!). Your brower key store will have examples of commonly trusted CA certificates.


1 Answers

I suspect that your private CA certificate is not installed on the current system (where you run the code) or it is installed incorrectly. The root CA certificate MUST be installed in the Trusted Root CAs container of Computer stire, not in the current user store. By default, X509Chain uses computer store to lookup for trusted anchors.

Also, your code do not perform what you want. It will accept and pass for any publically trusted root CA. Instead, you need to compare the last element in the X509Chain.ChainElements, whether the contained certificate is the one you are expecting (by comparing thumbprint values). The foolowing fix should apply:

if (verify.Build(new X509Certificate2(certificate)))
{
    return verify.ChainElements[verify.ChainElements.Count - 1]
        .Certificate.Thumbprint == cacert.thumbprint; // success?
}
return false;

where cacert is your root CA certificate.

like image 122
Crypt32 Avatar answered Oct 23 '22 00:10

Crypt32