diff options
author | jsing <> | 2022-03-02 11:28:00 +0000 |
---|---|---|
committer | jsing <> | 2022-03-02 11:28:00 +0000 |
commit | 3c3fcd217ad6d444723416dd9eca5e1dc42f4bed (patch) | |
tree | ef22bb60da9100fb77f57965fd90ea63a5b3733b /src/lib | |
parent | 4d809bb98b2046d02a7447203478b3d9d0846702 (diff) | |
download | openbsd-3c3fcd217ad6d444723416dd9eca5e1dc42f4bed.tar.gz openbsd-3c3fcd217ad6d444723416dd9eca5e1dc42f4bed.tar.bz2 openbsd-3c3fcd217ad6d444723416dd9eca5e1dc42f4bed.zip |
Rewrite ASN1_OBJECT content to ascii/text conversion.
Rewrite the ASN1_OBJECT content to ascii/text conversion code using CBB and
CBS. Currently there is a strange split with i2t_ASN1_OBJECT() calling
OBJ_obj2txt() which implements the conversion, while OBJ_txt2obj() calls
back into the misnamed a2d_ASN1_OBJECT() function. Move the conversion
code into asn1/a_object.c and have OBJ_txt2obj() call that instead.
ok inoguchi@ tb@
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libcrypto/asn1/a_object.c | 201 | ||||
-rw-r--r-- | src/lib/libcrypto/asn1/asn1_locl.h | 5 | ||||
-rw-r--r-- | src/lib/libcrypto/objects/obj_dat.c | 81 |
3 files changed, 186 insertions, 101 deletions
diff --git a/src/lib/libcrypto/asn1/a_object.c b/src/lib/libcrypto/asn1/a_object.c index 1407f7df1c..f26026e6aa 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.37 2022/01/07 11:13:54 tb Exp $ */ | 1 | /* $OpenBSD: a_object.c,v 1.38 2022/03/02 11:28:00 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 | * |
@@ -270,37 +270,190 @@ a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num) | |||
270 | return (0); | 270 | return (0); |
271 | } | 271 | } |
272 | 272 | ||
273 | static int | ||
274 | oid_parse_arc(CBS *cbs, uint64_t *out_arc) | ||
275 | { | ||
276 | uint64_t arc = 0; | ||
277 | uint8_t val; | ||
278 | |||
279 | do { | ||
280 | if (!CBS_get_u8(cbs, &val)) | ||
281 | return 0; | ||
282 | if (arc == 0 && val == 0x80) | ||
283 | return 0; | ||
284 | if (arc > (UINT64_MAX >> 7)) | ||
285 | return 0; | ||
286 | arc = (arc << 7) | (val & 0x7f); | ||
287 | } while (val & 0x80); | ||
288 | |||
289 | *out_arc = arc; | ||
290 | |||
291 | return 1; | ||
292 | } | ||
293 | |||
294 | static int | ||
295 | oid_add_arc_txt(CBB *cbb, uint64_t arc, int first) | ||
296 | { | ||
297 | const char *fmt = ".%llu"; | ||
298 | char s[22]; /* Digits in decimal representation of 2^64-1, plus '.' and NUL. */ | ||
299 | int n; | ||
300 | |||
301 | if (first) | ||
302 | fmt = "%llu"; | ||
303 | n = snprintf(s, sizeof(s), fmt, (unsigned long long)arc); | ||
304 | if (n < 0 || (size_t)n >= sizeof(s)) | ||
305 | return 0; | ||
306 | if (!CBB_add_bytes(cbb, s, n)) | ||
307 | return 0; | ||
308 | |||
309 | return 1; | ||
310 | } | ||
311 | |||
312 | static int | ||
313 | c2a_ASN1_OBJECT(CBS *cbs, CBB *cbb) | ||
314 | { | ||
315 | uint64_t arc, si1, si2; | ||
316 | |||
317 | /* | ||
318 | * X.690 section 8.19 - the first two subidentifiers are encoded as | ||
319 | * (x * 40) + y, with x being limited to [0,1,2]. | ||
320 | */ | ||
321 | if (!oid_parse_arc(cbs, &arc)) | ||
322 | return 0; | ||
323 | if ((si1 = arc / 40) > 2) | ||
324 | si1 = 2; | ||
325 | si2 = arc - si1 * 40; | ||
326 | |||
327 | if (!oid_add_arc_txt(cbb, si1, 1)) | ||
328 | return 0; | ||
329 | if (!oid_add_arc_txt(cbb, si2, 0)) | ||
330 | return 0; | ||
331 | |||
332 | while (CBS_len(cbs) > 0) { | ||
333 | if (!oid_parse_arc(cbs, &arc)) | ||
334 | return 0; | ||
335 | if (!oid_add_arc_txt(cbb, arc, 0)) | ||
336 | return 0; | ||
337 | } | ||
338 | |||
339 | /* NUL terminate. */ | ||
340 | if (!CBB_add_u8(cbb, 0)) | ||
341 | return 0; | ||
342 | |||
343 | return 1; | ||
344 | } | ||
345 | |||
346 | static int | ||
347 | i2t_ASN1_OBJECT_oid(const ASN1_OBJECT *aobj, CBB *cbb) | ||
348 | { | ||
349 | CBS cbs; | ||
350 | |||
351 | CBS_init(&cbs, aobj->data, aobj->length); | ||
352 | |||
353 | return c2a_ASN1_OBJECT(&cbs, cbb); | ||
354 | } | ||
355 | |||
356 | static int | ||
357 | i2t_ASN1_OBJECT_name(const ASN1_OBJECT *aobj, CBB *cbb, const char **out_name) | ||
358 | { | ||
359 | const char *name; | ||
360 | int nid; | ||
361 | |||
362 | if ((nid = OBJ_obj2nid(aobj)) == NID_undef) | ||
363 | return 0; | ||
364 | |||
365 | if ((name = OBJ_nid2ln(nid)) == NULL) | ||
366 | name = OBJ_nid2sn(nid); | ||
367 | if (name == NULL) | ||
368 | return 0; | ||
369 | |||
370 | *out_name = name; | ||
371 | |||
372 | if (!CBB_add_bytes(cbb, name, strlen(name))) | ||
373 | return 0; | ||
374 | |||
375 | /* NUL terminate. */ | ||
376 | if (!CBB_add_u8(cbb, 0)) | ||
377 | return 0; | ||
378 | |||
379 | return 1; | ||
380 | } | ||
381 | |||
382 | static int | ||
383 | i2t_ASN1_OBJECT_cbb(const ASN1_OBJECT *aobj, CBB *cbb, int no_name) | ||
384 | { | ||
385 | const char *name; | ||
386 | |||
387 | if (!no_name) { | ||
388 | if (i2t_ASN1_OBJECT_name(aobj, cbb, &name)) | ||
389 | return 1; | ||
390 | if (name != NULL) | ||
391 | return 0; | ||
392 | } | ||
393 | return i2t_ASN1_OBJECT_oid(aobj, cbb); | ||
394 | } | ||
395 | |||
396 | int | ||
397 | i2t_ASN1_OBJECT_internal(const ASN1_OBJECT *aobj, char *buf, int buf_len, int no_name) | ||
398 | { | ||
399 | uint8_t *data = NULL; | ||
400 | size_t data_len; | ||
401 | CBB cbb; | ||
402 | int ret = 0; | ||
403 | |||
404 | if (buf_len < 0) | ||
405 | return 0; | ||
406 | if (buf_len > 0) | ||
407 | buf[0] = '\0'; | ||
408 | |||
409 | if (!CBB_init(&cbb, 0)) | ||
410 | goto err; | ||
411 | if (!i2t_ASN1_OBJECT_cbb(aobj, &cbb, no_name)) | ||
412 | goto err; | ||
413 | if (!CBB_finish(&cbb, &data, &data_len)) | ||
414 | goto err; | ||
415 | |||
416 | ret = strlcpy(buf, data, buf_len); | ||
417 | err: | ||
418 | CBB_cleanup(&cbb); | ||
419 | free(data); | ||
420 | |||
421 | return ret; | ||
422 | } | ||
423 | |||
273 | int | 424 | int |
274 | i2t_ASN1_OBJECT(char *buf, int buf_len, const ASN1_OBJECT *a) | 425 | i2t_ASN1_OBJECT(char *buf, int buf_len, const ASN1_OBJECT *aobj) |
275 | { | 426 | { |
276 | return OBJ_obj2txt(buf, buf_len, a, 0); | 427 | return i2t_ASN1_OBJECT_internal(aobj, buf, buf_len, 0); |
277 | } | 428 | } |
278 | 429 | ||
279 | int | 430 | int |
280 | i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *a) | 431 | i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *aobj) |
281 | { | 432 | { |
282 | char *tmp = NULL; | 433 | uint8_t *data = NULL; |
283 | size_t tlen = 256; | 434 | size_t data_len; |
284 | int i = -1; | 435 | CBB cbb; |
436 | int ret = -1; | ||
285 | 437 | ||
286 | if ((a == NULL) || (a->data == NULL)) | 438 | if (aobj == NULL || aobj->data == NULL) |
287 | return(BIO_write(bp, "NULL", 4)); | 439 | return BIO_write(bp, "NULL", 4); |
288 | if ((tmp = malloc(tlen)) == NULL) | 440 | |
289 | return -1; | 441 | if (!CBB_init(&cbb, 0)) |
290 | i = i2t_ASN1_OBJECT(tmp, tlen, a); | 442 | goto err; |
291 | if (i > (int)(tlen - 1)) { | 443 | if (!i2t_ASN1_OBJECT_cbb(aobj, &cbb, 0)) { |
292 | freezero(tmp, tlen); | 444 | ret = BIO_write(bp, "<INVALID>", 9); |
293 | if ((tmp = malloc(i + 1)) == NULL) | 445 | goto err; |
294 | return -1; | ||
295 | tlen = i + 1; | ||
296 | i = i2t_ASN1_OBJECT(tmp, tlen, a); | ||
297 | } | 446 | } |
298 | if (i <= 0) | 447 | if (!CBB_finish(&cbb, &data, &data_len)) |
299 | i = BIO_write(bp, "<INVALID>", 9); | 448 | goto err; |
300 | else | 449 | |
301 | i = BIO_write(bp, tmp, i); | 450 | ret = BIO_write(bp, data, data_len); |
302 | freezero(tmp, tlen); | 451 | |
303 | return (i); | 452 | err: |
453 | CBB_cleanup(&cbb); | ||
454 | free(data); | ||
455 | |||
456 | return ret; | ||
304 | } | 457 | } |
305 | 458 | ||
306 | ASN1_OBJECT * | 459 | ASN1_OBJECT * |
diff --git a/src/lib/libcrypto/asn1/asn1_locl.h b/src/lib/libcrypto/asn1/asn1_locl.h index 7d34d7c17a..bb6a9fc91a 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.20 2022/01/14 08:53:53 tb Exp $ */ | 1 | /* $OpenBSD: asn1_locl.h,v 1.21 2022/03/02 11:28:00 jsing 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 | */ |
@@ -201,4 +201,7 @@ int asn1_get_object_cbs(CBS *cbs, int der_mode, uint8_t *out_class, | |||
201 | 201 | ||
202 | int asn1_tag2charwidth(int tag); | 202 | int asn1_tag2charwidth(int tag); |
203 | 203 | ||
204 | int i2t_ASN1_OBJECT_internal(const ASN1_OBJECT *aobj, char *buf, int buf_len, | ||
205 | int no_name); | ||
206 | |||
204 | __END_HIDDEN_DECLS | 207 | __END_HIDDEN_DECLS |
diff --git a/src/lib/libcrypto/objects/obj_dat.c b/src/lib/libcrypto/objects/obj_dat.c index 03e65f1dfe..786bed6c7a 100644 --- a/src/lib/libcrypto/objects/obj_dat.c +++ b/src/lib/libcrypto/objects/obj_dat.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: obj_dat.c,v 1.47 2022/02/12 03:01:59 jsing Exp $ */ | 1 | /* $OpenBSD: obj_dat.c,v 1.48 2022/03/02 11:28:00 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 | * |
@@ -524,83 +524,12 @@ OBJ_txt2obj(const char *s, int no_name) | |||
524 | } | 524 | } |
525 | 525 | ||
526 | int | 526 | int |
527 | OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name) | 527 | OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *aobj, int no_name) |
528 | { | 528 | { |
529 | int i, ret = 0, len, nid, first = 1; | 529 | if (aobj == NULL || aobj->data == NULL) |
530 | const unsigned char *p; | 530 | return 0; |
531 | uint64_t l; | ||
532 | |||
533 | /* Ensure that, at every state, |buf| is NUL-terminated. */ | ||
534 | if (buf_len > 0) | ||
535 | buf[0] = '\0'; | ||
536 | |||
537 | if ((a == NULL) || (a->data == NULL)) | ||
538 | goto err; | ||
539 | |||
540 | if (!no_name && (nid = OBJ_obj2nid(a)) != NID_undef) { | ||
541 | const char *s; | ||
542 | s = OBJ_nid2ln(nid); | ||
543 | if (s == NULL) | ||
544 | s = OBJ_nid2sn(nid); | ||
545 | if (s) { | ||
546 | ret = strlcpy(buf, s, buf_len); | ||
547 | goto out; | ||
548 | } | ||
549 | } | ||
550 | |||
551 | len = a->length; | ||
552 | p = a->data; | ||
553 | |||
554 | while (len > 0) { | ||
555 | l = 0; | ||
556 | for (;;) { | ||
557 | unsigned char c = *p++; | ||
558 | len--; | ||
559 | if ((len == 0) && (c & 0x80)) | ||
560 | goto err; | ||
561 | l |= c & 0x7f; | ||
562 | if (!(c & 0x80)) | ||
563 | break; | ||
564 | if (l > (UINT64_MAX >> 7L)) | ||
565 | goto err; | ||
566 | l <<= 7L; | ||
567 | } | ||
568 | |||
569 | if (first) { | ||
570 | first = 0; | ||
571 | if (l >= 80) { | ||
572 | i = 2; | ||
573 | l -= 80; | ||
574 | } else { | ||
575 | i = (int)(l / 40); | ||
576 | l -= (long)(i * 40); | ||
577 | } | ||
578 | if (buf_len > 1) { | ||
579 | *buf++ = i + '0'; | ||
580 | *buf = '\0'; | ||
581 | buf_len--; | ||
582 | } | ||
583 | ret++; | ||
584 | } | ||
585 | |||
586 | i = snprintf(buf, buf_len, ".%llu", l); | ||
587 | if (i < 0) | ||
588 | goto err; | ||
589 | if (i >= buf_len) { | ||
590 | buf_len = 0; | ||
591 | } else { | ||
592 | buf += i; | ||
593 | buf_len -= i; | ||
594 | } | ||
595 | ret += i; | ||
596 | } | ||
597 | |||
598 | out: | ||
599 | return ret; | ||
600 | 531 | ||
601 | err: | 532 | return i2t_ASN1_OBJECT_internal(aobj, buf, buf_len, no_name); |
602 | ret = 0; | ||
603 | goto out; | ||
604 | } | 533 | } |
605 | 534 | ||
606 | int | 535 | int |