diff options
author | beck <> | 2023-05-29 11:54:50 +0000 |
---|---|---|
committer | beck <> | 2023-05-29 11:54:50 +0000 |
commit | 3244a31e011c814d3d65b8b757a2dd3d28c542e2 (patch) | |
tree | 3ee54daae8ea3ccd2187904d345b85cb009a53dd /src/lib/libcrypto/x509/x509name.c | |
parent | 26e7d501966e054b9e377033e8b93db0c4e42412 (diff) | |
download | openbsd-3244a31e011c814d3d65b8b757a2dd3d28c542e2.tar.gz openbsd-3244a31e011c814d3d65b8b757a2dd3d28c542e2.tar.bz2 openbsd-3244a31e011c814d3d65b8b757a2dd3d28c542e2.zip |
Make X509_NAME_get_text_by[NID|OBJ] safer.
This is an un-revert with nits of the previously landed change
to do this which broke libtls. libtls has now been changed to
not use this function.
This change ensures that if something is returned it is "text"
(UTF-8) and a C string not containing a NUL byte. Historically
callers to this function assume the result is text and a C string
however the OpenSSL version simply hands them the bytes from an
ASN1_STRING and expects them to know bad things can happen which
they almost universally do not check for. Partly inspired by
goings on in boringssl.
ok jsing@ tb@
Diffstat (limited to 'src/lib/libcrypto/x509/x509name.c')
-rw-r--r-- | src/lib/libcrypto/x509/x509name.c | 38 |
1 files changed, 28 insertions, 10 deletions
diff --git a/src/lib/libcrypto/x509/x509name.c b/src/lib/libcrypto/x509/x509name.c index ecdf473ea9..d2df06ccc6 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.34 2023/05/03 08:10:23 beck Exp $ */ | 1 | /* $OpenBSD: x509name.c,v 1.35 2023/05/29 11:54:50 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,38 @@ 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 (len <= 0 || !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 | |||
117 | err: | ||
118 | free(text); | ||
119 | return (ret); | ||
102 | } | 120 | } |
103 | LCRYPTO_ALIAS(X509_NAME_get_text_by_OBJ); | 121 | LCRYPTO_ALIAS(X509_NAME_get_text_by_OBJ); |
104 | 122 | ||