I have to validate several SSL certificates in a none-browser application for HttpRequests
and websocket
connections which should run on IOS, Android and Linux.
When a connection via HTTPS
happens I receive an array of X509Certificate2
objects where the bottom one is the server certificate and the most top one the root CA (hopefully). As an example, when I connect to https://google.com
I receive 3 X509Certificate2
with the following SubjectName.Name
:
- 0 :
"CN=google.com, O=Google Inc, L=Mountain View, S=California, C=US"
- 1 :
"CN=Google Internet Authority G2, O=Google Inc, C=US"
- 2 :
"CN=GeoTrust Global CA, O=GeoTrust Inc., C=US"
I now need to verify the certificate validation with the given information and the following verifications:
- Chain-of-trust verification
- Hostname verification
- Certificate revocation verification
What I tried and not understood and failed:
When I call the X509Certificate2.Verify()
method on each certificate independently it returns false
everytime. I also do not understand why it can return anything else then false
because the verification happens independently. Instead the complete chain, meaning all certificates, should be checked as far as I understood the theory.
I then used the X509Chain
class:
foreach (X509Certificate2 cert in allthreecerts)
{
X509Chain chain = new X509Chain();
X509ChainPolicy chainPolicy = new X509ChainPolicy()
{
RevocationMode = X509RevocationMode.Offline,
RevocationFlag = X509RevocationFlag.EntireChain
};
chain.ChainPolicy = chainPolicy;
if (!chain.Build(cert))
{
foreach (X509ChainElement chainElement in chain.ChainElements)
{
foreach (X509ChainStatus chainStatus in chainElement.ChainElementStatus)
{
Debug.WriteLine(chainStatus.StatusInformation);
}
}
}
}
This prints out RevocationStatusUnknown
and OfflineRevocation
for each certificate.
Again, I do not understand why this should work since a chain is build which each certificate independently. Should not be the parent certificate be the Issue of the child certificate all down to the root CA?
What I think I need somehow but do not know how.
In order to verify the certificate revocation all clients need to provide a certificate revocation list. Where do I get such a list and where to I load it and tell the chain to use this local list?
The same problem is the Chain-of-trust verification since the last certification should be a root certification and must be one of the clients trusted root CA's. So I have to load, for example, all root CA which are shipped with Firefox and check if the root CA is one of them? What is the best way to do that?
[Update]
I made a copy paste mistake in the google.com
example where I pasted two identical certificate subject names.