Commit d064df18af for openssl.org

commit d064df18af85426f7b152ec77c2834d19e87c840
Author: Bob Beck <beck@openssl.org>
Date:   Wed Aug 19 13:54:48 2026 -0600

    Clamp negative lengths to 0 in ASN1_STRING_set0

    A negative length is never valid here, so store an empty string
    instead, while taking ownership of the data pointer as usual.

    Reviewed-by: Neil Horman <nhorman@openssl.org>
    Reviewed-by: Andrew Dinh <andrewd@openssl.org>
    Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
    Merge-date: Thu Aug 27 13:52:55 2026
    Merged-from: https://github.com/openssl/openssl/pull/32178

diff --git a/crypto/asn1/asn1_lib.c b/crypto/asn1/asn1_lib.c
index a73c677ffe..96ee35efb6 100644
--- a/crypto/asn1/asn1_lib.c
+++ b/crypto/asn1/asn1_lib.c
@@ -378,7 +378,7 @@ void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len)
     }
     str->flags &= ~ASN1_STRING_FLAG_DATA_NOT_OWNED;
     str->data = data;
-    str->length = len;
+    str->length = len < 0 ? 0 : len;
 }

 int ASN1_STRING_set1_data(ASN1_STRING *str, const uint8_t *data, size_t len_in)
diff --git a/test/asn1_string_test.c b/test/asn1_string_test.c
index 443635eab3..4efe63ebe6 100644
--- a/test/asn1_string_test.c
+++ b/test/asn1_string_test.c
@@ -550,6 +550,52 @@ err:
     return success;
 }

+static int
+asn1_string_set0_test(void)
+{
+    int success = 0;
+    ASN1_STRING *str = NULL;
+    uint8_t *data = NULL;
+
+    if (!TEST_ptr(str = ASN1_STRING_new()))
+        goto err;
+
+    if (!TEST_ptr(data = (uint8_t *)OPENSSL_strdup("hoobla")))
+        goto err;
+
+    /* A negative length can never be valid and is treated as empty */
+    ASN1_STRING_set0(str, data, -1);
+
+    if (!TEST_size_t_eq(ASN1_STRING_get_length(str), 0))
+        goto err;
+
+    /* The string takes ownership of the data even so */
+    if (!TEST_ptr_eq(ASN1_STRING_get0_data(str), data))
+        goto err;
+
+    data = NULL;
+
+    if (!TEST_ptr(data = (uint8_t *)OPENSSL_strdup("hoobla")))
+        goto err;
+
+    ASN1_STRING_set0(str, data, (int)strlen("hoobla"));
+
+    if (!TEST_size_t_eq(ASN1_STRING_get_length(str), 6))
+        goto err;
+
+    if (!TEST_ptr_eq(ASN1_STRING_get0_data(str), data))
+        goto err;
+
+    data = NULL;
+
+    success = 1;
+
+err:
+    OPENSSL_free(data);
+    ASN1_STRING_free(str);
+    return success;
+}
+
 static int
 asn1_universalstring_to_string_test(void)
 {
@@ -617,6 +663,7 @@ int setup_tests(void)
     ADD_TEST(asn1_string_new_not_owned_test);
     ADD_TEST(asn1_string_set_data_test);
     ADD_TEST(asn1_string_set_string_test);
+    ADD_TEST(asn1_string_set0_test);
     ADD_TEST(asn1_universalstring_to_string_test);
     return 1;
 }