zmap / zlint

X.509 Certificate Linter focused on Web PKI standards and requirements.
https://zmap.io
Apache License 2.0
353 stars 107 forks source link

Lint to check for invalid KU lengths #686

Closed christopher-henderson closed 1 year ago

christopher-henderson commented 2 years ago

@aarongable since you're the one that thought of this lint

As per RFC 5280 Section 4.2.1.3 a key usage is a bit string with only eight possible flags.

      KeyUsage ::= BIT STRING {
           digitalSignature        (0),
           nonRepudiation          (1), -- recent editions of X.509 have
                                -- renamed this bit to contentCommitment
           keyEncipherment         (2),
           dataEncipherment        (3),
           keyAgreement            (4),
           keyCertSign             (5),
           cRLSign                 (6),
           encipherOnly            (7),
           decipherOnly            (8) }

This lint checks that, if a KU is present, that it's bitstring is exactly one byte long.

CBonnell commented 2 years ago

I believe there's 9 possible values as defined in X.509 08/2005 and RFC 5280, so it is possible to have a KU BIT STRING whose value component is 2 octets.

zakird commented 2 years ago

Nice catch @CBonnell. It does look that way to me too, even in the Enum in the description.

christopher-henderson commented 2 years ago

Yikes, that's an embarassing misstep. Thanks @CBonnell and @zakird!

I swapped up the lint to do the following instead:

  1. Map the byte contents to an int64.
  2. Check for any value >= 512.

My reasoning is that this lint is primarily enforcing that there are no unknown flags present. That is, it does not concern itself with what combinations of flags may-or-may not be valid vis-a-vis a particular requirement, but rather only that there are no 1 flags set beyond the 9th bit.