summaryrefslogtreecommitdiffstats
path: root/crypto/asymmetric_keys/x509_cert_parser.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2012-10-02 14:36:16 +0100
committerRusty Russell <rusty@rustcorp.com.au>2012-10-10 20:06:37 +1030
commita5752d11b3853fcdb48b303573dd39b09d05e500 (patch)
treefdbf54986ce97f473661d62510a513bb4ba79aa9 /crypto/asymmetric_keys/x509_cert_parser.c
parentd5b719365ec13ef825f2548ba54903b9d029238c (diff)
downloadlinux-0-day-a5752d11b3853fcdb48b303573dd39b09d05e500.tar.gz
linux-0-day-a5752d11b3853fcdb48b303573dd39b09d05e500.tar.xz
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>
Diffstat (limited to 'crypto/asymmetric_keys/x509_cert_parser.c')
-rw-r--r--crypto/asymmetric_keys/x509_cert_parser.c25
1 files changed, 12 insertions, 13 deletions
diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c
index 8fcac9493b7a5..db07e8c9c8832 100644
--- a/crypto/asymmetric_keys/x509_cert_parser.c
+++ b/crypto/asymmetric_keys/x509_cert_parser.c
@@ -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: