Skip to content

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

Closed
@zzma

Description

@zzma

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsFixThe path to resolution is known, but the work has not been done.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions