diff options
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libcrypto/asn1/a_gentm.c | 106 | ||||
| -rw-r--r-- | src/lib/libcrypto/asn1/a_time.c | 25 | ||||
| -rw-r--r-- | src/lib/libcrypto/asn1/a_time_tm.c | 257 | ||||
| -rw-r--r-- | src/lib/libcrypto/asn1/a_utctm.c | 80 | ||||
| -rw-r--r-- | src/lib/libcrypto/asn1/asn1_locl.h | 6 | ||||
| -rw-r--r-- | src/lib/libcrypto/crypto/Makefile | 3 | ||||
| -rw-r--r-- | src/lib/libcrypto/x509/x509_lcl.h | 1 | ||||
| -rw-r--r-- | src/lib/libcrypto/x509/x509_vfy.c | 128 | ||||
| -rw-r--r-- | src/lib/libssl/src/crypto/asn1/a_gentm.c | 106 | ||||
| -rw-r--r-- | src/lib/libssl/src/crypto/asn1/a_time.c | 25 | ||||
| -rw-r--r-- | src/lib/libssl/src/crypto/asn1/a_time_tm.c | 257 | ||||
| -rw-r--r-- | src/lib/libssl/src/crypto/asn1/a_utctm.c | 80 | ||||
| -rw-r--r-- | src/lib/libssl/src/crypto/asn1/asn1_locl.h | 6 | ||||
| -rw-r--r-- | src/lib/libssl/src/crypto/x509/x509_lcl.h | 1 | ||||
| -rw-r--r-- | src/lib/libssl/src/crypto/x509/x509_vfy.c | 128 |
15 files changed, 666 insertions, 543 deletions
diff --git a/src/lib/libcrypto/asn1/a_gentm.c b/src/lib/libcrypto/asn1/a_gentm.c index 4cee40437c..594eb63058 100644 --- a/src/lib/libcrypto/asn1/a_gentm.c +++ b/src/lib/libcrypto/asn1/a_gentm.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: a_gentm.c,v 1.24 2015/09/30 18:04:02 jsing Exp $ */ | 1 | /* $OpenBSD: a_gentm.c,v 1.25 2015/10/02 15:04:45 beck Exp $ */ |
| 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * | 4 | * |
| @@ -66,86 +66,14 @@ | |||
| 66 | #include <openssl/err.h> | 66 | #include <openssl/err.h> |
| 67 | 67 | ||
| 68 | #include "o_time.h" | 68 | #include "o_time.h" |
| 69 | #include "asn1_locl.h" | ||
| 69 | 70 | ||
| 70 | int | 71 | int |
| 71 | ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *d) | 72 | ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *d) |
| 72 | { | 73 | { |
| 73 | static const int min[9] = {0, 0, 1, 1, 0, 0, 0, 0, 0}; | ||
| 74 | static const int max[9] = {99, 99, 12, 31, 23, 59, 59, 12, 59}; | ||
| 75 | char *a; | ||
| 76 | int n, i, l, o; | ||
| 77 | |||
| 78 | if (d->type != V_ASN1_GENERALIZEDTIME) | 74 | if (d->type != V_ASN1_GENERALIZEDTIME) |
| 79 | return (0); | 75 | return (0); |
| 80 | l = d->length; | 76 | return (d->type == asn1_time_parse(d->data, d->length, NULL, d->type)); |
| 81 | a = (char *)d->data; | ||
| 82 | o = 0; | ||
| 83 | /* GENERALIZEDTIME is similar to UTCTIME except the year is | ||
| 84 | * represented as YYYY. This stuff treats everything as a two digit | ||
| 85 | * field so make first two fields 00 to 99 | ||
| 86 | */ | ||
| 87 | if (l < 13) | ||
| 88 | goto err; | ||
| 89 | for (i = 0; i < 7; i++) { | ||
| 90 | if ((i == 6) && ((a[o] == 'Z') || | ||
| 91 | (a[o] == '+') || (a[o] == '-'))) { | ||
| 92 | i++; | ||
| 93 | break; | ||
| 94 | } | ||
| 95 | if ((a[o] < '0') || (a[o] > '9')) | ||
| 96 | goto err; | ||
| 97 | n= a[o]-'0'; | ||
| 98 | if (++o > l) | ||
| 99 | goto err; | ||
| 100 | |||
| 101 | if ((a[o] < '0') || (a[o] > '9')) | ||
| 102 | goto err; | ||
| 103 | n = (n * 10)+ a[o] - '0'; | ||
| 104 | if (++o > l) | ||
| 105 | goto err; | ||
| 106 | |||
| 107 | if ((n < min[i]) || (n > max[i])) | ||
| 108 | goto err; | ||
| 109 | } | ||
| 110 | /* Optional fractional seconds: decimal point followed by one | ||
| 111 | * or more digits. | ||
| 112 | */ | ||
| 113 | if (a[o] == '.') { | ||
| 114 | if (++o > l) | ||
| 115 | goto err; | ||
| 116 | i = o; | ||
| 117 | while ((a[o] >= '0') && (a[o] <= '9') && (o <= l)) | ||
| 118 | o++; | ||
| 119 | /* Must have at least one digit after decimal point */ | ||
| 120 | if (i == o) | ||
| 121 | goto err; | ||
| 122 | } | ||
| 123 | |||
| 124 | if (a[o] == 'Z') | ||
| 125 | o++; | ||
| 126 | else if ((a[o] == '+') || (a[o] == '-')) { | ||
| 127 | o++; | ||
| 128 | if (o + 4 > l) | ||
| 129 | goto err; | ||
| 130 | for (i = 7; i < 9; i++) { | ||
| 131 | if ((a[o] < '0') || (a[o] > '9')) | ||
| 132 | goto err; | ||
| 133 | n = a[o] - '0'; | ||
| 134 | o++; | ||
| 135 | if ((a[o] < '0') || (a[o] > '9')) | ||
| 136 | goto err; | ||
| 137 | n = (n * 10) + a[o] - '0'; | ||
| 138 | if ((n < min[i]) || (n > max[i])) | ||
| 139 | goto err; | ||
| 140 | o++; | ||
| 141 | } | ||
| 142 | } else { | ||
| 143 | /* Missing time zone information. */ | ||
| 144 | goto err; | ||
| 145 | } | ||
| 146 | return (o == l); | ||
| 147 | err: | ||
| 148 | return (0); | ||
| 149 | } | 77 | } |
| 150 | 78 | ||
| 151 | int | 79 | int |
| @@ -179,34 +107,26 @@ ASN1_GENERALIZEDTIME_adj_internal(ASN1_GENERALIZEDTIME *s, time_t t, | |||
| 179 | int offset_day, long offset_sec) | 107 | int offset_day, long offset_sec) |
| 180 | { | 108 | { |
| 181 | char *p; | 109 | char *p; |
| 182 | struct tm *ts; | 110 | struct tm *tm; |
| 183 | struct tm data; | 111 | struct tm data; |
| 184 | size_t len = 20; | ||
| 185 | 112 | ||
| 186 | ts = gmtime_r(&t, &data); | 113 | tm = gmtime_r(&t, &data); |
| 187 | if (ts == NULL) | 114 | if (tm == NULL) |
| 188 | return (NULL); | 115 | return (NULL); |
| 189 | 116 | ||
| 190 | if (offset_day || offset_sec) { | 117 | if (offset_day || offset_sec) { |
| 191 | if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec)) | 118 | if (!OPENSSL_gmtime_adj(tm, offset_day, offset_sec)) |
| 192 | return NULL; | 119 | return NULL; |
| 193 | } | 120 | } |
| 194 | 121 | ||
| 195 | p = (char *)s->data; | 122 | if ((p = gentime_string_from_tm(tm)) == NULL) { |
| 196 | if ((p == NULL) || ((size_t)s->length < len)) { | 123 | ASN1err(ASN1_F_ASN1_GENERALIZEDTIME_ADJ, ERR_R_MALLOC_FAILURE); |
| 197 | p = malloc(len); | 124 | return (NULL); |
| 198 | if (p == NULL) { | ||
| 199 | ASN1err(ASN1_F_ASN1_GENERALIZEDTIME_ADJ, | ||
| 200 | ERR_R_MALLOC_FAILURE); | ||
| 201 | return (NULL); | ||
| 202 | } | ||
| 203 | free(s->data); | ||
| 204 | s->data = (unsigned char *)p; | ||
| 205 | } | 125 | } |
| 206 | 126 | free(s->data); | |
| 207 | snprintf(p, len, "%04d%02d%02d%02d%02d%02dZ", ts->tm_year + 1900, | 127 | s->data = p; |
| 208 | ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min, ts->tm_sec); | ||
| 209 | s->length = strlen(p); | 128 | s->length = strlen(p); |
| 129 | |||
| 210 | s->type = V_ASN1_GENERALIZEDTIME; | 130 | s->type = V_ASN1_GENERALIZEDTIME; |
| 211 | return (s); | 131 | return (s); |
| 212 | } | 132 | } |
diff --git a/src/lib/libcrypto/asn1/a_time.c b/src/lib/libcrypto/asn1/a_time.c index 25a1805640..a6c7c8e736 100644 --- a/src/lib/libcrypto/asn1/a_time.c +++ b/src/lib/libcrypto/asn1/a_time.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: a_time.c,v 1.25 2015/09/30 18:04:02 jsing Exp $ */ | 1 | /* $OpenBSD: a_time.c,v 1.26 2015/10/02 15:04:45 beck Exp $ */ |
| 2 | /* ==================================================================== | 2 | /* ==================================================================== |
| 3 | * Copyright (c) 1999 The OpenSSL Project. All rights reserved. | 3 | * Copyright (c) 1999 The OpenSSL Project. All rights reserved. |
| 4 | * | 4 | * |
| @@ -68,7 +68,7 @@ | |||
| 68 | #include <openssl/err.h> | 68 | #include <openssl/err.h> |
| 69 | 69 | ||
| 70 | #include "o_time.h" | 70 | #include "o_time.h" |
| 71 | 71 | #include "asn1_locl.h" | |
| 72 | 72 | ||
| 73 | const ASN1_ITEM ASN1_TIME_it = { | 73 | const ASN1_ITEM ASN1_TIME_it = { |
| 74 | .itype = ASN1_ITYPE_MSTRING, | 74 | .itype = ASN1_ITYPE_MSTRING, |
| @@ -135,11 +135,9 @@ ASN1_TIME_adj(ASN1_TIME *s, time_t t, int offset_day, long offset_sec) | |||
| 135 | int | 135 | int |
| 136 | ASN1_TIME_check(ASN1_TIME *t) | 136 | ASN1_TIME_check(ASN1_TIME *t) |
| 137 | { | 137 | { |
| 138 | if (t->type == V_ASN1_GENERALIZEDTIME) | 138 | if (t->type != V_ASN1_GENERALIZEDTIME && t->type != V_ASN1_UTCTIME) |
| 139 | return ASN1_GENERALIZEDTIME_check(t); | 139 | return 0; |
| 140 | else if (t->type == V_ASN1_UTCTIME) | 140 | return (t->type == asn1_time_parse(t->data, t->length, NULL, t->type)); |
| 141 | return ASN1_UTCTIME_check(t); | ||
| 142 | return 0; | ||
| 143 | } | 141 | } |
| 144 | 142 | ||
| 145 | /* Convert an ASN1_TIME structure to GeneralizedTime */ | 143 | /* Convert an ASN1_TIME structure to GeneralizedTime */ |
| @@ -210,13 +208,12 @@ ASN1_TIME_set_string(ASN1_TIME *s, const char *str) | |||
| 210 | t.data = (unsigned char *)str; | 208 | t.data = (unsigned char *)str; |
| 211 | t.flags = 0; | 209 | t.flags = 0; |
| 212 | 210 | ||
| 213 | t.type = V_ASN1_UTCTIME; | 211 | t.type = asn1_time_parse(t.data, t.length, NULL, V_ASN1_UTCTIME); |
| 214 | 212 | if (t.type == -1) | |
| 215 | if (!ASN1_TIME_check(&t)) { | 213 | t.type = asn1_time_parse(t.data, t.length, NULL, |
| 216 | t.type = V_ASN1_GENERALIZEDTIME; | 214 | V_ASN1_GENERALIZEDTIME); |
| 217 | if (!ASN1_TIME_check(&t)) | 215 | if (t.type == -1) |
| 218 | return 0; | 216 | return 0; |
| 219 | } | ||
| 220 | 217 | ||
| 221 | if (s && !ASN1_STRING_copy((ASN1_STRING *)s, (ASN1_STRING *)&t)) | 218 | if (s && !ASN1_STRING_copy((ASN1_STRING *)s, (ASN1_STRING *)&t)) |
| 222 | return 0; | 219 | return 0; |
diff --git a/src/lib/libcrypto/asn1/a_time_tm.c b/src/lib/libcrypto/asn1/a_time_tm.c new file mode 100644 index 0000000000..65f75c68cc --- /dev/null +++ b/src/lib/libcrypto/asn1/a_time_tm.c | |||
| @@ -0,0 +1,257 @@ | |||
| 1 | /* $OpenBSD: a_time_tm.c,v 1.1 2015/10/02 15:04:45 beck Exp $ */ | ||
| 2 | /* | ||
| 3 | * Copyright (c) 2015 Bob Beck <beck@openbsd.org> | ||
| 4 | * | ||
| 5 | * Permission to use, copy, modify, and distribute this software for any | ||
| 6 | * purpose with or without fee is hereby granted, provided that the above | ||
| 7 | * copyright notice and this permission notice appear in all copies. | ||
| 8 | * | ||
| 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <stdio.h> | ||
| 19 | #include <string.h> | ||
| 20 | #include <time.h> | ||
| 21 | #include <ctype.h> | ||
| 22 | #include <sys/limits.h> | ||
| 23 | |||
| 24 | #include <openssl/asn1t.h> | ||
| 25 | #include <openssl/err.h> | ||
| 26 | |||
| 27 | #include "o_time.h" | ||
| 28 | #include "asn1_locl.h" | ||
| 29 | |||
| 30 | char * | ||
| 31 | gentime_string_from_tm(struct tm *tm) | ||
| 32 | { | ||
| 33 | char *ret = NULL; | ||
| 34 | int year; | ||
| 35 | year = tm->tm_year + 1900; | ||
| 36 | if (year < 0 || year > 9999) | ||
| 37 | return (NULL); | ||
| 38 | if (asprintf(&ret, "%04u%02u%02u%02u%02u%02uZ", year, | ||
| 39 | tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, | ||
| 40 | tm->tm_sec) == -1) | ||
| 41 | ret = NULL; | ||
| 42 | return (ret); | ||
| 43 | } | ||
| 44 | |||
| 45 | char * | ||
| 46 | utctime_string_from_tm(struct tm *tm) | ||
| 47 | { | ||
| 48 | char *ret = NULL; | ||
| 49 | if (tm->tm_year >= 150 || tm->tm_year < 50) | ||
| 50 | return (NULL); | ||
| 51 | if (asprintf(&ret, "%02u%02u%02u%02u%02u%02uZ", | ||
| 52 | tm->tm_year % 100, tm->tm_mon + 1, tm->tm_mday, | ||
| 53 | tm->tm_hour, tm->tm_min, tm->tm_sec) == -1) | ||
| 54 | ret = NULL; | ||
| 55 | return (ret); | ||
| 56 | } | ||
| 57 | |||
| 58 | /* | ||
| 59 | * Parse an ASN.1 time string. | ||
| 60 | * | ||
| 61 | * mode must be: | ||
| 62 | * 0 if we expect to parse a time as specified in RFC 5280 from an | ||
| 63 | * X509 certificate. | ||
| 64 | * V_ASN1_UTCTIME if we wish to parse a legacy ASN1 UTC time. | ||
| 65 | * V_ASN1_GENERALIZEDTIME if we wish to parse a legacy ASN1 | ||
| 66 | * Generalizd time. | ||
| 67 | * | ||
| 68 | * Returns: | ||
| 69 | * -1 if the string was invalid. | ||
| 70 | * V_ASN1_UTCTIME if the string validated as a UTC time string. | ||
| 71 | * V_ASN1_GENERALIZEDTIME if the string validated as a Generalized time string. | ||
| 72 | * | ||
| 73 | * Fills in *tm with the corresponding time if tm is non NULL. | ||
| 74 | */ | ||
| 75 | #define RFC5280 0 | ||
| 76 | #define ATOI2(ar) ((ar) += 2, ((ar)[-2] - '0') * 10 + ((ar)[-1] - '0')) | ||
| 77 | int asn1_time_parse(const char * bytes, size_t len, struct tm *tm, int mode) | ||
| 78 | { | ||
| 79 | char *p, *buf = NULL, *dot = NULL, *tz = NULL; | ||
| 80 | int i, offset, noseconds = 0, type = 0; | ||
| 81 | struct tm ltm; | ||
| 82 | struct tm *lt; | ||
| 83 | size_t tlen; | ||
| 84 | char tzc; | ||
| 85 | |||
| 86 | if (bytes == NULL) | ||
| 87 | goto err; | ||
| 88 | |||
| 89 | if (len > INT_MAX) | ||
| 90 | goto err; | ||
| 91 | |||
| 92 | /* Constrain the RFC5280 case within max/min valid lengths. */ | ||
| 93 | if (mode == RFC5280 && (len > 15 || len < 13)) | ||
| 94 | goto err; | ||
| 95 | |||
| 96 | if ((buf = strndup(bytes, len)) == NULL) | ||
| 97 | goto err; | ||
| 98 | lt = tm; | ||
| 99 | if (lt == NULL) { | ||
| 100 | time_t t = time(NULL); | ||
| 101 | lt = gmtime_r(&t, <m); | ||
| 102 | if (lt == NULL) | ||
| 103 | goto err; | ||
| 104 | } | ||
| 105 | |||
| 106 | /* | ||
| 107 | * Find position of the optional fractional seconds, and the | ||
| 108 | * start of the timezone, while ensuring everything else is | ||
| 109 | * digits. | ||
| 110 | */ | ||
| 111 | for (i = 0; i < len; i++) { | ||
| 112 | char *t = buf + i; | ||
| 113 | if (isdigit((unsigned char)*t)) | ||
| 114 | continue; | ||
| 115 | if (*t == '.' && dot == NULL) { | ||
| 116 | dot = t; | ||
| 117 | continue; | ||
| 118 | } | ||
| 119 | if ((*t == 'Z' || *t == '+' || *t == '-') && tz == NULL) { | ||
| 120 | tz = t; | ||
| 121 | continue; | ||
| 122 | } | ||
| 123 | goto err; | ||
| 124 | } | ||
| 125 | |||
| 126 | /* | ||
| 127 | * Timezone is required. For the non-RFC case it may be | ||
| 128 | * either Z or +- HHMM, but for RFC5280 it may be only Z. | ||
| 129 | */ | ||
| 130 | if (tz == NULL) | ||
| 131 | goto err; | ||
| 132 | tzc = *tz; | ||
| 133 | *tz++ = '\0'; | ||
| 134 | if (tzc == 'Z') { | ||
| 135 | if (*tz != '\0') | ||
| 136 | goto err; | ||
| 137 | offset = 0; | ||
| 138 | } else if (mode != RFC5280 && (tzc == '+' || tzc == '-') && | ||
| 139 | (strlen(tz) == 4)) { | ||
| 140 | int hours, mins; | ||
| 141 | hours = ATOI2(tz); | ||
| 142 | mins = ATOI2(tz); | ||
| 143 | if (hours > 12 || mins > 59) | ||
| 144 | goto err; | ||
| 145 | offset = hours * 3600 + mins * 60; | ||
| 146 | if (tzc == '-') | ||
| 147 | offset = -offset; | ||
| 148 | } else | ||
| 149 | goto err; | ||
| 150 | |||
| 151 | if (mode != RFC5280) { | ||
| 152 | /* XXX - yuck - OPENSSL_gmtime_adj should go away */ | ||
| 153 | if (!OPENSSL_gmtime_adj(lt, 0, offset)) | ||
| 154 | goto err; | ||
| 155 | } | ||
| 156 | |||
| 157 | /* | ||
| 158 | * We only allow fractional seconds to be present if we are in | ||
| 159 | * the non-RFC case of a Generalized time. RFC 5280 forbids | ||
| 160 | * fractional seconds. | ||
| 161 | */ | ||
| 162 | if (dot != NULL) { | ||
| 163 | if (mode != V_ASN1_GENERALIZEDTIME) | ||
| 164 | goto err; | ||
| 165 | *dot++ = '\0'; | ||
| 166 | if (!isdigit((unsigned char)*dot)) | ||
| 167 | goto err; | ||
| 168 | } | ||
| 169 | |||
| 170 | /* | ||
| 171 | * Validate and convert the time | ||
| 172 | */ | ||
| 173 | p = buf; | ||
| 174 | tlen = strlen(buf); | ||
| 175 | switch (tlen) { | ||
| 176 | case 14: | ||
| 177 | lt->tm_year = (ATOI2(p) * 100) - 1900; /* cc */ | ||
| 178 | if (mode == RFC5280 || mode == V_ASN1_GENERALIZEDTIME) | ||
| 179 | type = V_ASN1_GENERALIZEDTIME; | ||
| 180 | else | ||
| 181 | goto err; | ||
| 182 | /* FALLTHROUGH */ | ||
| 183 | case 12: | ||
| 184 | if (type == 0 && mode == V_ASN1_GENERALIZEDTIME) { | ||
| 185 | /* | ||
| 186 | * In the non-RFC case of a Generalized time | ||
| 187 | * seconds may not have been provided. RFC | ||
| 188 | * 5280 mandates that seconds must be present. | ||
| 189 | */ | ||
| 190 | noseconds = 1; | ||
| 191 | lt->tm_year = (ATOI2(p) * 100) - 1900; /* cc */ | ||
| 192 | type = V_ASN1_GENERALIZEDTIME; | ||
| 193 | } | ||
| 194 | /* FALLTHROUGH */ | ||
| 195 | case 10: | ||
| 196 | if (type == 0) { | ||
| 197 | /* | ||
| 198 | * At this point we must have a UTC time. | ||
| 199 | * In the RFC 5280 case it must have the | ||
| 200 | * seconds present. In the non-RFC case | ||
| 201 | * may have no seconds. | ||
| 202 | */ | ||
| 203 | if (mode == V_ASN1_GENERALIZEDTIME) | ||
| 204 | goto err; | ||
| 205 | if (tlen == 10) { | ||
| 206 | if (mode == V_ASN1_UTCTIME) | ||
| 207 | noseconds = 1; | ||
| 208 | else | ||
| 209 | goto err; | ||
| 210 | } | ||
| 211 | type = V_ASN1_UTCTIME; | ||
| 212 | } | ||
| 213 | lt->tm_year += ATOI2(p); /* yy */ | ||
| 214 | if (type == V_ASN1_UTCTIME) { | ||
| 215 | if (lt->tm_year < 50) | ||
| 216 | lt->tm_year += 100; | ||
| 217 | } | ||
| 218 | lt->tm_mon = ATOI2(p); /* mm */ | ||
| 219 | if ((lt->tm_mon > 12) || !lt->tm_mon) | ||
| 220 | goto err; | ||
| 221 | --lt->tm_mon; /* struct tm is 0 - 11 */ | ||
| 222 | lt->tm_mday = ATOI2(p); /* dd */ | ||
| 223 | if ((lt->tm_mday > 31) || !lt->tm_mday) | ||
| 224 | goto err; | ||
| 225 | lt->tm_hour = ATOI2(p); /* HH */ | ||
| 226 | if (lt->tm_hour > 23) | ||
| 227 | goto err; | ||
| 228 | lt->tm_min = ATOI2(p); /* MM */ | ||
| 229 | if (lt->tm_min > 59) | ||
| 230 | goto err; | ||
| 231 | lt->tm_sec = 0; /* SS */ | ||
| 232 | if (noseconds) | ||
| 233 | break; | ||
| 234 | lt->tm_sec = ATOI2(p); | ||
| 235 | /* Leap second 60 is not accepted. Reconsider later? */ | ||
| 236 | if (lt->tm_sec > 59) | ||
| 237 | goto err; | ||
| 238 | break; | ||
| 239 | default: | ||
| 240 | goto err; | ||
| 241 | } | ||
| 242 | |||
| 243 | /* RFC 5280 section 4.1.2.5 */ | ||
| 244 | if (mode == RFC5280 && lt->tm_year < 150 && | ||
| 245 | type != V_ASN1_UTCTIME) | ||
| 246 | goto err; | ||
| 247 | if (mode == RFC5280 && lt->tm_year >= 150 && | ||
| 248 | type != V_ASN1_GENERALIZEDTIME) | ||
| 249 | goto err; | ||
| 250 | |||
| 251 | free(buf); | ||
| 252 | return type; | ||
| 253 | |||
| 254 | err: | ||
| 255 | free(buf); | ||
| 256 | return -1; | ||
| 257 | } | ||
diff --git a/src/lib/libcrypto/asn1/a_utctm.c b/src/lib/libcrypto/asn1/a_utctm.c index ca19a8c7a0..c208d494c3 100644 --- a/src/lib/libcrypto/asn1/a_utctm.c +++ b/src/lib/libcrypto/asn1/a_utctm.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: a_utctm.c,v 1.28 2015/09/30 18:26:07 jsing Exp $ */ | 1 | /* $OpenBSD: a_utctm.c,v 1.29 2015/10/02 15:04:45 beck Exp $ */ |
| 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * | 4 | * |
| @@ -64,66 +64,14 @@ | |||
| 64 | #include <openssl/err.h> | 64 | #include <openssl/err.h> |
| 65 | 65 | ||
| 66 | #include "o_time.h" | 66 | #include "o_time.h" |
| 67 | #include "asn1_locl.h" | ||
| 67 | 68 | ||
| 68 | int | 69 | int |
| 69 | ASN1_UTCTIME_check(ASN1_UTCTIME *d) | 70 | ASN1_UTCTIME_check(ASN1_UTCTIME *d) |
| 70 | { | 71 | { |
| 71 | static const int min[8] = {0, 1, 1, 0, 0, 0, 0, 0}; | ||
| 72 | static const int max[8] = {99, 12, 31, 23, 59, 59, 12, 59}; | ||
| 73 | char *a; | ||
| 74 | int n, i, l, o; | ||
| 75 | |||
| 76 | if (d->type != V_ASN1_UTCTIME) | 72 | if (d->type != V_ASN1_UTCTIME) |
| 77 | return (0); | 73 | return (0); |
| 78 | l = d->length; | 74 | return(d->type == asn1_time_parse(d->data, d->length, NULL, d->type)); |
| 79 | a = (char *)d->data; | ||
| 80 | o = 0; | ||
| 81 | |||
| 82 | if (l < 11) | ||
| 83 | |||
| 84 | goto err; | ||
| 85 | for (i = 0; i < 6; i++) { | ||
| 86 | if ((i == 5) && ((a[o] == 'Z') || | ||
| 87 | (a[o] == '+') || (a[o] == '-'))) { | ||
| 88 | i++; | ||
| 89 | break; | ||
| 90 | } | ||
| 91 | if ((a[o] < '0') || (a[o] > '9')) | ||
| 92 | goto err; | ||
| 93 | n = a[o]-'0'; | ||
| 94 | if (++o > l) | ||
| 95 | goto err; | ||
| 96 | if ((a[o] < '0') || (a[o] > '9')) | ||
| 97 | goto err; | ||
| 98 | n = (n * 10) + a[o] - '0'; | ||
| 99 | if (++o > l) | ||
| 100 | goto err; | ||
| 101 | if ((n < min[i]) || (n > max[i])) | ||
| 102 | goto err; | ||
| 103 | } | ||
| 104 | if (a[o] == 'Z') | ||
| 105 | o++; | ||
| 106 | else if ((a[o] == '+') || (a[o] == '-')) { | ||
| 107 | o++; | ||
| 108 | if (o + 4 > l) | ||
| 109 | goto err; | ||
| 110 | for (i = 6; i < 8; i++) { | ||
| 111 | if ((a[o] < '0') || (a[o] > '9')) | ||
| 112 | goto err; | ||
| 113 | n = a[o] -'0'; | ||
| 114 | o++; | ||
| 115 | if ((a[o] < '0') || (a[o] > '9')) | ||
| 116 | goto err; | ||
| 117 | n = (n * 10) + a[o] - '0'; | ||
| 118 | if ((n < min[i]) || (n > max[i])) | ||
| 119 | goto err; | ||
| 120 | o++; | ||
| 121 | } | ||
| 122 | } | ||
| 123 | return (o == l); | ||
| 124 | |||
| 125 | err: | ||
| 126 | return (0); | ||
| 127 | } | 75 | } |
| 128 | 76 | ||
| 129 | int | 77 | int |
| @@ -159,7 +107,6 @@ ASN1_UTCTIME_adj_internal(ASN1_UTCTIME *s, time_t t, int offset_day, | |||
| 159 | char *p; | 107 | char *p; |
| 160 | struct tm *ts; | 108 | struct tm *ts; |
| 161 | struct tm data; | 109 | struct tm data; |
| 162 | size_t len = 20; | ||
| 163 | 110 | ||
| 164 | ts = gmtime_r(&t, &data); | 111 | ts = gmtime_r(&t, &data); |
| 165 | if (ts == NULL) | 112 | if (ts == NULL) |
| @@ -170,23 +117,14 @@ ASN1_UTCTIME_adj_internal(ASN1_UTCTIME *s, time_t t, int offset_day, | |||
| 170 | return NULL; | 117 | return NULL; |
| 171 | } | 118 | } |
| 172 | 119 | ||
| 173 | if ((ts->tm_year < 50) || (ts->tm_year >= 150)) | 120 | if ((p = utctime_string_from_tm(ts)) == NULL) { |
| 174 | return NULL; | 121 | ASN1err(ASN1_F_ASN1_UTCTIME_ADJ, ERR_R_MALLOC_FAILURE); |
| 175 | 122 | return (NULL); | |
| 176 | p = (char *)s->data; | ||
| 177 | if ((p == NULL) || ((size_t)s->length < len)) { | ||
| 178 | p = malloc(len); | ||
| 179 | if (p == NULL) { | ||
| 180 | ASN1err(ASN1_F_ASN1_UTCTIME_ADJ, ERR_R_MALLOC_FAILURE); | ||
| 181 | return (NULL); | ||
| 182 | } | ||
| 183 | free(s->data); | ||
| 184 | s->data = (unsigned char *)p; | ||
| 185 | } | 123 | } |
| 186 | 124 | free(s->data); | |
| 187 | snprintf(p, len, "%02d%02d%02d%02d%02d%02dZ", ts->tm_year % 100, | 125 | s->data = p; |
| 188 | ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min, ts->tm_sec); | ||
| 189 | s->length = strlen(p); | 126 | s->length = strlen(p); |
| 127 | |||
| 190 | s->type = V_ASN1_UTCTIME; | 128 | s->type = V_ASN1_UTCTIME; |
| 191 | return (s); | 129 | return (s); |
| 192 | } | 130 | } |
diff --git a/src/lib/libcrypto/asn1/asn1_locl.h b/src/lib/libcrypto/asn1/asn1_locl.h index c6c80aa6aa..d4994c7cee 100644 --- a/src/lib/libcrypto/asn1/asn1_locl.h +++ b/src/lib/libcrypto/asn1/asn1_locl.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: asn1_locl.h,v 1.5 2014/06/12 15:49:27 deraadt Exp $ */ | 1 | /* $OpenBSD: asn1_locl.h,v 1.6 2015/10/02 15:04:45 beck Exp $ */ |
| 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
| 3 | * project 2006. | 3 | * project 2006. |
| 4 | */ | 4 | */ |
| @@ -58,6 +58,10 @@ | |||
| 58 | 58 | ||
| 59 | /* Internal ASN1 structures and functions: not for application use */ | 59 | /* Internal ASN1 structures and functions: not for application use */ |
| 60 | 60 | ||
| 61 | char * gentime_string_from_tm(struct tm *tm); | ||
| 62 | char * utctime_string_from_tm(struct tm *tm); | ||
| 63 | int asn1_time_parse(const char *, size_t, struct tm *, int); | ||
| 64 | |||
| 61 | /* ASN1 print context structure */ | 65 | /* ASN1 print context structure */ |
| 62 | 66 | ||
| 63 | struct asn1_pctx_st { | 67 | struct asn1_pctx_st { |
diff --git a/src/lib/libcrypto/crypto/Makefile b/src/lib/libcrypto/crypto/Makefile index 9a58b30627..64ee774518 100644 --- a/src/lib/libcrypto/crypto/Makefile +++ b/src/lib/libcrypto/crypto/Makefile | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | # $OpenBSD: Makefile,v 1.65 2015/09/14 01:45:03 doug Exp $ | 1 | # $OpenBSD: Makefile,v 1.66 2015/10/02 15:04:45 beck Exp $ |
| 2 | 2 | ||
| 3 | LIB= crypto | 3 | LIB= crypto |
| 4 | 4 | ||
| @@ -49,6 +49,7 @@ SRCS+= f_enum.c x_pkey.c a_bool.c x_exten.c bio_asn1.c bio_ndef.c asn_mime.c | |||
| 49 | SRCS+= asn1_gen.c asn1_par.c asn1_lib.c asn1_err.c a_bytes.c a_strnid.c | 49 | SRCS+= asn1_gen.c asn1_par.c asn1_lib.c asn1_err.c a_bytes.c a_strnid.c |
| 50 | SRCS+= evp_asn1.c asn_pack.c p5_pbe.c p5_pbev2.c p8_pkey.c asn_moid.c | 50 | SRCS+= evp_asn1.c asn_pack.c p5_pbe.c p5_pbev2.c p8_pkey.c asn_moid.c |
| 51 | SRCS+= a_set.c | 51 | SRCS+= a_set.c |
| 52 | SRCS+= a_time_tm.c | ||
| 52 | 53 | ||
| 53 | # bf/ | 54 | # bf/ |
| 54 | SRCS+= bf_skey.c bf_ecb.c bf_cfb64.c bf_ofb64.c | 55 | SRCS+= bf_skey.c bf_ecb.c bf_cfb64.c bf_ofb64.c |
diff --git a/src/lib/libcrypto/x509/x509_lcl.h b/src/lib/libcrypto/x509/x509_lcl.h index b16df78ad7..0c1c130d5c 100644 --- a/src/lib/libcrypto/x509/x509_lcl.h +++ b/src/lib/libcrypto/x509/x509_lcl.h | |||
| @@ -57,3 +57,4 @@ | |||
| 57 | */ | 57 | */ |
| 58 | 58 | ||
| 59 | int x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int quiet); | 59 | int x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int quiet); |
| 60 | int asn1_time_parse(const char *, size_t, struct tm *, int); | ||
diff --git a/src/lib/libcrypto/x509/x509_vfy.c b/src/lib/libcrypto/x509/x509_vfy.c index 8d4d15668e..c48143f351 100644 --- a/src/lib/libcrypto/x509/x509_vfy.c +++ b/src/lib/libcrypto/x509/x509_vfy.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: x509_vfy.c,v 1.45 2015/09/14 16:13:39 jsing Exp $ */ | 1 | /* $OpenBSD: x509_vfy.c,v 1.46 2015/10/02 15:04:45 beck Exp $ */ |
| 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * | 4 | * |
| @@ -1631,106 +1631,50 @@ X509_cmp_current_time(const ASN1_TIME *ctm) | |||
| 1631 | return X509_cmp_time(ctm, NULL); | 1631 | return X509_cmp_time(ctm, NULL); |
| 1632 | } | 1632 | } |
| 1633 | 1633 | ||
| 1634 | /* | ||
| 1635 | * Compare a possibly unvalidated ASN1_TIME string against a time_t | ||
| 1636 | * using RFC 5280 rules for the time string. If *cmp_time is NULL | ||
| 1637 | * the current system time is used. | ||
| 1638 | * | ||
| 1639 | * XXX NOTE that unlike what you expect a "cmp" function to do in C, | ||
| 1640 | * XXX this one is "special", and returns 0 for error. | ||
| 1641 | * | ||
| 1642 | * Returns: | ||
| 1643 | * -1 if the ASN1_time is earlier than OR the same as *cmp_time. | ||
| 1644 | * 1 if the ASN1_time is later than *cmp_time. | ||
| 1645 | * 0 on error. | ||
| 1646 | */ | ||
| 1634 | int | 1647 | int |
| 1635 | X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) | 1648 | X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) |
| 1636 | { | 1649 | { |
| 1637 | char *str; | 1650 | time_t time1, time2; |
| 1638 | ASN1_TIME atm; | 1651 | struct tm tm1; |
| 1639 | long offset; | 1652 | int ret = 0; |
| 1640 | char buff1[24], buff2[24], *p; | ||
| 1641 | int i, j; | ||
| 1642 | 1653 | ||
| 1643 | p = buff1; | 1654 | if (cmp_time == NULL) |
| 1644 | i = ctm->length; | 1655 | time2 = time(NULL); |
| 1645 | str = (char *)ctm->data; | 1656 | else |
| 1646 | if (ctm->type == V_ASN1_UTCTIME) { | 1657 | time2 = *cmp_time; |
| 1647 | if ((i < 11) || (i > 17)) | ||
| 1648 | return 0; | ||
| 1649 | memcpy(p, str, 10); | ||
| 1650 | p += 10; | ||
| 1651 | str += 10; | ||
| 1652 | i -= 10; | ||
| 1653 | } else { | ||
| 1654 | if (i < 13) | ||
| 1655 | return 0; | ||
| 1656 | memcpy(p, str, 12); | ||
| 1657 | p += 12; | ||
| 1658 | str += 12; | ||
| 1659 | i -= 12; | ||
| 1660 | } | ||
| 1661 | 1658 | ||
| 1662 | if (i < 1) | 1659 | memset(&tm1, 0, sizeof(tm1)); |
| 1663 | return 0; | ||
| 1664 | if ((*str == 'Z') || (*str == '-') || (*str == '+')) { | ||
| 1665 | *(p++) = '0'; | ||
| 1666 | *(p++) = '0'; | ||
| 1667 | } else { | ||
| 1668 | if (i < 2) | ||
| 1669 | return 0; | ||
| 1670 | *(p++) = *(str++); | ||
| 1671 | *(p++) = *(str++); | ||
| 1672 | i -= 2; | ||
| 1673 | if (i < 1) | ||
| 1674 | return 0; | ||
| 1675 | /* Skip any fractional seconds... */ | ||
| 1676 | if (*str == '.') { | ||
| 1677 | str++; | ||
| 1678 | i--; | ||
| 1679 | while (i > 1 && (*str >= '0') && (*str <= '9')) { | ||
| 1680 | str++; | ||
| 1681 | i--; | ||
| 1682 | } | ||
| 1683 | } | ||
| 1684 | } | ||
| 1685 | *(p++) = 'Z'; | ||
| 1686 | *(p++) = '\0'; | ||
| 1687 | 1660 | ||
| 1688 | if (i < 1) | 1661 | if (asn1_time_parse(ctm->data, ctm->length, &tm1, 0) == -1) |
| 1689 | return 0; | 1662 | goto out; /* invalid time */ |
| 1690 | if (*str == 'Z') { | ||
| 1691 | if (i != 1) | ||
| 1692 | return 0; | ||
| 1693 | offset = 0; | ||
| 1694 | } else { | ||
| 1695 | if (i != 5) | ||
| 1696 | return 0; | ||
| 1697 | if ((*str != '+') && (*str != '-')) | ||
| 1698 | return 0; | ||
| 1699 | if (str[1] < '0' || str[1] > '9' || | ||
| 1700 | str[2] < '0' || str[2] > '9' || | ||
| 1701 | str[3] < '0' || str[3] > '9' || | ||
| 1702 | str[4] < '0' || str[4] > '9') | ||
| 1703 | return 0; | ||
| 1704 | offset = ((str[1] - '0') * 10 + (str[2] - '0')) * 60; | ||
| 1705 | offset += (str[3] - '0') * 10 + (str[4] - '0'); | ||
| 1706 | if (*str == '-') | ||
| 1707 | offset = -offset; | ||
| 1708 | } | ||
| 1709 | atm.type = ctm->type; | ||
| 1710 | atm.flags = 0; | ||
| 1711 | atm.length = sizeof(buff2); | ||
| 1712 | atm.data = (unsigned char *)buff2; | ||
| 1713 | 1663 | ||
| 1714 | if (X509_time_adj(&atm, offset * 60, cmp_time) == NULL) | 1664 | /* |
| 1715 | return 0; | 1665 | * Defensively fail if the time string is not representable as |
| 1666 | * a time_t. A time_t must be sane if you care about times after | ||
| 1667 | * Jan 19 2038. | ||
| 1668 | */ | ||
| 1669 | if ((time1 = timegm(&tm1)) == -1) | ||
| 1670 | goto out; | ||
| 1716 | 1671 | ||
| 1717 | if (ctm->type == V_ASN1_UTCTIME) { | 1672 | if (time1 <= time2) |
| 1718 | i = (buff1[0] - '0') * 10 + (buff1[1] - '0'); | 1673 | ret = -1; |
| 1719 | if (i < 50) | ||
| 1720 | i += 100; /* cf. RFC 2459 */ | ||
| 1721 | j = (buff2[0] - '0') * 10 + (buff2[1] - '0'); | ||
| 1722 | if (j < 50) | ||
| 1723 | j += 100; | ||
| 1724 | if (i < j) | ||
| 1725 | return -1; | ||
| 1726 | if (i > j) | ||
| 1727 | return 1; | ||
| 1728 | } | ||
| 1729 | i = strcmp(buff1, buff2); | ||
| 1730 | if (i == 0) /* wait a second then return younger :-) */ | ||
| 1731 | return -1; | ||
| 1732 | else | 1674 | else |
| 1733 | return i; | 1675 | ret = 1; |
| 1676 | out: | ||
| 1677 | return (ret); | ||
| 1734 | } | 1678 | } |
| 1735 | 1679 | ||
| 1736 | ASN1_TIME * | 1680 | ASN1_TIME * |
diff --git a/src/lib/libssl/src/crypto/asn1/a_gentm.c b/src/lib/libssl/src/crypto/asn1/a_gentm.c index 4cee40437c..594eb63058 100644 --- a/src/lib/libssl/src/crypto/asn1/a_gentm.c +++ b/src/lib/libssl/src/crypto/asn1/a_gentm.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: a_gentm.c,v 1.24 2015/09/30 18:04:02 jsing Exp $ */ | 1 | /* $OpenBSD: a_gentm.c,v 1.25 2015/10/02 15:04:45 beck Exp $ */ |
| 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * | 4 | * |
| @@ -66,86 +66,14 @@ | |||
| 66 | #include <openssl/err.h> | 66 | #include <openssl/err.h> |
| 67 | 67 | ||
| 68 | #include "o_time.h" | 68 | #include "o_time.h" |
| 69 | #include "asn1_locl.h" | ||
| 69 | 70 | ||
| 70 | int | 71 | int |
| 71 | ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *d) | 72 | ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *d) |
| 72 | { | 73 | { |
| 73 | static const int min[9] = {0, 0, 1, 1, 0, 0, 0, 0, 0}; | ||
| 74 | static const int max[9] = {99, 99, 12, 31, 23, 59, 59, 12, 59}; | ||
| 75 | char *a; | ||
| 76 | int n, i, l, o; | ||
| 77 | |||
| 78 | if (d->type != V_ASN1_GENERALIZEDTIME) | 74 | if (d->type != V_ASN1_GENERALIZEDTIME) |
| 79 | return (0); | 75 | return (0); |
| 80 | l = d->length; | 76 | return (d->type == asn1_time_parse(d->data, d->length, NULL, d->type)); |
| 81 | a = (char *)d->data; | ||
| 82 | o = 0; | ||
| 83 | /* GENERALIZEDTIME is similar to UTCTIME except the year is | ||
| 84 | * represented as YYYY. This stuff treats everything as a two digit | ||
| 85 | * field so make first two fields 00 to 99 | ||
| 86 | */ | ||
| 87 | if (l < 13) | ||
| 88 | goto err; | ||
| 89 | for (i = 0; i < 7; i++) { | ||
| 90 | if ((i == 6) && ((a[o] == 'Z') || | ||
| 91 | (a[o] == '+') || (a[o] == '-'))) { | ||
| 92 | i++; | ||
| 93 | break; | ||
| 94 | } | ||
| 95 | if ((a[o] < '0') || (a[o] > '9')) | ||
| 96 | goto err; | ||
| 97 | n= a[o]-'0'; | ||
| 98 | if (++o > l) | ||
| 99 | goto err; | ||
| 100 | |||
| 101 | if ((a[o] < '0') || (a[o] > '9')) | ||
| 102 | goto err; | ||
| 103 | n = (n * 10)+ a[o] - '0'; | ||
| 104 | if (++o > l) | ||
| 105 | goto err; | ||
| 106 | |||
| 107 | if ((n < min[i]) || (n > max[i])) | ||
| 108 | goto err; | ||
| 109 | } | ||
| 110 | /* Optional fractional seconds: decimal point followed by one | ||
| 111 | * or more digits. | ||
| 112 | */ | ||
| 113 | if (a[o] == '.') { | ||
| 114 | if (++o > l) | ||
| 115 | goto err; | ||
| 116 | i = o; | ||
| 117 | while ((a[o] >= '0') && (a[o] <= '9') && (o <= l)) | ||
| 118 | o++; | ||
| 119 | /* Must have at least one digit after decimal point */ | ||
| 120 | if (i == o) | ||
| 121 | goto err; | ||
| 122 | } | ||
| 123 | |||
| 124 | if (a[o] == 'Z') | ||
| 125 | o++; | ||
| 126 | else if ((a[o] == '+') || (a[o] == '-')) { | ||
| 127 | o++; | ||
| 128 | if (o + 4 > l) | ||
| 129 | goto err; | ||
| 130 | for (i = 7; i < 9; i++) { | ||
| 131 | if ((a[o] < '0') || (a[o] > '9')) | ||
| 132 | goto err; | ||
| 133 | n = a[o] - '0'; | ||
| 134 | o++; | ||
| 135 | if ((a[o] < '0') || (a[o] > '9')) | ||
| 136 | goto err; | ||
| 137 | n = (n * 10) + a[o] - '0'; | ||
| 138 | if ((n < min[i]) || (n > max[i])) | ||
| 139 | goto err; | ||
| 140 | o++; | ||
| 141 | } | ||
| 142 | } else { | ||
| 143 | /* Missing time zone information. */ | ||
| 144 | goto err; | ||
| 145 | } | ||
| 146 | return (o == l); | ||
| 147 | err: | ||
| 148 | return (0); | ||
| 149 | } | 77 | } |
| 150 | 78 | ||
| 151 | int | 79 | int |
| @@ -179,34 +107,26 @@ ASN1_GENERALIZEDTIME_adj_internal(ASN1_GENERALIZEDTIME *s, time_t t, | |||
| 179 | int offset_day, long offset_sec) | 107 | int offset_day, long offset_sec) |
| 180 | { | 108 | { |
| 181 | char *p; | 109 | char *p; |
| 182 | struct tm *ts; | 110 | struct tm *tm; |
| 183 | struct tm data; | 111 | struct tm data; |
| 184 | size_t len = 20; | ||
| 185 | 112 | ||
| 186 | ts = gmtime_r(&t, &data); | 113 | tm = gmtime_r(&t, &data); |
| 187 | if (ts == NULL) | 114 | if (tm == NULL) |
| 188 | return (NULL); | 115 | return (NULL); |
| 189 | 116 | ||
| 190 | if (offset_day || offset_sec) { | 117 | if (offset_day || offset_sec) { |
| 191 | if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec)) | 118 | if (!OPENSSL_gmtime_adj(tm, offset_day, offset_sec)) |
| 192 | return NULL; | 119 | return NULL; |
| 193 | } | 120 | } |
| 194 | 121 | ||
| 195 | p = (char *)s->data; | 122 | if ((p = gentime_string_from_tm(tm)) == NULL) { |
| 196 | if ((p == NULL) || ((size_t)s->length < len)) { | 123 | ASN1err(ASN1_F_ASN1_GENERALIZEDTIME_ADJ, ERR_R_MALLOC_FAILURE); |
| 197 | p = malloc(len); | 124 | return (NULL); |
| 198 | if (p == NULL) { | ||
| 199 | ASN1err(ASN1_F_ASN1_GENERALIZEDTIME_ADJ, | ||
| 200 | ERR_R_MALLOC_FAILURE); | ||
| 201 | return (NULL); | ||
| 202 | } | ||
| 203 | free(s->data); | ||
| 204 | s->data = (unsigned char *)p; | ||
| 205 | } | 125 | } |
| 206 | 126 | free(s->data); | |
| 207 | snprintf(p, len, "%04d%02d%02d%02d%02d%02dZ", ts->tm_year + 1900, | 127 | s->data = p; |
| 208 | ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min, ts->tm_sec); | ||
| 209 | s->length = strlen(p); | 128 | s->length = strlen(p); |
| 129 | |||
| 210 | s->type = V_ASN1_GENERALIZEDTIME; | 130 | s->type = V_ASN1_GENERALIZEDTIME; |
| 211 | return (s); | 131 | return (s); |
| 212 | } | 132 | } |
diff --git a/src/lib/libssl/src/crypto/asn1/a_time.c b/src/lib/libssl/src/crypto/asn1/a_time.c index 25a1805640..a6c7c8e736 100644 --- a/src/lib/libssl/src/crypto/asn1/a_time.c +++ b/src/lib/libssl/src/crypto/asn1/a_time.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: a_time.c,v 1.25 2015/09/30 18:04:02 jsing Exp $ */ | 1 | /* $OpenBSD: a_time.c,v 1.26 2015/10/02 15:04:45 beck Exp $ */ |
| 2 | /* ==================================================================== | 2 | /* ==================================================================== |
| 3 | * Copyright (c) 1999 The OpenSSL Project. All rights reserved. | 3 | * Copyright (c) 1999 The OpenSSL Project. All rights reserved. |
| 4 | * | 4 | * |
| @@ -68,7 +68,7 @@ | |||
| 68 | #include <openssl/err.h> | 68 | #include <openssl/err.h> |
| 69 | 69 | ||
| 70 | #include "o_time.h" | 70 | #include "o_time.h" |
| 71 | 71 | #include "asn1_locl.h" | |
| 72 | 72 | ||
| 73 | const ASN1_ITEM ASN1_TIME_it = { | 73 | const ASN1_ITEM ASN1_TIME_it = { |
| 74 | .itype = ASN1_ITYPE_MSTRING, | 74 | .itype = ASN1_ITYPE_MSTRING, |
| @@ -135,11 +135,9 @@ ASN1_TIME_adj(ASN1_TIME *s, time_t t, int offset_day, long offset_sec) | |||
| 135 | int | 135 | int |
| 136 | ASN1_TIME_check(ASN1_TIME *t) | 136 | ASN1_TIME_check(ASN1_TIME *t) |
| 137 | { | 137 | { |
| 138 | if (t->type == V_ASN1_GENERALIZEDTIME) | 138 | if (t->type != V_ASN1_GENERALIZEDTIME && t->type != V_ASN1_UTCTIME) |
| 139 | return ASN1_GENERALIZEDTIME_check(t); | 139 | return 0; |
| 140 | else if (t->type == V_ASN1_UTCTIME) | 140 | return (t->type == asn1_time_parse(t->data, t->length, NULL, t->type)); |
| 141 | return ASN1_UTCTIME_check(t); | ||
| 142 | return 0; | ||
| 143 | } | 141 | } |
| 144 | 142 | ||
| 145 | /* Convert an ASN1_TIME structure to GeneralizedTime */ | 143 | /* Convert an ASN1_TIME structure to GeneralizedTime */ |
| @@ -210,13 +208,12 @@ ASN1_TIME_set_string(ASN1_TIME *s, const char *str) | |||
| 210 | t.data = (unsigned char *)str; | 208 | t.data = (unsigned char *)str; |
| 211 | t.flags = 0; | 209 | t.flags = 0; |
| 212 | 210 | ||
| 213 | t.type = V_ASN1_UTCTIME; | 211 | t.type = asn1_time_parse(t.data, t.length, NULL, V_ASN1_UTCTIME); |
| 214 | 212 | if (t.type == -1) | |
| 215 | if (!ASN1_TIME_check(&t)) { | 213 | t.type = asn1_time_parse(t.data, t.length, NULL, |
| 216 | t.type = V_ASN1_GENERALIZEDTIME; | 214 | V_ASN1_GENERALIZEDTIME); |
| 217 | if (!ASN1_TIME_check(&t)) | 215 | if (t.type == -1) |
| 218 | return 0; | 216 | return 0; |
| 219 | } | ||
| 220 | 217 | ||
| 221 | if (s && !ASN1_STRING_copy((ASN1_STRING *)s, (ASN1_STRING *)&t)) | 218 | if (s && !ASN1_STRING_copy((ASN1_STRING *)s, (ASN1_STRING *)&t)) |
| 222 | return 0; | 219 | return 0; |
diff --git a/src/lib/libssl/src/crypto/asn1/a_time_tm.c b/src/lib/libssl/src/crypto/asn1/a_time_tm.c new file mode 100644 index 0000000000..65f75c68cc --- /dev/null +++ b/src/lib/libssl/src/crypto/asn1/a_time_tm.c | |||
| @@ -0,0 +1,257 @@ | |||
| 1 | /* $OpenBSD: a_time_tm.c,v 1.1 2015/10/02 15:04:45 beck Exp $ */ | ||
| 2 | /* | ||
| 3 | * Copyright (c) 2015 Bob Beck <beck@openbsd.org> | ||
| 4 | * | ||
| 5 | * Permission to use, copy, modify, and distribute this software for any | ||
| 6 | * purpose with or without fee is hereby granted, provided that the above | ||
| 7 | * copyright notice and this permission notice appear in all copies. | ||
| 8 | * | ||
| 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <stdio.h> | ||
| 19 | #include <string.h> | ||
| 20 | #include <time.h> | ||
| 21 | #include <ctype.h> | ||
| 22 | #include <sys/limits.h> | ||
| 23 | |||
| 24 | #include <openssl/asn1t.h> | ||
| 25 | #include <openssl/err.h> | ||
| 26 | |||
| 27 | #include "o_time.h" | ||
| 28 | #include "asn1_locl.h" | ||
| 29 | |||
| 30 | char * | ||
| 31 | gentime_string_from_tm(struct tm *tm) | ||
| 32 | { | ||
| 33 | char *ret = NULL; | ||
| 34 | int year; | ||
| 35 | year = tm->tm_year + 1900; | ||
| 36 | if (year < 0 || year > 9999) | ||
| 37 | return (NULL); | ||
| 38 | if (asprintf(&ret, "%04u%02u%02u%02u%02u%02uZ", year, | ||
| 39 | tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, | ||
| 40 | tm->tm_sec) == -1) | ||
| 41 | ret = NULL; | ||
| 42 | return (ret); | ||
| 43 | } | ||
| 44 | |||
| 45 | char * | ||
| 46 | utctime_string_from_tm(struct tm *tm) | ||
| 47 | { | ||
| 48 | char *ret = NULL; | ||
| 49 | if (tm->tm_year >= 150 || tm->tm_year < 50) | ||
| 50 | return (NULL); | ||
| 51 | if (asprintf(&ret, "%02u%02u%02u%02u%02u%02uZ", | ||
| 52 | tm->tm_year % 100, tm->tm_mon + 1, tm->tm_mday, | ||
| 53 | tm->tm_hour, tm->tm_min, tm->tm_sec) == -1) | ||
| 54 | ret = NULL; | ||
| 55 | return (ret); | ||
| 56 | } | ||
| 57 | |||
| 58 | /* | ||
| 59 | * Parse an ASN.1 time string. | ||
| 60 | * | ||
| 61 | * mode must be: | ||
| 62 | * 0 if we expect to parse a time as specified in RFC 5280 from an | ||
| 63 | * X509 certificate. | ||
| 64 | * V_ASN1_UTCTIME if we wish to parse a legacy ASN1 UTC time. | ||
| 65 | * V_ASN1_GENERALIZEDTIME if we wish to parse a legacy ASN1 | ||
| 66 | * Generalizd time. | ||
| 67 | * | ||
| 68 | * Returns: | ||
| 69 | * -1 if the string was invalid. | ||
| 70 | * V_ASN1_UTCTIME if the string validated as a UTC time string. | ||
| 71 | * V_ASN1_GENERALIZEDTIME if the string validated as a Generalized time string. | ||
| 72 | * | ||
| 73 | * Fills in *tm with the corresponding time if tm is non NULL. | ||
| 74 | */ | ||
| 75 | #define RFC5280 0 | ||
| 76 | #define ATOI2(ar) ((ar) += 2, ((ar)[-2] - '0') * 10 + ((ar)[-1] - '0')) | ||
| 77 | int asn1_time_parse(const char * bytes, size_t len, struct tm *tm, int mode) | ||
| 78 | { | ||
| 79 | char *p, *buf = NULL, *dot = NULL, *tz = NULL; | ||
| 80 | int i, offset, noseconds = 0, type = 0; | ||
| 81 | struct tm ltm; | ||
| 82 | struct tm *lt; | ||
| 83 | size_t tlen; | ||
| 84 | char tzc; | ||
| 85 | |||
| 86 | if (bytes == NULL) | ||
| 87 | goto err; | ||
| 88 | |||
| 89 | if (len > INT_MAX) | ||
| 90 | goto err; | ||
| 91 | |||
| 92 | /* Constrain the RFC5280 case within max/min valid lengths. */ | ||
| 93 | if (mode == RFC5280 && (len > 15 || len < 13)) | ||
| 94 | goto err; | ||
| 95 | |||
| 96 | if ((buf = strndup(bytes, len)) == NULL) | ||
| 97 | goto err; | ||
| 98 | lt = tm; | ||
| 99 | if (lt == NULL) { | ||
| 100 | time_t t = time(NULL); | ||
| 101 | lt = gmtime_r(&t, <m); | ||
| 102 | if (lt == NULL) | ||
| 103 | goto err; | ||
| 104 | } | ||
| 105 | |||
| 106 | /* | ||
| 107 | * Find position of the optional fractional seconds, and the | ||
| 108 | * start of the timezone, while ensuring everything else is | ||
| 109 | * digits. | ||
| 110 | */ | ||
| 111 | for (i = 0; i < len; i++) { | ||
| 112 | char *t = buf + i; | ||
| 113 | if (isdigit((unsigned char)*t)) | ||
| 114 | continue; | ||
| 115 | if (*t == '.' && dot == NULL) { | ||
| 116 | dot = t; | ||
| 117 | continue; | ||
| 118 | } | ||
| 119 | if ((*t == 'Z' || *t == '+' || *t == '-') && tz == NULL) { | ||
| 120 | tz = t; | ||
| 121 | continue; | ||
| 122 | } | ||
| 123 | goto err; | ||
| 124 | } | ||
| 125 | |||
| 126 | /* | ||
| 127 | * Timezone is required. For the non-RFC case it may be | ||
| 128 | * either Z or +- HHMM, but for RFC5280 it may be only Z. | ||
| 129 | */ | ||
| 130 | if (tz == NULL) | ||
| 131 | goto err; | ||
| 132 | tzc = *tz; | ||
| 133 | *tz++ = '\0'; | ||
| 134 | if (tzc == 'Z') { | ||
| 135 | if (*tz != '\0') | ||
| 136 | goto err; | ||
| 137 | offset = 0; | ||
| 138 | } else if (mode != RFC5280 && (tzc == '+' || tzc == '-') && | ||
| 139 | (strlen(tz) == 4)) { | ||
| 140 | int hours, mins; | ||
| 141 | hours = ATOI2(tz); | ||
| 142 | mins = ATOI2(tz); | ||
| 143 | if (hours > 12 || mins > 59) | ||
| 144 | goto err; | ||
| 145 | offset = hours * 3600 + mins * 60; | ||
| 146 | if (tzc == '-') | ||
| 147 | offset = -offset; | ||
| 148 | } else | ||
| 149 | goto err; | ||
| 150 | |||
| 151 | if (mode != RFC5280) { | ||
| 152 | /* XXX - yuck - OPENSSL_gmtime_adj should go away */ | ||
| 153 | if (!OPENSSL_gmtime_adj(lt, 0, offset)) | ||
| 154 | goto err; | ||
| 155 | } | ||
| 156 | |||
| 157 | /* | ||
| 158 | * We only allow fractional seconds to be present if we are in | ||
| 159 | * the non-RFC case of a Generalized time. RFC 5280 forbids | ||
| 160 | * fractional seconds. | ||
| 161 | */ | ||
| 162 | if (dot != NULL) { | ||
| 163 | if (mode != V_ASN1_GENERALIZEDTIME) | ||
| 164 | goto err; | ||
| 165 | *dot++ = '\0'; | ||
| 166 | if (!isdigit((unsigned char)*dot)) | ||
| 167 | goto err; | ||
| 168 | } | ||
| 169 | |||
| 170 | /* | ||
| 171 | * Validate and convert the time | ||
| 172 | */ | ||
| 173 | p = buf; | ||
| 174 | tlen = strlen(buf); | ||
| 175 | switch (tlen) { | ||
| 176 | case 14: | ||
| 177 | lt->tm_year = (ATOI2(p) * 100) - 1900; /* cc */ | ||
| 178 | if (mode == RFC5280 || mode == V_ASN1_GENERALIZEDTIME) | ||
| 179 | type = V_ASN1_GENERALIZEDTIME; | ||
| 180 | else | ||
| 181 | goto err; | ||
| 182 | /* FALLTHROUGH */ | ||
| 183 | case 12: | ||
| 184 | if (type == 0 && mode == V_ASN1_GENERALIZEDTIME) { | ||
| 185 | /* | ||
| 186 | * In the non-RFC case of a Generalized time | ||
| 187 | * seconds may not have been provided. RFC | ||
| 188 | * 5280 mandates that seconds must be present. | ||
| 189 | */ | ||
| 190 | noseconds = 1; | ||
| 191 | lt->tm_year = (ATOI2(p) * 100) - 1900; /* cc */ | ||
| 192 | type = V_ASN1_GENERALIZEDTIME; | ||
| 193 | } | ||
| 194 | /* FALLTHROUGH */ | ||
| 195 | case 10: | ||
| 196 | if (type == 0) { | ||
| 197 | /* | ||
| 198 | * At this point we must have a UTC time. | ||
| 199 | * In the RFC 5280 case it must have the | ||
| 200 | * seconds present. In the non-RFC case | ||
| 201 | * may have no seconds. | ||
| 202 | */ | ||
| 203 | if (mode == V_ASN1_GENERALIZEDTIME) | ||
| 204 | goto err; | ||
| 205 | if (tlen == 10) { | ||
| 206 | if (mode == V_ASN1_UTCTIME) | ||
| 207 | noseconds = 1; | ||
| 208 | else | ||
| 209 | goto err; | ||
| 210 | } | ||
| 211 | type = V_ASN1_UTCTIME; | ||
| 212 | } | ||
| 213 | lt->tm_year += ATOI2(p); /* yy */ | ||
| 214 | if (type == V_ASN1_UTCTIME) { | ||
| 215 | if (lt->tm_year < 50) | ||
| 216 | lt->tm_year += 100; | ||
| 217 | } | ||
| 218 | lt->tm_mon = ATOI2(p); /* mm */ | ||
| 219 | if ((lt->tm_mon > 12) || !lt->tm_mon) | ||
| 220 | goto err; | ||
| 221 | --lt->tm_mon; /* struct tm is 0 - 11 */ | ||
| 222 | lt->tm_mday = ATOI2(p); /* dd */ | ||
| 223 | if ((lt->tm_mday > 31) || !lt->tm_mday) | ||
| 224 | goto err; | ||
| 225 | lt->tm_hour = ATOI2(p); /* HH */ | ||
| 226 | if (lt->tm_hour > 23) | ||
| 227 | goto err; | ||
| 228 | lt->tm_min = ATOI2(p); /* MM */ | ||
| 229 | if (lt->tm_min > 59) | ||
| 230 | goto err; | ||
| 231 | lt->tm_sec = 0; /* SS */ | ||
| 232 | if (noseconds) | ||
| 233 | break; | ||
| 234 | lt->tm_sec = ATOI2(p); | ||
| 235 | /* Leap second 60 is not accepted. Reconsider later? */ | ||
| 236 | if (lt->tm_sec > 59) | ||
| 237 | goto err; | ||
| 238 | break; | ||
| 239 | default: | ||
| 240 | goto err; | ||
| 241 | } | ||
| 242 | |||
| 243 | /* RFC 5280 section 4.1.2.5 */ | ||
| 244 | if (mode == RFC5280 && lt->tm_year < 150 && | ||
| 245 | type != V_ASN1_UTCTIME) | ||
| 246 | goto err; | ||
| 247 | if (mode == RFC5280 && lt->tm_year >= 150 && | ||
| 248 | type != V_ASN1_GENERALIZEDTIME) | ||
| 249 | goto err; | ||
| 250 | |||
| 251 | free(buf); | ||
| 252 | return type; | ||
| 253 | |||
| 254 | err: | ||
| 255 | free(buf); | ||
| 256 | return -1; | ||
| 257 | } | ||
diff --git a/src/lib/libssl/src/crypto/asn1/a_utctm.c b/src/lib/libssl/src/crypto/asn1/a_utctm.c index ca19a8c7a0..c208d494c3 100644 --- a/src/lib/libssl/src/crypto/asn1/a_utctm.c +++ b/src/lib/libssl/src/crypto/asn1/a_utctm.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: a_utctm.c,v 1.28 2015/09/30 18:26:07 jsing Exp $ */ | 1 | /* $OpenBSD: a_utctm.c,v 1.29 2015/10/02 15:04:45 beck Exp $ */ |
| 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * | 4 | * |
| @@ -64,66 +64,14 @@ | |||
| 64 | #include <openssl/err.h> | 64 | #include <openssl/err.h> |
| 65 | 65 | ||
| 66 | #include "o_time.h" | 66 | #include "o_time.h" |
| 67 | #include "asn1_locl.h" | ||
| 67 | 68 | ||
| 68 | int | 69 | int |
| 69 | ASN1_UTCTIME_check(ASN1_UTCTIME *d) | 70 | ASN1_UTCTIME_check(ASN1_UTCTIME *d) |
| 70 | { | 71 | { |
| 71 | static const int min[8] = {0, 1, 1, 0, 0, 0, 0, 0}; | ||
| 72 | static const int max[8] = {99, 12, 31, 23, 59, 59, 12, 59}; | ||
| 73 | char *a; | ||
| 74 | int n, i, l, o; | ||
| 75 | |||
| 76 | if (d->type != V_ASN1_UTCTIME) | 72 | if (d->type != V_ASN1_UTCTIME) |
| 77 | return (0); | 73 | return (0); |
| 78 | l = d->length; | 74 | return(d->type == asn1_time_parse(d->data, d->length, NULL, d->type)); |
| 79 | a = (char *)d->data; | ||
| 80 | o = 0; | ||
| 81 | |||
| 82 | if (l < 11) | ||
| 83 | |||
| 84 | goto err; | ||
| 85 | for (i = 0; i < 6; i++) { | ||
| 86 | if ((i == 5) && ((a[o] == 'Z') || | ||
| 87 | (a[o] == '+') || (a[o] == '-'))) { | ||
| 88 | i++; | ||
| 89 | break; | ||
| 90 | } | ||
| 91 | if ((a[o] < '0') || (a[o] > '9')) | ||
| 92 | goto err; | ||
| 93 | n = a[o]-'0'; | ||
| 94 | if (++o > l) | ||
| 95 | goto err; | ||
| 96 | if ((a[o] < '0') || (a[o] > '9')) | ||
| 97 | goto err; | ||
| 98 | n = (n * 10) + a[o] - '0'; | ||
| 99 | if (++o > l) | ||
| 100 | goto err; | ||
| 101 | if ((n < min[i]) || (n > max[i])) | ||
| 102 | goto err; | ||
| 103 | } | ||
| 104 | if (a[o] == 'Z') | ||
| 105 | o++; | ||
| 106 | else if ((a[o] == '+') || (a[o] == '-')) { | ||
| 107 | o++; | ||
| 108 | if (o + 4 > l) | ||
| 109 | goto err; | ||
| 110 | for (i = 6; i < 8; i++) { | ||
| 111 | if ((a[o] < '0') || (a[o] > '9')) | ||
| 112 | goto err; | ||
| 113 | n = a[o] -'0'; | ||
| 114 | o++; | ||
| 115 | if ((a[o] < '0') || (a[o] > '9')) | ||
| 116 | goto err; | ||
| 117 | n = (n * 10) + a[o] - '0'; | ||
| 118 | if ((n < min[i]) || (n > max[i])) | ||
| 119 | goto err; | ||
| 120 | o++; | ||
| 121 | } | ||
| 122 | } | ||
| 123 | return (o == l); | ||
| 124 | |||
| 125 | err: | ||
| 126 | return (0); | ||
| 127 | } | 75 | } |
| 128 | 76 | ||
| 129 | int | 77 | int |
| @@ -159,7 +107,6 @@ ASN1_UTCTIME_adj_internal(ASN1_UTCTIME *s, time_t t, int offset_day, | |||
| 159 | char *p; | 107 | char *p; |
| 160 | struct tm *ts; | 108 | struct tm *ts; |
| 161 | struct tm data; | 109 | struct tm data; |
| 162 | size_t len = 20; | ||
| 163 | 110 | ||
| 164 | ts = gmtime_r(&t, &data); | 111 | ts = gmtime_r(&t, &data); |
| 165 | if (ts == NULL) | 112 | if (ts == NULL) |
| @@ -170,23 +117,14 @@ ASN1_UTCTIME_adj_internal(ASN1_UTCTIME *s, time_t t, int offset_day, | |||
| 170 | return NULL; | 117 | return NULL; |
| 171 | } | 118 | } |
| 172 | 119 | ||
| 173 | if ((ts->tm_year < 50) || (ts->tm_year >= 150)) | 120 | if ((p = utctime_string_from_tm(ts)) == NULL) { |
| 174 | return NULL; | 121 | ASN1err(ASN1_F_ASN1_UTCTIME_ADJ, ERR_R_MALLOC_FAILURE); |
| 175 | 122 | return (NULL); | |
| 176 | p = (char *)s->data; | ||
| 177 | if ((p == NULL) || ((size_t)s->length < len)) { | ||
| 178 | p = malloc(len); | ||
| 179 | if (p == NULL) { | ||
| 180 | ASN1err(ASN1_F_ASN1_UTCTIME_ADJ, ERR_R_MALLOC_FAILURE); | ||
| 181 | return (NULL); | ||
| 182 | } | ||
| 183 | free(s->data); | ||
| 184 | s->data = (unsigned char *)p; | ||
| 185 | } | 123 | } |
| 186 | 124 | free(s->data); | |
| 187 | snprintf(p, len, "%02d%02d%02d%02d%02d%02dZ", ts->tm_year % 100, | 125 | s->data = p; |
| 188 | ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min, ts->tm_sec); | ||
| 189 | s->length = strlen(p); | 126 | s->length = strlen(p); |
| 127 | |||
| 190 | s->type = V_ASN1_UTCTIME; | 128 | s->type = V_ASN1_UTCTIME; |
| 191 | return (s); | 129 | return (s); |
| 192 | } | 130 | } |
diff --git a/src/lib/libssl/src/crypto/asn1/asn1_locl.h b/src/lib/libssl/src/crypto/asn1/asn1_locl.h index c6c80aa6aa..d4994c7cee 100644 --- a/src/lib/libssl/src/crypto/asn1/asn1_locl.h +++ b/src/lib/libssl/src/crypto/asn1/asn1_locl.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: asn1_locl.h,v 1.5 2014/06/12 15:49:27 deraadt Exp $ */ | 1 | /* $OpenBSD: asn1_locl.h,v 1.6 2015/10/02 15:04:45 beck Exp $ */ |
| 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
| 3 | * project 2006. | 3 | * project 2006. |
| 4 | */ | 4 | */ |
| @@ -58,6 +58,10 @@ | |||
| 58 | 58 | ||
| 59 | /* Internal ASN1 structures and functions: not for application use */ | 59 | /* Internal ASN1 structures and functions: not for application use */ |
| 60 | 60 | ||
| 61 | char * gentime_string_from_tm(struct tm *tm); | ||
| 62 | char * utctime_string_from_tm(struct tm *tm); | ||
| 63 | int asn1_time_parse(const char *, size_t, struct tm *, int); | ||
| 64 | |||
| 61 | /* ASN1 print context structure */ | 65 | /* ASN1 print context structure */ |
| 62 | 66 | ||
| 63 | struct asn1_pctx_st { | 67 | struct asn1_pctx_st { |
diff --git a/src/lib/libssl/src/crypto/x509/x509_lcl.h b/src/lib/libssl/src/crypto/x509/x509_lcl.h index b16df78ad7..0c1c130d5c 100644 --- a/src/lib/libssl/src/crypto/x509/x509_lcl.h +++ b/src/lib/libssl/src/crypto/x509/x509_lcl.h | |||
| @@ -57,3 +57,4 @@ | |||
| 57 | */ | 57 | */ |
| 58 | 58 | ||
| 59 | int x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int quiet); | 59 | int x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int quiet); |
| 60 | int asn1_time_parse(const char *, size_t, struct tm *, int); | ||
diff --git a/src/lib/libssl/src/crypto/x509/x509_vfy.c b/src/lib/libssl/src/crypto/x509/x509_vfy.c index 8d4d15668e..c48143f351 100644 --- a/src/lib/libssl/src/crypto/x509/x509_vfy.c +++ b/src/lib/libssl/src/crypto/x509/x509_vfy.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: x509_vfy.c,v 1.45 2015/09/14 16:13:39 jsing Exp $ */ | 1 | /* $OpenBSD: x509_vfy.c,v 1.46 2015/10/02 15:04:45 beck Exp $ */ |
| 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * | 4 | * |
| @@ -1631,106 +1631,50 @@ X509_cmp_current_time(const ASN1_TIME *ctm) | |||
| 1631 | return X509_cmp_time(ctm, NULL); | 1631 | return X509_cmp_time(ctm, NULL); |
| 1632 | } | 1632 | } |
| 1633 | 1633 | ||
| 1634 | /* | ||
| 1635 | * Compare a possibly unvalidated ASN1_TIME string against a time_t | ||
| 1636 | * using RFC 5280 rules for the time string. If *cmp_time is NULL | ||
| 1637 | * the current system time is used. | ||
| 1638 | * | ||
| 1639 | * XXX NOTE that unlike what you expect a "cmp" function to do in C, | ||
| 1640 | * XXX this one is "special", and returns 0 for error. | ||
| 1641 | * | ||
| 1642 | * Returns: | ||
| 1643 | * -1 if the ASN1_time is earlier than OR the same as *cmp_time. | ||
| 1644 | * 1 if the ASN1_time is later than *cmp_time. | ||
| 1645 | * 0 on error. | ||
| 1646 | */ | ||
| 1634 | int | 1647 | int |
| 1635 | X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) | 1648 | X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) |
| 1636 | { | 1649 | { |
| 1637 | char *str; | 1650 | time_t time1, time2; |
| 1638 | ASN1_TIME atm; | 1651 | struct tm tm1; |
| 1639 | long offset; | 1652 | int ret = 0; |
| 1640 | char buff1[24], buff2[24], *p; | ||
| 1641 | int i, j; | ||
| 1642 | 1653 | ||
| 1643 | p = buff1; | 1654 | if (cmp_time == NULL) |
| 1644 | i = ctm->length; | 1655 | time2 = time(NULL); |
| 1645 | str = (char *)ctm->data; | 1656 | else |
| 1646 | if (ctm->type == V_ASN1_UTCTIME) { | 1657 | time2 = *cmp_time; |
| 1647 | if ((i < 11) || (i > 17)) | ||
| 1648 | return 0; | ||
| 1649 | memcpy(p, str, 10); | ||
| 1650 | p += 10; | ||
| 1651 | str += 10; | ||
| 1652 | i -= 10; | ||
| 1653 | } else { | ||
| 1654 | if (i < 13) | ||
| 1655 | return 0; | ||
| 1656 | memcpy(p, str, 12); | ||
| 1657 | p += 12; | ||
| 1658 | str += 12; | ||
| 1659 | i -= 12; | ||
| 1660 | } | ||
| 1661 | 1658 | ||
| 1662 | if (i < 1) | 1659 | memset(&tm1, 0, sizeof(tm1)); |
| 1663 | return 0; | ||
| 1664 | if ((*str == 'Z') || (*str == '-') || (*str == '+')) { | ||
| 1665 | *(p++) = '0'; | ||
| 1666 | *(p++) = '0'; | ||
| 1667 | } else { | ||
| 1668 | if (i < 2) | ||
| 1669 | return 0; | ||
| 1670 | *(p++) = *(str++); | ||
| 1671 | *(p++) = *(str++); | ||
| 1672 | i -= 2; | ||
| 1673 | if (i < 1) | ||
| 1674 | return 0; | ||
| 1675 | /* Skip any fractional seconds... */ | ||
| 1676 | if (*str == '.') { | ||
| 1677 | str++; | ||
| 1678 | i--; | ||
| 1679 | while (i > 1 && (*str >= '0') && (*str <= '9')) { | ||
| 1680 | str++; | ||
| 1681 | i--; | ||
| 1682 | } | ||
| 1683 | } | ||
| 1684 | } | ||
| 1685 | *(p++) = 'Z'; | ||
| 1686 | *(p++) = '\0'; | ||
| 1687 | 1660 | ||
| 1688 | if (i < 1) | 1661 | if (asn1_time_parse(ctm->data, ctm->length, &tm1, 0) == -1) |
| 1689 | return 0; | 1662 | goto out; /* invalid time */ |
| 1690 | if (*str == 'Z') { | ||
| 1691 | if (i != 1) | ||
| 1692 | return 0; | ||
| 1693 | offset = 0; | ||
| 1694 | } else { | ||
| 1695 | if (i != 5) | ||
| 1696 | return 0; | ||
| 1697 | if ((*str != '+') && (*str != '-')) | ||
| 1698 | return 0; | ||
| 1699 | if (str[1] < '0' || str[1] > '9' || | ||
| 1700 | str[2] < '0' || str[2] > '9' || | ||
| 1701 | str[3] < '0' || str[3] > '9' || | ||
| 1702 | str[4] < '0' || str[4] > '9') | ||
| 1703 | return 0; | ||
| 1704 | offset = ((str[1] - '0') * 10 + (str[2] - '0')) * 60; | ||
| 1705 | offset += (str[3] - '0') * 10 + (str[4] - '0'); | ||
| 1706 | if (*str == '-') | ||
| 1707 | offset = -offset; | ||
| 1708 | } | ||
| 1709 | atm.type = ctm->type; | ||
| 1710 | atm.flags = 0; | ||
| 1711 | atm.length = sizeof(buff2); | ||
| 1712 | atm.data = (unsigned char *)buff2; | ||
| 1713 | 1663 | ||
| 1714 | if (X509_time_adj(&atm, offset * 60, cmp_time) == NULL) | 1664 | /* |
| 1715 | return 0; | 1665 | * Defensively fail if the time string is not representable as |
| 1666 | * a time_t. A time_t must be sane if you care about times after | ||
| 1667 | * Jan 19 2038. | ||
| 1668 | */ | ||
| 1669 | if ((time1 = timegm(&tm1)) == -1) | ||
| 1670 | goto out; | ||
| 1716 | 1671 | ||
| 1717 | if (ctm->type == V_ASN1_UTCTIME) { | 1672 | if (time1 <= time2) |
| 1718 | i = (buff1[0] - '0') * 10 + (buff1[1] - '0'); | 1673 | ret = -1; |
| 1719 | if (i < 50) | ||
| 1720 | i += 100; /* cf. RFC 2459 */ | ||
| 1721 | j = (buff2[0] - '0') * 10 + (buff2[1] - '0'); | ||
| 1722 | if (j < 50) | ||
| 1723 | j += 100; | ||
| 1724 | if (i < j) | ||
| 1725 | return -1; | ||
| 1726 | if (i > j) | ||
| 1727 | return 1; | ||
| 1728 | } | ||
| 1729 | i = strcmp(buff1, buff2); | ||
| 1730 | if (i == 0) /* wait a second then return younger :-) */ | ||
| 1731 | return -1; | ||
| 1732 | else | 1674 | else |
| 1733 | return i; | 1675 | ret = 1; |
| 1676 | out: | ||
| 1677 | return (ret); | ||
| 1734 | } | 1678 | } |
| 1735 | 1679 | ||
| 1736 | ASN1_TIME * | 1680 | ASN1_TIME * |
