PR: 2482
[openssl.git] / crypto / x509v3 / v3_addr.c
index d97944f8481cdaa458d336a9ad084c56282588eb..d27a707407291b7cbf333e2d371ad0d7878fd341 100644 (file)
@@ -384,6 +384,7 @@ static int range_should_be_prefix(const unsigned char *min,
   unsigned char mask;
   int i, j;
 
+  OPENSSL_assert(memcmp(min, max, length) <= 0);
   for (i = 0; i < length && min[i] == max[i]; i++)
     ;
   for (j = length - 1; j >= 0 && min[j] == 0x00 && max[j] == 0xFF; j--)
@@ -801,14 +802,16 @@ int v3_addr_is_canonical(IPAddrBlocks *addr)
     }
 
     /*
-     * Check final range to see if it should be a prefix.
+     * Check range to see if it's inverted or should be a
+     * prefix.
      */
     j = sk_IPAddressOrRange_num(aors) - 1;
     {
       IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
-      if (a->type == IPAddressOrRange_addressRange) {
+      if (a != NULL && a->type == IPAddressOrRange_addressRange) {
        extract_min_max(a, a_min, a_max, length);
-       if (range_should_be_prefix(a_min, a_max, length) >= 0)
+       if (memcmp(a_min, a_max, length) > 0 ||
+           range_should_be_prefix(a_min, a_max, length) >= 0)
          return 0;
       }
     }
@@ -845,6 +848,13 @@ static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors,
     extract_min_max(a, a_min, a_max, length);
     extract_min_max(b, b_min, b_max, length);
 
+    /*
+     * Punt inverted ranges.
+     */
+    if (memcmp(a_min, a_max, length) > 0 ||
+       memcmp(b_min, b_max, length) > 0)
+      return 0;
+
     /*
      * Punt overlaps.
      */
@@ -870,6 +880,20 @@ static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors,
     }
   }
 
+  /*
+   * Check for inverted final range.
+   */
+  j = sk_IPAddressOrRange_num(aors) - 1;
+  {
+    IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
+    if (a != NULL && a->type == IPAddressOrRange_addressRange) {
+      unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
+      extract_min_max(a, a_min, a_max, length);
+      if (memcmp(a_min, a_max, length) > 0)
+       return 0;
+    }
+  }
+
   return 1;
 }
 
@@ -1018,6 +1042,11 @@ static void *v2i_IPAddrBlocks(struct v3_ext_method *method,
        X509V3_conf_err(val);
        goto err;
       }
+      if (memcmp(min, max, length_from_afi(afi)) > 0) {
+       X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR);
+       X509V3_conf_err(val);
+       goto err;
+      }
       if (!v3_addr_add_range(addr, afi, safi, min, max)) {
        X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
        goto err;