Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ISSUE: lint "e_key_usage_and_extended_key_usage_inconsistent" in technically constrained CA certificates #593

Open
sandorszoke opened this issue Apr 30, 2021 · 11 comments

Comments

@sandorszoke
Copy link

Short Summary

As part of a wider test we checked all of our CA certificates by Zlint ver.3.0.0 (?) and we could identify a potential issue with different types of technically constrained CA certificates.

Some of the certificates with this potential issue

CA Type Common Name crt.sh link
Code Signing e-Szigno Class2 CodeSigning CA 2020 https://crt.sh/?id=3302241234
Code Signing e-Szigno Class3 CodeSigning CA 2020 https://crt.sh/?id=3302241235
Time Stamping e-Szigno TSA CA 2020 https://crt.sh/?id=3302241237
Time Stamping e-Szigno TSA CA 2020 https://crt.sh/?id=3302241238

The summarized result of the zlint test

Each certificate has the following summarized test result.

LEVEL # OCCURRENCES DETAILS
info 0 -
warn 0 -
error 1 e_key_usage_and_extended_key_usage_inconsistent
fatal 0 -

The scope of lint "e_key_usage_and_extended_key_usage_inconsistent"

When we tried to find details about this lint we realized that this lint has already been removed from Zlint, at least temporarily.
Some corresponding issues are:

#497
#528
#553
#556
#557

As I see there is no common agreement on this requirement so let me summarize our findings.

Our interpretation

  • Originally, RFC5280 introduced the EKU to further specify the use of the public key included in the certificate.
  • The EKU is intended to be used primarily for end-entity certificates, but it may also be used for Subordinate CA certificates.
  • The KU and EKU settings shall be consistent.
  • There are no different requirements for Subordinate CA and end-entity certificates.
  • Currently EKU is widely used in CA certificates to technically constrain the CA to issue only enduser certificates of a particular type (EKU chaining), based on CABF BR and other requirements.

Current cases

Our Subordinate CA certificate contains the CodeSigning EKU but does not contain the digitalSignature KU.
This way it can not be used to sign codes due to a key usage conflict according to RFC 5280.
In our interpretation it is not an error, because we definitely do not want to sign codes with this Subordinate CA certificate. The purpose of having this EKU in the CA certificate is to technically constrain its use only to issue code signing end-entity certificates (EKU chaining).

Our proposal

If you agree with our interpretation we suggest to make difference between the Subordinate CA certificates and end-entity certificates.
The KU - EKU consistency should be checked for both types, but the finding should have different weight.

  • In case of end-entity certificate the "ERROR" is OK.
  • In case of Subordinate CA certificates it would be probably better to have only a WARNING or even an INFORMATION.
@sleevi
Copy link
Contributor

sleevi commented Apr 30, 2021

Thanks @sandorszoke !

I think you're spot on here: the KU/EKU consistency check in the context of RFC 5280 assumes an end-entity certificate, because RFC 5280 only normatively addresses the behaviour of EKUs with respect to end-entity certificates. Despite several efforts of various vendors, representing clear "rough code and (real world) rough consensus", the treatment of EKUs on CA certificates wasn't included as part of RFC 5280.

So I think your proposed outcome sounds entirely reasonable, and apologies for missing it during review!

Would you like to submit a patch to resolve this, or is the primary goal to raise the issue to the community?

@sandorszoke
Copy link
Author

We do not have any experience with the ZLint source code, so our primary goal was to raise this issue to the community.

@cpu cpu added the bug label May 10, 2021
@cpu
Copy link
Member

cpu commented May 10, 2021

Hi @sandorszoke, thanks for filing this issue (and testing ZLint releases).

As part of a wider test we checked all of our CA certificates by Zlint ver.3.0.0 (?)

Is the question mark here because you're not sure if it was 3.0.0 or 3.1.0 you tested?

If you agree with our interpretation we suggest to make difference between the Subordinate CA certificates and end-entity certificates.
The KU - EKU consistency should be checked for both types, but the finding should have different weight.

In case of end-entity certificate the "ERROR" is OK.
In case of Subordinate CA certificates it would be probably better to have only a WARNING or even an INFORMATION.

This sounds good to me but I think will necessitate splitting the lint. Guidance on adding new lints documents a desire to keep each lint to a single result level.

@sandorszoke
Copy link
Author

Hi @cpu,

yes, the question mark means we are not sure which version of Zlint used for the original test.

The reason is that the version of Zlint is not indicated in our logs and we could not find how to request the version of Zlint from the installed program.

Is there any way to ask the installed version from Zlint?

We are absolutely sure that the version used was not 3.1.0 because the output contained only 270 lints and version 3.1.0 uses 274 lints.

After realizing this version issue, we upgraded our test environment and ran all tests again. The ver. 3.1.0 does not contain this problematic lint.

I checked the guidance and you are right, this issue can only be solved by splitting this lint into CA-lint and not-CA lint.

@cpu
Copy link
Member

cpu commented May 11, 2021

Is there any way to ask the installed version from Zlint?

Not at the current time, we have an open feature request for this: #519

After realizing this version issue, we upgraded our test environment and ran all tests again. The ver. 3.1.0 does not contain this problematic lint.

Great 👍

I checked the guidance and you are right, this issue can only be solved by splitting this lint into CA-lint and not-CA lint.

Certainly doable. I'm not sure I'll have time to implement this myself in the next week or so but will keep it in-mind.

@cpu
Copy link
Member

cpu commented May 12, 2021

Is there any way to ask the installed version from Zlint?

Not at the current time, we have an open feature request for this: #519

@sandorszoke While looking into this I realized you can run zlint -h on a release binary and it includes the version information at the very top of the usage output. (For 3.1.0 in particular it shows v3.1.0-rc1 because of a hiccup in the release process for that release.):

curl -L https://github.com/zmap/zlint/releases/download/v3.1.0/zlint_3.1.0_Linux_x86_64.tar.gz -o latest.tar.gz 2>/dev/null && \
  tar -xvf latest.tar.gz 2>/dev/null && \
  zlint_3.1.0-rc1_Linux_x86_64/zlint -h
ZLint version 3.1.0-rc1
<snipped>

Clearly that's too subtle (I forgot it was even implemented!) so #598 adds an explicit -version flag.

@sandorszoke
Copy link
Author

@cpu Thank you for this useful information.
zlint -h really gives the zlint version in the first output line, so the installed version can be verified before running the tests.

-version flag will be also useful to include the version information into each test result.

@sandorszoke
Copy link
Author

PKI Consortium supports zlint

PKI Consortium decided to help the improvement of zlint, and as a first step we studied the lint e_key_usage_and_extended_key_usage_inconsistent.
We would like to discuss the requirement, make the necessary changes in the code and reactivate it in zlint.

We checked the RFC requirements for using KU and EKU, and the correspondig zlint issues:

#581 #591 #602

#497 #519 #528 #553 #556 #557 #561 #583 #595 #598 #605

Summary of our main findings

  • ZLINT has lints in different "groups", the "rfc" contains requirements for several different RFC norms and it is not easy to see which requirements are related to wich RFC norms
  • several RFC norms have requirements for KU and/or EKU
  • each lint deals only with a specific requirement
  • in this lint we shall focus only on RFC5280, other requirements shall be managed in other lints
  • this lint focuses only on the KU/EKU mapping requirements set in chapter 4.2.1.12. Extended Key Usagerequirements of RFC5280
  • these requirements target mainly Subscriber certificates, so this lint shall return with value "N/A" in case of CA certificates
  • if the EKU extension is present, it shall contain at least one EKU value
  • the wording of the RFC5280 requirement is not absolutely clear, various interpretations are possible due to the use of list separators. We suggest the following interpretation:
  • "or" in the text should be interpreted as a logical XOR, so keyEncipherment and keyAgreement EKU shall not be present together in a certificate
  • "comma" in the text should be interpreted as a logical OR, so any of the listed EKU values (one or more) may be present in the certificate
  • "and/or" in the text should be interpreted as a logical OR, so any of the listed EKU values (one or more) may be present in the certificate

Following this interpretation, we created the logical functions that should be checked in case of the presence of an EKU:

anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 }
>> no limitations, so it may be present with any KU values, no check is needed

id-kp-serverAuth             OBJECT IDENTIFIER ::= { id-kp 1 }
-- TLS WWW server authentication
-- Key usage bits that may be consistent: digitalSignature,
-- keyEncipherment or keyAgreement
>>	(digitalSignature OR (keyEncipherment XOR keyAgreement))

id-kp-clientAuth             OBJECT IDENTIFIER ::= { id-kp 2 }
-- TLS WWW client authentication
-- Key usage bits that may be consistent: digitalSignature
-- and/or keyAgreement
>>	(digitalSignature OR keyAgreement)

id-kp-codeSigning             OBJECT IDENTIFIER ::= { id-kp 3 }
-- Signing of downloadable executable code
-- Key usage bits that may be consistent: digitalSignature
>>	(digitalSignature)

id-kp-emailProtection         OBJECT IDENTIFIER ::= { id-kp 4 }
-- Email protection
-- Key usage bits that may be consistent: digitalSignature,
-- nonRepudiation, and/or (keyEncipherment or keyAgreement)
>>	(digitalSignature OR nonRepudiation OR (keyEncipherment XOR keyAgreement))

id-kp-timeStamping            OBJECT IDENTIFIER ::= { id-kp 8 }
-- Binding the hash of an object to a time
-- Key usage bits that may be consistent: digitalSignature
-- and/or nonRepudiation
>>	(digitalSignature OR nonRepudiation)

id-kp-OCSPSigning            OBJECT IDENTIFIER ::= { id-kp 9 }
-- Signing OCSP responses
-- Key usage bits that may be consistent: digitalSignature
-- and/or nonRepudiation
>>	(digitalSignature OR nonRepudiation)

The EKU name in the logical functions means a Boolean value, 
which value is “true” if the given EKU is present in the certificate, 
and the value is “false” if the EKU is not present.

Current status

The e_key_usage_and_extended_key_usage_inconsistent lint is currently not included in zlint due to the identified problems.

The retired lint can be found here:
https://github.com/zmap/zlint/blob/c1c6681339ef2247dca5ff81162ab80c4811b154/v3/lints/rfc/lint_key_usage_and_extended_key_usage_inconsistent.go

The previous version of this lint checked all the requirements in one lint and could only result a general warning message.
It is an option to split this lint into multiple lints, which would result more informative warning messages about the identified problem.
This can be problematic due to the large number of already existing lints, so this option should be discussed with the zlint editors.

Potential issues to be solved

Currently PKIC suggests the following actions

  1. The lint should be used only for Subscriber certificates, so a new condition should be added to function CheckApplies(c *x509.Certificate)
  2. The map function for serverAuth EKU does not contain all the possible KU bit combinations, it should be upgraded. The source of the potential problem can be the interpretation of the requirement due to the missing brackets
  3. Possible it would be better to split this lint into 6 independent lints, which would result more appropriate Warning messages and flexibility in use

@sandorszoke
Copy link
Author

Hi @sleevi and @cpu ,
if you agree with the proposed changes, we plan to submit our first zlint patch to resolve this issue.

@primetomas
Copy link

@sandorszoke I like the thorough listing of consistency checks. Different logic for a field in different types of certificates almost always leads to issues in the field so good linting support for this is important and very helpful.
I'd like to see this in zlint.

@vanbroup
Copy link
Contributor

Resolved by #708

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants