Commit 1a4923aa2e for openssl.org

commit 1a4923aa2e5248ca0f8f6c97ec0e6d321a0b98fc
Author: Dmitry Belyavskiy <beldmit@gmail.com>
Date:   Sat Jul 4 19:01:09 2026 +0200

    Test that we don't crash on programmatically added X.509 extensions

    Reviewed-by: Mounir Idrassi <mounir.idrassi@idrix.fr>
    Reviewed-by: Simo Sorce <simo@redhat.com>
    MergeDate: Thu Sep 10 19:05:25 2026
    (Merged from https://github.com/openssl/openssl/pull/31636)

diff --git a/test/x509_req_test.c b/test/x509_req_test.c
index b37fd0599a..1ac626732f 100644
--- a/test/x509_req_test.c
+++ b/test/x509_req_test.c
@@ -7,8 +7,10 @@
  * https://www.openssl.org/source/license.html
  */

+#include <openssl/core_names.h>
 #include <openssl/pem.h>
 #include <openssl/x509.h>
+#include <openssl/x509v3.h>

 #include "testutil.h"

@@ -53,6 +55,83 @@ err:
     return ret;
 }

+static int add_ext(STACK_OF(X509_EXTENSION) *sk, int nid, char *value)
+{
+    X509_EXTENSION *ex;
+    ex = X509V3_EXT_conf_nid(NULL, NULL, nid, value);
+    if (!ex)
+        return 0;
+    if (sk_X509_EXTENSION_push(sk, ex) <= 0) {
+        X509_EXTENSION_free(ex);
+        return 0;
+    }
+
+    return 1;
+}
+
+static int test_x509_req_add_exts(void)
+{
+    X509_REQ *x = NULL;
+    STACK_OF(X509_EXTENSION) *exts = NULL;
+    EVP_PKEY_CTX *ctx = NULL;
+    EVP_PKEY *pkey = NULL;
+    int ret = 0;
+    int nid = NID_undef;
+    OSSL_PARAM params[2];
+    size_t bits = 2048;
+
+    params[0] = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_RSA_BITS, &bits);
+    params[1] = OSSL_PARAM_construct_end();
+
+    ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
+    if (ctx == NULL
+        || EVP_PKEY_keygen_init(ctx) <= 0
+        || EVP_PKEY_CTX_set_params(ctx, params) <= 0
+        || EVP_PKEY_keygen(ctx, &pkey) <= 0
+        || (x = X509_REQ_new()) == NULL
+        || X509_REQ_set_pubkey(x, pkey) <= 0)
+        goto err;
+
+    exts = sk_X509_EXTENSION_new_null();
+    if (!TEST_ptr(exts))
+        goto err;
+
+    /*
+     * For request extensions they are all packed in a single attribute. We
+     * save them in a STACK and add them all at once later...
+     */
+
+    if (!TEST_int_eq(add_ext(exts, NID_netscape_cert_type, "client,email"), 1)
+        || !TEST_int_eq(add_ext(exts, NID_subject_alt_name, "email:steve@openssl.org"), 1)
+        || !TEST_int_eq(add_ext(exts, NID_crl_distribution_points, "URI:http://example.org"), 1)
+        /* These tests require some underlying config but we just check that we don't crash */
+        || !TEST_int_eq(add_ext(exts, NID_proxyCertInfo, "text:xxx"), 0)
+        || !TEST_int_eq(add_ext(exts, NID_certificate_policies, "xxx:yyy"), 0)
+        /* Some Netscape specific extensions */
+        || !TEST_int_eq(add_ext(exts, NID_netscape_cert_type, "client,email"), 1))
+        goto err;
+
+    /* Maybe even add our own extension based on existing */
+    nid = OBJ_create("1.2.3.4", "MyAlias", "My Test Alias Extension");
+    if (!TEST_int_ne(nid, NID_undef)
+        || !TEST_int_gt(X509V3_EXT_add_alias(nid, NID_netscape_comment), 0)
+        || !TEST_int_eq(add_ext(exts, nid, "example comment alias"), 1)
+        || !TEST_int_eq(X509_REQ_add_extensions(x, exts), 1))
+        goto err;
+
+    if (!X509_REQ_sign(x, pkey, EVP_sha256()))
+        goto err;
+
+    ret = 1;
+err:
+    EVP_PKEY_CTX_free(ctx);
+
+    X509_REQ_free(x);
+    EVP_PKEY_free(pkey);
+    sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
+
+    return ret;
+}
 OPT_TEST_DECLARE_USAGE("certdir\n")

 int setup_tests(void)
@@ -65,6 +144,7 @@ int setup_tests(void)
         return 0;

     ADD_TEST(test_x509_req_detect_invalid_version);
+    ADD_TEST(test_x509_req_add_exts);
     return 1;
 }