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_utctm.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_utctm.c')
-rw-r--r-- | crypto/asn1/a_utctm.c | 113 |
1 files changed, 2 insertions, 111 deletions
diff --git a/crypto/asn1/a_utctm.c b/crypto/asn1/a_utctm.c index 5a4b1742f7..2a864180e3 100644 --- a/crypto/asn1/a_utctm.c +++ b/crypto/asn1/a_utctm.c @@ -15,119 +15,10 @@ int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d) { - static const int min[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; - static const int max[8] = { 99, 12, 31, 23, 59, 59, 12, 59 }; - char *a; - int n, i, l, o, min_l = 11, strict = 0; - + /* wrapper around ans1_time_to_tm */ if (d->type != V_ASN1_UTCTIME) return 0; - l = d->length; - a = (char *)d->data; - o = 0; - - /* - * 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 - */ - - if (d->flags & ASN1_STRING_FLAG_X509_TIME) { - min_l = 13; - strict = 1; - } - - if (l < min_l) - goto err; - for (i = 0; i < 6; i++) { - if (!strict && (i == 5) && ((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 < 50 ? n + 100 : n; - break; - case 1: - tm->tm_mon = n - 1; - break; - case 2: - tm->tm_mday = n; - break; - case 3: - tm->tm_hour = n; - break; - case 4: - tm->tm_min = n; - break; - case 5: - tm->tm_sec = n; - break; - } - } - } - - /* - * '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 (o + 4 != l) - goto err; - for (i = 6; i < 8; 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 == 6) - offset = n * 3600; - else if (i == 7) - offset += n * 60; - } - o++; - } - if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign)) - return 0; - } else { - /* not Z, or not +/- in non-strict mode */ - return 0; - } - return o == l; - err: - return 0; + return asn1_time_to_tm(tm, d); } int ASN1_UTCTIME_check(const ASN1_UTCTIME *d) |