diff options
author | Paul Yang <yang.yang@baishancloud.com> | 2017-07-11 03:01:24 +0800 |
---|---|---|
committer | Pauli <paul.dale@oracle.com> | 2017-07-24 08:27:27 +1000 |
commit | 3d0f1cb9fdd630c6c920bc97bf496538717e7705 (patch) | |
tree | 9158a0ff2ce5d7385fd441d6ecd5eb05bcd1d63a /crypto/asn1/a_gentm.c | |
parent | a1099821f9937717f92464056d80f2e303a73a4d (diff) |
Add asn1_time_to_tm function and check days in month
Based on discussion in PR #3566. Reduce duplicated code in original
asn1_utctime_to_tm and asn1_generalizedtime_to_tm, and introduce a new
internal function asn1_time_to_tm. This function also checks if the days
in the input time string is valid or not for the corresponding month.
Test cases are also added.
Reviewed-by: Andy Polyakov <appro@openssl.org>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/3905)
Diffstat (limited to 'crypto/asn1/a_gentm.c')
-rw-r--r-- | crypto/asn1/a_gentm.c | 152 |
1 files changed, 4 insertions, 148 deletions
diff --git a/crypto/asn1/a_gentm.c b/crypto/asn1/a_gentm.c index 5cfc3ff15e..8b2b66b964 100644 --- a/crypto/asn1/a_gentm.c +++ b/crypto/asn1/a_gentm.c @@ -19,155 +19,11 @@ int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d) { - static const int min[9] = { 0, 0, 1, 1, 0, 0, 0, 0, 0 }; - static const int max[9] = { 99, 99, 12, 31, 23, 59, 59, 12, 59 }; - char *a; - int n, i, l, o, min_l = 13, strict = 0; - + /* wrapper around asn1_time_to_tm */ if (d->type != V_ASN1_GENERALIZEDTIME) - return (0); - l = d->length; - a = (char *)d->data; - o = 0; - /* - * GENERALIZEDTIME is similar to UTCTIME except the year is represented - * as YYYY. This stuff treats everything as a two digit field so make - * first two fields 00 to 99 - */ - - /* - * ASN1_STRING_FLAG_X509_TIME is used to enforce RFC 5280 - * time string format, in which: - * - * 1. "seconds" is a 'MUST' - * 2. "Zulu" timezone is a 'MUST' - * 3. "+|-" is not allowed to indicate a time zone - * 4. fractional seconds are not allowed in GeneralizedTime - */ - - if (d->flags & ASN1_STRING_FLAG_X509_TIME) { - min_l = 15; - strict = 1; - } - - if (l < min_l) - goto err; - for (i = 0; i < 7; i++) { - if (!strict && (i == 6) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) { - i++; - if (tm) - tm->tm_sec = 0; - break; - } - if ((a[o] < '0') || (a[o] > '9')) - goto err; - n = a[o] - '0'; - /* incomplete 2-digital number */ - if (++o == l) - goto err; - - if ((a[o] < '0') || (a[o] > '9')) - goto err; - n = (n * 10) + a[o] - '0'; - /* no more bytes to read, but we haven't seen time-zone yet */ - if (++o == l) - goto err; - - if ((n < min[i]) || (n > max[i])) - goto err; - if (tm) { - switch (i) { - case 0: - tm->tm_year = n * 100 - 1900; - break; - case 1: - tm->tm_year += n; - break; - case 2: - tm->tm_mon = n - 1; - break; - case 3: - tm->tm_mday = n; - break; - case 4: - tm->tm_hour = n; - break; - case 5: - tm->tm_min = n; - break; - case 6: - tm->tm_sec = n; - break; - } - } - } - /* - * Optional fractional seconds: decimal point followed by one or more - * digits. - */ - if (a[o] == '.') { - if (strict) - /* RFC 5280 forbids fractional seconds */ - goto err; - if (++o == l) - goto err; - i = o; - while ((o < l) && (a[o] >= '0') && (a[o] <= '9')) - o++; - /* Must have at least one digit after decimal point */ - if (i == o) - goto err; - /* no more bytes to read, but we haven't seen time-zone yet */ - if (o == l) - goto err; - } - - /* - * 'o' will never point to '\0' at this point, the only chance - * 'o' can point th '\0' is either the subsequent if or the first - * else if is true. - */ - if (a[o] == 'Z') { - o++; - } else if (!strict && ((a[o] == '+') || (a[o] == '-'))) { - int offsign = a[o] == '-' ? 1 : -1, offset = 0; - o++; - /* - * if not equal, no need to do subsequent checks - * since the following for-loop will add 'o' by 4 - * and the final return statement will check if 'l' - * and 'o' are equal. - */ - if (o + 4 != l) - goto err; - for (i = 7; i < 9; i++) { - if ((a[o] < '0') || (a[o] > '9')) - goto err; - n = a[o] - '0'; - o++; - if ((a[o] < '0') || (a[o] > '9')) - goto err; - n = (n * 10) + a[o] - '0'; - if ((n < min[i]) || (n > max[i])) - goto err; - if (tm) { - if (i == 7) - offset = n * 3600; - else if (i == 8) - offset += n * 60; - } - o++; - } - if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign)) - return 0; - } else if (a[o]) { - /* Missing time zone information. */ - goto err; - } - return (o == l); - err: - return (0); -} + return 0; + return asn1_time_to_tm(tm, d); + } int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *d) { |