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

RFC 5280 X509 compliance issues in OpenSSL v3.1.1 or later #24258

Open
joyantaDebnath opened this issue Apr 24, 2024 · 9 comments
Open

RFC 5280 X509 compliance issues in OpenSSL v3.1.1 or later #24258

joyantaDebnath opened this issue Apr 24, 2024 · 9 comments
Labels
branch: master Merge to master branch help wanted triaged: feature The issue/pr requests/adds a feature

Comments

@joyantaDebnath
Copy link

joyantaDebnath commented Apr 24, 2024

  1. It allows empty DirectoryString (e.g., "") in Distinguished name structures of Issuer and Subject name. (RFC 5280 non-compliant)
  2. You should not allow 0 (zero) as certificate serial number. RFC 5280 says, "The serial number MUST be a positive integer assigned by the CA to each cer- tificate...CAs MUST force the serial Number to be a non-negative integer...Non- conforming CAs may issue certificates with serial numbers that are negative or zero. Certificate users SHOULD be prepared to gracefully handle such certificates."
  3. We found your implementation do not report any error or warning for Version 4 - 10 (value 3-9) certificates whereas Certificate Version can be either 1 (value 0), 2 (value 1), or 3 (value 2). (RFC 5280 non-compliant)
@joyantaDebnath joyantaDebnath added the issue: bug report The issue was opened to report a bug label Apr 24, 2024
@t8m t8m added branch: master Merge to master branch help wanted triaged: feature The issue/pr requests/adds a feature and removed issue: bug report The issue was opened to report a bug labels Apr 25, 2024
@nhorman nhorman changed the title Reporting Bugs in OpenSSL v3.1.1 or later RFC 5280 X509 compliance issues in OpenSSL v3.1.1 or later Apr 25, 2024
@kroeckx
Copy link
Member

kroeckx commented Apr 25, 2024

  1. All relevant standards seems to agree that the minimum size for a DirectoryString is 1.
  2. As you quote yourself, we SHOULD handle the value of 0, it's the CA that should force it to be positive.
  3. Note that version 3 means it conforms to RFC5280. The RFC says: "Implementations SHOULD be prepared to accept any version certificate", that includes unknown versions.

@dcooper16
Copy link
Contributor

Hello @joyantaDebnath,

It is not clear to me in items 1. and 2. in your comment whether you are noting that OpenSSL will allow such certificates to be created, or just that is does not complain when verifying such certificates.

RFC 5280 is a profile of X.509, and sometimes RFC 5280 imposes restrictions on what a conforming CA may do that X.509 does not. However, RFC 5280 generally recommends that implementations of certificate validation be able to accept any valid X.509 certification path, even if the certificates were not issued in conformance with RFC 5280.

As noted in https://github.com/openssl/openssl/blob/master/doc/man1/openssl-verification-options.pod, OpenSSL has an -x509_strict flag, which should result in verification throwing a flag if the certificates were not issued in conformance with RFC 5280. Did you try this flag?

While RFC 5280 requires serial numbers to be positive, X.509 does not. So, it seems reasonable for OpenSSL to be able to issue certificates with a serial number of 0, but perhaps should flag such certificates when verifying them (but only if the -x509_strict flag is set).

The issue with empty issuer and subject names is more complex. RFC 5280 does allow for empty subject names in end-entity certificates, but not in CA certificates. RFC 5280 also says that the issuer field must contain a non-empty name. According to https://github.com/openssl/openssl/blob/master/doc/man1/openssl-verification-options.pod, OpenSSL checks for this if the -x509_strict flag is set.

The complexity is that X.509 used to allow both the issuer and subject fields to contain empty (null) names. However, it seems that has changed, and the edition from 10/2019 matches RFC 5280 in only allowing empty (null) names in the subject field of end-entity certificates.

As for the version number, that may be question for the IETF PKIX mail list. As @kroeckx noted, RFC 5280 says:

This [version] field describes the version of the encoded certificate. When extensions are used, as expected in this profile, version MUST be 3 (value is 2). If no extensions are present, but a UniqueIdentifier is present, the version SHOULD be 2 (value is 1); however, the version MAY be 3. If only basic fields are present, the version SHOULD be 1 (the value is omitted from the certificate as the default value); however, the version MAY be 2 or 3.

Implementations SHOULD be prepared to accept any version certificate. At a minimum, conforming implementations MUST recognize version 3 certificates.

Generation of version 2 certificates is not expected by implementations based on this profile.

This text in RFC 5280 is nearly identical to what was in the original version of the IETF PKIX profile (RFC 2459).

The question is whether "any version certificate" meant version 1, 2, and 3, or was it also intended to include versions that had not yet been defined? I would guess that it only intended to mean that implementations should be prepared to accept version 1, 2, and 3 certificates. I don't see how an implementation created today could be prepared to accept a version 4, 5, or 6 certificate. But, I can see how it could be interpreted the other way.

@kroeckx
Copy link
Member

kroeckx commented Apr 26, 2024 via email

@dcooper16
Copy link
Contributor

Hello @kroeckx,

Yes, you are correct and I misread @joyantaDebnath's comment. I thought @joyantaDebnath was talking about empty distinguished names (i.e., names that are SEQUENCE of 0 relative distinguished names -- 30 00):

The issuer field MUST contain a non-empty distinguished name (DN).

If the comment actually meant that it allowed the issuer and subject field to contain AttributeTypeAndValue structures where the attribute value corresponding to the attribute type is of type DirectoryString and the value is a string of length 0, then that would seem to not be allowed by the ASN.1 (e.g., c="US", o="My Company", ou="").

@joyantaDebnath
Copy link
Author

joyantaDebnath commented Apr 26, 2024

Hello @dcooper16,

Sorry for the confusion. I am concerned about only certificate chain validation, not issuance. RFC 5280 puts additional restrictions on X.509 format during certificate chain validation. My argument is implementations should conform to RFC 5280 for inter-operability and possibly security reasons.

(1) @kroeckx is spot on for (1). Please , look at this sample certificate that I created: empty_string.pem

In this certificate, the UTF8String in stateOrProvinceName attribute of Subject RDN is an empty string of SIZE 0(bytes --> 0C 00), which is not allowed by RFC 5280 as @kroeckx showed. OpenSSL does not report any error or warning for such case. I tested an found such noncompliance case is also present for Issuer RDN. It should be an easy fix to enforce this length constraints.

(2) Yes, RFC 5280 is confusing here. What do you mean by gracefully handling certificates with 0 or negative serial number? This can be accept or reject? How about you reject such values for serial number at least with the x509_strict flag?

(3) Version 3 certificate is in the market for more than two/three decades till today. Do you think version 4, 5, 6, .... will come soon? Though the RFC 5280 says Implementations SHOULD be prepared to accept any version certificate, I think this sentence needs to be carefully interpreted. In my opinion, any version is still within the allowed versions (1, 2, or 3). The RFC 5280 also explicitly mentioned that When extensions are used, as expected in this profile, version MUST be 3. That means, extensions are not allowed for version > 3. Please, look at this version 9 certificate with extensions. OpenSSL does not report any error or warning. version_9.pem. How about at least enforce this in x509_strict flag?

@kroeckx
Copy link
Member

kroeckx commented Apr 28, 2024 via email

@kroeckx
Copy link
Member

kroeckx commented Apr 28, 2024 via email

@kroeckx
Copy link
Member

kroeckx commented Apr 28, 2024 via email

@dcooper16
Copy link
Contributor

Hello @joyantaDebnath,

I'm not an OpenSSL developer, so I won't speak to what checks OpenSSL should or should not perform to check that a CA didn't issue a malformed certificate (e.g., invalid version number or attribute value in a directory name with an invalid length).

(1) @kroeckx is spot on for (1).

Okay. In case case, I would guess this doesn't only apply to the issuer and subject name, but anywhere that a distinguished name might appear (CRL distribution points, issuing distribution point, name constraints, etc.). Have you tried other similar errors, such as a countryName attribute (2.5.4.6) that isn't a PrintableString of length 2 (e.g., one that is encoded as UTF8String or has a length of 3)?

(2) Yes, RFC 5280 is confusing here. What do you mean by gracefully handling certificates with 0 or negative serial number? This can be accept or reject?

I agree that "gracefully handling" is rather vague. It seems that RFC 2459 didn't say anything against CAs issuing certificates with a serial number of 0 or a negative serial number. RFC 3280 required conforming CAs to only use positive serial numbers, and added this text about gracefully handling 0 and negative serial numbers. The text wasn't changed in RFC 5280.

I would guess that either accepting or rejecting would count as "gracefully handling." I can imagine an example of not "gracefully handling" would be treating "02 01 FF" as 255 instead of -1, and thus "02 01 FF" as being the same as "02 02 00 FF."

(3) Version 3 certificate is in the market for more than two/three decades till today. Do you think version 4, 5, 6, .... will come soon? Though the RFC 5280 says Implementations SHOULD be prepared to accept any version certificate, I think this sentence needs to be carefully interpreted. In my opinion, any version is still within the allowed versions (1, 2, or 3).

As noted above, I agree. I think the sentence in RFC 5280 meant that implementations should be prepared to accept version 1, 2, and 3 certificates, not versions that had yet to be defined.

RFC 5280 puts additional restrictions on X.509 format during certificate chain validation. My argument is implementations should conform to RFC 5280 for inter-operability and possibly security reasons.

Can you explain what you mean by this? Section 6.1 of RFC 5280 says:

While the certificate and CRL profiles specified in Sections 4 and 5 of this document specify values for certificate and CRL fields and extensions that are considered to be appropriate for the Internet PKI, the algorithm presented in this section is not limited to accepting certificates and CRLs that conform to these profiles. Therefore, the algorithm only includes checks to verify that the certification path is valid according to X.509 and does not include checks to verify that the certificates and CRLs conform to this profile. While the algorithm could be extended to include checks for conformance to the profiles in Sections 4 and 5, this profile RECOMMENDS against including such checks.

Step (f) in Section 6.3.3 imposes a restriction that does not appear in X.509 -- when validating a CRL, the certification path for CRL must start at the same trust anchor as the certification path for the target certificate -- but I can't think of any other additional restrictions that RFC 5280 puts on validation. It has, however, been many years since I looked at RFC 5280.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
branch: master Merge to master branch help wanted triaged: feature The issue/pr requests/adds a feature
Projects
None yet
Development

No branches or pull requests

4 participants