diff options
-rw-r--r-- | src/lib/libcrypto/man/X509_NAME_get_index_by_NID.3 | 30 | ||||
-rw-r--r-- | src/lib/libcrypto/x509/x509name.c | 37 | ||||
-rw-r--r-- | src/regress/lib/libcrypto/x509/x509_asn1.c | 79 |
3 files changed, 124 insertions, 22 deletions
diff --git a/src/lib/libcrypto/man/X509_NAME_get_index_by_NID.3 b/src/lib/libcrypto/man/X509_NAME_get_index_by_NID.3 index 71dd98ce46..19a123a4ac 100644 --- a/src/lib/libcrypto/man/X509_NAME_get_index_by_NID.3 +++ b/src/lib/libcrypto/man/X509_NAME_get_index_by_NID.3 | |||
@@ -1,4 +1,4 @@ | |||
1 | .\" $OpenBSD: X509_NAME_get_index_by_NID.3,v 1.13 2022/07/02 17:09:09 jsing Exp $ | 1 | .\" $OpenBSD: X509_NAME_get_index_by_NID.3,v 1.14 2023/05/02 14:13:05 beck Exp $ |
2 | .\" OpenSSL aebb9aac Jul 19 09:27:53 2016 -0400 | 2 | .\" OpenSSL aebb9aac Jul 19 09:27:53 2016 -0400 |
3 | .\" | 3 | .\" |
4 | .\" This file was written by Dr. Stephen Henson <steve@openssl.org>. | 4 | .\" This file was written by Dr. Stephen Henson <steve@openssl.org>. |
@@ -49,7 +49,7 @@ | |||
49 | .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | 49 | .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
50 | .\" OF THE POSSIBILITY OF SUCH DAMAGE. | 50 | .\" OF THE POSSIBILITY OF SUCH DAMAGE. |
51 | .\" | 51 | .\" |
52 | .Dd $Mdocdate: July 2 2022 $ | 52 | .Dd $Mdocdate: May 2 2023 $ |
53 | .Dt X509_NAME_GET_INDEX_BY_NID 3 | 53 | .Dt X509_NAME_GET_INDEX_BY_NID 3 |
54 | .Os | 54 | .Os |
55 | .Sh NAME | 55 | .Sh NAME |
@@ -136,22 +136,32 @@ run from 0 to | |||
136 | .Fn X509_NAME_get_text_by_NID | 136 | .Fn X509_NAME_get_text_by_NID |
137 | and | 137 | and |
138 | .Fn X509_NAME_get_text_by_OBJ | 138 | .Fn X509_NAME_get_text_by_OBJ |
139 | retrieve the "text" from the first entry in | 139 | retrieve the bytes encoded as UTF-8 from the first entry in |
140 | .Fa name | 140 | .Fa name |
141 | which matches | 141 | which matches |
142 | .Fa nid | 142 | .Fa nid |
143 | or | 143 | or |
144 | .Fa obj . | 144 | .Fa obj . |
145 | At most | ||
146 | .Fa len | ||
147 | bytes will be written and the text written to | ||
148 | .Fa buf | ||
149 | will be NUL terminated. | ||
150 | If | 145 | If |
151 | .Fa buf | 146 | .Fa buf |
152 | is | 147 | is |
153 | .Dv NULL , | 148 | .Dv NULL , |
154 | nothing is written, but the return value is calculated as usual. | 149 | nothing is written, but the return value is calculated as usual. |
150 | If | ||
151 | .Fa buf | ||
152 | is not | ||
153 | .Dv NULL , | ||
154 | no more than | ||
155 | .Fa len | ||
156 | bytes will be written and the text written to | ||
157 | .Fa buf | ||
158 | will be NUL terminated. | ||
159 | .Pp | ||
160 | Nothing is written and it is a failure if | ||
161 | .Fa len | ||
162 | is not large enough to hold the NUL byte terminated UTF-8 encoding of | ||
163 | the text, or if the UTF-8 encoding ot the text would contins a NUL | ||
164 | byte. | ||
155 | .Pp | 165 | .Pp |
156 | All relevant | 166 | All relevant |
157 | .Dv NID_* | 167 | .Dv NID_* |
@@ -189,8 +199,8 @@ if the index is invalid. | |||
189 | .Fn X509_NAME_get_text_by_NID | 199 | .Fn X509_NAME_get_text_by_NID |
190 | and | 200 | and |
191 | .Fn X509_NAME_get_text_by_OBJ | 201 | .Fn X509_NAME_get_text_by_OBJ |
192 | return the length of the output string written, not counting the | 202 | return the length of the output UTF-8 string written, not counting the |
193 | terminating NUL, or -1 if no match is found. | 203 | terminating NUL, or -1 in the case of an error or no match being found. |
194 | .Pp | 204 | .Pp |
195 | In some cases of failure of | 205 | In some cases of failure of |
196 | .Fn X509_NAME_get_index_by_NID | 206 | .Fn X509_NAME_get_index_by_NID |
diff --git a/src/lib/libcrypto/x509/x509name.c b/src/lib/libcrypto/x509/x509name.c index a6e4dbef89..3c9e224c1b 100644 --- a/src/lib/libcrypto/x509/x509name.c +++ b/src/lib/libcrypto/x509/x509name.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: x509name.c,v 1.31 2023/02/16 08:38:17 tb Exp $ */ | 1 | /* $OpenBSD: x509name.c,v 1.32 2023/05/02 14:13:05 beck 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 | * |
@@ -66,6 +66,7 @@ | |||
66 | #include <openssl/stack.h> | 66 | #include <openssl/stack.h> |
67 | #include <openssl/x509.h> | 67 | #include <openssl/x509.h> |
68 | 68 | ||
69 | #include "bytestring.h" | ||
69 | #include "x509_local.h" | 70 | #include "x509_local.h" |
70 | 71 | ||
71 | int | 72 | int |
@@ -84,21 +85,37 @@ int | |||
84 | X509_NAME_get_text_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, char *buf, | 85 | X509_NAME_get_text_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, char *buf, |
85 | int len) | 86 | int len) |
86 | { | 87 | { |
87 | int i; | 88 | unsigned char *text = NULL; |
88 | ASN1_STRING *data; | 89 | ASN1_STRING *data; |
90 | int i, text_len; | ||
91 | int ret = -1; | ||
92 | CBS cbs; | ||
89 | 93 | ||
90 | i = X509_NAME_get_index_by_OBJ(name, obj, -1); | 94 | i = X509_NAME_get_index_by_OBJ(name, obj, -1); |
91 | if (i < 0) | 95 | if (i < 0) |
92 | return (-1); | 96 | goto err; |
93 | data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i)); | 97 | data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i)); |
94 | i = (data->length > (len - 1)) ? (len - 1) : data->length; | 98 | /* |
95 | if (buf == NULL) | 99 | * Fail if we cannot encode as UTF-8, or if the UTF-8 encoding of the |
96 | return (data->length); | 100 | * string contains a 0 byte, because mortal callers seldom handle the |
97 | if (i >= 0) { | 101 | * length difference correctly |
98 | memcpy(buf, data->data, i); | 102 | */ |
99 | buf[i] = '\0'; | 103 | if ((text_len = ASN1_STRING_to_UTF8(&text, data)) < 0) |
104 | goto err; | ||
105 | CBS_init(&cbs, text, text_len); | ||
106 | if (CBS_contains_zero_byte(&cbs)) | ||
107 | goto err; | ||
108 | /* We still support the "pass NULL to find out how much" API */ | ||
109 | if (buf != NULL) { | ||
110 | if (!CBS_write_bytes(&cbs, buf, len - 1, NULL)) | ||
111 | goto err; | ||
112 | /* It must be a C string */ | ||
113 | buf[text_len] = '\0'; | ||
100 | } | 114 | } |
101 | return (i); | 115 | ret = text_len; |
116 | err: | ||
117 | free(text); | ||
118 | return (ret); | ||
102 | } | 119 | } |
103 | LCRYPTO_ALIAS(X509_NAME_get_text_by_OBJ); | 120 | LCRYPTO_ALIAS(X509_NAME_get_text_by_OBJ); |
104 | 121 | ||
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 | ||