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.