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/lib/libcrypto/x509/x509name.c | |
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 '')
-rw-r--r-- | src/lib/libcrypto/x509/x509name.c | 37 |
1 files changed, 27 insertions, 10 deletions
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 | ||