summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsing <>2022-03-19 17:35:52 +0000
committerjsing <>2022-03-19 17:35:52 +0000
commit1886782bdfd11c86949b1ea6243e8ffcb02455ea (patch)
tree72c751aeba9f06d9f06d95487ff72b4b19165a49
parentaffcb4376993774ff70241876bfbf4ce93d38812 (diff)
downloadopenbsd-1886782bdfd11c86949b1ea6243e8ffcb02455ea.tar.gz
openbsd-1886782bdfd11c86949b1ea6243e8ffcb02455ea.tar.bz2
openbsd-1886782bdfd11c86949b1ea6243e8ffcb02455ea.zip
Rewrite ascii/text to ASN.1 object conversion.
Rewrite the ascii/text to ASN.1 object conversion code using CBB/CBS, while also addressing some of the bizarre behaviour (such as allowing mixed separators and treating '..' as a zero value). ok inoguchi@ tb@
-rw-r--r--src/lib/libcrypto/asn1/a_object.c288
1 files changed, 167 insertions, 121 deletions
diff --git a/src/lib/libcrypto/asn1/a_object.c b/src/lib/libcrypto/asn1/a_object.c
index 120437bf10..0061ccb880 100644
--- a/src/lib/libcrypto/asn1/a_object.c
+++ b/src/lib/libcrypto/asn1/a_object.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: a_object.c,v 1.41 2022/03/15 18:47:22 jsing Exp $ */ 1/* $OpenBSD: a_object.c,v 1.42 2022/03/19 17:35:52 jsing 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 *
@@ -62,7 +62,6 @@
62 62
63#include <openssl/asn1.h> 63#include <openssl/asn1.h>
64#include <openssl/asn1t.h> 64#include <openssl/asn1t.h>
65#include <openssl/bn.h>
66#include <openssl/err.h> 65#include <openssl/err.h>
67#include <openssl/buffer.h> 66#include <openssl/buffer.h>
68#include <openssl/objects.h> 67#include <openssl/objects.h>
@@ -146,128 +145,25 @@ i2d_ASN1_OBJECT(const ASN1_OBJECT *a, unsigned char **pp)
146 return (objsize); 145 return (objsize);
147} 146}
148 147
149int 148static int
150a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num) 149oid_add_arc(CBB *cbb, uint64_t arc)
151{ 150{
152 int i, first, len = 0, c, use_bn; 151 int started = 0;
153 char ftmp[24], *tmp = ftmp; 152 uint8_t val;
154 int tmpsize = sizeof ftmp; 153 int i;
155 const char *p; 154
156 unsigned long l; 155 for (i = (sizeof(arc) * 8) / 7; i >= 0; i--) {
157 BIGNUM *bl = NULL; 156 val = (arc >> (i * 7)) & 0x7f;
158 157 if (!started && i != 0 && val == 0)
159 if (num == 0) 158 continue;
160 return (0); 159 if (i > 0)
161 else if (num == -1) 160 val |= 0x80;
162 num = strlen(buf); 161 if (!CBB_add_u8(cbb, val))
163 162 return 0;
164 p = buf; 163 started = 1;
165 c = *(p++);
166 num--;
167 if ((c >= '0') && (c <= '2')) {
168 first= c-'0';
169 } else {
170 ASN1error(ASN1_R_FIRST_NUM_TOO_LARGE);
171 goto err;
172 }
173
174 if (num <= 0) {
175 ASN1error(ASN1_R_MISSING_SECOND_NUMBER);
176 goto err;
177 }
178 c = *(p++);
179 num--;
180 for (;;) {
181 if (num <= 0)
182 break;
183 if ((c != '.') && (c != ' ')) {
184 ASN1error(ASN1_R_INVALID_SEPARATOR);
185 goto err;
186 }
187 l = 0;
188 use_bn = 0;
189 for (;;) {
190 if (num <= 0)
191 break;
192 num--;
193 c = *(p++);
194 if ((c == ' ') || (c == '.'))
195 break;
196 if ((c < '0') || (c > '9')) {
197 ASN1error(ASN1_R_INVALID_DIGIT);
198 goto err;
199 }
200 if (!use_bn && l >= ((ULONG_MAX - 80) / 10L)) {
201 use_bn = 1;
202 if (!bl)
203 bl = BN_new();
204 if (!bl || !BN_set_word(bl, l))
205 goto err;
206 }
207 if (use_bn) {
208 if (!BN_mul_word(bl, 10L) ||
209 !BN_add_word(bl, c-'0'))
210 goto err;
211 } else
212 l = l * 10L + (long)(c - '0');
213 }
214 if (len == 0) {
215 if ((first < 2) && (l >= 40)) {
216 ASN1error(ASN1_R_SECOND_NUMBER_TOO_LARGE);
217 goto err;
218 }
219 if (use_bn) {
220 if (!BN_add_word(bl, first * 40))
221 goto err;
222 } else
223 l += (long)first * 40;
224 }
225 i = 0;
226 if (use_bn) {
227 int blsize;
228 blsize = BN_num_bits(bl);
229 blsize = (blsize + 6) / 7;
230 if (blsize > tmpsize) {
231 if (tmp != ftmp)
232 free(tmp);
233 tmpsize = blsize + 32;
234 tmp = malloc(tmpsize);
235 if (!tmp)
236 goto err;
237 }
238 while (blsize--)
239 tmp[i++] = (unsigned char)BN_div_word(bl, 0x80L);
240 } else {
241
242 for (;;) {
243 tmp[i++] = (unsigned char)l & 0x7f;
244 l >>= 7L;
245 if (l == 0L)
246 break;
247 }
248
249 }
250 if (out != NULL) {
251 if (len + i > olen) {
252 ASN1error(ASN1_R_BUFFER_TOO_SMALL);
253 goto err;
254 }
255 while (--i > 0)
256 out[len++] = tmp[i]|0x80;
257 out[len++] = tmp[0];
258 } else
259 len += i;
260 } 164 }
261 if (tmp != ftmp)
262 free(tmp);
263 BN_free(bl);
264 return (len);
265 165
266 err: 166 return 1;
267 if (tmp != ftmp)
268 free(tmp);
269 BN_free(bl);
270 return (0);
271} 167}
272 168
273static int 169static int
@@ -310,6 +206,111 @@ oid_add_arc_txt(CBB *cbb, uint64_t arc, int first)
310} 206}
311 207
312static int 208static int
209oid_parse_arc_txt(CBS *cbs, uint64_t *out_arc, char *separator, int first)
210{
211 uint64_t arc = 0;
212 int digits = 0;
213 uint8_t val;
214
215 if (!first) {
216 if (!CBS_get_u8(cbs, &val))
217 return 0;
218 if ((*separator == 0 && val != '.' && val != ' ') ||
219 (*separator != 0 && val != *separator)) {
220 ASN1error(ASN1_R_INVALID_SEPARATOR);
221 return 0;
222 }
223 *separator = val;
224 }
225
226 while (CBS_len(cbs) > 0) {
227 if (!CBS_peek_u8(cbs, &val))
228 return 0;
229 if (val == '.' || val == ' ')
230 break;
231
232 if (!CBS_get_u8(cbs, &val))
233 return 0;
234 if (val < '0' || val > '9') {
235 /* For the first arc we treat this as the separator. */
236 if (first) {
237 ASN1error(ASN1_R_INVALID_SEPARATOR);
238 return 0;
239 }
240 ASN1error(ASN1_R_INVALID_DIGIT);
241 return 0;
242 }
243 val -= '0';
244
245 if (digits > 0 && arc == 0 && val == 0) {
246 ASN1error(ASN1_R_INVALID_NUMBER);
247 return 0;
248 }
249 digits++;
250
251 if (arc > UINT64_MAX / 10) {
252 ASN1error(ASN1_R_TOO_LONG);
253 return 0;
254 }
255 arc = arc * 10 + val;
256 }
257
258 if (digits < 1) {
259 ASN1error(ASN1_R_INVALID_NUMBER);
260 return 0;
261 }
262
263 *out_arc = arc;
264
265 return 1;
266}
267
268static int
269a2c_ASN1_OBJECT_internal(CBB *cbb, CBS *cbs)
270{
271 uint64_t arc, si1, si2;
272 char separator = 0;
273
274 if (!oid_parse_arc_txt(cbs, &si1, &separator, 1))
275 return 0;
276
277 if (CBS_len(cbs) == 0) {
278 ASN1error(ASN1_R_MISSING_SECOND_NUMBER);
279 return 0;
280 }
281
282 if (!oid_parse_arc_txt(cbs, &si2, &separator, 0))
283 return 0;
284
285 /*
286 * X.690 section 8.19 - the first two subidentifiers are encoded as
287 * (x * 40) + y, with x being limited to [0,1,2]. The second
288 * subidentifier cannot exceed 39 for x < 2.
289 */
290 if (si1 > 2) {
291 ASN1error(ASN1_R_FIRST_NUM_TOO_LARGE);
292 return 0;
293 }
294 if ((si1 < 2 && si2 >= 40) || si2 > UINT64_MAX - si1 * 40) {
295 ASN1error(ASN1_R_SECOND_NUMBER_TOO_LARGE);
296 return 0;
297 }
298 arc = si1 * 40 + si2;
299
300 if (!oid_add_arc(cbb, arc))
301 return 0;
302
303 while (CBS_len(cbs) > 0) {
304 if (!oid_parse_arc_txt(cbs, &arc, &separator, 0))
305 return 0;
306 if (!oid_add_arc(cbb, arc))
307 return 0;
308 }
309
310 return 1;
311}
312
313static int
313c2a_ASN1_OBJECT(CBS *cbs, CBB *cbb) 314c2a_ASN1_OBJECT(CBS *cbs, CBB *cbb)
314{ 315{
315 uint64_t arc, si1, si2; 316 uint64_t arc, si1, si2;
@@ -343,6 +344,51 @@ c2a_ASN1_OBJECT(CBS *cbs, CBB *cbb)
343 return 1; 344 return 1;
344} 345}
345 346
347int
348a2d_ASN1_OBJECT(unsigned char *out, int out_len, const char *in, int in_len)
349{
350 uint8_t *data = NULL;
351 size_t data_len;
352 CBS cbs;
353 CBB cbb;
354 int ret = 0;
355
356 memset(&cbb, 0, sizeof(cbb));
357
358 if (in_len == -1)
359 in_len = strlen(in);
360 if (in_len <= 0)
361 goto err;
362
363 CBS_init(&cbs, in, in_len);
364
365 if (!CBB_init(&cbb, 0))
366 goto err;
367 if (!a2c_ASN1_OBJECT_internal(&cbb, &cbs))
368 goto err;
369 if (!CBB_finish(&cbb, &data, &data_len))
370 goto err;
371
372 if (data_len > INT_MAX)
373 goto err;
374
375 if (out != NULL) {
376 if (out_len <= 0 || (size_t)out_len < data_len) {
377 ASN1error(ASN1_R_BUFFER_TOO_SMALL);
378 goto err;
379 }
380 memcpy(out, data, data_len);
381 }
382
383 ret = (int)data_len;
384
385 err:
386 CBB_cleanup(&cbb);
387 free(data);
388
389 return ret;
390}
391
346static int 392static int
347i2t_ASN1_OBJECT_oid(const ASN1_OBJECT *aobj, CBB *cbb) 393i2t_ASN1_OBJECT_oid(const ASN1_OBJECT *aobj, CBB *cbb)
348{ 394{