I have a certificate chain that looks like this: root CA -> intermediate CA -> client certificate
. How can I validate that a received certificate is explicitly created by "root CA"?
To validate the whole chain is not a problem. This can be done like this:
X509Certificate2 rootCert = new X509Certificate2(rootCertFile);
X509Certificate2 intermediateCert = new X509Certificate2(intermediateCertFile);
X509Certificate2 clientCert = new X509Certificate2(clientCertFile);
chain.ChainPolicy.ExtraStore.Add(rootCert);
chain.ChainPolicy.ExtraStore.Add(intermediateCert);
if(chain.Build(clientCert))
{
// ... chain is valid
}
The issue here is that the certificate gets validated against the (Windows) certificate store but I just want to validate it against a specific root CA.
I also thought that it would be possible to check if the chain.ChainElements
contains my expected root CA. But what if someone sends me a valid chain from a different root CA and just adds the my expected root CA?
The only you can verify is whether the certificate is valid for the usage at the requested level of certificate chain. If the certificate is the right one, it will be accepted, otherwise -- rejected.
You can check if the correct root certificate is installed by querying our platform using the following cURL command: curl --verbose https://live.cardeasexml.com/ultradns.php . If the connection is successful and verified by the root certificate, you will see the following entry below.
To verify a certificate, a browser will obtain a sequence of certificates, each one having signed the next certificate in the sequence, connecting the signing CA's root to the server's certificate. This sequence of certificates is called a certification path.
The certificate chain API checks that each element signed the preceding element, so there's no way that someone can just tack your root CA on the end (provided you're not using something like a 384-bit RSA key with MD5 signatures, in which case they can just forge your signature).
You can encode any extra checks that you like, such as that you know none of your chains will exceed length 3 (though you could just have encoded that in your root CA's X509 Basic Constraints extension).
if (!chain.Build(cert))
{
return false;
}
if (chain.ChainElements.Length > 3)
{
return false;
}
X509Certificate2 chainRoot = chain.ChainElements[chain.ChainElements.Length - 1].Certificate;
return chainRoot.Equals(root);
If you prefer the last line could be return root.RawData.SequenceEquals(chainRoot.RawData);
(ensure they have the same bytes).
Some things of note:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With