Question

Our application currently validates server certificates in unmanaged code using openssl (http://www.openssl.org/docs/crypto/X509_verify_cert.html). We are moving that into managed code. I have the X509 certificate being marshalled over into the managed side, but how to validate that certificate in C#?

a) Is there a simple way to validate that certificate against the currently installed trusted roots?

b) If not, what is the manual process to validate? Is it documented somewhere?

I've explored the classes in Mono.Security.X509, which gives me tools to work with certificates and stores, but I'm having trouble connecting the dots.


EDIT I added my ultimate solution below. I would welcome further feedback on the approach.

Was it helpful?

Solution

Based on the information here and here, I determine the following:

  • Ideally we should check certificate revocation, however this is non-trivial and seems to be not worth the effort
  • At a minimum we can check that the certificate is current and the chain is trusted
  • If we wish we can also validate application specific things like whether the certificate is self-signed, etc

For a simple example, we can use Mono X509Chain to build a certificate chain and validate it against the user trusted roots:

var x509 = new Mono.Security.X509.X509Certificate(certificateBytes);
var chain = new Mono.Security.X509.X509Chain();
bool certificateStatus = chain.Build(x509);

From examining the Mono source, I can see that this checks the trust on the certificate chain and also the dates on the certificate. Certificate revocation is not implemented, however.

We also check that the name on the cert matches the name of the host the user is connecting to. The .NET framework gives us an easy way to get that info:

var x5092 = new System.Security.Cryptography.X509Certificates.X509Certificate2(certificateBytes);
string hostName = x5092.GetNameInfo(System.Security.Cryptography.X509Certificates.X509NameType.DnsName, false);
bool hostNameMatch = string.Compare(hostName, this.Server, true) == 0;

Certificates can also have alternative names that should be checked, but using X509NameType.DnsAlternativeName doesn't seem to be implemented on Mono (it's hard-coded to return string.Empty).

As far as I can see this is a good, basic solution.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top