As discussed with Volker off-list, the fact that the name constraint
'permitted;IP.0=10.0.0.0/255.0.0.0' from the config isn't accepted is
yet another bug from that diff. As far as I can see from a quick scan
of the spec and the code that's the only thing that needs special casing
for name constraints.

   The syntax of iPAddress MUST be as described in Section 4.2.1.6 with
   the following additions specifically for name constraints.  For IPv4
   addresses, the iPAddress field of GeneralName MUST contain eight (8)
   octets, encoded in the style of RFC 4632 (CIDR) to represent an
   address range [RFC4632].  For IPv6 addresses, the iPAddress field
   MUST contain 32 octets similarly encoded.  For example, a name
   constraint for "class C" subnet 192.0.2.0 is represented as the
   octets C0 00 02 00 FF FF FF 00, representing the CIDR notation
   192.0.2.0/24 (mask 255.255.255.0).

https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.10

So for name constraints the length checks for IP addresses are incorrect.
The following addresses this and works for me.

So, to sum up the first hunk is a missing error check to fix the
segfault from

permitted;IP.0=10.0.0.0/8

The second hunk is to fix the length check for name constraints and the
third hunk avoids the double free this report was initially about.

Hopefully that's all...

Index: x509/x509_alt.c
===================================================================
RCS file: /cvs/src/lib/libcrypto/x509/x509_alt.c,v
retrieving revision 1.5
diff -u -p -r1.5 x509_alt.c
--- x509/x509_alt.c     28 Oct 2021 10:58:23 -0000      1.5
+++ x509/x509_alt.c     9 Feb 2022 18:32:20 -0000
@@ -649,6 +649,8 @@ v2i_GENERAL_NAME_ex(GENERAL_NAME *out, c
        }
 
        ret = a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc);
+       if (ret == NULL)
+               return NULL;
 
        /* Validate what we have for sanity */
        type = x509_constraints_general_to_bytes(ret, &bytes, &len);
@@ -675,7 +677,8 @@ v2i_GENERAL_NAME_ex(GENERAL_NAME *out, c
                }
                break;
        case GEN_IPADD:
-               if (len != 4 && len != 16) {
+               if ((!is_nc && len != 4 && len != 16) ||
+                   (is_nc && len != 8 && len != 32)) {
                        X509V3error(X509V3_R_BAD_IP_ADDRESS);
                        ERR_asprintf_error_data("name=%s len=%zu", name, len);
                        goto err;
@@ -686,7 +689,8 @@ v2i_GENERAL_NAME_ex(GENERAL_NAME *out, c
        }
        return ret;
  err:
-       GENERAL_NAME_free(ret);
+       if (out == NULL)
+               GENERAL_NAME_free(ret);
        return NULL;
 }
 

Reply via email to