You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
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.
seankhliao
changed the title
x509 Certificate.CheckSignatureFrom() inconsistency with OpenSSL
crypto/x509: Certificate.CheckSignatureFrom() inconsistency with OpenSSL
Feb 12, 2021
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?go env
OutputIssue 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.
The text was updated successfully, but these errors were encountered: