diff options
author | beck <> | 2015-10-02 15:04:45 +0000 |
---|---|---|
committer | beck <> | 2015-10-02 15:04:45 +0000 |
commit | 61992d68f1934e7e4171e633f39fb76a4654b5a2 (patch) | |
tree | 8649498e5e9fdda4e44ebac5989504efbcc57b61 /src/lib/libcrypto/asn1/a_gentm.c | |
parent | 5951a0298417b41fc2a1fb4ad8a057fb9530e872 (diff) | |
download | openbsd-61992d68f1934e7e4171e633f39fb76a4654b5a2.tar.gz openbsd-61992d68f1934e7e4171e633f39fb76a4654b5a2.tar.bz2 openbsd-61992d68f1934e7e4171e633f39fb76a4654b5a2.zip |
Flense the greasy black guts of unreadble string parsing code out of three areas
in asn1 and x509 code, all dealing with an ASN1_TIME. This brings the parsing
together in one function that converts into a struct tm. While we are at it this
also brings us into conformance with RFC 5280 for times allowed in an X509 cert,
as OpenSSL is very liberal with what it allows.
input and fixes from deraadt@ jsing@ guethther@ and others.
ok krw@, guenther@, jsing@
Diffstat (limited to 'src/lib/libcrypto/asn1/a_gentm.c')
-rw-r--r-- | src/lib/libcrypto/asn1/a_gentm.c | 106 |
1 files changed, 13 insertions, 93 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 | } |