diff options
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libcrypto/x509/x509_utl.c | 194 |
1 files changed, 124 insertions, 70 deletions
diff --git a/src/lib/libcrypto/x509/x509_utl.c b/src/lib/libcrypto/x509/x509_utl.c index 0cc5fb4068..28e9179e95 100644 --- a/src/lib/libcrypto/x509/x509_utl.c +++ b/src/lib/libcrypto/x509/x509_utl.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: x509_utl.c,v 1.14 2023/04/23 11:52:14 tb Exp $ */ | 1 | /* $OpenBSD: x509_utl.c,v 1.15 2023/05/12 13:56:17 tb 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. | 3 | * project. |
| 4 | */ | 4 | */ |
| @@ -55,9 +55,9 @@ | |||
| 55 | * Hudson (tjh@cryptsoft.com). | 55 | * Hudson (tjh@cryptsoft.com). |
| 56 | * | 56 | * |
| 57 | */ | 57 | */ |
| 58 | /* X509 v3 extension utilities */ | ||
| 59 | 58 | ||
| 60 | #include <ctype.h> | 59 | #include <ctype.h> |
| 60 | #include <limits.h> | ||
| 61 | #include <stdio.h> | 61 | #include <stdio.h> |
| 62 | #include <string.h> | 62 | #include <string.h> |
| 63 | 63 | ||
| @@ -67,6 +67,8 @@ | |||
| 67 | #include <openssl/err.h> | 67 | #include <openssl/err.h> |
| 68 | #include <openssl/x509v3.h> | 68 | #include <openssl/x509v3.h> |
| 69 | 69 | ||
| 70 | #include "bytestring.h" | ||
| 71 | |||
| 70 | static char *bn_to_string(const BIGNUM *bn); | 72 | static char *bn_to_string(const BIGNUM *bn); |
| 71 | static char *strip_spaces(char *name); | 73 | static char *strip_spaces(char *name); |
| 72 | static int sk_strcmp(const char * const *a, const char * const *b); | 74 | static int sk_strcmp(const char * const *a, const char * const *b); |
| @@ -459,97 +461,149 @@ strip_spaces(char *name) | |||
| 459 | return p; | 461 | return p; |
| 460 | } | 462 | } |
| 461 | 463 | ||
| 462 | /* hex string utilities */ | 464 | static const char hex_digits[] = "0123456789ABCDEF"; |
| 463 | 465 | ||
| 464 | /* Given a buffer of length 'len' return a malloc'ed string with its | ||
| 465 | * hex representation | ||
| 466 | */ | ||
| 467 | char * | 466 | char * |
| 468 | hex_to_string(const unsigned char *buffer, long len) | 467 | hex_to_string(const unsigned char *buffer, long len) |
| 469 | { | 468 | { |
| 470 | char *tmp, *q; | 469 | CBB cbb; |
| 471 | const unsigned char *p; | 470 | CBS cbs; |
| 472 | int i; | 471 | uint8_t *out = NULL; |
| 473 | static const char hexdig[] = "0123456789ABCDEF"; | 472 | uint8_t c; |
| 473 | size_t out_len; | ||
| 474 | |||
| 475 | if (!CBB_init(&cbb, 0)) | ||
| 476 | goto err; | ||
| 474 | 477 | ||
| 475 | if (len < 0) | 478 | if (len < 0) |
| 476 | return NULL; | 479 | goto err; |
| 477 | if (len == 0) | 480 | |
| 478 | return calloc(1, 1); | 481 | CBS_init(&cbs, buffer, len); |
| 479 | if ((tmp = calloc(len, 3)) == NULL) { | 482 | while (CBS_len(&cbs) > 0) { |
| 480 | X509V3error(ERR_R_MALLOC_FAILURE); | 483 | if (!CBS_get_u8(&cbs, &c)) |
| 481 | return NULL; | 484 | goto err; |
| 482 | } | 485 | if (!CBB_add_u8(&cbb, hex_digits[c >> 4])) |
| 483 | q = tmp; | 486 | goto err; |
| 484 | for (i = 0, p = buffer; i < len; i++, p++) { | 487 | if (!CBB_add_u8(&cbb, hex_digits[c & 0xf])) |
| 485 | *q++ = hexdig[(*p >> 4) & 0xf]; | 488 | goto err; |
| 486 | *q++ = hexdig[*p & 0xf]; | 489 | if (CBS_len(&cbs) > 0) { |
| 487 | *q++ = ':'; | 490 | if (!CBB_add_u8(&cbb, ':')) |
| 491 | goto err; | ||
| 492 | } | ||
| 488 | } | 493 | } |
| 489 | q[-1] = 0; | 494 | |
| 490 | return tmp; | 495 | if (!CBB_add_u8(&cbb, '\0')) |
| 496 | goto err; | ||
| 497 | |||
| 498 | if (!CBB_finish(&cbb, &out, &out_len)) | ||
| 499 | goto err; | ||
| 500 | |||
| 501 | err: | ||
| 502 | CBB_cleanup(&cbb); | ||
| 503 | |||
| 504 | return out; | ||
| 491 | } | 505 | } |
| 492 | LCRYPTO_ALIAS(hex_to_string); | 506 | LCRYPTO_ALIAS(hex_to_string); |
| 493 | 507 | ||
| 494 | /* Give a string of hex digits convert to | 508 | static int |
| 495 | * a buffer | 509 | x509_skip_colons_cbs(CBS *cbs) |
| 496 | */ | 510 | { |
| 511 | uint8_t c; | ||
| 512 | |||
| 513 | while (CBS_len(cbs) > 0) { | ||
| 514 | if (!CBS_peek_u8(cbs, &c)) | ||
| 515 | return 0; | ||
| 516 | if (c != ':') | ||
| 517 | return 1; | ||
| 518 | if (!CBS_get_u8(cbs, &c)) | ||
| 519 | return 0; | ||
| 520 | } | ||
| 521 | |||
| 522 | return 1; | ||
| 523 | |||
| 524 | } | ||
| 525 | |||
| 526 | static int | ||
| 527 | x509_get_xdigit_nibble_cbs(CBS *cbs, uint8_t *out_nibble) { | ||
| 528 | uint8_t c; | ||
| 529 | |||
| 530 | if (!CBS_get_u8(cbs, &c)) | ||
| 531 | return 0; | ||
| 532 | |||
| 533 | if (c >= '0' && c <= '9') { | ||
| 534 | *out_nibble = c - '0'; | ||
| 535 | return 1; | ||
| 536 | } | ||
| 537 | if (c >= 'a' && c <= 'f') { | ||
| 538 | *out_nibble = c - 'a' + 10; | ||
| 539 | return 1; | ||
| 540 | } | ||
| 541 | if (c >= 'A' && c <= 'F') { | ||
| 542 | *out_nibble = c - 'A' + 10; | ||
| 543 | return 1; | ||
| 544 | } | ||
| 545 | |||
| 546 | X509V3error(X509V3_R_ILLEGAL_HEX_DIGIT); | ||
| 547 | return 0; | ||
| 548 | |||
| 549 | } | ||
| 497 | 550 | ||
| 498 | unsigned char * | 551 | unsigned char * |
| 499 | string_to_hex(const char *str, long *len) | 552 | string_to_hex(const char *str, long *len) |
| 500 | { | 553 | { |
| 501 | unsigned char *hexbuf, *q; | 554 | CBB cbb; |
| 502 | unsigned char ch, cl, *p; | 555 | CBS cbs; |
| 503 | if (!str) { | 556 | uint8_t *out = NULL; |
| 504 | X509V3error(X509V3_R_INVALID_NULL_ARGUMENT); | 557 | size_t out_len; |
| 505 | return NULL; | 558 | uint8_t hi, lo; |
| 506 | } | ||
| 507 | if (!(hexbuf = malloc(strlen(str) >> 1))) | ||
| 508 | goto err; | ||
| 509 | for (p = (unsigned char *)str, q = hexbuf; *p; ) { | ||
| 510 | ch = *p++; | ||
| 511 | if (ch == ':') | ||
| 512 | continue; | ||
| 513 | cl = *p++; | ||
| 514 | if (!cl) { | ||
| 515 | X509V3error(X509V3_R_ODD_NUMBER_OF_DIGITS); | ||
| 516 | free(hexbuf); | ||
| 517 | return NULL; | ||
| 518 | } | ||
| 519 | ch = tolower(ch); | ||
| 520 | cl = tolower(cl); | ||
| 521 | 559 | ||
| 522 | if ((ch >= '0') && (ch <= '9')) | 560 | *len = 0; |
| 523 | ch -= '0'; | ||
| 524 | else if ((ch >= 'a') && (ch <= 'f')) | ||
| 525 | ch -= 'a' - 10; | ||
| 526 | else | ||
| 527 | goto badhex; | ||
| 528 | 561 | ||
| 529 | if ((cl >= '0') && (cl <= '9')) | 562 | if (!CBB_init(&cbb, 0)) |
| 530 | cl -= '0'; | 563 | goto err; |
| 531 | else if ((cl >= 'a') && (cl <= 'f')) | ||
| 532 | cl -= 'a' - 10; | ||
| 533 | else | ||
| 534 | goto badhex; | ||
| 535 | 564 | ||
| 536 | *q++ = (ch << 4) | cl; | 565 | if (str == NULL) { |
| 566 | X509V3error(X509V3_R_INVALID_NULL_ARGUMENT); | ||
| 567 | goto err; | ||
| 568 | } | ||
| 569 | |||
| 570 | CBS_init(&cbs, str, strlen(str)); | ||
| 571 | while (CBS_len(&cbs) > 0) { | ||
| 572 | /* | ||
| 573 | * Skipping only a single colon between two pairs of digits | ||
| 574 | * would make more sense - history... | ||
| 575 | */ | ||
| 576 | if (!x509_skip_colons_cbs(&cbs)) | ||
| 577 | goto err; | ||
| 578 | /* Another historic idiocy. */ | ||
| 579 | if (CBS_len(&cbs) == 0) | ||
| 580 | break; | ||
| 581 | if (!x509_get_xdigit_nibble_cbs(&cbs, &hi)) | ||
| 582 | goto err; | ||
| 583 | if (CBS_len(&cbs) == 0) { | ||
| 584 | X509error(X509V3_R_ODD_NUMBER_OF_DIGITS); | ||
| 585 | goto err; | ||
| 586 | } | ||
| 587 | if (!x509_get_xdigit_nibble_cbs(&cbs, &lo)) | ||
| 588 | goto err; | ||
| 589 | if (!CBB_add_u8(&cbb, hi << 4 | lo)) | ||
| 590 | goto err; | ||
| 537 | } | 591 | } |
| 538 | 592 | ||
| 539 | if (len) | 593 | if (!CBB_finish(&cbb, &out, &out_len)) |
| 540 | *len = q - hexbuf; | 594 | goto err; |
| 595 | if (out_len > LONG_MAX) { | ||
| 596 | freezero(out, out_len); | ||
| 597 | out = NULL; | ||
| 598 | goto err; | ||
| 599 | } | ||
| 541 | 600 | ||
| 542 | return hexbuf; | 601 | *len = out_len; |
| 543 | 602 | ||
| 544 | err: | 603 | err: |
| 545 | free(hexbuf); | 604 | CBB_cleanup(&cbb); |
| 546 | X509V3error(ERR_R_MALLOC_FAILURE); | ||
| 547 | return NULL; | ||
| 548 | 605 | ||
| 549 | badhex: | 606 | return out; |
| 550 | free(hexbuf); | ||
| 551 | X509V3error(X509V3_R_ILLEGAL_HEX_DIGIT); | ||
| 552 | return NULL; | ||
| 553 | } | 607 | } |
| 554 | LCRYPTO_ALIAS(string_to_hex); | 608 | LCRYPTO_ALIAS(string_to_hex); |
| 555 | 609 | ||
