outer AlgorithmIdentifer parameters are not verified against tbsCertificate
Description of problem:
I think GnuTLS might not be conforming with RFC5280 section 126.96.36.199.
This field MUST contain the same algorithm identifier as the signature field in the sequence tbsCertificate (Section 188.8.131.52).
GnuTLS does not consider the parameters of the
signatureAlgorithm to be part of the
AlgorithmIdentifier, and therefore the outer
signatureAlgorithm can be different from the
signatureAlgorithm. This behavior does not match the behaviour of OpenSSL and NSS who do consider the parameters part of the identifier.
I think that this isn't a security vulnerability on it's own (although, I am not a cryptographer), because most (do any?) algorithms don't specify any parameters. However, you can modify and add new objects to signed certificates and they will still verify.
That really feels like it might have significant consequences, even though I don't have the crypto skills to analyze it.
Version of gnutls used:
Distributor of gnutls (e.g., Ubuntu, Fedora, RHEL)
Built from source
I modified this certificate to change the outer
signatureAlgorithm to have a 1 byte BIT STRING object (rather than the RFC-required NULL object).
I could make the object larger because the signature starts with an empty byte I can truncate (maybe there are certificates with more room).
Steps to Reproduce:
- Download the attached pem certificate.
- Observe that the file is different from the original.
- Notice that gnutls still verifies the certificate.
OpenSSL does not consider it valid.
$ certtool --verify-allow-broken --verify --infile AlgorithmIdentifer.parameters.pem Loaded system trust (299 CAs available) Subject: CN=RapidSSL CA,O=GeoTrust\, Inc.,C=US Issuer: CN=GeoTrust Global CA,O=GeoTrust Inc.,C=US Checked against: CN=GeoTrust Global CA,O=GeoTrust Inc.,C=US Signature algorithm: RSA-SHA1 Output: Verified. The certificate is trusted. Chain verification output: Verified. The certificate is trusted.
$ openssl verify AlgorithmIdentifer.parameters.pem C = US, O = "GeoTrust, Inc.", CN = RapidSSL CA error 7 at 0 depth lookup: certificate signature failure error AlgorithmIdentifer.parameters.pem: verification failed
If you look at the diff between the two certificates, you can see the changes I made:
--- /dev/fd/63 2019-02-05 14:13:31.409400948 -0800 +++ /dev/fd/62 2019-02-05 14:13:31.409400948 -0800 @@ -1,4 +1,4 @@ - 0:d=0 hl=4 l= 981 cons: SEQUENCE + 0:d=0 hl=4 l= 982 cons: SEQUENCE 4:d=1 hl=4 l= 701 cons: SEQUENCE 8:d=2 hl=2 l= 3 cons: cont [ 0 ] 10:d=3 hl=2 l= 1 prim: INTEGER :02 @@ -62,7 +62,7 @@ 655:d=4 hl=2 l= 52 cons: SEQUENCE 657:d=5 hl=2 l= 8 prim: OBJECT :Authority Information Access 667:d=5 hl=2 l= 40 prim: OCTET STRING [HEX DUMP]:3026302406082B060105050730018618687474703A2F2F6F6373702E67656F74727573742E636F6D - 709:d=1 hl=2 l= 13 cons: SEQUENCE + 709:d=1 hl=2 l= 14 cons: SEQUENCE 711:d=2 hl=2 l= 9 prim: OBJECT :sha1WithRSAEncryption - 722:d=2 hl=2 l= 0 prim: NULL - 724:d=1 hl=4 l= 257 prim: BIT STRING + 722:d=2 hl=2 l= 1 prim: OCTET STRING :A + 725:d=1 hl=4 l= 257 prim: BIT STRING
Notice I just added an OCTET STRING where the parameters are supposed to be (in fact, the RFC says it SHALL be NULL, so this is non-conforming)