summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorbeck <>2023-05-02 14:13:05 +0000
committerbeck <>2023-05-02 14:13:05 +0000
commitbcec9e3700677dff4d40f3813e166d89598a6329 (patch)
tree9b7516cbe9c5101c44087b7ca6a0b2d7374ebb84 /src/lib
parentb51ca2264f3c87ae6c0f6bd726ff14aae7906760 (diff)
downloadopenbsd-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/lib')
-rw-r--r--src/lib/libcrypto/man/X509_NAME_get_index_by_NID.330
-rw-r--r--src/lib/libcrypto/x509/x509name.c37
2 files changed, 47 insertions, 20 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
137and 137and
138.Fn X509_NAME_get_text_by_OBJ 138.Fn X509_NAME_get_text_by_OBJ
139retrieve the "text" from the first entry in 139retrieve the bytes encoded as UTF-8 from the first entry in
140.Fa name 140.Fa name
141which matches 141which matches
142.Fa nid 142.Fa nid
143or 143or
144.Fa obj . 144.Fa obj .
145At most
146.Fa len
147bytes will be written and the text written to
148.Fa buf
149will be NUL terminated.
150If 145If
151.Fa buf 146.Fa buf
152is 147is
153.Dv NULL , 148.Dv NULL ,
154nothing is written, but the return value is calculated as usual. 149nothing is written, but the return value is calculated as usual.
150If
151.Fa buf
152is not
153.Dv NULL ,
154no more than
155.Fa len
156bytes will be written and the text written to
157.Fa buf
158will be NUL terminated.
159.Pp
160Nothing is written and it is a failure if
161.Fa len
162is not large enough to hold the NUL byte terminated UTF-8 encoding of
163the text, or if the UTF-8 encoding ot the text would contins a NUL
164byte.
155.Pp 165.Pp
156All relevant 166All 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
190and 200and
191.Fn X509_NAME_get_text_by_OBJ 201.Fn X509_NAME_get_text_by_OBJ
192return the length of the output string written, not counting the 202return the length of the output UTF-8 string written, not counting the
193terminating NUL, or -1 if no match is found. 203terminating NUL, or -1 in the case of an error or no match being found.
194.Pp 204.Pp
195In some cases of failure of 205In 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
71int 72int
@@ -84,21 +85,37 @@ int
84X509_NAME_get_text_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, char *buf, 85X509_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}
103LCRYPTO_ALIAS(X509_NAME_get_text_by_OBJ); 120LCRYPTO_ALIAS(X509_NAME_get_text_by_OBJ);
104 121