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

crypto/x509: Certificate.CheckSignatureFrom() inconsistency with OpenSSL #44237

Closed
zzma opened this issue Feb 12, 2021 · 3 comments
Closed

crypto/x509: Certificate.CheckSignatureFrom() inconsistency with OpenSSL #44237

zzma opened this issue Feb 12, 2021 · 3 comments
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.

Comments

@zzma
Copy link

zzma commented Feb 12, 2021

What version of Go are you using (go version)?

$ go version
go version go1.15.8 darwin/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GOARCH="amd64"
GOHOSTARCH="amd64"
GOHOSTOS="darwin"

Issue Summary

Go's CheckSignatureFrom() function differs from OpenSSL's signature verification. This is because Golang does not check for exact byte match between the signatureAlgorithm field in the TBS and the signatureAlgorithm field outside the TBS. Golang ignores the outside-TBS signatureAlgorithm and populates the Certificate struct with the in-TBS field. OpenSSL seems to perform this check and fails signature validation if it is not the case.

One additional consideration is that Certificate Transparency logs that rely on CheckSignatureFrom()
will validate the signature chain for any certificate that has its outside-of-TBS signatureAlgorithm trivially modified or extended. This is a way to circumvent CT's chain verification spam-control mechanism.

I've discussed this issue briefly with @rolandshoemaker.

What did you do?

Ran CheckSignatureFrom() on a x509.Certificate that has mismatching in-TBS/outside-TBS signatureAlgorithm fields. As long as the in-TBS sigAlgorithm works, the outside-TBS sigAlgorithm ASN.1 sequence can contain nearly anything. The CheckSignature() function also exhibits this divergence from OpenSSL, but it takes in a TBSCert as its argument, so can't enforce OpenSSL-consistent behavior.

Example: https://play.golang.org/p/xegQcq0dU7f

To compare with OpenSSL (tested on LibreSSL 2.8.3 and OpenSSL 1.1.1f): openssl verify -CAfile parent.pem child.pem

What did you expect to see?

An error indicating that the signature is not valid.

What did you see instead?

The signature validates with golang, but throws an error with OpenSSL.

@rolandshoemaker
Copy link
Member

Similar to #21118 (the missing parameters version of this), should be fixed by https://go-review.googlesource.com/c/go/+/235118/.

@seankhliao seankhliao changed the title x509 Certificate.CheckSignatureFrom() inconsistency with OpenSSL crypto/x509: Certificate.CheckSignatureFrom() inconsistency with OpenSSL Feb 12, 2021
@seankhliao seankhliao added the NeedsFix The path to resolution is known, but the work has not been done. label Feb 12, 2021
@networkimprov
Copy link

cc @FiloSottile

@gopherbot
Copy link
Contributor

Change https://golang.org/cl/274234 mentions this issue: crypto/x509: rewrite certificate parser

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

5 participants