Validate config options during x509 extension creation
authorNeil Horman <nhorman@openssl.org>
Tue, 2 Jan 2024 20:48:00 +0000 (15:48 -0500)
committerNeil Horman <nhorman@openssl.org>
Fri, 5 Jan 2024 18:20:34 +0000 (13:20 -0500)
There are several points during x509 extension creation which rely on
configuration options which may have been incorrectly parsed due to
invalid settings.  Preform a value check for null in those locations to
avoid various crashes/undefined behaviors

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/23183)

crypto/x509/v3_addr.c
crypto/x509/v3_asid.c
crypto/x509/v3_crld.c
crypto/x509/v3_ist.c
test/invalid-x509.cnf [new file with mode: 0644]
test/recipes/25-test_x509.t

index da9604cf963a3f138a9c4190681ce6f24b4d4c8d..bd937388f365fbb708f7824be3c4269163948a19 100644 (file)
@@ -988,6 +988,10 @@ static void *v2i_IPAddrBlocks(const struct v3_ext_method *method,
          * the other input values.
          */
         if (safi != NULL) {
+            if (val->value == NULL) {
+                ERR_raise(ERR_LIB_X509V3, X509V3_R_MISSING_VALUE);
+                goto err;
+            }
             *safi = strtoul(val->value, &t, 0);
             t += strspn(t, " \t");
             if (*safi > 0xFF || *t++ != ':') {
index 251243b7237320141e5c4fb54650d4d230922ecb..1cb892df670024c02d2aade0ea8eb0f5377c9d81 100644 (file)
@@ -545,6 +545,11 @@ static void *v2i_ASIdentifiers(const struct v3_ext_method *method,
             goto err;
         }
 
+        if (val->value == NULL) {
+            ERR_raise(ERR_LIB_X509V3, X509V3_R_EXTENSION_VALUE_ERROR);
+            goto err;
+        }
+
         /*
          * Handle inheritance.
          */
index 08df3faf86eefaffcab792351183a6806a92f603..e9f6e08e27a7cc94c3f0eb49e4188fdb78b9be4b 100644 (file)
@@ -70,6 +70,11 @@ static int set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx,
     STACK_OF(GENERAL_NAME) *fnm = NULL;
     STACK_OF(X509_NAME_ENTRY) *rnm = NULL;
 
+    if (cnf->value == NULL) {
+        ERR_raise(ERR_LIB_X509V3, X509V3_R_MISSING_VALUE);
+        goto err;
+    }
+
     if (HAS_PREFIX(cnf->name, "fullname")) {
         fnm = gnames_from_sectname(ctx, cnf->value);
         if (!fnm)
index 978a0f3ed867030f76084aa642306a3edb963780..4d5fe82f329e1bc4fe56ef5f49e64b667d2df262 100644 (file)
@@ -50,25 +50,33 @@ static ISSUER_SIGN_TOOL *v2i_issuer_sign_tool(X509V3_EXT_METHOD *method, X509V3_
         }
         if (strcmp(cnf->name, "signTool") == 0) {
             ist->signTool = ASN1_UTF8STRING_new();
-            if (ist->signTool == NULL || !ASN1_STRING_set(ist->signTool, cnf->value, strlen(cnf->value))) {
+            if (ist->signTool == NULL
+                || cnf->value == NULL
+                || !ASN1_STRING_set(ist->signTool, cnf->value, strlen(cnf->value))) {
                 ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB);
                 goto err;
             }
         } else if (strcmp(cnf->name, "cATool") == 0) {
             ist->cATool = ASN1_UTF8STRING_new();
-            if (ist->cATool == NULL || !ASN1_STRING_set(ist->cATool, cnf->value, strlen(cnf->value))) {
+            if (ist->cATool == NULL
+                || cnf->value == NULL
+                || !ASN1_STRING_set(ist->cATool, cnf->value, strlen(cnf->value))) {
                 ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB);
                 goto err;
             }
         } else if (strcmp(cnf->name, "signToolCert") == 0) {
             ist->signToolCert = ASN1_UTF8STRING_new();
-            if (ist->signToolCert == NULL || !ASN1_STRING_set(ist->signToolCert, cnf->value, strlen(cnf->value))) {
+            if (ist->signToolCert == NULL
+                || cnf->value == NULL
+                || !ASN1_STRING_set(ist->signToolCert, cnf->value, strlen(cnf->value))) {
                 ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB);
                 goto err;
             }
         } else if (strcmp(cnf->name, "cAToolCert") == 0) {
             ist->cAToolCert = ASN1_UTF8STRING_new();
-            if (ist->cAToolCert == NULL || !ASN1_STRING_set(ist->cAToolCert, cnf->value, strlen(cnf->value))) {
+            if (ist->cAToolCert == NULL
+                || cnf->value == NULL
+                || !ASN1_STRING_set(ist->cAToolCert, cnf->value, strlen(cnf->value))) {
                 ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB);
                 goto err;
             }
diff --git a/test/invalid-x509.cnf b/test/invalid-x509.cnf
new file mode 100644 (file)
index 0000000..f982edb
--- /dev/null
@@ -0,0 +1,6 @@
+[ext]
+issuerSignTool = signTool
+sbgp-autonomousSysNum = AS
+issuingDistributionPoint = fullname
+sbgp-ipAddrBlock = IPv4-SAFI
+
index 9bf011c1885cd4b118913c4daa0bc7013f4741bf..9b11169a98269ac012725bac5d98c8b152cf9d54 100644 (file)
@@ -16,7 +16,7 @@ use OpenSSL::Test qw/:DEFAULT srctop_file/;
 
 setup("test_x509");
 
-plan tests => 43;
+plan tests => 44;
 
 # Prevent MSys2 filename munging for arguments that look like file paths but
 # aren't
@@ -217,6 +217,14 @@ ok(run(app(["openssl", "x509", "-in", $a_cert, "-CA", $ca_cert,
 # verify issuer is CA
 ok (get_issuer($a2_cert) =~ /CN=ca.example.com/);
 
+my $in_csr = srctop_file('test', 'certs', 'x509-check.csr');
+my $in_key = srctop_file('test', 'certs', 'x509-check-key.pem');
+my $invextfile = srctop_file('test', 'invalid-x509.cnf');
+# Test that invalid extensions settings fail
+ok(!run(app(["openssl", "x509", "-req", "-in", $in_csr, "-signkey", $in_key,
+            "-out", "/dev/null", "-days", "3650" , "-extensions", "ext",
+            "-extfile", $invextfile])));
+
 # Tests for issue #16080 (fixed in 1.1.1o)
 my $b_key = "b-key.pem";
 my $b_csr = "b-cert.csr";