diff options
| author | jsing <> | 2022-03-02 11:28:00 +0000 |
|---|---|---|
| committer | jsing <> | 2022-03-02 11:28:00 +0000 |
| commit | 82fb0381802967c4e0623e7f4bde8e684c08dbc6 (patch) | |
| tree | ef22bb60da9100fb77f57965fd90ea63a5b3733b /src | |
| parent | 3afe4b6f29d7548f490e80402e8bf0ef7229dac1 (diff) | |
| download | openbsd-82fb0381802967c4e0623e7f4bde8e684c08dbc6.tar.gz openbsd-82fb0381802967c4e0623e7f4bde8e684c08dbc6.tar.bz2 openbsd-82fb0381802967c4e0623e7f4bde8e684c08dbc6.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')
| -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 |
