summaryrefslogtreecommitdiff
path: root/regress
diff options
context:
space:
mode:
authorBob Beck <beck@cvs.openbsd.org>2023-05-29 11:54:51 +0000
committerBob Beck <beck@cvs.openbsd.org>2023-05-29 11:54:51 +0000
commitbf17cbd7cae3cc7260950b1261e892ce03a66363 (patch)
tree60bcf4885cf2c2b82c3888b0c8563ef2fe2f25d8 /regress
parentf8491326f8be0af4ca2224c60ca0a81d3501ee2a (diff)
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 'regress')
-rw-r--r--regress/lib/libcrypto/x509/x509_asn1.c79
1 files changed, 77 insertions, 2 deletions
diff --git a/regress/lib/libcrypto/x509/x509_asn1.c b/regress/lib/libcrypto/x509/x509_asn1.c
index d96a51880e2..4c038c9bbf4 100644
--- a/regress/lib/libcrypto/x509/x509_asn1.c
+++ b/regress/lib/libcrypto/x509/x509_asn1.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: x509_asn1.c,v 1.18 2023/05/03 08:10:23 beck Exp $ */
+/* $OpenBSD: x509_asn1.c,v 1.19 2023/05/29 11:54:50 beck Exp $ */
/*
* Copyright (c) 2023 Job Snijders <job@openbsd.org>
*
@@ -512,13 +512,88 @@ test_x509_req_setters(void)
return failed;
}
-int main(void)
+static const struct testcase {
+ char *data;
+ int len;
+ int len_to_pass;
+ int encode_type;
+ int expected_result;
+ char *expected_string;
+} testCases[] = {
+ /* should work */
+ {"fozzie", 6, 80, MBSTRING_ASC, 6, "fozzie"},
+ /* should work */
+ {"fozzie", 6, -1, MBSTRING_ASC, 6, ""},
+ /* should fail, truncation */
+ {"muppet", 6, 5, MBSTRING_ASC, -1, ""},
+ /* should fail, contains 0 byte */
+ {"g\0nzo", 5, 80, MBSTRING_ASC, -1, ""},
+ /* should fail, can't encode as utf-8 */
+ {"\x30\x00", 2, 80, V_ASN1_SEQUENCE, -1, ""},
+};
+
+#define NUM_TEST_CASES (sizeof(testCases) / sizeof(testCases[0]))
+
+static int
+test_x509_name_get(void)
+{
+ int failed = 0;
+ size_t i;
+
+ for (i = 0; i < NUM_TEST_CASES; i++) {
+ const struct testcase *test = testCases + i;
+ X509_NAME_ENTRY *entry = NULL;
+ X509_NAME *name = NULL;
+ char textbuf[80];
+ int result;
+
+ textbuf[0] = '\0';
+ if ((name = X509_NAME_new()) == NULL)
+ err(1, "X509_NAME_new");
+ if ((entry = X509_NAME_ENTRY_new()) == NULL)
+ err(1, "X509_NAME_ENTRY_new");
+ if (!X509_NAME_ENTRY_set_object(entry,
+ OBJ_nid2obj(NID_commonName)))
+ err(1, "X509_NAME_ENTRY_set_object");
+ if (!X509_NAME_ENTRY_set_data(entry, test->encode_type,
+ test->data, test->len))
+ err(1, "X509_NAME_ENTRY_set_data");
+ if (!X509_NAME_add_entry(name, entry, -1, 0))
+ err(1, "X509_NAME_add_entry");
+ if (test->len_to_pass == -1)
+ result = X509_NAME_get_text_by_NID(name, NID_commonName,
+ NULL, 0);
+ else
+ result = X509_NAME_get_text_by_NID(name, NID_commonName,
+ textbuf, test->len_to_pass);
+ if (result != test->expected_result) {
+ fprintf(stderr,
+ "Test %zu X509_GET_text_by_NID returned %d,"
+ "expected %d\n", i, result, test->expected_result);
+ failed++;
+ }
+ if (result != -1 &&
+ strcmp(test->expected_string, textbuf) != 0) {
+ fprintf(stderr,
+ "Test %zu, X509_GET_text_by_NID returned bytes do"
+ "not match \n", i);
+ failed++;
+ }
+ X509_NAME_ENTRY_free(entry);
+ X509_NAME_free(name);
+ }
+ return failed;
+}
+
+int
+main(void)
{
int failed = 0;
failed |= test_x509_setters();
/* failed |= */ test_x509_crl_setters();
/* failed |= */ test_x509_req_setters();
+ failed |= test_x509_name_get();
OPENSSL_cleanup();