diff options
author | beck <> | 2023-05-02 14:13:05 +0000 |
---|---|---|
committer | beck <> | 2023-05-02 14:13:05 +0000 |
commit | bcec9e3700677dff4d40f3813e166d89598a6329 (patch) | |
tree | 9b7516cbe9c5101c44087b7ca6a0b2d7374ebb84 /src/regress | |
parent | b51ca2264f3c87ae6c0f6bd726ff14aae7906760 (diff) | |
download | openbsd-bcec9e3700677dff4d40f3813e166d89598a6329.tar.gz openbsd-bcec9e3700677dff4d40f3813e166d89598a6329.tar.bz2 openbsd-bcec9e3700677dff4d40f3813e166d89598a6329.zip |
Change X509_NAME_get_index_by[NID|OBJ] to be safer.
Currently these functions return raw ASN1_STRING bytes as
a C string and ignore the encoding in a "hold my beer I am
a toolkit not a functioning API surely it's just for testing
and you'd never send nasty bytes" kind of way.
Sadly some callers seem to use them to fetch things liks
subject name components for comparisons, and often just
use the result as a C string.
Instead, encode the resulting bytes as UTF-8 so it is
something like "text",
Add a failure case if the length provided is inadequate
or if the resulting text would contain an nul byte.
based on boringssl.
nits by dlg@
ok tb@
Diffstat (limited to 'src/regress')
-rw-r--r-- | src/regress/lib/libcrypto/x509/x509_asn1.c | 79 |
1 files changed, 77 insertions, 2 deletions
diff --git a/src/regress/lib/libcrypto/x509/x509_asn1.c b/src/regress/lib/libcrypto/x509/x509_asn1.c index 146b0aba70..1ce8ed3aa8 100644 --- a/src/regress/lib/libcrypto/x509/x509_asn1.c +++ b/src/regress/lib/libcrypto/x509/x509_asn1.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: x509_asn1.c,v 1.16 2023/05/01 11:02:23 job Exp $ */ | 1 | /* $OpenBSD: x509_asn1.c,v 1.17 2023/05/02 14:13:05 beck Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2023 Job Snijders <job@openbsd.org> | 3 | * Copyright (c) 2023 Job Snijders <job@openbsd.org> |
4 | * | 4 | * |
@@ -512,13 +512,88 @@ test_x509_req_setters(void) | |||
512 | return failed; | 512 | return failed; |
513 | } | 513 | } |
514 | 514 | ||
515 | int main(void) | 515 | static const struct testcase { |
516 | char *data; | ||
517 | int len; | ||
518 | int len_to_pass; | ||
519 | int encode_type; | ||
520 | int expected_result; | ||
521 | char *expected_string; | ||
522 | } testCases[] = { | ||
523 | /* should work */ | ||
524 | {"fozzie", 6, 80, MBSTRING_ASC, 6, "fozzie"}, | ||
525 | /* should work */ | ||
526 | {"fozzie", 6, -1, MBSTRING_ASC, 6, ""}, | ||
527 | /* should fail, truncation */ | ||
528 | {"muppet", 6, 5, MBSTRING_ASC, -1, ""}, | ||
529 | /* should fail, contains 0 byte */ | ||
530 | {"g\0nzo", 5, 80, MBSTRING_ASC, -1, ""}, | ||
531 | /* should fail, can't encode as utf-8 */ | ||
532 | {"\x30\x00", 2, 80, V_ASN1_SEQUENCE, -1, ""}, | ||
533 | }; | ||
534 | |||
535 | #define NUM_TEST_CASES (sizeof(testCases) / sizeof(testCases[0])) | ||
536 | |||
537 | static int | ||
538 | test_x509_name_get(void) | ||
539 | { | ||
540 | int failed = 0; | ||
541 | size_t i; | ||
542 | |||
543 | for (i = 0; i < NUM_TEST_CASES; i++) { | ||
544 | const struct testcase *test = testCases + i; | ||
545 | X509_NAME_ENTRY *entry = NULL; | ||
546 | X509_NAME *name = NULL; | ||
547 | char textbuf[80]; | ||
548 | int result; | ||
549 | |||
550 | textbuf[0] = '\0'; | ||
551 | if ((name = X509_NAME_new()) == NULL) | ||
552 | err(1, "X509_NAME_new"); | ||
553 | if ((entry = X509_NAME_ENTRY_new()) == NULL) | ||
554 | err(1, "X509_NAME_ENTRY_new"); | ||
555 | if (!X509_NAME_ENTRY_set_object(entry, | ||
556 | OBJ_nid2obj(NID_commonName))) | ||
557 | err(1, "X509_NAME_ENTRY_set_object"); | ||
558 | if (!X509_NAME_ENTRY_set_data(entry, test->encode_type, | ||
559 | test->data, test->len)) | ||
560 | err(1, "X509_NAME_ENTRY_set_data"); | ||
561 | if (!X509_NAME_add_entry(name, entry, -1, 0)) | ||
562 | err(1, "X509_NAME_add_entry"); | ||
563 | if (test->len_to_pass == -1) | ||
564 | result = X509_NAME_get_text_by_NID(name, NID_commonName, | ||
565 | NULL, 0); | ||
566 | else | ||
567 | result = X509_NAME_get_text_by_NID(name, NID_commonName, | ||
568 | textbuf, test->len_to_pass); | ||
569 | if (result != test->expected_result) { | ||
570 | fprintf(stderr, | ||
571 | "Test %zu X509_GET_text_by_NID returned %d," | ||
572 | "expected %d\n", i, result, test->expected_result); | ||
573 | failed++; | ||
574 | } | ||
575 | if (result != -1 && | ||
576 | strcmp(test->expected_string, textbuf) != 0) { | ||
577 | fprintf(stderr, | ||
578 | "Test %zu, X509_GET_text_by_NID returned bytes do" | ||
579 | "not match \n", i); | ||
580 | failed++; | ||
581 | } | ||
582 | X509_NAME_ENTRY_free(entry); | ||
583 | X509_NAME_free(name); | ||
584 | } | ||
585 | return failed; | ||
586 | } | ||
587 | |||
588 | int | ||
589 | main(void) | ||
516 | { | 590 | { |
517 | int failed = 0; | 591 | int failed = 0; |
518 | 592 | ||
519 | failed |= test_x509_setters(); | 593 | failed |= test_x509_setters(); |
520 | /* failed |= */ test_x509_crl_setters(); | 594 | /* failed |= */ test_x509_crl_setters(); |
521 | /* failed |= */ test_x509_req_setters(); | 595 | /* failed |= */ test_x509_req_setters(); |
596 | failed |= test_x509_name_get(); | ||
522 | 597 | ||
523 | OPENSSL_cleanup(); | 598 | OPENSSL_cleanup(); |
524 | 599 | ||