Skip to content

crypto/x509: ParseCRL allows revocation serial number that is a non-positive integer #73433

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

Open
onepeople158 opened this issue Apr 18, 2025 · 10 comments
Labels
BugReport Issues describing a possible bug in the Go implementation. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@onepeople158
Copy link

Go version

go version go1.24.2 linux/amd64

Output of go env in your module/workspace:

CRL Issuer: CN=My Root CA,OU=My Root CA,O=My Company,L=San Francisco,ST=California,C=US
This Update Time: 2025-01-01 08:00:00 +0800 CST
Next Update Time: 2025-12-01 08:00:00 +0800 CST
Signature Algorithm: SHA256-RSA
Number of Revoked Certificates: 1

Revoked Entry Details:
============================
Serial Number: -24
Revocation Time: 2025-04-14 20:00:00 +0800 CST
  Extensions:
    2.5.29.21 (CRL Reason): KeyCompromise
----------------------------
CRL Issuer: CN=My Root CA,OU=My Root CA,O=My Company,L=San Francisco,ST=California,C=US
This Update Time: 2025-01-01 08:00:00 +0800 CST
Next Update Time: 2025-12-01 08:00:00 +0800 CST
Signature Algorithm: SHA256-RSA
Number of Revoked Certificates: 1

Revoked Entry Details:
============================
Serial Number: 0
Revocation Time: 2025-04-14 20:00:00 +0800 CST
  Extensions:
    2.5.29.21 (CRL Reason): KeyCompromise
----------------------------

What did you do?

Hello developer, Go successfully parsed a CRL file with revoked certificate serial numbers 0 and -36 without any errors. According to RFC5280, the certificate serial number must be a positive integer.

What did you see happen?

Go successfully parsed a CRL file with revoked certificate serial numbers 0 and -36 without any errors.

What did you expect to see?

Test Case:

go_certs.zip

@gabyhelp gabyhelp added the BugReport Issues describing a possible bug in the Go implementation. label Apr 18, 2025
@seankhliao seankhliao changed the title crypto/x509:Go parsed a CRL file with a revocation serial number that is a non-positive integer. crypto/x509: ParseCRL allows revocation serial number that is a non-positive integer Apr 18, 2025
@prattmic
Copy link
Member

cc @FiloSottile @rolandshoemaker @cpu @golang/security

@prattmic prattmic added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Apr 18, 2025
@prattmic prattmic added this to the Backlog milestone Apr 18, 2025
@FiloSottile
Copy link
Contributor

Is this different from #73029?

@onepeople158
Copy link
Author

Is this different from #73029?

Hello, developer. I initiated this report because I am unsure whether the CRL Number and Revoked serial use the same parameter type.

@cpu
Copy link
Member

cpu commented Apr 18, 2025

I think it's reasonable to tighten this up, but ParseRevocationList should probably mimick x509.ParseCertificate and respect the x509negativeserial godebug flag. As long as there's an escape hatch to parse a cert with a negative serial I think it's reasonable to allow the same cert to appear in a CRL.

@cpu
Copy link
Member

cpu commented Apr 18, 2025

Without any deep attachment to a particular outcome, here's a WIP in case it helps discussion: https://go-review.googlesource.com/c/go/+/666695

ParseRevocationList should probably mimick x509.ParseCertificate and respect the x509negativeserial godebug flag.

I convinced myself a new GODEBUG is required here in order to properly reflect the version that the behavior changed, and to not muddy the waters with the metric associated for the Certificate context. I also think it's sensible to make CreateRevocationList err for negative serials unless toggled otherwise.

@rolandshoemaker
Copy link
Member

I convinced myself a new GODEBUG is required here in order to properly reflect the version that the behavior changed, and to not muddy the waters with the metric associated for the Certificate context. I also think it's sensible to make CreateRevocationList err for negative serials unless toggled otherwise.

This seems correct to me.

@AGWA
Copy link

AGWA commented Apr 22, 2025

This seems like a bad idea, as it would put CAs who misissue a certificate with a non-positive serial number between a rock and a hard place. If they revoke the certificate, their CRL won't be parseable by a major implementation by default. If they don't revoke the certificate, they would be violating the BRs and may also be putting RPs which accept certificates with non-positive serial numbers at risk (consider that the certificate may also have more serious problems, like improper DCV).

Given that the prohibition against non-positive serial numbers is in Section 4, which describes certificates, and there is no corresponding prohibition in Section 5, which describes CRLs, it's not clear to me that it's even a violation of RFC 5280 for CAs to put non-positive serial numbers in a CRL's revokedCertificates sequence. (It's true that Section 5 refers to "the ASN.1 in Section 4.1" for the definition of CertificateSerialNumber but the ASN.1 just defines CertificateSerialNumber as an INTEGER; the prohibition against non-positive serial numbers in Section 4.1.2.2 applies to just the TBSCertificate field rather than all instances of the CertificateSerialNumber type.)

Even if it were a violation of RFC 5280, I don't think the usual arguments in favor of strict parsing apply here. Non-positive serial numbers are still syntactically valid ASN.1 INTEGERs, so it's unlikely Go would interpret them differently from other implementations. Preventing badness from spreading in the ecosystem is better enforced during certificate parsing. Enforcing it in CRL parsing doesn't discourage CAs from issuing certificates with non-positive serial numbers; it just discourages CAs from revoking them.

Are there arguments in favor of this that I'm overlooking?

@rolandshoemaker
Copy link
Member

Hm, this is a good point that I didn't consider.

We don't really support doing anything with CRLs currently (as in, using them for revocation checking in crypto/x509 itself) but plausibly other people could be implementing that themselves. We probably shouldn't be preventing malformed certificates from being included in CRLs. Similarly we probably shouldn't be preventing CRLs from being created with said serials.

Really wish CRLs hadn't used serial as the identifier, but whatever.

@cpu
Copy link
Member

cpu commented Apr 28, 2025

As mentioned I don't feel strongly here and did always intend to leave an escape hatch for including malformed serials in the CRL. However, I am swayed by the argument that making it opt-in could perversely incentivize a CA to not revoke a certificate it would have otherwise.

Seems like the consensus is to close as WONTFIX?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
BugReport Issues describing a possible bug in the Go implementation. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

7 participants