简体   繁体   中英

Distinguish between Root CA and Intermediate CA Certificate

I have managed to figure out if a cert in a x509Certificate2Collection is a certificate authority cert but how can I safely determine if it's a Root cert or an Intermediate cert please? Is the following safe enough?

var collection = new X509Certificate2Collection();
collection.Import("test.pfx", "password", X509KeyStorageFlags.PersistKeySet);

foreach (X509Certificate2 cert in collection)
{
    var basicConstraintExt = cert.Extensions["2.5.29.19"] as X509BasicConstraintsExtension;
    if (basicConstraintExt != null)
    {
        Log.Debug($"    Subject is: '{cert.Subject}'");
        Log.Debug($"    Issuer is: '{cert.Issuer}'");
        if (basicConstraintExt.CertificateAuthority)
        {
            Log.Debug("I am a CA Cert.");
            if (cert.Subject == cert.Issuer)
            {
                Log.Debug("My Subject matches Issuer.");
            }
            else
            {
                Log.Debug("My Subject does not match Issuer.");
            }
            Log.Debug(cert.Verify() ? "I verify" : "I do not verify");
        }
        else
        {
            Log.Debug("I am not a CA Cert.");
        }
    }
}

Results:

 Displaying Cert #1 in collection
 ********************************

 Subject is: 'CN=Intermediate-CA, DC=test, DC=lan'
 Issuer is: 'CN=Root-CA, DC=test, DC=lan'
 - I am a CA Cert.
 - My Subject does not match Issuer.
 - I do not verify


 Displaying Cert #2 in collection
 ********************************

 Subject is: 'CN=Root-CA, DC=test, DC=lan'
 Issuer is: 'CN=Root-CA, DC=test, DC=lan'
 - I am a CA Cert.
 - My Subject matches Issuer.
 - I do not verify

Not sure if this helps with Kestrel, but I would try the code below.

We will use X509Chain class to construct and validate the chain.

var collection = new X509Certificate2Collection();
collection.Import("test.pfx", "password");

var chain = new X509Chain();
chain.ChainPolicy.ExtraStore.AddRange(collection);
// untrusted root error raise false-positive errors, for example RevocationOffline
// so skip possible untrusted root chain error.
chain.VerificationFlags |= X509VerificationFlags.AllowUnknownCertificateAuthority;
// revocation checking is client's responsibility. Skip it.
chain.RevocationMode = X509VerificationFlags.NoCheck;
// build the chain.
Boolean isValid = chain.Build(collection[0]);
// explore chain.ChainElements collection. First item should be your leaf
// certificate and last item should be root certificate

All this stuff is located in System.Security.Cryptography.X509Certificates namespace. In this code piece, I'm assuming that first certificate in PFX is leaf certificate (it is in 99% cases unless someone tries to ignore standards). By exploring chain.ChainElements collection, you can find issues with every certificate in the chain.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM