Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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);
like image 889
savagepanda Avatar asked Nov 01 '25 15:11

savagepanda


2 Answers

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.

like image 196
Crypt32 Avatar answered Nov 04 '25 04:11

Crypt32


You can verify the chain manually as you are doing without the Key Encipherment check. Then, you can manually check if the certificate has a Key Encipherment usage.

Use the following code to check the key usage:

static public bool UsageHasKeyEncipherment(X509Certificate2 tmpCert)
{

    foreach (X509KeyUsageExtension usage_extension in tmpCert.Extensions.OfType<X509KeyUsageExtension>())
    {
        if ((usage_extension.KeyUsages & X509KeyUsageFlags.KeyEncipherment) == X509KeyUsageFlags.KeyEncipherment)
        {
            return true;
        }
    }

    return false;
}
like image 37
Yacoub Massad Avatar answered Nov 04 '25 05:11

Yacoub Massad



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!