MODSIGN: Fix 32-bit overflow in X.509 certificate validity date checking

The current choice of lifetime for the autogenerated X.509 of 100 years,
putting the validTo date in 2112, causes problems on 32-bit systems where a
32-bit time_t wraps in 2106.  64-bit x86_64 systems seem to be unaffected.

This can result in something like:

	Loading module verification certificates
	X.509: Cert 6e03943da0f3b015ba6ed7f5e0cac4fe48680994 has expired
	MODSIGN: Problem loading in-kernel X.509 certificate (-127)

Or:

	X.509: Cert 6e03943da0f3b015ba6ed7f5e0cac4fe48680994 is not yet valid
	MODSIGN: Problem loading in-kernel X.509 certificate (-129)

Instead of turning the dates into time_t values and comparing, turn the system
clock and the ASN.1 dates into tm structs and compare those piecemeal instead.

Reported-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Josh Boyer <jwboyer@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
David Howells
2012-10-02 14:36:16 +01:00
committed by Rusty Russell
parent d5b719365e
commit a5752d11b3
3 changed files with 51 additions and 20 deletions

View File

@@ -434,11 +434,10 @@ int x509_process_extension(void *context, size_t hdrlen,
/*
* Record a certificate time.
*/
static int x509_note_time(time_t *_time, size_t hdrlen,
static int x509_note_time(struct tm *tm, size_t hdrlen,
unsigned char tag,
const unsigned char *value, size_t vlen)
{
unsigned YY, MM, DD, hh, mm, ss;
const unsigned char *p = value;
#define dec2bin(X) ((X) - '0')
@@ -448,30 +447,30 @@ static int x509_note_time(time_t *_time, size_t hdrlen,
/* UTCTime: YYMMDDHHMMSSZ */
if (vlen != 13)
goto unsupported_time;
YY = DD2bin(p);
if (YY > 50)
YY += 1900;
tm->tm_year = DD2bin(p);
if (tm->tm_year >= 50)
tm->tm_year += 1900;
else
YY += 2000;
tm->tm_year += 2000;
} else if (tag == ASN1_GENTIM) {
/* GenTime: YYYYMMDDHHMMSSZ */
if (vlen != 15)
goto unsupported_time;
YY = DD2bin(p) * 100 + DD2bin(p);
tm->tm_year = DD2bin(p) * 100 + DD2bin(p);
} else {
goto unsupported_time;
}
MM = DD2bin(p);
DD = DD2bin(p);
hh = DD2bin(p);
mm = DD2bin(p);
ss = DD2bin(p);
tm->tm_year -= 1900;
tm->tm_mon = DD2bin(p) - 1;
tm->tm_mday = DD2bin(p);
tm->tm_hour = DD2bin(p);
tm->tm_min = DD2bin(p);
tm->tm_sec = DD2bin(p);
if (*p != 'Z')
goto unsupported_time;
*_time = mktime(YY, MM, DD, hh, mm, ss);
return 0;
unsupported_time: