diff options
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libcrypto/asn1/a_gentm.c | 153 | ||||
| -rw-r--r-- | src/lib/libcrypto/asn1/a_time.c | 117 | ||||
| -rw-r--r-- | src/lib/libcrypto/asn1/a_time_tm.c | 462 | ||||
| -rw-r--r-- | src/lib/libcrypto/asn1/a_utctm.c | 173 | ||||
| -rw-r--r-- | src/lib/libcrypto/asn1/asn1_locl.h | 6 | ||||
| -rw-r--r-- | src/lib/libcrypto/crypto/Makefile | 4 | ||||
| -rw-r--r-- | src/lib/libcrypto/x509/x509_lcl.h | 1 | ||||
| -rw-r--r-- | src/lib/libcrypto/x509/x509_vfy.c | 45 |
8 files changed, 350 insertions, 611 deletions
diff --git a/src/lib/libcrypto/asn1/a_gentm.c b/src/lib/libcrypto/asn1/a_gentm.c deleted file mode 100644 index 594eb63058..0000000000 --- a/src/lib/libcrypto/asn1/a_gentm.c +++ /dev/null | |||
| @@ -1,153 +0,0 @@ | |||
| 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) | ||
| 3 | * All rights reserved. | ||
| 4 | * | ||
| 5 | * This package is an SSL implementation written | ||
| 6 | * by Eric Young (eay@cryptsoft.com). | ||
| 7 | * The implementation was written so as to conform with Netscapes SSL. | ||
| 8 | * | ||
| 9 | * This library is free for commercial and non-commercial use as long as | ||
| 10 | * the following conditions are aheared to. The following conditions | ||
| 11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
| 12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
| 13 | * included with this distribution is covered by the same copyright terms | ||
| 14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
| 15 | * | ||
| 16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
| 17 | * the code are not to be removed. | ||
| 18 | * If this package is used in a product, Eric Young should be given attribution | ||
| 19 | * as the author of the parts of the library used. | ||
| 20 | * This can be in the form of a textual message at program startup or | ||
| 21 | * in documentation (online or textual) provided with the package. | ||
| 22 | * | ||
| 23 | * Redistribution and use in source and binary forms, with or without | ||
| 24 | * modification, are permitted provided that the following conditions | ||
| 25 | * are met: | ||
| 26 | * 1. Redistributions of source code must retain the copyright | ||
| 27 | * notice, this list of conditions and the following disclaimer. | ||
| 28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 29 | * notice, this list of conditions and the following disclaimer in the | ||
| 30 | * documentation and/or other materials provided with the distribution. | ||
| 31 | * 3. All advertising materials mentioning features or use of this software | ||
| 32 | * must display the following acknowledgement: | ||
| 33 | * "This product includes cryptographic software written by | ||
| 34 | * Eric Young (eay@cryptsoft.com)" | ||
| 35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
| 36 | * being used are not cryptographic related :-). | ||
| 37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
| 38 | * the apps directory (application code) you must include an acknowledgement: | ||
| 39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
| 40 | * | ||
| 41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
| 42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
| 45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 51 | * SUCH DAMAGE. | ||
| 52 | * | ||
| 53 | * The licence and distribution terms for any publically available version or | ||
| 54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
| 55 | * copied and put under another distribution licence | ||
| 56 | * [including the GNU Public Licence.] | ||
| 57 | */ | ||
| 58 | |||
| 59 | /* GENERALIZEDTIME implementation, written by Steve Henson. Based on UTCTIME */ | ||
| 60 | |||
| 61 | #include <stdio.h> | ||
| 62 | #include <string.h> | ||
| 63 | #include <time.h> | ||
| 64 | |||
| 65 | #include <openssl/asn1.h> | ||
| 66 | #include <openssl/err.h> | ||
| 67 | |||
| 68 | #include "o_time.h" | ||
| 69 | #include "asn1_locl.h" | ||
| 70 | |||
| 71 | int | ||
| 72 | ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *d) | ||
| 73 | { | ||
| 74 | if (d->type != V_ASN1_GENERALIZEDTIME) | ||
| 75 | return (0); | ||
| 76 | return (d->type == asn1_time_parse(d->data, d->length, NULL, d->type)); | ||
| 77 | } | ||
| 78 | |||
| 79 | int | ||
| 80 | ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str) | ||
| 81 | { | ||
| 82 | ASN1_GENERALIZEDTIME t; | ||
| 83 | |||
| 84 | t.type = V_ASN1_GENERALIZEDTIME; | ||
| 85 | t.length = strlen(str); | ||
| 86 | t.data = (unsigned char *)str; | ||
| 87 | if (ASN1_GENERALIZEDTIME_check(&t)) { | ||
| 88 | if (s != NULL) { | ||
| 89 | if (!ASN1_STRING_set((ASN1_STRING *)s, | ||
| 90 | (unsigned char *)str, t.length)) | ||
| 91 | return 0; | ||
| 92 | s->type = V_ASN1_GENERALIZEDTIME; | ||
| 93 | } | ||
| 94 | return (1); | ||
| 95 | } else | ||
| 96 | return (0); | ||
| 97 | } | ||
| 98 | |||
| 99 | ASN1_GENERALIZEDTIME * | ||
| 100 | ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s, time_t t) | ||
| 101 | { | ||
| 102 | return ASN1_GENERALIZEDTIME_adj(s, t, 0, 0); | ||
| 103 | } | ||
| 104 | |||
| 105 | static ASN1_GENERALIZEDTIME * | ||
| 106 | ASN1_GENERALIZEDTIME_adj_internal(ASN1_GENERALIZEDTIME *s, time_t t, | ||
| 107 | int offset_day, long offset_sec) | ||
| 108 | { | ||
| 109 | char *p; | ||
| 110 | struct tm *tm; | ||
| 111 | struct tm data; | ||
| 112 | |||
| 113 | tm = gmtime_r(&t, &data); | ||
| 114 | if (tm == NULL) | ||
| 115 | return (NULL); | ||
| 116 | |||
| 117 | if (offset_day || offset_sec) { | ||
| 118 | if (!OPENSSL_gmtime_adj(tm, offset_day, offset_sec)) | ||
| 119 | return NULL; | ||
| 120 | } | ||
| 121 | |||
| 122 | if ((p = gentime_string_from_tm(tm)) == NULL) { | ||
| 123 | ASN1err(ASN1_F_ASN1_GENERALIZEDTIME_ADJ, ERR_R_MALLOC_FAILURE); | ||
| 124 | return (NULL); | ||
| 125 | } | ||
| 126 | free(s->data); | ||
| 127 | s->data = p; | ||
| 128 | s->length = strlen(p); | ||
| 129 | |||
| 130 | s->type = V_ASN1_GENERALIZEDTIME; | ||
| 131 | return (s); | ||
| 132 | } | ||
| 133 | |||
| 134 | ASN1_GENERALIZEDTIME * | ||
| 135 | ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, time_t t, int offset_day, | ||
| 136 | long offset_sec) | ||
| 137 | { | ||
| 138 | ASN1_GENERALIZEDTIME *tmp = NULL, *ret; | ||
| 139 | |||
| 140 | if (s == NULL) { | ||
| 141 | tmp = ASN1_GENERALIZEDTIME_new(); | ||
| 142 | if (tmp == NULL) | ||
| 143 | return NULL; | ||
| 144 | s = tmp; | ||
| 145 | } | ||
| 146 | |||
| 147 | ret = ASN1_GENERALIZEDTIME_adj_internal(s, t, offset_day, offset_sec); | ||
| 148 | if (ret == NULL && tmp != NULL) | ||
| 149 | ASN1_GENERALIZEDTIME_free(tmp); | ||
| 150 | |||
| 151 | return ret; | ||
| 152 | |||
| 153 | } | ||
diff --git a/src/lib/libcrypto/asn1/a_time.c b/src/lib/libcrypto/asn1/a_time.c index a6c7c8e736..7a3742fd70 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.26 2015/10/02 15:04:45 beck Exp $ */ | 1 | /* $OpenBSD: a_time.c,v 1.27 2015/10/19 16:32:37 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 | * |
| @@ -105,118 +105,3 @@ ASN1_TIME_free(ASN1_TIME *a) | |||
| 105 | { | 105 | { |
| 106 | ASN1_item_free((ASN1_VALUE *)a, &ASN1_TIME_it); | 106 | ASN1_item_free((ASN1_VALUE *)a, &ASN1_TIME_it); |
| 107 | } | 107 | } |
| 108 | |||
| 109 | ASN1_TIME * | ||
| 110 | ASN1_TIME_set(ASN1_TIME *s, time_t t) | ||
| 111 | { | ||
| 112 | return ASN1_TIME_adj(s, t, 0, 0); | ||
| 113 | } | ||
| 114 | |||
| 115 | ASN1_TIME * | ||
| 116 | ASN1_TIME_adj(ASN1_TIME *s, time_t t, int offset_day, long offset_sec) | ||
| 117 | { | ||
| 118 | struct tm *ts; | ||
| 119 | struct tm data; | ||
| 120 | |||
| 121 | ts = gmtime_r(&t, &data); | ||
| 122 | if (ts == NULL) { | ||
| 123 | ASN1err(ASN1_F_ASN1_TIME_ADJ, ASN1_R_ERROR_GETTING_TIME); | ||
| 124 | return NULL; | ||
| 125 | } | ||
| 126 | if (offset_day || offset_sec) { | ||
| 127 | if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec)) | ||
| 128 | return NULL; | ||
| 129 | } | ||
| 130 | if ((ts->tm_year >= 50) && (ts->tm_year < 150)) | ||
| 131 | return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec); | ||
| 132 | return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec); | ||
| 133 | } | ||
| 134 | |||
| 135 | int | ||
| 136 | ASN1_TIME_check(ASN1_TIME *t) | ||
| 137 | { | ||
| 138 | if (t->type != V_ASN1_GENERALIZEDTIME && t->type != V_ASN1_UTCTIME) | ||
| 139 | return 0; | ||
| 140 | return (t->type == asn1_time_parse(t->data, t->length, NULL, t->type)); | ||
| 141 | } | ||
| 142 | |||
| 143 | /* Convert an ASN1_TIME structure to GeneralizedTime */ | ||
| 144 | static ASN1_GENERALIZEDTIME * | ||
| 145 | ASN1_TIME_to_generalizedtime_internal(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out) | ||
| 146 | { | ||
| 147 | ASN1_GENERALIZEDTIME *ret; | ||
| 148 | char *str; | ||
| 149 | int newlen; | ||
| 150 | int i; | ||
| 151 | |||
| 152 | if (!ASN1_TIME_check(t)) | ||
| 153 | return NULL; | ||
| 154 | |||
| 155 | ret = *out; | ||
| 156 | |||
| 157 | /* If already GeneralizedTime just copy across */ | ||
| 158 | if (t->type == V_ASN1_GENERALIZEDTIME) { | ||
| 159 | if (!ASN1_STRING_set(ret, t->data, t->length)) | ||
| 160 | return NULL; | ||
| 161 | return ret; | ||
| 162 | } | ||
| 163 | |||
| 164 | /* grow the string */ | ||
| 165 | if (!ASN1_STRING_set(ret, NULL, t->length + 2)) | ||
| 166 | return NULL; | ||
| 167 | /* ASN1_STRING_set() allocated 'len + 1' bytes. */ | ||
| 168 | newlen = t->length + 2 + 1; | ||
| 169 | str = (char *)ret->data; | ||
| 170 | /* XXX ASN1_TIME is not Y2050 compatible */ | ||
| 171 | i = snprintf(str, newlen, "%s%s", (t->data[0] >= '5') ? "19" : "20", | ||
| 172 | (char *) t->data); | ||
| 173 | if (i == -1 || i >= newlen) { | ||
| 174 | ASN1_GENERALIZEDTIME_free(ret); | ||
| 175 | *out = NULL; | ||
| 176 | return NULL; | ||
| 177 | } | ||
| 178 | return ret; | ||
| 179 | } | ||
| 180 | |||
| 181 | ASN1_GENERALIZEDTIME * | ||
| 182 | ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out) | ||
| 183 | { | ||
| 184 | ASN1_GENERALIZEDTIME *tmp = NULL, *ret; | ||
| 185 | |||
| 186 | if (!out || !*out) { | ||
| 187 | if (!(tmp = ASN1_GENERALIZEDTIME_new())) | ||
| 188 | return NULL; | ||
| 189 | if (out != NULL) | ||
| 190 | *out = tmp; | ||
| 191 | else | ||
| 192 | out = &tmp; | ||
| 193 | } | ||
| 194 | |||
| 195 | ret = ASN1_TIME_to_generalizedtime_internal(t, out); | ||
| 196 | if (ret == NULL && tmp != NULL) | ||
| 197 | ASN1_GENERALIZEDTIME_free(tmp); | ||
| 198 | |||
| 199 | return ret; | ||
| 200 | } | ||
| 201 | |||
| 202 | int | ||
| 203 | ASN1_TIME_set_string(ASN1_TIME *s, const char *str) | ||
| 204 | { | ||
| 205 | ASN1_TIME t; | ||
| 206 | |||
| 207 | t.length = strlen(str); | ||
| 208 | t.data = (unsigned char *)str; | ||
| 209 | t.flags = 0; | ||
| 210 | |||
| 211 | t.type = asn1_time_parse(t.data, t.length, NULL, V_ASN1_UTCTIME); | ||
| 212 | if (t.type == -1) | ||
| 213 | t.type = asn1_time_parse(t.data, t.length, NULL, | ||
| 214 | V_ASN1_GENERALIZEDTIME); | ||
| 215 | if (t.type == -1) | ||
| 216 | return 0; | ||
| 217 | |||
| 218 | if (s && !ASN1_STRING_copy((ASN1_STRING *)s, (ASN1_STRING *)&t)) | ||
| 219 | return 0; | ||
| 220 | |||
| 221 | return 1; | ||
| 222 | } | ||
diff --git a/src/lib/libcrypto/asn1/a_time_tm.c b/src/lib/libcrypto/asn1/a_time_tm.c index 53443fa965..352b9159ee 100644 --- a/src/lib/libcrypto/asn1/a_time_tm.c +++ b/src/lib/libcrypto/asn1/a_time_tm.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: a_time_tm.c,v 1.5 2015/10/08 02:26:31 beck Exp $ */ | 1 | /* $OpenBSD: a_time_tm.c,v 1.6 2015/10/19 16:32:37 beck Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2015 Bob Beck <beck@openbsd.org> | 3 | * Copyright (c) 2015 Bob Beck <beck@openbsd.org> |
| 4 | * | 4 | * |
| @@ -14,7 +14,6 @@ | |||
| 14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | 14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
| 15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
| 16 | */ | 16 | */ |
| 17 | |||
| 18 | #include <ctype.h> | 17 | #include <ctype.h> |
| 19 | #include <limits.h> | 18 | #include <limits.h> |
| 20 | #include <stdio.h> | 19 | #include <stdio.h> |
| @@ -25,8 +24,41 @@ | |||
| 25 | #include <openssl/err.h> | 24 | #include <openssl/err.h> |
| 26 | 25 | ||
| 27 | #include "o_time.h" | 26 | #include "o_time.h" |
| 28 | #include "asn1_locl.h" | ||
| 29 | 27 | ||
| 28 | #define RFC5280 0 | ||
| 29 | #define GENTIME_LENGTH 15 | ||
| 30 | #define UTCTIME_LENGTH 13 | ||
| 31 | |||
| 32 | int | ||
| 33 | asn1_tm_cmp(struct tm *tm1, struct tm *tm2) { | ||
| 34 | if (tm1->tm_year < tm2->tm_year) | ||
| 35 | return (-1); | ||
| 36 | if (tm1->tm_year > tm2->tm_year) | ||
| 37 | return (1); | ||
| 38 | if (tm1->tm_mon < tm2->tm_mon) | ||
| 39 | return (-1); | ||
| 40 | if (tm1->tm_mon > tm2->tm_mon) | ||
| 41 | return (1); | ||
| 42 | if (tm1->tm_mday < tm2->tm_mday) | ||
| 43 | return (-1); | ||
| 44 | if (tm1->tm_mday > tm2->tm_mday) | ||
| 45 | return (1); | ||
| 46 | if (tm1->tm_hour < tm2->tm_hour) | ||
| 47 | return (-1); | ||
| 48 | if (tm1->tm_hour > tm2->tm_hour) | ||
| 49 | return (1); | ||
| 50 | if (tm1->tm_min < tm2->tm_min) | ||
| 51 | return (-1); | ||
| 52 | if (tm1->tm_min > tm2->tm_min) | ||
| 53 | return (1); | ||
| 54 | if (tm1->tm_sec < tm2->tm_sec) | ||
| 55 | return (-1); | ||
| 56 | if (tm1->tm_sec > tm2->tm_sec) | ||
| 57 | return (1); | ||
| 58 | return 0; | ||
| 59 | } | ||
| 60 | |||
| 61 | /* Format a time as an RFC 5280 format Generalized time */ | ||
| 30 | char * | 62 | char * |
| 31 | gentime_string_from_tm(struct tm *tm) | 63 | gentime_string_from_tm(struct tm *tm) |
| 32 | { | 64 | { |
| @@ -45,6 +77,7 @@ gentime_string_from_tm(struct tm *tm) | |||
| 45 | return (ret); | 77 | return (ret); |
| 46 | } | 78 | } |
| 47 | 79 | ||
| 80 | /* Format a time as an RFC 5280 format UTC time */ | ||
| 48 | char * | 81 | char * |
| 49 | utctime_string_from_tm(struct tm *tm) | 82 | utctime_string_from_tm(struct tm *tm) |
| 50 | { | 83 | { |
| @@ -61,14 +94,32 @@ utctime_string_from_tm(struct tm *tm) | |||
| 61 | return (ret); | 94 | return (ret); |
| 62 | } | 95 | } |
| 63 | 96 | ||
| 97 | /* Format a time correctly for an X509 object as per RFC 5280 */ | ||
| 98 | char * | ||
| 99 | rfc5280_string_from_tm(struct tm *tm) | ||
| 100 | { | ||
| 101 | char *ret = NULL; | ||
| 102 | int year; | ||
| 103 | |||
| 104 | year = tm->tm_year + 1900; | ||
| 105 | if (year < 1950 || year > 9999) | ||
| 106 | return (NULL); | ||
| 107 | |||
| 108 | if (year < 2050) | ||
| 109 | ret = utctime_string_from_tm(tm); | ||
| 110 | else | ||
| 111 | ret = gentime_string_from_tm(tm); | ||
| 112 | |||
| 113 | return (ret); | ||
| 114 | } | ||
| 115 | |||
| 64 | /* | 116 | /* |
| 65 | * Parse an ASN.1 time string. | 117 | * Parse an RFC 5280 format ASN.1 time string. |
| 66 | * | 118 | * |
| 67 | * mode must be: | 119 | * mode must be: |
| 68 | * 0 if we expect to parse a time as specified in RFC 5280 from an | 120 | * 0 if we expect to parse a time as specified in RFC 5280 from an X509 object. |
| 69 | * X509 certificate. | 121 | * V_ASN1_UTCTIME if we wish to parse on RFC5280 format UTC time. |
| 70 | * V_ASN1_UTCTIME if we wish to parse a legacy ASN1 UTC time. | 122 | * V_ASN1_GENERALIZEDTIME if we wish to parse an RFC5280 format Generalized time. |
| 71 | * V_ASN1_GENERALIZEDTIME if we wish to parse a legacy ASN1 Generalized time. | ||
| 72 | * | 123 | * |
| 73 | * Returns: | 124 | * Returns: |
| 74 | * -1 if the string was invalid. | 125 | * -1 if the string was invalid. |
| @@ -77,141 +128,54 @@ utctime_string_from_tm(struct tm *tm) | |||
| 77 | * | 128 | * |
| 78 | * Fills in *tm with the corresponding time if tm is non NULL. | 129 | * Fills in *tm with the corresponding time if tm is non NULL. |
| 79 | */ | 130 | */ |
| 80 | #define RFC5280 0 | ||
| 81 | #define ATOI2(ar) ((ar) += 2, ((ar)[-2] - '0') * 10 + ((ar)[-1] - '0')) | 131 | #define ATOI2(ar) ((ar) += 2, ((ar)[-2] - '0') * 10 + ((ar)[-1] - '0')) |
| 82 | int | 132 | int |
| 83 | asn1_time_parse(const char *bytes, size_t len, struct tm *tm, int mode) | 133 | asn1_time_parse(const char *bytes, size_t len, struct tm *tm, int mode) |
| 84 | { | 134 | { |
| 85 | char *p, *buf = NULL, *dot = NULL, *tz = NULL; | 135 | int i, type = 0; |
| 86 | int i, offset = 0, noseconds = 0, type = 0, ret = -1; | ||
| 87 | struct tm ltm; | 136 | struct tm ltm; |
| 88 | struct tm *lt; | 137 | struct tm *lt; |
| 89 | size_t tlen; | 138 | const char *p; |
| 90 | char tzc; | ||
| 91 | 139 | ||
| 92 | if (bytes == NULL) | 140 | if (bytes == NULL) |
| 93 | goto err; | 141 | return (-1); |
| 94 | |||
| 95 | if (len > INT_MAX) | ||
| 96 | goto err; | ||
| 97 | 142 | ||
| 98 | /* Constrain the RFC5280 case within min/max valid lengths. */ | 143 | /* Constrain to valid lengths. */ |
| 99 | if (mode == RFC5280 && (len < 13 || len > 15)) | 144 | if (len != UTCTIME_LENGTH && len != GENTIME_LENGTH) |
| 100 | goto err; | 145 | return (-1); |
| 101 | |||
| 102 | if ((buf = strndup(bytes, len)) == NULL) | ||
| 103 | goto err; | ||
| 104 | 146 | ||
| 105 | lt = tm; | 147 | lt = tm; |
| 106 | if (lt == NULL) { | 148 | if (lt == NULL) { |
| 107 | time_t t = time(NULL); | 149 | memset(<m, 0, sizeof(ltm)); |
| 108 | lt = gmtime_r(&t, <m); | 150 | lt = <m; |
| 109 | if (lt == NULL) | ||
| 110 | goto err; | ||
| 111 | } | 151 | } |
| 112 | 152 | ||
| 113 | /* | 153 | /* Timezone is required and must be GMT (Zulu). */ |
| 114 | * Find position of the optional fractional seconds, and the | 154 | if (bytes[len - 1] != 'Z') |
| 115 | * start of the timezone, while ensuring everything else is | 155 | return (-1); |
| 116 | * digits. | ||
| 117 | */ | ||
| 118 | for (i = 0; i < len; i++) { | ||
| 119 | char *t = buf + i; | ||
| 120 | if (isdigit((unsigned char)*t)) | ||
| 121 | continue; | ||
| 122 | if (*t == '.' && dot == NULL && tz == NULL) { | ||
| 123 | dot = t; | ||
| 124 | continue; | ||
| 125 | } | ||
| 126 | if ((*t == 'Z' || *t == '+' || *t == '-') && tz == NULL) { | ||
| 127 | tz = t; | ||
| 128 | continue; | ||
| 129 | } | ||
| 130 | goto err; | ||
| 131 | } | ||
| 132 | |||
| 133 | /* | ||
| 134 | * Timezone is required. For the non-RFC case it may be | ||
| 135 | * either Z or +- HHMM, but for RFC5280 it may be only Z. | ||
| 136 | */ | ||
| 137 | if (tz == NULL) | ||
| 138 | goto err; | ||
| 139 | tzc = *tz; | ||
| 140 | *tz++ = '\0'; | ||
| 141 | if (tzc == 'Z') { | ||
| 142 | if (*tz != '\0') | ||
| 143 | goto err; | ||
| 144 | } else if (mode != RFC5280 && (tzc == '+' || tzc == '-') && | ||
| 145 | strlen(tz) == 4) { | ||
| 146 | int hours = ATOI2(tz); | ||
| 147 | int mins = ATOI2(tz); | ||
| 148 | |||
| 149 | if (hours < 0 || hours > 12 || mins < 0 || mins > 59) | ||
| 150 | goto err; | ||
| 151 | offset = hours * 3600 + mins * 60; | ||
| 152 | if (tzc == '-') | ||
| 153 | offset = -offset; | ||
| 154 | } else | ||
| 155 | goto err; | ||
| 156 | |||
| 157 | if (offset != 0) { | ||
| 158 | /* XXX - yuck - OPENSSL_gmtime_adj should go away */ | ||
| 159 | if (!OPENSSL_gmtime_adj(lt, 0, offset)) | ||
| 160 | goto err; | ||
| 161 | } | ||
| 162 | 156 | ||
| 163 | /* | 157 | /* Make sure everything else is digits. */ |
| 164 | * We only allow fractional seconds to be present if we are in | 158 | for (i = 0; i < len - 1; i++) { |
| 165 | * the non-RFC case of a Generalized time. RFC 5280 forbids | 159 | if (isdigit((unsigned char)bytes[i])) |
| 166 | * fractional seconds. | 160 | continue; |
| 167 | */ | 161 | return (-1); |
| 168 | if (dot != NULL) { | ||
| 169 | if (mode != V_ASN1_GENERALIZEDTIME) | ||
| 170 | goto err; | ||
| 171 | *dot++ = '\0'; | ||
| 172 | if (!isdigit((unsigned char)*dot)) | ||
| 173 | goto err; | ||
| 174 | } | 162 | } |
| 175 | 163 | ||
| 176 | /* | 164 | /* |
| 177 | * Validate and convert the time | 165 | * Validate and convert the time |
| 178 | */ | 166 | */ |
| 179 | p = buf; | 167 | p = bytes; |
| 180 | tlen = strlen(buf); | 168 | switch (len) { |
| 181 | switch (tlen) { | 169 | case GENTIME_LENGTH: |
| 182 | case 14: | 170 | if (mode == V_ASN1_UTCTIME) |
| 171 | return (-1); | ||
| 183 | lt->tm_year = (ATOI2(p) * 100) - 1900; /* cc */ | 172 | lt->tm_year = (ATOI2(p) * 100) - 1900; /* cc */ |
| 184 | if (mode != RFC5280 && mode != V_ASN1_GENERALIZEDTIME) | ||
| 185 | goto err; | ||
| 186 | type = V_ASN1_GENERALIZEDTIME; | 173 | type = V_ASN1_GENERALIZEDTIME; |
| 187 | /* FALLTHROUGH */ | 174 | /* FALLTHROUGH */ |
| 188 | case 12: | 175 | case UTCTIME_LENGTH: |
| 189 | if (type == 0 && mode == V_ASN1_GENERALIZEDTIME) { | ||
| 190 | /* | ||
| 191 | * In the non-RFC case of a Generalized time | ||
| 192 | * seconds may not have been provided. RFC | ||
| 193 | * 5280 mandates that seconds must be present. | ||
| 194 | */ | ||
| 195 | noseconds = 1; | ||
| 196 | lt->tm_year = (ATOI2(p) * 100) - 1900; /* cc */ | ||
| 197 | type = V_ASN1_GENERALIZEDTIME; | ||
| 198 | } | ||
| 199 | /* FALLTHROUGH */ | ||
| 200 | case 10: | ||
| 201 | if (type == 0) { | 176 | if (type == 0) { |
| 202 | /* | ||
| 203 | * At this point we must have a UTC time. | ||
| 204 | * In the RFC 5280 case it must have the | ||
| 205 | * seconds present. In the non-RFC case | ||
| 206 | * may have no seconds. | ||
| 207 | */ | ||
| 208 | if (mode == V_ASN1_GENERALIZEDTIME) | 177 | if (mode == V_ASN1_GENERALIZEDTIME) |
| 209 | goto err; | 178 | return (-1); |
| 210 | if (tlen == 10) { | ||
| 211 | if (mode != V_ASN1_UTCTIME) | ||
| 212 | goto err; | ||
| 213 | noseconds = 1; | ||
| 214 | } | ||
| 215 | type = V_ASN1_UTCTIME; | 179 | type = V_ASN1_UTCTIME; |
| 216 | } | 180 | } |
| 217 | lt->tm_year += ATOI2(p); /* yy */ | 181 | lt->tm_year += ATOI2(p); /* yy */ |
| @@ -221,40 +185,258 @@ asn1_time_parse(const char *bytes, size_t len, struct tm *tm, int mode) | |||
| 221 | } | 185 | } |
| 222 | lt->tm_mon = ATOI2(p) - 1; /* mm */ | 186 | lt->tm_mon = ATOI2(p) - 1; /* mm */ |
| 223 | if (lt->tm_mon < 0 || lt->tm_mon > 11) | 187 | if (lt->tm_mon < 0 || lt->tm_mon > 11) |
| 224 | goto err; | 188 | return (-1); |
| 225 | lt->tm_mday = ATOI2(p); /* dd */ | 189 | lt->tm_mday = ATOI2(p); /* dd */ |
| 226 | if (lt->tm_mday < 1 || lt->tm_mday > 31) | 190 | if (lt->tm_mday < 1 || lt->tm_mday > 31) |
| 227 | goto err; | 191 | return (-1); |
| 228 | lt->tm_hour = ATOI2(p); /* HH */ | 192 | lt->tm_hour = ATOI2(p); /* HH */ |
| 229 | if (lt->tm_hour < 0 || lt->tm_hour > 23) | 193 | if (lt->tm_hour < 0 || lt->tm_hour > 23) |
| 230 | goto err; | 194 | return (-1); |
| 231 | lt->tm_min = ATOI2(p); /* MM */ | 195 | lt->tm_min = ATOI2(p); /* MM */ |
| 232 | if (lt->tm_hour < 0 || lt->tm_min > 59) | 196 | if (lt->tm_min < 0 || lt->tm_min > 59) |
| 233 | goto err; | 197 | return (-1); |
| 234 | lt->tm_sec = 0; /* SS */ | 198 | lt->tm_sec = ATOI2(p); /* SS */ |
| 235 | if (noseconds) | ||
| 236 | break; | ||
| 237 | lt->tm_sec = ATOI2(p); | ||
| 238 | /* Leap second 60 is not accepted. Reconsider later? */ | 199 | /* Leap second 60 is not accepted. Reconsider later? */ |
| 239 | if (lt->tm_hour < 0 || lt->tm_sec > 59) | 200 | if (lt->tm_sec < 0 || lt->tm_sec > 59) |
| 240 | goto err; | 201 | return (-1); |
| 241 | break; | 202 | break; |
| 242 | default: | 203 | default: |
| 243 | goto err; | 204 | return (-1); |
| 205 | } | ||
| 206 | |||
| 207 | return (type); | ||
| 208 | } | ||
| 209 | |||
| 210 | /* | ||
| 211 | * ASN1_TIME generic functions. | ||
| 212 | */ | ||
| 213 | |||
| 214 | static int | ||
| 215 | ASN1_TIME_set_string_internal(ASN1_TIME *s, const char *str, int mode) | ||
| 216 | { | ||
| 217 | int type; | ||
| 218 | char *tmp; | ||
| 219 | |||
| 220 | if ((type = asn1_time_parse(str, strlen(str), NULL, mode)) == -1) | ||
| 221 | return (0); | ||
| 222 | if (mode != 0 && mode != type) | ||
| 223 | return (0); | ||
| 224 | if ((tmp = strdup(str)) == NULL) | ||
| 225 | return (0); | ||
| 226 | free(s->data); | ||
| 227 | s->data = tmp; | ||
| 228 | s->length = strlen(tmp); | ||
| 229 | s->type = type; | ||
| 230 | return (1); | ||
| 231 | } | ||
| 232 | |||
| 233 | static ASN1_TIME * | ||
| 234 | ASN1_TIME_adj_internal(ASN1_TIME *s, time_t t, int offset_day, long offset_sec, | ||
| 235 | int mode) | ||
| 236 | { | ||
| 237 | int allocated = 0; | ||
| 238 | struct tm tm; | ||
| 239 | size_t len; | ||
| 240 | char * p; | ||
| 241 | |||
| 242 | if (gmtime_r(&t, &tm) == NULL) | ||
| 243 | return (NULL); | ||
| 244 | |||
| 245 | if (offset_day || offset_sec) { | ||
| 246 | if (!OPENSSL_gmtime_adj(&tm, offset_day, offset_sec)) | ||
| 247 | return (NULL); | ||
| 244 | } | 248 | } |
| 245 | 249 | ||
| 246 | /* RFC 5280 section 4.1.2.5 */ | 250 | switch (mode) { |
| 247 | if (mode == RFC5280) { | 251 | case V_ASN1_UTCTIME: |
| 248 | if (lt->tm_year < 150 && type != V_ASN1_UTCTIME) | 252 | p = utctime_string_from_tm(&tm); |
| 249 | goto err; | 253 | break; |
| 250 | if (lt->tm_year >= 150 && type != V_ASN1_GENERALIZEDTIME) | 254 | case V_ASN1_GENERALIZEDTIME: |
| 251 | goto err; | 255 | p = gentime_string_from_tm(&tm); |
| 256 | break; | ||
| 257 | case RFC5280: | ||
| 258 | p = rfc5280_string_from_tm(&tm); | ||
| 259 | break; | ||
| 260 | default: | ||
| 261 | return (NULL); | ||
| 262 | } | ||
| 263 | if (p == NULL) { | ||
| 264 | ASN1err(ASN1_F_ASN1_GENERALIZEDTIME_ADJ, | ||
| 265 | ASN1_R_ILLEGAL_TIME_VALUE); | ||
| 266 | return (NULL); | ||
| 252 | } | 267 | } |
| 253 | 268 | ||
| 254 | ret = type; | 269 | if (s == NULL) { |
| 270 | if ((s = ASN1_TIME_new()) == NULL) | ||
| 271 | return (NULL); | ||
| 272 | allocated = 1; | ||
| 273 | } | ||
| 255 | 274 | ||
| 256 | err: | 275 | len = strlen(p); |
| 257 | free(buf); | 276 | switch (len) { |
| 277 | case GENTIME_LENGTH: | ||
| 278 | s->type = V_ASN1_GENERALIZEDTIME; | ||
| 279 | break; | ||
| 280 | case UTCTIME_LENGTH: | ||
| 281 | s->type = V_ASN1_UTCTIME; | ||
| 282 | break; | ||
| 283 | default: | ||
| 284 | if (allocated) | ||
| 285 | ASN1_TIME_free(s); | ||
| 286 | free(p); | ||
| 287 | return (NULL); | ||
| 288 | } | ||
| 289 | free(s->data); | ||
| 290 | s->data = p; | ||
| 291 | s->length = len; | ||
| 292 | return (s); | ||
| 293 | } | ||
| 258 | 294 | ||
| 259 | return (ret); | 295 | ASN1_TIME * |
| 296 | ASN1_TIME_set(ASN1_TIME *s, time_t t) | ||
| 297 | { | ||
| 298 | return (ASN1_TIME_adj(s, t, 0, 0)); | ||
| 260 | } | 299 | } |
| 300 | |||
| 301 | ASN1_TIME * | ||
| 302 | ASN1_TIME_adj(ASN1_TIME *s, time_t t, int offset_day, long offset_sec) | ||
| 303 | { | ||
| 304 | return (ASN1_TIME_adj_internal(s, t, offset_day, offset_sec, RFC5280)); | ||
| 305 | } | ||
| 306 | |||
| 307 | int | ||
| 308 | ASN1_TIME_check(ASN1_TIME *t) | ||
| 309 | { | ||
| 310 | if (t->type != V_ASN1_GENERALIZEDTIME && t->type != V_ASN1_UTCTIME) | ||
| 311 | return (0); | ||
| 312 | return (t->type == asn1_time_parse(t->data, t->length, NULL, t->type)); | ||
| 313 | } | ||
| 314 | |||
| 315 | ASN1_GENERALIZEDTIME * | ||
| 316 | ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out) | ||
| 317 | { | ||
| 318 | ASN1_GENERALIZEDTIME *tmp = NULL; | ||
| 319 | struct tm tm; | ||
| 320 | char *str; | ||
| 321 | |||
| 322 | if (t->type != V_ASN1_GENERALIZEDTIME && t->type != V_ASN1_UTCTIME) | ||
| 323 | return (NULL); | ||
| 324 | |||
| 325 | memset(&tm, 0, sizeof(tm)); | ||
| 326 | if (t->type != asn1_time_parse(t->data, t->length, &tm, t->type)) | ||
| 327 | return (NULL); | ||
| 328 | if ((str = gentime_string_from_tm(&tm)) == NULL) | ||
| 329 | return (NULL); | ||
| 330 | |||
| 331 | if (out != NULL) | ||
| 332 | tmp = *out; | ||
| 333 | if (tmp == NULL && (tmp = ASN1_GENERALIZEDTIME_new()) == NULL) { | ||
| 334 | free(str); | ||
| 335 | return (NULL); | ||
| 336 | } | ||
| 337 | if (out != NULL) | ||
| 338 | *out = tmp; | ||
| 339 | |||
| 340 | free(tmp->data); | ||
| 341 | tmp->data = str; | ||
| 342 | tmp->length = strlen(str); | ||
| 343 | return (tmp); | ||
| 344 | } | ||
| 345 | |||
| 346 | int | ||
| 347 | ASN1_TIME_set_string(ASN1_TIME *s, const char *str) | ||
| 348 | { | ||
| 349 | return (ASN1_TIME_set_string_internal(s, str, 0)); | ||
| 350 | } | ||
| 351 | |||
| 352 | /* | ||
| 353 | * ASN1_UTCTIME wrappers | ||
| 354 | */ | ||
| 355 | |||
| 356 | int | ||
| 357 | ASN1_UTCTIME_check(ASN1_UTCTIME *d) | ||
| 358 | { | ||
| 359 | if (d->type != V_ASN1_UTCTIME) | ||
| 360 | return (0); | ||
| 361 | return (d->type == asn1_time_parse(d->data, d->length, NULL, d->type)); | ||
| 362 | } | ||
| 363 | |||
| 364 | int | ||
| 365 | ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str) | ||
| 366 | { | ||
| 367 | if (s->type != V_ASN1_UTCTIME) | ||
| 368 | return (0); | ||
| 369 | return (ASN1_TIME_set_string_internal(s, str, V_ASN1_UTCTIME)); | ||
| 370 | } | ||
| 371 | |||
| 372 | ASN1_UTCTIME * | ||
| 373 | ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t) | ||
| 374 | { | ||
| 375 | return (ASN1_UTCTIME_adj(s, t, 0, 0)); | ||
| 376 | } | ||
| 377 | |||
| 378 | ASN1_UTCTIME * | ||
| 379 | ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, int offset_day, long offset_sec) | ||
| 380 | { | ||
| 381 | return (ASN1_TIME_adj_internal(s, t, offset_day, offset_sec, | ||
| 382 | V_ASN1_UTCTIME)); | ||
| 383 | } | ||
| 384 | |||
| 385 | int | ||
| 386 | ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t2) | ||
| 387 | { | ||
| 388 | struct tm tm1, tm2; | ||
| 389 | |||
| 390 | /* | ||
| 391 | * This function has never handled failure conditions properly | ||
| 392 | * and should be deprecated. The OpenSSL version used to | ||
| 393 | * simply follow NULL pointers on failure. BoringSSL and | ||
| 394 | * OpenSSL now make it return -2 on failure. | ||
| 395 | * | ||
| 396 | * The danger is that users of this function will not | ||
| 397 | * differentiate the -2 failure case from t1 < t2. | ||
| 398 | */ | ||
| 399 | if (asn1_time_parse(s->data, s->length, &tm1, V_ASN1_UTCTIME) == -1) | ||
| 400 | return (-2); /* XXX */ | ||
| 401 | |||
| 402 | if (gmtime_r(&t2, &tm2) == NULL) | ||
| 403 | return (-2); /* XXX */ | ||
| 404 | |||
| 405 | return asn1_tm_cmp(&tm1, &tm2); | ||
| 406 | } | ||
| 407 | |||
| 408 | /* | ||
| 409 | * ASN1_GENERALIZEDTIME wrappers | ||
| 410 | */ | ||
| 411 | |||
| 412 | int | ||
| 413 | ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *d) | ||
| 414 | { | ||
| 415 | if (d->type != V_ASN1_GENERALIZEDTIME) | ||
| 416 | return (0); | ||
| 417 | return (d->type == asn1_time_parse(d->data, d->length, NULL, d->type)); | ||
| 418 | } | ||
| 419 | |||
| 420 | int | ||
| 421 | ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str) | ||
| 422 | { | ||
| 423 | if (s->type != V_ASN1_GENERALIZEDTIME) | ||
| 424 | return (0); | ||
| 425 | return (ASN1_TIME_set_string_internal(s, str, V_ASN1_GENERALIZEDTIME)); | ||
| 426 | } | ||
| 427 | |||
| 428 | ASN1_GENERALIZEDTIME * | ||
| 429 | ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s, time_t t) | ||
| 430 | { | ||
| 431 | return (ASN1_GENERALIZEDTIME_adj(s, t, 0, 0)); | ||
| 432 | } | ||
| 433 | |||
| 434 | ASN1_GENERALIZEDTIME * | ||
| 435 | ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, time_t t, int offset_day, | ||
| 436 | long offset_sec) | ||
| 437 | { | ||
| 438 | return (ASN1_TIME_adj_internal(s, t, offset_day, offset_sec, | ||
| 439 | V_ASN1_GENERALIZEDTIME)); | ||
| 440 | } | ||
| 441 | |||
| 442 | |||
diff --git a/src/lib/libcrypto/asn1/a_utctm.c b/src/lib/libcrypto/asn1/a_utctm.c deleted file mode 100644 index 495c497bc8..0000000000 --- a/src/lib/libcrypto/asn1/a_utctm.c +++ /dev/null | |||
| @@ -1,173 +0,0 @@ | |||
| 1 | /* $OpenBSD: a_utctm.c,v 1.32 2015/10/08 02:42:58 beck Exp $ */ | ||
| 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
| 3 | * All rights reserved. | ||
| 4 | * | ||
| 5 | * This package is an SSL implementation written | ||
| 6 | * by Eric Young (eay@cryptsoft.com). | ||
| 7 | * The implementation was written so as to conform with Netscapes SSL. | ||
| 8 | * | ||
| 9 | * This library is free for commercial and non-commercial use as long as | ||
| 10 | * the following conditions are aheared to. The following conditions | ||
| 11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
| 12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
| 13 | * included with this distribution is covered by the same copyright terms | ||
| 14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
| 15 | * | ||
| 16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
| 17 | * the code are not to be removed. | ||
| 18 | * If this package is used in a product, Eric Young should be given attribution | ||
| 19 | * as the author of the parts of the library used. | ||
| 20 | * This can be in the form of a textual message at program startup or | ||
| 21 | * in documentation (online or textual) provided with the package. | ||
| 22 | * | ||
| 23 | * Redistribution and use in source and binary forms, with or without | ||
| 24 | * modification, are permitted provided that the following conditions | ||
| 25 | * are met: | ||
| 26 | * 1. Redistributions of source code must retain the copyright | ||
| 27 | * notice, this list of conditions and the following disclaimer. | ||
| 28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 29 | * notice, this list of conditions and the following disclaimer in the | ||
| 30 | * documentation and/or other materials provided with the distribution. | ||
| 31 | * 3. All advertising materials mentioning features or use of this software | ||
| 32 | * must display the following acknowledgement: | ||
| 33 | * "This product includes cryptographic software written by | ||
| 34 | * Eric Young (eay@cryptsoft.com)" | ||
| 35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
| 36 | * being used are not cryptographic related :-). | ||
| 37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
| 38 | * the apps directory (application code) you must include an acknowledgement: | ||
| 39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
| 40 | * | ||
| 41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
| 42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
| 45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 51 | * SUCH DAMAGE. | ||
| 52 | * | ||
| 53 | * The licence and distribution terms for any publically available version or | ||
| 54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
| 55 | * copied and put under another distribution licence | ||
| 56 | * [including the GNU Public Licence.] | ||
| 57 | */ | ||
| 58 | |||
| 59 | #include <stdio.h> | ||
| 60 | #include <string.h> | ||
| 61 | #include <time.h> | ||
| 62 | |||
| 63 | #include <openssl/asn1.h> | ||
| 64 | #include <openssl/err.h> | ||
| 65 | |||
| 66 | #include "o_time.h" | ||
| 67 | #include "asn1_locl.h" | ||
| 68 | |||
| 69 | int | ||
| 70 | ASN1_UTCTIME_check(ASN1_UTCTIME *d) | ||
| 71 | { | ||
| 72 | if (d->type != V_ASN1_UTCTIME) | ||
| 73 | return (0); | ||
| 74 | return(d->type == asn1_time_parse(d->data, d->length, NULL, d->type)); | ||
| 75 | } | ||
| 76 | |||
| 77 | int | ||
| 78 | ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str) | ||
| 79 | { | ||
| 80 | ASN1_UTCTIME t; | ||
| 81 | |||
| 82 | t.type = V_ASN1_UTCTIME; | ||
| 83 | t.length = strlen(str); | ||
| 84 | t.data = (unsigned char *)str; | ||
| 85 | if (ASN1_UTCTIME_check(&t)) { | ||
| 86 | if (s != NULL) { | ||
| 87 | if (!ASN1_STRING_set((ASN1_STRING *)s, | ||
| 88 | (unsigned char *)str, t.length)) | ||
| 89 | return 0; | ||
| 90 | s->type = V_ASN1_UTCTIME; | ||
| 91 | } | ||
| 92 | return (1); | ||
| 93 | } else | ||
| 94 | return (0); | ||
| 95 | } | ||
| 96 | |||
| 97 | ASN1_UTCTIME * | ||
| 98 | ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t) | ||
| 99 | { | ||
| 100 | return ASN1_UTCTIME_adj(s, t, 0, 0); | ||
| 101 | } | ||
| 102 | |||
| 103 | static ASN1_UTCTIME * | ||
| 104 | ASN1_UTCTIME_adj_internal(ASN1_UTCTIME *s, time_t t, int offset_day, | ||
| 105 | long offset_sec) | ||
| 106 | { | ||
| 107 | char *p; | ||
| 108 | struct tm *ts; | ||
| 109 | struct tm data; | ||
| 110 | |||
| 111 | ts = gmtime_r(&t, &data); | ||
| 112 | if (ts == NULL) | ||
| 113 | return (NULL); | ||
| 114 | |||
| 115 | if (offset_day || offset_sec) { | ||
| 116 | if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec)) | ||
| 117 | return NULL; | ||
| 118 | } | ||
| 119 | |||
| 120 | if ((p = utctime_string_from_tm(ts)) == NULL) { | ||
| 121 | ASN1err(ASN1_F_ASN1_UTCTIME_ADJ, ERR_R_MALLOC_FAILURE); | ||
| 122 | return (NULL); | ||
| 123 | } | ||
| 124 | free(s->data); | ||
| 125 | s->data = p; | ||
| 126 | s->length = strlen(p); | ||
| 127 | |||
| 128 | s->type = V_ASN1_UTCTIME; | ||
| 129 | return (s); | ||
| 130 | } | ||
| 131 | |||
| 132 | ASN1_UTCTIME * | ||
| 133 | ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, int offset_day, long offset_sec) | ||
| 134 | { | ||
| 135 | ASN1_UTCTIME *tmp = NULL, *ret; | ||
| 136 | |||
| 137 | if (s == NULL) { | ||
| 138 | tmp = ASN1_UTCTIME_new(); | ||
| 139 | if (tmp == NULL) | ||
| 140 | return NULL; | ||
| 141 | s = tmp; | ||
| 142 | } | ||
| 143 | |||
| 144 | ret = ASN1_UTCTIME_adj_internal(s, t, offset_day, offset_sec); | ||
| 145 | if (ret == NULL && tmp != NULL) | ||
| 146 | ASN1_UTCTIME_free(tmp); | ||
| 147 | |||
| 148 | return ret; | ||
| 149 | } | ||
| 150 | |||
| 151 | int | ||
| 152 | ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t2) | ||
| 153 | { | ||
| 154 | struct tm tm1; | ||
| 155 | time_t t1; | ||
| 156 | |||
| 157 | /* | ||
| 158 | * This function has never handled failure conditions properly | ||
| 159 | * and should be deprecated. BoringSSL makes it return -2 on | ||
| 160 | * failures, the OpenSSL version follows NULL pointers instead. | ||
| 161 | */ | ||
| 162 | if (asn1_time_parse(s->data, s->length, &tm1, V_ASN1_UTCTIME) == -1) | ||
| 163 | return (-2); /* XXX */ | ||
| 164 | |||
| 165 | if ((t1 = timegm(&tm1)) == -1) | ||
| 166 | return (-2); /* XXX */ | ||
| 167 | |||
| 168 | if (t1 < t2) | ||
| 169 | return (-1); | ||
| 170 | if (t1 > t2) | ||
| 171 | return (1); | ||
| 172 | return (0); | ||
| 173 | } | ||
diff --git a/src/lib/libcrypto/asn1/asn1_locl.h b/src/lib/libcrypto/asn1/asn1_locl.h index d4994c7cee..9b612c8183 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.6 2015/10/02 15:04:45 beck Exp $ */ | 1 | /* $OpenBSD: asn1_locl.h,v 1.7 2015/10/19 16:32:37 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,10 +58,6 @@ | |||
| 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 | |||
| 65 | /* ASN1 print context structure */ | 61 | /* ASN1 print context structure */ |
| 66 | 62 | ||
| 67 | struct asn1_pctx_st { | 63 | struct asn1_pctx_st { |
diff --git a/src/lib/libcrypto/crypto/Makefile b/src/lib/libcrypto/crypto/Makefile index 64ee774518..d662aecc24 100644 --- a/src/lib/libcrypto/crypto/Makefile +++ b/src/lib/libcrypto/crypto/Makefile | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | # $OpenBSD: Makefile,v 1.66 2015/10/02 15:04:45 beck Exp $ | 1 | # $OpenBSD: Makefile,v 1.67 2015/10/19 16:32:37 beck Exp $ |
| 2 | 2 | ||
| 3 | LIB= crypto | 3 | LIB= crypto |
| 4 | 4 | ||
| @@ -35,7 +35,7 @@ SRCS+= aes_misc.c aes_ecb.c aes_cfb.c aes_ofb.c | |||
| 35 | SRCS+= aes_ctr.c aes_ige.c aes_wrap.c | 35 | SRCS+= aes_ctr.c aes_ige.c aes_wrap.c |
| 36 | 36 | ||
| 37 | # asn1/ | 37 | # asn1/ |
| 38 | SRCS+= a_object.c a_bitstr.c a_utctm.c a_gentm.c a_time.c a_int.c a_octet.c | 38 | SRCS+= a_object.c a_bitstr.c a_time.c a_int.c a_octet.c |
| 39 | SRCS+= a_print.c a_type.c a_dup.c a_d2i_fp.c a_i2d_fp.c | 39 | SRCS+= a_print.c a_type.c a_dup.c a_d2i_fp.c a_i2d_fp.c |
| 40 | SRCS+= a_enum.c a_utf8.c a_sign.c a_digest.c a_verify.c a_mbstr.c a_strex.c | 40 | SRCS+= a_enum.c a_utf8.c a_sign.c a_digest.c a_verify.c a_mbstr.c a_strex.c |
| 41 | SRCS+= x_algor.c x_val.c x_pubkey.c x_sig.c x_req.c x_attrib.c x_bignum.c | 41 | SRCS+= x_algor.c x_val.c x_pubkey.c x_sig.c x_req.c x_attrib.c x_bignum.c |
diff --git a/src/lib/libcrypto/x509/x509_lcl.h b/src/lib/libcrypto/x509/x509_lcl.h index 0c1c130d5c..9ffdd01e61 100644 --- a/src/lib/libcrypto/x509/x509_lcl.h +++ b/src/lib/libcrypto/x509/x509_lcl.h | |||
| @@ -58,3 +58,4 @@ | |||
| 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); | 60 | int asn1_time_parse(const char *, size_t, struct tm *, int); |
| 61 | int asn1_tm_cmp(struct tm *tm1, struct tm *tm2); | ||
diff --git a/src/lib/libcrypto/x509/x509_vfy.c b/src/lib/libcrypto/x509/x509_vfy.c index c48143f351..159d60b034 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.46 2015/10/02 15:04:45 beck Exp $ */ | 1 | /* $OpenBSD: x509_vfy.c,v 1.47 2015/10/19 16:32:37 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 | * |
| @@ -1648,8 +1648,9 @@ int | |||
| 1648 | X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) | 1648 | X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) |
| 1649 | { | 1649 | { |
| 1650 | time_t time1, time2; | 1650 | time_t time1, time2; |
| 1651 | struct tm tm1; | 1651 | struct tm tm1, tm2; |
| 1652 | int ret = 0; | 1652 | int ret = 0; |
| 1653 | int type; | ||
| 1653 | 1654 | ||
| 1654 | if (cmp_time == NULL) | 1655 | if (cmp_time == NULL) |
| 1655 | time2 = time(NULL); | 1656 | time2 = time(NULL); |
| @@ -1658,9 +1659,15 @@ X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) | |||
| 1658 | 1659 | ||
| 1659 | memset(&tm1, 0, sizeof(tm1)); | 1660 | memset(&tm1, 0, sizeof(tm1)); |
| 1660 | 1661 | ||
| 1661 | if (asn1_time_parse(ctm->data, ctm->length, &tm1, 0) == -1) | 1662 | if ((type = asn1_time_parse(ctm->data, ctm->length, &tm1, 0)) == -1) |
| 1662 | goto out; /* invalid time */ | 1663 | goto out; /* invalid time */ |
| 1663 | 1664 | ||
| 1665 | /* RFC 5280 section 4.1.2.5 */ | ||
| 1666 | if (tm1.tm_year < 150 && type != V_ASN1_UTCTIME) | ||
| 1667 | goto out; | ||
| 1668 | if (tm1.tm_year >= 150 && type != V_ASN1_GENERALIZEDTIME) | ||
| 1669 | goto out; | ||
| 1670 | |||
| 1664 | /* | 1671 | /* |
| 1665 | * Defensively fail if the time string is not representable as | 1672 | * 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 | 1673 | * a time_t. A time_t must be sane if you care about times after |
| @@ -1669,10 +1676,12 @@ X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) | |||
| 1669 | if ((time1 = timegm(&tm1)) == -1) | 1676 | if ((time1 = timegm(&tm1)) == -1) |
| 1670 | goto out; | 1677 | goto out; |
| 1671 | 1678 | ||
| 1672 | if (time1 <= time2) | 1679 | if (gmtime_r(&time2, &tm2) == NULL) |
| 1673 | ret = -1; | 1680 | goto out; |
| 1674 | else | 1681 | |
| 1675 | ret = 1; | 1682 | ret = asn1_tm_cmp(&tm1, &tm2); |
| 1683 | if (ret == 0) | ||
| 1684 | ret = -1; /* 0 is used for error, so map same to less than */ | ||
| 1676 | out: | 1685 | out: |
| 1677 | return (ret); | 1686 | return (ret); |
| 1678 | } | 1687 | } |
| @@ -1684,28 +1693,20 @@ X509_gmtime_adj(ASN1_TIME *s, long adj) | |||
| 1684 | } | 1693 | } |
| 1685 | 1694 | ||
| 1686 | ASN1_TIME * | 1695 | ASN1_TIME * |
| 1687 | X509_time_adj(ASN1_TIME *s, long offset_sec, time_t *in_tm) | 1696 | X509_time_adj(ASN1_TIME *s, long offset_sec, time_t *in_time) |
| 1688 | { | 1697 | { |
| 1689 | return X509_time_adj_ex(s, 0, offset_sec, in_tm); | 1698 | return X509_time_adj_ex(s, 0, offset_sec, in_time); |
| 1690 | } | 1699 | } |
| 1691 | 1700 | ||
| 1692 | ASN1_TIME * | 1701 | ASN1_TIME * |
| 1693 | X509_time_adj_ex(ASN1_TIME *s, int offset_day, long offset_sec, time_t *in_tm) | 1702 | X509_time_adj_ex(ASN1_TIME *s, int offset_day, long offset_sec, time_t *in_time) |
| 1694 | { | 1703 | { |
| 1695 | time_t t; | 1704 | time_t t; |
| 1696 | 1705 | if (in_time == NULL) | |
| 1697 | if (in_tm) | 1706 | t = time(NULL); |
| 1698 | t = *in_tm; | ||
| 1699 | else | 1707 | else |
| 1700 | time(&t); | 1708 | t = *in_time; |
| 1701 | 1709 | ||
| 1702 | if (s && !(s->flags & ASN1_STRING_FLAG_MSTRING)) { | ||
| 1703 | if (s->type == V_ASN1_UTCTIME) | ||
| 1704 | return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec); | ||
| 1705 | if (s->type == V_ASN1_GENERALIZEDTIME) | ||
| 1706 | return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, | ||
| 1707 | offset_sec); | ||
| 1708 | } | ||
| 1709 | return ASN1_TIME_adj(s, t, offset_day, offset_sec); | 1710 | return ASN1_TIME_adj(s, t, offset_day, offset_sec); |
| 1710 | } | 1711 | } |
| 1711 | 1712 | ||
