From 8c69e467527c5ee484c9a921e9b5fd18c0c49b12 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Fri, 29 Mar 2013 13:17:29 +0100 Subject: Don't respect timezones for CKA_START_DATE or CKA_END_DATE The PKCS#11 specification does not note what timezone these dates are in. In addition the time values are not represented in PKCS#11. So don't reinterpret certificate dates, other than filling in the century for dates that have a two digit year. Lastly, these are low resolution optional fields so not being all strict about timezones here is appropriate. https://bugs.freedesktop.org/show_bug.cgi?id=62825 --- common/asn1.c | 332 ---------------------------------------------------------- common/asn1.h | 6 -- 2 files changed, 338 deletions(-) (limited to 'common') diff --git a/common/asn1.c b/common/asn1.c index c98d959..45d91ab 100644 --- a/common/asn1.c +++ b/common/asn1.c @@ -192,338 +192,6 @@ p11_asn1_encode (node_asn *asn, return der; } -static int -atoin (const char *p, - int digits) -{ - int ret = 0, base = 1; - while(--digits >= 0) { - if (p[digits] < '0' || p[digits] > '9') - return -1; - ret += (p[digits] - '0') * base; - base *= 10; - } - return ret; -} - -static int -two_to_four_digit_year (int year) -{ - time_t now; - struct tm tm; - int century, current; - - return_val_if_fail (year >= 0 && year <= 99, -1); - - /* Get the current year */ - now = time (NULL); - return_val_if_fail (now >= 0, -1); - if (!gmtime_r (&now, &tm)) - return_val_if_reached (-1); - - current = (tm.tm_year % 100); - century = (tm.tm_year + 1900) - current; - - /* - * Check if it's within 40 years before the - * current date. - */ - if (current < 40) { - if (year < current) - return century + year; - if (year > 100 - (40 - current)) - return (century - 100) + year; - } else { - if (year < current && year > (current - 40)) - return century + year; - } - - /* - * If it's after then adjust for overflows to - * the next century. - */ - if (year < current) - return century + 100 + year; - else - return century + year; -} - -static int -parse_utc_time (const char *time, - size_t n_time, - struct tm *when, - int *offset) -{ - const char *p, *e; - int year; - - assert (when != NULL); - assert (time != NULL); - assert (offset != NULL); - - /* YYMMDDhhmmss.ffff Z | +0000 */ - if (n_time < 6 || n_time >= 28) - return 0; - - /* Reset everything to default legal values */ - memset (when, 0, sizeof (*when)); - *offset = 0; - when->tm_mday = 1; - - /* Select the digits part of it */ - p = time; - for (e = p; *e >= '0' && *e <= '9'; ++e); - - if (p + 2 <= e) { - year = atoin (p, 2); - p += 2; - - /* - * 40 years in the past is our century. 60 years - * in the future is the next century. - */ - when->tm_year = two_to_four_digit_year (year) - 1900; - } - if (p + 2 <= e) { - when->tm_mon = atoin (p, 2) - 1; - p += 2; - } - if (p + 2 <= e) { - when->tm_mday = atoin (p, 2); - p += 2; - } - if (p + 2 <= e) { - when->tm_hour = atoin (p, 2); - p += 2; - } - if (p + 2 <= e) { - when->tm_min = atoin (p, 2); - p += 2; - } - if (p + 2 <= e) { - when->tm_sec = atoin (p, 2); - p += 2; - } - - if (when->tm_year < 0 || when->tm_year > 9999 || - when->tm_mon < 0 || when->tm_mon > 11 || - when->tm_mday < 1 || when->tm_mday > 31 || - when->tm_hour < 0 || when->tm_hour > 23 || - when->tm_min < 0 || when->tm_min > 59 || - when->tm_sec < 0 || when->tm_sec > 59) - return 0; - - /* Make sure all that got parsed */ - if (p != e) - return 0; - - /* Now the remaining optional stuff */ - e = time + n_time; - - /* See if there's a fraction, and discard it if so */ - if (p < e && *p == '.' && p + 5 <= e) - p += 5; - - /* See if it's UTC */ - if (p < e && *p == 'Z') { - p += 1; - - /* See if it has a timezone */ - } else if ((*p == '-' || *p == '+') && p + 3 <= e) { - int off, neg; - - neg = *p == '-'; - ++p; - - off = atoin (p, 2) * 3600; - if (off < 0 || off > 86400) - return 0; - p += 2; - - if (p + 2 <= e) { - off += atoin (p, 2) * 60; - p += 2; - } - - /* Use TZ offset */ - if (neg) - *offset = 0 - off; - else - *offset = off; - } - - /* Make sure everything got parsed */ - if (p != e) - return 0; - - return 1; -} - -static int -parse_general_time (const char *time, - size_t n_time, - struct tm *when, - int *offset) -{ - const char *p, *e; - - assert (time != NULL); - assert (when != NULL); - assert (offset != NULL); - - /* YYYYMMDDhhmmss.ffff Z | +0000 */ - if (n_time < 8 || n_time >= 30) - return 0; - - /* Reset everything to default legal values */ - memset (when, 0, sizeof (*when)); - *offset = 0; - when->tm_mday = 1; - - /* Select the digits part of it */ - p = time; - for (e = p; *e >= '0' && *e <= '9'; ++e); - - if (p + 4 <= e) { - when->tm_year = atoin (p, 4) - 1900; - p += 4; - } - if (p + 2 <= e) { - when->tm_mon = atoin (p, 2) - 1; - p += 2; - } - if (p + 2 <= e) { - when->tm_mday = atoin (p, 2); - p += 2; - } - if (p + 2 <= e) { - when->tm_hour = atoin (p, 2); - p += 2; - } - if (p + 2 <= e) { - when->tm_min = atoin (p, 2); - p += 2; - } - if (p + 2 <= e) { - when->tm_sec = atoin (p, 2); - p += 2; - } - - if (when->tm_year < 0 || when->tm_year > 9999 || - when->tm_mon < 0 || when->tm_mon > 11 || - when->tm_mday < 1 || when->tm_mday > 31 || - when->tm_hour < 0 || when->tm_hour > 23 || - when->tm_min < 0 || when->tm_min > 59 || - when->tm_sec < 0 || when->tm_sec > 59) - return 0; - - /* Make sure all that got parsed */ - if (p != e) - return 0; - - /* Now the remaining optional stuff */ - e = time + n_time; - - /* See if there's a fraction, and discard it if so */ - if (p < e && *p == '.' && p + 5 <= e) - p += 5; - - /* See if it's UTC */ - if (p < e && *p == 'Z') { - p += 1; - - /* See if it has a timezone */ - } else if ((*p == '-' || *p == '+') && p + 3 <= e) { - int off, neg; - - neg = *p == '-'; - ++p; - - off = atoin (p, 2) * 3600; - if (off < 0 || off > 86400) - return 0; - p += 2; - - if (p + 2 <= e) { - off += atoin (p, 2) * 60; - p += 2; - } - - /* Use TZ offset */ - if (neg) - *offset = 0 - off; - else - *offset = off; - } - - /* Make sure everything got parsed */ - if (p != e) - return 0; - - return 1; -} - -static time_t -when_and_offset_to_time_t (struct tm *when, - int tz_offset) -{ - time_t timet; - - /* A 32-bit time, cannot represent this time */ - if (sizeof (time_t) <= 4 && when->tm_year >= 138) { - return -1; - - /* Convert to seconds since epoch */ - } else { - timet = timegm (when); - return_val_if_fail (timet >= 0, -1); - timet += tz_offset; - } - - if (!gmtime_r (&timet, when)) - return_val_if_reached (-1); - - return timet; -} - -time_t -p11_asn1_parse_utc (const char *time_str, - struct tm *when) -{ - struct tm dummy; - int tz_offset; - int ret; - - if (!when) - when = &dummy; - - ret = parse_utc_time (time_str, strlen (time_str), - when, &tz_offset); - if (!ret) - return -1; - - return when_and_offset_to_time_t (when, tz_offset); -} - -time_t -p11_asn1_parse_general (const char *time_str, - struct tm *when) -{ - struct tm dummy; - int tz_offset; - int ret; - - if (!when) - when = &dummy; - - ret = parse_general_time (time_str, strlen (time_str), - when, &tz_offset); - if (!ret) - return -1; - - return when_and_offset_to_time_t (when, tz_offset); -} - ssize_t p11_asn1_tlv_length (const unsigned char *data, size_t length) diff --git a/common/asn1.h b/common/asn1.h index c79e8f6..1bd7dd1 100644 --- a/common/asn1.h +++ b/common/asn1.h @@ -55,12 +55,6 @@ node_asn * p11_asn1_create (p11_dict *asn1_defs, unsigned char * p11_asn1_encode (node_asn *asn, size_t *der_len); -time_t p11_asn1_parse_utc (const char *time_str, - struct tm *when); - -time_t p11_asn1_parse_general (const char *time_str, - struct tm *when); - ssize_t p11_asn1_tlv_length (const unsigned char *data, size_t length); -- cgit v1.1