PR: 2482
[openssl.git] / crypto / x509v3 / v3_addr.c
index 07835501675751e194ba294156de835f7bb2c741..d27a707407291b7cbf333e2d371ad0d7878fd341 100644 (file)
@@ -61,7 +61,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-#include <assert.h>
+
 #include "cryptlib.h"
 #include <openssl/conf.h>
 #include <openssl/asn1.h>
@@ -128,7 +128,7 @@ static int length_from_afi(const unsigned afi)
 /*
  * Extract the AFI from an IPAddressFamily.
  */
-unsigned v3_addr_get_afi(const IPAddressFamily *f)
+unsigned int v3_addr_get_afi(const IPAddressFamily *f)
 {
   return ((f != NULL &&
           f->addressFamily != NULL &&
@@ -147,7 +147,7 @@ static void addr_expand(unsigned char *addr,
                        const int length,
                        const unsigned char fill)
 {
-  assert(bs->length >= 0 && bs->length <= length);
+  OPENSSL_assert(bs->length >= 0 && bs->length <= length);
   if (bs->length > 0) {
     memcpy(addr, bs->data, bs->length);
     if ((bs->flags & 7) != 0) {
@@ -177,12 +177,18 @@ static int i2r_address(BIO *out,
   unsigned char addr[ADDR_RAW_BUF_LEN];
   int i, n;
 
+  if (bs->length < 0)
+    return 0;
   switch (afi) {
   case IANA_AFI_IPV4:
+    if (bs->length > 4)
+      return 0;
     addr_expand(addr, bs, 4, fill);
     BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
     break;
   case IANA_AFI_IPV6:
+    if (bs->length > 16)
+      return 0;
     addr_expand(addr, bs, 16, fill);
     for (n = 16; n > 1 && addr[n-1] == 0x00 && addr[n-2] == 0x00; n -= 2)
       ;
@@ -245,7 +251,7 @@ static int i2r_IPAddrBlocks(X509V3_EXT_METHOD *method,
   int i;
   for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
     IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
-    const unsigned afi = v3_addr_get_afi(f);
+    const unsigned int afi = v3_addr_get_afi(f);
     switch (afi) {
     case IANA_AFI_IPV4:
       BIO_printf(out, "%*sIPv4", indent, "");
@@ -378,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--)
@@ -455,7 +462,7 @@ static int make_addressRange(IPAddressOrRange **result,
   if ((aor = IPAddressOrRange_new()) == NULL)
     return 0;
   aor->type = IPAddressOrRange_addressRange;
-  assert(aor->u.addressRange == NULL);
+  OPENSSL_assert(aor->u.addressRange == NULL);
   if ((aor->u.addressRange = IPAddressRange_new()) == NULL)
     goto err;
   if (aor->u.addressRange->min == NULL &&
@@ -524,7 +531,7 @@ static IPAddressFamily *make_IPAddressFamily(IPAddrBlocks *addr,
 
   for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
     f = sk_IPAddressFamily_value(addr, i);
-    assert(f->addressFamily->data != NULL);
+    OPENSSL_assert(f->addressFamily->data != NULL);
     if (f->addressFamily->length == keylen &&
        !memcmp(f->addressFamily->data, key, keylen))
       return f;
@@ -656,7 +663,7 @@ static void extract_min_max(IPAddressOrRange *aor,
                            unsigned char *max,
                            int length)
 {
-  assert(aor != NULL && min != NULL && max != NULL);
+  OPENSSL_assert(aor != NULL && min != NULL && max != NULL);
   switch (aor->type) {
   case IPAddressOrRange_addressPrefix:
     addr_expand(min, aor->u.addressPrefix, length, 0x00);
@@ -795,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;
       }
     }
@@ -839,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.
      */
@@ -864,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;
 }
 
@@ -882,7 +912,7 @@ int v3_addr_canonize(IPAddrBlocks *addr)
   }
   (void)sk_IPAddressFamily_set_cmp_func(addr, IPAddressFamily_cmp);
   sk_IPAddressFamily_sort(addr);
-  assert(v3_addr_is_canonical(addr));
+  OPENSSL_assert(v3_addr_is_canonical(addr));
   return 1;
 }
 
@@ -1012,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;
@@ -1129,7 +1164,10 @@ int v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b)
   for (i = 0; i < sk_IPAddressFamily_num(a); i++) {
     IPAddressFamily *fa = sk_IPAddressFamily_value(a, i);
     int j = sk_IPAddressFamily_find(b, fa);
-    IPAddressFamily *fb = sk_IPAddressFamily_value(b, j);
+    IPAddressFamily *fb;
+    fb = sk_IPAddressFamily_value(b, j);
+    if (fb == NULL)
+       return 0;
     if (!addr_contains(fb->ipAddressChoice->u.addressesOrRanges, 
                       fa->ipAddressChoice->u.addressesOrRanges,
                       length_from_afi(v3_addr_get_afi(fb))))
@@ -1166,9 +1204,9 @@ static int v3_addr_validate_path_internal(X509_STORE_CTX *ctx,
   int i, j, ret = 1;
   X509 *x = NULL;
 
-  assert(chain != NULL && sk_X509_num(chain) > 0);
-  assert(ctx != NULL || ext != NULL);
-  assert(ctx == NULL || ctx->verify_cb != NULL);
+  OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0);
+  OPENSSL_assert(ctx != NULL || ext != NULL);
+  OPENSSL_assert(ctx == NULL || ctx->verify_cb != NULL);
 
   /*
    * Figure out where to start.  If we don't have an extension to
@@ -1180,7 +1218,7 @@ static int v3_addr_validate_path_internal(X509_STORE_CTX *ctx,
   } else {
     i = 0;
     x = sk_X509_value(chain, i);
-    assert(x != NULL);
+    OPENSSL_assert(x != NULL);
     if ((ext = x->rfc3779_addr) == NULL)
       goto done;
   }
@@ -1199,7 +1237,7 @@ static int v3_addr_validate_path_internal(X509_STORE_CTX *ctx,
    */
   for (i++; i < sk_X509_num(chain); i++) {
     x = sk_X509_value(chain, i);
-    assert(x != NULL);
+    OPENSSL_assert(x != NULL);
     if (!v3_addr_is_canonical(x->rfc3779_addr))
       validation_err(X509_V_ERR_INVALID_EXTENSION);
     if (x->rfc3779_addr == NULL) {