Search code examples
c#.netx509certificate2

How do I verify Certificate for KeyUsage


I'm trying to validate certificate to make sure it has the right keyUsage. But don't see how I can specify my X509KeyUsageFlags.KeyEncypherment usage flag into this application policy.

This is the code I have so far. Any one else got this to work?

X509Certificate2 tmpCert = new X509Certificate2(Cert);

X509Chain ch = new X509Chain();
ch.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
ch.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;

var kUsage = new System.Security.Cryptography.Oid("2.5.29.15");                    
ch.ChainPolicy.ApplicationPolicy.Add(kUsage);

bool success = ch.Build(tmpCert);

Solution

  • KeyUsage extension is not a part of the chain, as there are no constraints to this extension. As the result, you need two separate procedures

    1. validate certificate chain
    2. validate single certificate(s) in the chain for other requirements.

    The code provided by @Yacoub lacks an important outcome: when Key Usage extension is not presented in the certificate. In this case, the key is assumed to be valid for all usages, except certKeySign and cRLSign usages for all type of V3 certificates. In the case of V1 or V2 certificate, the absence of KeyUsage extension literally means all usages.

    I would propose the following code:

    using System.Linq;
    using System.Security.Cryptography.X509Certificates;
    // there should go namespace and class definition
    ...
    //
    public bool KeyUsageHasUsage(X509Certificate2 cert, X509KeyUsageFlags flag) {
        if (cert.Version < 3) { return true; }
        List<X509KeyUsageExtension> extensions = cert.Extensions.OfType<X509KeyUsageExtension>().ToList();
        if (!extensions.Any()) {
            return flag != X509KeyUsageFlags.CrlSign && flag != X509KeyUsageFlags.KeyCertSign;
        }
        return (extensions[0].KeyUsages & flag) > 0;
    }
    

    it is implemented as an universal function to validate arbitrary key usage flag.