gnutls fails to reject certificates with Generalized time prior to 2049
Reported by Theofilos Petsios by mail:
- Our understanding, based on RFC 5280, section 4.1.2.5 is that
CAs conforming to this profile MUST always encode certificate
validity dates through the year 2049 as UTCTime; certificate validity
dates in 2050 or later MUST be encoded as GeneralizedTime.
Conforming applications MUST be able to process validity dates that
are encoded in either UTCTime or GeneralizedTime.
With respect to the above, any date before 2049 should be encoded as UTC. Now, even if this direction is not applied and a date before 2049 is encoded as GMT, how does GnuTLS handle the GMT time? Shouldn't the year be parsed as 0000 instead of 1970?
- When verifying 'leaf_cert.pem' against the given CA, OpenSSL, LibreSSL, wolfSSL and mbedTLS parse the certificate according to ASN1 and not conforming to the RFC. However, if the timestamps are encoded as GMT using the ASN1 encoding, the notAfter date is 20160691091623Z (aka June with an invalid day number of 91) and
the certificate should be treated as either invalid or expired regardless of its notBefore date. In fact, all other libraries reject the certificate. Contrary, GnuTLS accepts it even if the date is set to be 2016-08-09.
It seems that there is some decision in the parsing of the certificate that causes the notAfter date to be Tue Aug 30 09:16:23 UTC 2016 and the NotBefore date to be parsed as Thu Jan 01 00:00:00 UTC 1970 which is not in conformance with other popular libraries nor the RFC. In particular
- For UTCTime parsing, from the same RFC we see
... Conforming systems MUST interpret the year field (YY) as follows:
Where YY is greater than or equal to 50, the year SHALL be interpreted as 19YY; and Where YY is less than 50, the year SHALL be interpreted as 20YY.
Given the above, even if the time was to be parsed as UTC (regardless of being too long for a UTC encoding), it should have been interpreted as 2000 no? We are not sure how 1970 was calculated here or what the reasoning behind the 31BC calculation is. It seems that this is an ASN1 parsing decision?