/*
 * Contributed to the OpenSSL Project by the American Registry for
 * Internet Numbers ("ARIN").
 */
/* ====================================================================
 * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 */

/*
 * Implementation of RFC 3779 section 2.2.
 */

#include <stdio.h>
#include <stdlib.h>

#include "cryptlib.h"
#include <openssl/conf.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/buffer.h>
#include <openssl/x509v3.h>

#ifndef OPENSSL_NO_RFC3779

/*
 * OpenSSL ASN.1 template translation of RFC 3779 2.2.3.
 */

ASN1_SEQUENCE(IPAddressRange) = {
  ASN1_SIMPLE(IPAddressRange, min, ASN1_BIT_STRING),
  ASN1_SIMPLE(IPAddressRange, max, ASN1_BIT_STRING)
} ASN1_SEQUENCE_END(IPAddressRange)

ASN1_CHOICE(IPAddressOrRange) = {
  ASN1_SIMPLE(IPAddressOrRange, u.addressPrefix, ASN1_BIT_STRING),
  ASN1_SIMPLE(IPAddressOrRange, u.addressRange,  IPAddressRange)
} ASN1_CHOICE_END(IPAddressOrRange)

ASN1_CHOICE(IPAddressChoice) = {
  ASN1_SIMPLE(IPAddressChoice,      u.inherit,           ASN1_NULL),
  ASN1_SEQUENCE_OF(IPAddressChoice, u.addressesOrRanges, IPAddressOrRange)
} ASN1_CHOICE_END(IPAddressChoice)

ASN1_SEQUENCE(IPAddressFamily) = {
  ASN1_SIMPLE(IPAddressFamily, addressFamily,   ASN1_OCTET_STRING),
  ASN1_SIMPLE(IPAddressFamily, ipAddressChoice, IPAddressChoice)
} ASN1_SEQUENCE_END(IPAddressFamily)

ASN1_ITEM_TEMPLATE(IPAddrBlocks) = 
  ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0,
			IPAddrBlocks, IPAddressFamily)
ASN1_ITEM_TEMPLATE_END(IPAddrBlocks)

IMPLEMENT_ASN1_FUNCTIONS(IPAddressRange)
IMPLEMENT_ASN1_FUNCTIONS(IPAddressOrRange)
IMPLEMENT_ASN1_FUNCTIONS(IPAddressChoice)
IMPLEMENT_ASN1_FUNCTIONS(IPAddressFamily)

/*
 * How much buffer space do we need for a raw address?
 */
#define ADDR_RAW_BUF_LEN	16

/*
 * What's the address length associated with this AFI?
 */
static int length_from_afi(const unsigned afi)
{
  switch (afi) {
  case IANA_AFI_IPV4:
    return 4;
  case IANA_AFI_IPV6:
    return 16;
  default:
    return 0;
  }
}

/*
 * Extract the AFI from an IPAddressFamily.
 */
unsigned int v3_addr_get_afi(const IPAddressFamily *f)
{
  return ((f != NULL &&
	   f->addressFamily != NULL &&
	   f->addressFamily->data != NULL)
	  ? ((f->addressFamily->data[0] << 8) |
	     (f->addressFamily->data[1]))
	  : 0);
}

/*
 * Expand the bitstring form of an address into a raw byte array.
 * At the moment this is coded for simplicity, not speed.
 */
static int addr_expand(unsigned char *addr,
			const ASN1_BIT_STRING *bs,
			const int length,
			const unsigned char fill)
{
  if (bs->length < 0 || bs->length > length)
    return 0;
  if (bs->length > 0) {
    memcpy(addr, bs->data, bs->length);
    if ((bs->flags & 7) != 0) {
      unsigned char mask = 0xFF >> (8 - (bs->flags & 7));
      if (fill == 0)
	addr[bs->length - 1] &= ~mask;
      else
	addr[bs->length - 1] |= mask;
    }
  }
  memset(addr + bs->length, fill, length - bs->length);
  return 1;
}

/*
 * Extract the prefix length from a bitstring.
 */
#define addr_prefixlen(bs) ((int) ((bs)->length * 8 - ((bs)->flags & 7)))

/*
 * i2r handler for one address bitstring.
 */
static int i2r_address(BIO *out,
		       const unsigned afi,
		       const unsigned char fill,
		       const ASN1_BIT_STRING *bs)
{
  unsigned char addr[ADDR_RAW_BUF_LEN];
  int i, n;

  if (bs->length < 0)
    return 0;
  switch (afi) {
  case IANA_AFI_IPV4:
    if (!addr_expand(addr, bs, 4, fill))
      return 0;
    BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
    break;
  case IANA_AFI_IPV6:
    if (!addr_expand(addr, bs, 16, fill))
      return 0;
    for (n = 16; n > 1 && addr[n-1] == 0x00 && addr[n-2] == 0x00; n -= 2)
      ;
    for (i = 0; i < n; i += 2)
      BIO_printf(out, "%x%s", (addr[i] << 8) | addr[i+1], (i < 14 ? ":" : ""));
    if (i < 16)
      BIO_puts(out, ":");
    if (i == 0)
      BIO_puts(out, ":");
    break;
  default:
    for (i = 0; i < bs->length; i++)
      BIO_printf(out, "%s%02x", (i > 0 ? ":" : ""), bs->data[i]);
    BIO_printf(out, "[%d]", (int) (bs->flags & 7));
    break;
  }
  return 1;
}

/*
 * i2r handler for a sequence of addresses and ranges.
 */
static int i2r_IPAddressOrRanges(BIO *out,
				 const int indent,
				 const IPAddressOrRanges *aors,
				 const unsigned afi)
{
  int i;
  for (i = 0; i < sk_IPAddressOrRange_num(aors); i++) {
    const IPAddressOrRange *aor = sk_IPAddressOrRange_value(aors, i);
    BIO_printf(out, "%*s", indent, "");
    switch (aor->type) {
    case IPAddressOrRange_addressPrefix:
      if (!i2r_address(out, afi, 0x00, aor->u.addressPrefix))
	return 0;
      BIO_printf(out, "/%d\n", addr_prefixlen(aor->u.addressPrefix));
      continue;
    case IPAddressOrRange_addressRange:
      if (!i2r_address(out, afi, 0x00, aor->u.addressRange->min))
	return 0;
      BIO_puts(out, "-");
      if (!i2r_address(out, afi, 0xFF, aor->u.addressRange->max))
	return 0;
      BIO_puts(out, "\n");
      continue;
    }
  }
  return 1;
}

/*
 * i2r handler for an IPAddrBlocks extension.
 */
static int i2r_IPAddrBlocks(const X509V3_EXT_METHOD *method,
			    void *ext,
			    BIO *out,
			    int indent)
{
  const IPAddrBlocks *addr = ext;
  int i;
  for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
    IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
    const unsigned int afi = v3_addr_get_afi(f);
    switch (afi) {
    case IANA_AFI_IPV4:
      BIO_printf(out, "%*sIPv4", indent, "");
      break;
    case IANA_AFI_IPV6:
      BIO_printf(out, "%*sIPv6", indent, "");
      break;
    default:
      BIO_printf(out, "%*sUnknown AFI %u", indent, "", afi);
      break;
    }
    if (f->addressFamily->length > 2) {
      switch (f->addressFamily->data[2]) {
      case   1:
	BIO_puts(out, " (Unicast)");
	break;
      case   2:
	BIO_puts(out, " (Multicast)");
	break;
      case   3:
	BIO_puts(out, " (Unicast/Multicast)");
	break;
      case   4:
	BIO_puts(out, " (MPLS)");
	break;
      case  64:
	BIO_puts(out, " (Tunnel)");
	break;
      case  65:
	BIO_puts(out, " (VPLS)");
	break;
      case  66:
	BIO_puts(out, " (BGP MDT)");
	break;
      case 128:
	BIO_puts(out, " (MPLS-labeled VPN)");
	break;
      default:  
	BIO_printf(out, " (Unknown SAFI %u)",
		   (unsigned) f->addressFamily->data[2]);
	break;
      }
    }
    switch (f->ipAddressChoice->type) {
    case IPAddressChoice_inherit:
      BIO_puts(out, ": inherit\n");
      break;
    case IPAddressChoice_addressesOrRanges:
      BIO_puts(out, ":\n");
      if (!i2r_IPAddressOrRanges(out,
				 indent + 2,
				 f->ipAddressChoice->u.addressesOrRanges,
				 afi))
	return 0;
      break;
    }
  }
  return 1;
}

/*
 * Sort comparison function for a sequence of IPAddressOrRange
 * elements.
 *
 * There's no sane answer we can give if addr_expand() fails, and an
 * assertion failure on externally supplied data is seriously uncool,
 * so we just arbitrarily declare that if given invalid inputs this
 * function returns -1.  If this messes up your preferred sort order
 * for garbage input, tough noogies.
 */
static int IPAddressOrRange_cmp(const IPAddressOrRange *a,
				const IPAddressOrRange *b,
				const int length)
{
  unsigned char addr_a[ADDR_RAW_BUF_LEN], addr_b[ADDR_RAW_BUF_LEN];
  int prefixlen_a = 0, prefixlen_b = 0;
  int r;

  switch (a->type) {
  case IPAddressOrRange_addressPrefix:
    if (!addr_expand(addr_a, a->u.addressPrefix, length, 0x00))
      return -1;
    prefixlen_a = addr_prefixlen(a->u.addressPrefix);
    break;
  case IPAddressOrRange_addressRange:
    if (!addr_expand(addr_a, a->u.addressRange->min, length, 0x00))
      return -1;
    prefixlen_a = length * 8;
    break;
  }

  switch (b->type) {
  case IPAddressOrRange_addressPrefix:
    if (!addr_expand(addr_b, b->u.addressPrefix, length, 0x00))
      return -1;
    prefixlen_b = addr_prefixlen(b->u.addressPrefix);
    break;
  case IPAddressOrRange_addressRange:
    if (!addr_expand(addr_b, b->u.addressRange->min, length, 0x00))
      return -1;
    prefixlen_b = length * 8;
    break;
  }

  if ((r = memcmp(addr_a, addr_b, length)) != 0)
    return r;
  else
    return prefixlen_a - prefixlen_b;
}

/*
 * IPv4-specific closure over IPAddressOrRange_cmp, since sk_sort()
 * comparision routines are only allowed two arguments.
 */
static int v4IPAddressOrRange_cmp(const IPAddressOrRange * const *a,
				  const IPAddressOrRange * const *b)
{
  return IPAddressOrRange_cmp(*a, *b, 4);
}

/*
 * IPv6-specific closure over IPAddressOrRange_cmp, since sk_sort()
 * comparision routines are only allowed two arguments.
 */
static int v6IPAddressOrRange_cmp(const IPAddressOrRange * const *a,
				  const IPAddressOrRange * const *b)
{
  return IPAddressOrRange_cmp(*a, *b, 16);
}

/*
 * Calculate whether a range collapses to a prefix.
 * See last paragraph of RFC 3779 2.2.3.7.
 */
static int range_should_be_prefix(const unsigned char *min,
				  const unsigned char *max,
				  const int length)
{
  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--)
    ;
  if (i < j)
    return -1;
  if (i > j)
    return i * 8;
  mask = min[i] ^ max[i];
  switch (mask) {
  case 0x01: j = 7; break;
  case 0x03: j = 6; break;
  case 0x07: j = 5; break;
  case 0x0F: j = 4; break;
  case 0x1F: j = 3; break;
  case 0x3F: j = 2; break;
  case 0x7F: j = 1; break;
  default:   return -1;
  }
  if ((min[i] & mask) != 0 || (max[i] & mask) != mask)
    return -1;
  else
    return i * 8 + j;
}

/*
 * Construct a prefix.
 */
static int make_addressPrefix(IPAddressOrRange **result,
			      unsigned char *addr,
			      const int prefixlen)
{
  int bytelen = (prefixlen + 7) / 8, bitlen = prefixlen % 8;
  IPAddressOrRange *aor = IPAddressOrRange_new();

  if (aor == NULL)
    return 0;
  aor->type = IPAddressOrRange_addressPrefix;
  if (aor->u.addressPrefix == NULL &&
      (aor->u.addressPrefix = ASN1_BIT_STRING_new()) == NULL)
    goto err;
  if (!ASN1_BIT_STRING_set(aor->u.addressPrefix, addr, bytelen))
    goto err;
  aor->u.addressPrefix->flags &= ~7;
  aor->u.addressPrefix->flags |= ASN1_STRING_FLAG_BITS_LEFT;
  if (bitlen > 0) {
    aor->u.addressPrefix->data[bytelen - 1] &= ~(0xFF >> bitlen);
    aor->u.addressPrefix->flags |= 8 - bitlen;
  }
  
  *result = aor;
  return 1;

 err:
  IPAddressOrRange_free(aor);
  return 0;
}

/*
 * Construct a range.  If it can be expressed as a prefix,
 * return a prefix instead.  Doing this here simplifies
 * the rest of the code considerably.
 */
static int make_addressRange(IPAddressOrRange **result,
			     unsigned char *min,
			     unsigned char *max,
			     const int length)
{
  IPAddressOrRange *aor;
  int i, prefixlen;

  if ((prefixlen = range_should_be_prefix(min, max, length)) >= 0)
    return make_addressPrefix(result, min, prefixlen);

  if ((aor = IPAddressOrRange_new()) == NULL)
    return 0;
  aor->type = IPAddressOrRange_addressRange;
  OPENSSL_assert(aor->u.addressRange == NULL);
  if ((aor->u.addressRange = IPAddressRange_new()) == NULL)
    goto err;
  if (aor->u.addressRange->min == NULL &&
      (aor->u.addressRange->min = ASN1_BIT_STRING_new()) == NULL)
    goto err;
  if (aor->u.addressRange->max == NULL &&
      (aor->u.addressRange->max = ASN1_BIT_STRING_new()) == NULL)
    goto err;

  for (i = length; i > 0 && min[i - 1] == 0x00; --i)
    ;
  if (!ASN1_BIT_STRING_set(aor->u.addressRange->min, min, i))
    goto err;
  aor->u.addressRange->min->flags &= ~7;
  aor->u.addressRange->min->flags |= ASN1_STRING_FLAG_BITS_LEFT;
  if (i > 0) {
    unsigned char b = min[i - 1];
    int j = 1;
    while ((b & (0xFFU >> j)) != 0) 
      ++j;
    aor->u.addressRange->min->flags |= 8 - j;
  }

  for (i = length; i > 0 && max[i - 1] == 0xFF; --i)
    ;
  if (!ASN1_BIT_STRING_set(aor->u.addressRange->max, max, i))
    goto err;
  aor->u.addressRange->max->flags &= ~7;
  aor->u.addressRange->max->flags |= ASN1_STRING_FLAG_BITS_LEFT;
  if (i > 0) {
    unsigned char b = max[i - 1];
    int j = 1;
    while ((b & (0xFFU >> j)) != (0xFFU >> j))
      ++j;
    aor->u.addressRange->max->flags |= 8 - j;
  }

  *result = aor;
  return 1;

 err:
  IPAddressOrRange_free(aor);
  return 0;
}

/*
 * Construct a new address family or find an existing one.
 */
static IPAddressFamily *make_IPAddressFamily(IPAddrBlocks *addr,
					     const unsigned afi,
					     const unsigned *safi)
{
  IPAddressFamily *f;
  unsigned char key[3];
  unsigned keylen;
  int i;

  key[0] = (afi >> 8) & 0xFF;
  key[1] = afi & 0xFF;
  if (safi != NULL) {
    key[2] = *safi & 0xFF;
    keylen = 3;
  } else {
    keylen = 2;
  }

  for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
    f = sk_IPAddressFamily_value(addr, i);
    OPENSSL_assert(f->addressFamily->data != NULL);
    if (f->addressFamily->length == keylen &&
	!memcmp(f->addressFamily->data, key, keylen))
      return f;
  }

  if ((f = IPAddressFamily_new()) == NULL)
    goto err;
  if (f->ipAddressChoice == NULL &&
      (f->ipAddressChoice = IPAddressChoice_new()) == NULL)
    goto err;
  if (f->addressFamily == NULL && 
      (f->addressFamily = ASN1_OCTET_STRING_new()) == NULL)
    goto err;
  if (!ASN1_OCTET_STRING_set(f->addressFamily, key, keylen))
    goto err;
  if (!sk_IPAddressFamily_push(addr, f))
    goto err;

  return f;

 err:
  IPAddressFamily_free(f);
  return NULL;
}

/*
 * Add an inheritance element.
 */
int v3_addr_add_inherit(IPAddrBlocks *addr,
			const unsigned afi,
			const unsigned *safi)
{
  IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi);
  if (f == NULL ||
      f->ipAddressChoice == NULL ||
      (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges &&
       f->ipAddressChoice->u.addressesOrRanges != NULL))
    return 0;
  if (f->ipAddressChoice->type == IPAddressChoice_inherit &&
      f->ipAddressChoice->u.inherit != NULL)
    return 1;
  if (f->ipAddressChoice->u.inherit == NULL &&
      (f->ipAddressChoice->u.inherit = ASN1_NULL_new()) == NULL)
    return 0;
  f->ipAddressChoice->type = IPAddressChoice_inherit;
  return 1;
}

/*
 * Construct an IPAddressOrRange sequence, or return an existing one.
 */
static IPAddressOrRanges *make_prefix_or_range(IPAddrBlocks *addr,
					       const unsigned afi,
					       const unsigned *safi)
{
  IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi);
  IPAddressOrRanges *aors = NULL;

  if (f == NULL ||
      f->ipAddressChoice == NULL ||
      (f->ipAddressChoice->type == IPAddressChoice_inherit &&
       f->ipAddressChoice->u.inherit != NULL))
    return NULL;
  if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges)
    aors = f->ipAddressChoice->u.addressesOrRanges;
  if (aors != NULL)
    return aors;
  if ((aors = sk_IPAddressOrRange_new_null()) == NULL)
    return NULL;
  switch (afi) {
  case IANA_AFI_IPV4:
    (void) sk_IPAddressOrRange_set_cmp_func(aors, v4IPAddressOrRange_cmp);
    break;
  case IANA_AFI_IPV6:
    (void) sk_IPAddressOrRange_set_cmp_func(aors, v6IPAddressOrRange_cmp);
    break;
  }
  f->ipAddressChoice->type = IPAddressChoice_addressesOrRanges;
  f->ipAddressChoice->u.addressesOrRanges = aors;
  return aors;
}

/*
 * Add a prefix.
 */
int v3_addr_add_prefix(IPAddrBlocks *addr,
		       const unsigned afi,
		       const unsigned *safi,
		       unsigned char *a,
		       const int prefixlen)
{
  IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi);
  IPAddressOrRange *aor;
  if (aors == NULL || !make_addressPrefix(&aor, a, prefixlen))
    return 0;
  if (sk_IPAddressOrRange_push(aors, aor))
    return 1;
  IPAddressOrRange_free(aor);
  return 0;
}

/*
 * Add a range.
 */
int v3_addr_add_range(IPAddrBlocks *addr,
		      const unsigned afi,
		      const unsigned *safi,
		      unsigned char *min,
		      unsigned char *max)
{
  IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi);
  IPAddressOrRange *aor;
  int length = length_from_afi(afi);
  if (aors == NULL)
    return 0;
  if (!make_addressRange(&aor, min, max, length))
    return 0;
  if (sk_IPAddressOrRange_push(aors, aor))
    return 1;
  IPAddressOrRange_free(aor);
  return 0;
}

/*
 * Extract min and max values from an IPAddressOrRange.
 */
static int extract_min_max(IPAddressOrRange *aor,
			    unsigned char *min,
			    unsigned char *max,
			    int length)
{
  if (aor == NULL || min == NULL || max == NULL)
    return 0;
  switch (aor->type) {
  case IPAddressOrRange_addressPrefix:
    return (addr_expand(min, aor->u.addressPrefix, length, 0x00) &&
	    addr_expand(max, aor->u.addressPrefix, length, 0xFF));
  case IPAddressOrRange_addressRange:
    return (addr_expand(min, aor->u.addressRange->min, length, 0x00) &&
	    addr_expand(max, aor->u.addressRange->max, length, 0xFF));
  }
  return 0;
}

/*
 * Public wrapper for extract_min_max().
 */
int v3_addr_get_range(IPAddressOrRange *aor,
		      const unsigned afi,
		      unsigned char *min,
		      unsigned char *max,
		      const int length)
{
  int afi_length = length_from_afi(afi);
  if (aor == NULL || min == NULL || max == NULL ||
      afi_length == 0 || length < afi_length ||
      (aor->type != IPAddressOrRange_addressPrefix &&
       aor->type != IPAddressOrRange_addressRange) ||
      !extract_min_max(aor, min, max, afi_length))
    return 0;

  return afi_length;
}

/*
 * Sort comparision function for a sequence of IPAddressFamily.
 *
 * The last paragraph of RFC 3779 2.2.3.3 is slightly ambiguous about
 * the ordering: I can read it as meaning that IPv6 without a SAFI
 * comes before IPv4 with a SAFI, which seems pretty weird.  The
 * examples in appendix B suggest that the author intended the
 * null-SAFI rule to apply only within a single AFI, which is what I
 * would have expected and is what the following code implements.
 */
static int IPAddressFamily_cmp(const IPAddressFamily * const *a_,
			       const IPAddressFamily * const *b_)
{
  const ASN1_OCTET_STRING *a = (*a_)->addressFamily;
  const ASN1_OCTET_STRING *b = (*b_)->addressFamily;
  int len = ((a->length <= b->length) ? a->length : b->length);
  int cmp = memcmp(a->data, b->data, len);
  return cmp ? cmp : a->length - b->length;
}

/*
 * Check whether an IPAddrBLocks is in canonical form.
 */
int v3_addr_is_canonical(IPAddrBlocks *addr)
{
  unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
  unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN];
  IPAddressOrRanges *aors;
  int i, j, k;

  /*
   * Empty extension is cannonical.
   */
  if (addr == NULL)
    return 1;

  /*
   * Check whether the top-level list is in order.
   */
  for (i = 0; i < sk_IPAddressFamily_num(addr) - 1; i++) {
    const IPAddressFamily *a = sk_IPAddressFamily_value(addr, i);
    const IPAddressFamily *b = sk_IPAddressFamily_value(addr, i + 1);
    if (IPAddressFamily_cmp(&a, &b) >= 0)
      return 0;
  }

  /*
   * Top level's ok, now check each address family.
   */
  for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
    IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
    int length = length_from_afi(v3_addr_get_afi(f));

    /*
     * Inheritance is canonical.  Anything other than inheritance or
     * a SEQUENCE OF IPAddressOrRange is an ASN.1 error or something.
     */
    if (f == NULL || f->ipAddressChoice == NULL)
      return 0;
    switch (f->ipAddressChoice->type) {
    case IPAddressChoice_inherit:
      continue;
    case IPAddressChoice_addressesOrRanges:
      break;
    default:
      return 0;
    }

    /*
     * It's an IPAddressOrRanges sequence, check it.
     */
    aors = f->ipAddressChoice->u.addressesOrRanges;
    if (sk_IPAddressOrRange_num(aors) == 0)
      return 0;
    for (j = 0; j < sk_IPAddressOrRange_num(aors) - 1; j++) {
      IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
      IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, j + 1);

      if (!extract_min_max(a, a_min, a_max, length) ||
	  !extract_min_max(b, b_min, b_max, length))
	return 0;

      /*
       * Punt misordered list, overlapping start, or inverted range.
       */
      if (memcmp(a_min, b_min, length) >= 0 ||
	  memcmp(a_min, a_max, length) > 0 ||
	  memcmp(b_min, b_max, length) > 0)
	return 0;

      /*
       * Punt if adjacent or overlapping.  Check for adjacency by
       * subtracting one from b_min first.
       */
      for (k = length - 1; k >= 0 && b_min[k]-- == 0x00; k--)
	;
      if (memcmp(a_max, b_min, length) >= 0)
	return 0;

      /*
       * Check for range that should be expressed as a prefix.
       */
      if (a->type == IPAddressOrRange_addressRange &&
	  range_should_be_prefix(a_min, a_max, length) >= 0)
	return 0;
    }

    /*
     * 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 != NULL && a->type == IPAddressOrRange_addressRange) {
	if (!extract_min_max(a, a_min, a_max, length))
	  return 0;
	if (memcmp(a_min, a_max, length) > 0 ||
	    range_should_be_prefix(a_min, a_max, length) >= 0)
	  return 0;
      }
    }
  }

  /*
   * If we made it through all that, we're happy.
   */
  return 1;
}

/*
 * Whack an IPAddressOrRanges into canonical form.
 */
static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors,
				      const unsigned afi)
{
  int i, j, length = length_from_afi(afi);

  /*
   * Sort the IPAddressOrRanges sequence.
   */
  sk_IPAddressOrRange_sort(aors);

  /*
   * Clean up representation issues, punt on duplicates or overlaps.
   */
  for (i = 0; i < sk_IPAddressOrRange_num(aors) - 1; i++) {
    IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, i);
    IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, i + 1);
    unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
    unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN];

    if (!extract_min_max(a, a_min, a_max, length) ||
	!extract_min_max(b, b_min, b_max, length))
      return 0;

    /*
     * Punt inverted ranges.
     */
    if (memcmp(a_min, a_max, length) > 0 ||
	memcmp(b_min, b_max, length) > 0)
      return 0;

    /*
     * Punt overlaps.
     */
    if (memcmp(a_max, b_min, length) >= 0)
      return 0;

    /*
     * Merge if a and b are adjacent.  We check for
     * adjacency by subtracting one from b_min first.
     */
    for (j = length - 1; j >= 0 && b_min[j]-- == 0x00; j--)
      ;
    if (memcmp(a_max, b_min, length) == 0) {
      IPAddressOrRange *merged;
      if (!make_addressRange(&merged, a_min, b_max, length))
	return 0;
      (void) sk_IPAddressOrRange_set(aors, i, merged);
      (void) sk_IPAddressOrRange_delete(aors, i + 1);
      IPAddressOrRange_free(a);
      IPAddressOrRange_free(b);
      --i;
      continue;
    }
  }

  /*
   * 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;
}

/*
 * Whack an IPAddrBlocks extension into canonical form.
 */
int v3_addr_canonize(IPAddrBlocks *addr)
{
  int i;
  for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
    IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
    if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges &&
	!IPAddressOrRanges_canonize(f->ipAddressChoice->u.addressesOrRanges,
				    v3_addr_get_afi(f)))
      return 0;
  }
  (void) sk_IPAddressFamily_set_cmp_func(addr, IPAddressFamily_cmp);
  sk_IPAddressFamily_sort(addr);
  OPENSSL_assert(v3_addr_is_canonical(addr));
  return 1;
}

/*
 * v2i handler for the IPAddrBlocks extension.
 */
static void *v2i_IPAddrBlocks(const struct v3_ext_method *method,
			      struct v3_ext_ctx *ctx,
			      STACK_OF(CONF_VALUE) *values)
{
  static const char v4addr_chars[] = "0123456789.";
  static const char v6addr_chars[] = "0123456789.:abcdefABCDEF";
  IPAddrBlocks *addr = NULL;
  char *s = NULL, *t;
  int i;
  
  if ((addr = sk_IPAddressFamily_new(IPAddressFamily_cmp)) == NULL) {
    X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
    return NULL;
  }

  for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
    CONF_VALUE *val = sk_CONF_VALUE_value(values, i);
    unsigned char min[ADDR_RAW_BUF_LEN], max[ADDR_RAW_BUF_LEN];
    unsigned afi, *safi = NULL, safi_;
    const char *addr_chars;
    int prefixlen, i1, i2, delim, length;

    if (       !name_cmp(val->name, "IPv4")) {
      afi = IANA_AFI_IPV4;
    } else if (!name_cmp(val->name, "IPv6")) {
      afi = IANA_AFI_IPV6;
    } else if (!name_cmp(val->name, "IPv4-SAFI")) {
      afi = IANA_AFI_IPV4;
      safi = &safi_;
    } else if (!name_cmp(val->name, "IPv6-SAFI")) {
      afi = IANA_AFI_IPV6;
      safi = &safi_;
    } else {
      X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_NAME_ERROR);
      X509V3_conf_err(val);
      goto err;
    }

    switch (afi) {
    case IANA_AFI_IPV4:
      addr_chars = v4addr_chars;
      break;
    case IANA_AFI_IPV6:
      addr_chars = v6addr_chars;
      break;
    }

    length = length_from_afi(afi);

    /*
     * Handle SAFI, if any, and BUF_strdup() so we can null-terminate
     * the other input values.
     */
    if (safi != NULL) {
      *safi = strtoul(val->value, &t, 0);
      t += strspn(t, " \t");
      if (*safi > 0xFF || *t++ != ':') {
	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_SAFI);
	X509V3_conf_err(val);
	goto err;
      }
      t += strspn(t, " \t");
      s = BUF_strdup(t);
    } else {
      s = BUF_strdup(val->value);
    }
    if (s == NULL) {
      X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
      goto err;
    }

    /*
     * Check for inheritance.  Not worth additional complexity to
     * optimize this (seldom-used) case.
     */
    if (!strcmp(s, "inherit")) {
      if (!v3_addr_add_inherit(addr, afi, safi)) {
	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_INHERITANCE);
	X509V3_conf_err(val);
	goto err;
      }
      OPENSSL_free(s);
      s = NULL;
      continue;
    }

    i1 = strspn(s, addr_chars);
    i2 = i1 + strspn(s + i1, " \t");
    delim = s[i2++];
    s[i1] = '\0';

    if (a2i_ipadd(min, s) != length) {
      X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_IPADDRESS);
      X509V3_conf_err(val);
      goto err;
    }

    switch (delim) {
    case '/':
      prefixlen = (int) strtoul(s + i2, &t, 10);
      if (t == s + i2 || *t != '\0') {
	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR);
	X509V3_conf_err(val);
	goto err;
      }
      if (!v3_addr_add_prefix(addr, afi, safi, min, prefixlen)) {
	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
	goto err;
      }
      break;
    case '-':
      i1 = i2 + strspn(s + i2, " \t");
      i2 = i1 + strspn(s + i1, addr_chars);
      if (i1 == i2 || s[i2] != '\0') {
	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR);
	X509V3_conf_err(val);
	goto err;
      }
      if (a2i_ipadd(max, s + i1) != length) {
	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_IPADDRESS);
	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;
      }
      break;
    case '\0':
      if (!v3_addr_add_prefix(addr, afi, safi, min, length * 8)) {
	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
	goto err;
      }
      break;
    default:
      X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR);
      X509V3_conf_err(val);
      goto err;
    }

    OPENSSL_free(s);
    s = NULL;
  }

  /*
   * Canonize the result, then we're done.
   */
  if (!v3_addr_canonize(addr))
    goto err;    
  return addr;

 err:
  OPENSSL_free(s);
  sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free);
  return NULL;
}

/*
 * OpenSSL dispatch
 */
const X509V3_EXT_METHOD v3_addr = {
  NID_sbgp_ipAddrBlock,		/* nid */
  0,				/* flags */
  ASN1_ITEM_ref(IPAddrBlocks),	/* template */
  0, 0, 0, 0,			/* old functions, ignored */
  0,				/* i2s */
  0,				/* s2i */
  0,				/* i2v */
  v2i_IPAddrBlocks,		/* v2i */
  i2r_IPAddrBlocks,		/* i2r */
  0,				/* r2i */
  NULL				/* extension-specific data */
};

/*
 * Figure out whether extension sues inheritance.
 */
int v3_addr_inherits(IPAddrBlocks *addr)
{
  int i;
  if (addr == NULL)
    return 0;
  for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
    IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
    if (f->ipAddressChoice->type == IPAddressChoice_inherit)
      return 1;
  }
  return 0;
}

/*
 * Figure out whether parent contains child.
 */
static int addr_contains(IPAddressOrRanges *parent,
			 IPAddressOrRanges *child,
			 int length)
{
  unsigned char p_min[ADDR_RAW_BUF_LEN], p_max[ADDR_RAW_BUF_LEN];
  unsigned char c_min[ADDR_RAW_BUF_LEN], c_max[ADDR_RAW_BUF_LEN];
  int p, c;

  if (child == NULL || parent == child)
    return 1;
  if (parent == NULL)
    return 0;

  p = 0;
  for (c = 0; c < sk_IPAddressOrRange_num(child); c++) {
    if (!extract_min_max(sk_IPAddressOrRange_value(child, c),
			 c_min, c_max, length))
      return -1;
    for (;; p++) {
      if (p >= sk_IPAddressOrRange_num(parent))
	return 0;
      if (!extract_min_max(sk_IPAddressOrRange_value(parent, p),
			   p_min, p_max, length))
	return 0;
      if (memcmp(p_max, c_max, length) < 0)
	continue;
      if (memcmp(p_min, c_min, length) > 0)
	return 0;
      break;
    }
  }

  return 1;
}

/*
 * Test whether a is a subset of b.
 */
int v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b)
{
  int i;
  if (a == NULL || a == b)
    return 1;
  if (b == NULL || v3_addr_inherits(a) || v3_addr_inherits(b))
    return 0;
  (void) sk_IPAddressFamily_set_cmp_func(b, IPAddressFamily_cmp);
  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;
    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))))
      return 0;
  }
  return 1;
}

/*
 * Validation error handling via callback.
 */
#define validation_err(_err_)		\
  do {					\
    if (ctx != NULL) {			\
      ctx->error = _err_;		\
      ctx->error_depth = i;		\
      ctx->current_cert = x;		\
      ret = ctx->verify_cb(0, ctx);	\
    } else {				\
      ret = 0;				\
    }					\
    if (!ret)				\
      goto done;			\
  } while (0)

/*
 * Core code for RFC 3779 2.3 path validation.
 */
static int v3_addr_validate_path_internal(X509_STORE_CTX *ctx,
					  STACK_OF(X509) *chain,
					  IPAddrBlocks *ext)
{
  IPAddrBlocks *child = NULL;
  int i, j, ret = 1;
  X509 *x;

  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
   * check, we're done.  Otherwise, check canonical form and
   * set up for walking up the chain.
   */
  if (ext != NULL) {
    i = -1;
    x = NULL;
  } else {
    i = 0;
    x = sk_X509_value(chain, i);
    OPENSSL_assert(x != NULL);
    if ((ext = x->rfc3779_addr) == NULL)
      goto done;
  }
  if (!v3_addr_is_canonical(ext))
    validation_err(X509_V_ERR_INVALID_EXTENSION);
  (void) sk_IPAddressFamily_set_cmp_func(ext, IPAddressFamily_cmp);
  if ((child = sk_IPAddressFamily_dup(ext)) == NULL) {
    X509V3err(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL, ERR_R_MALLOC_FAILURE);
    ret = 0;
    goto done;
  }

  /*
   * Now walk up the chain.  No cert may list resources that its
   * parent doesn't list.
   */
  for (i++; i < sk_X509_num(chain); i++) {
    x = sk_X509_value(chain, i);
    OPENSSL_assert(x != NULL);
    if (!v3_addr_is_canonical(x->rfc3779_addr))
      validation_err(X509_V_ERR_INVALID_EXTENSION);
    if (x->rfc3779_addr == NULL) {
      for (j = 0; j < sk_IPAddressFamily_num(child); j++) {
	IPAddressFamily *fc = sk_IPAddressFamily_value(child, j);
	if (fc->ipAddressChoice->type != IPAddressChoice_inherit) {
	  validation_err(X509_V_ERR_UNNESTED_RESOURCE);
	  break;
	}
      }
      continue;
    }
    (void) sk_IPAddressFamily_set_cmp_func(x->rfc3779_addr, IPAddressFamily_cmp);
    for (j = 0; j < sk_IPAddressFamily_num(child); j++) {
      IPAddressFamily *fc = sk_IPAddressFamily_value(child, j);
      int k = sk_IPAddressFamily_find(x->rfc3779_addr, fc);
      IPAddressFamily *fp = sk_IPAddressFamily_value(x->rfc3779_addr, k);
      if (fp == NULL) {
	if (fc->ipAddressChoice->type == IPAddressChoice_addressesOrRanges) {
	  validation_err(X509_V_ERR_UNNESTED_RESOURCE);
	  break;
	}
	continue;
      }
      if (fp->ipAddressChoice->type == IPAddressChoice_addressesOrRanges) {
	if (fc->ipAddressChoice->type == IPAddressChoice_inherit ||
	    addr_contains(fp->ipAddressChoice->u.addressesOrRanges, 
			  fc->ipAddressChoice->u.addressesOrRanges,
			  length_from_afi(v3_addr_get_afi(fc))))
	  sk_IPAddressFamily_set(child, j, fp);
	else
	  validation_err(X509_V_ERR_UNNESTED_RESOURCE);
      }
    }
  }

  /*
   * Trust anchor can't inherit.
   */
  OPENSSL_assert(x != NULL);
  if (x->rfc3779_addr != NULL) {
    for (j = 0; j < sk_IPAddressFamily_num(x->rfc3779_addr); j++) {
      IPAddressFamily *fp = sk_IPAddressFamily_value(x->rfc3779_addr, j);
      if (fp->ipAddressChoice->type == IPAddressChoice_inherit &&
	  sk_IPAddressFamily_find(child, fp) >= 0)
	validation_err(X509_V_ERR_UNNESTED_RESOURCE);
    }
  }

 done:
  sk_IPAddressFamily_free(child);
  return ret;
}

#undef validation_err

/*
 * RFC 3779 2.3 path validation -- called from X509_verify_cert().
 */
int v3_addr_validate_path(X509_STORE_CTX *ctx)
{
  return v3_addr_validate_path_internal(ctx, ctx->chain, NULL);
}

/*
 * RFC 3779 2.3 path validation of an extension.
 * Test whether chain covers extension.
 */
int v3_addr_validate_resource_set(STACK_OF(X509) *chain,
				  IPAddrBlocks *ext,
				  int allow_inheritance)
{
  if (ext == NULL)
    return 1;
  if (chain == NULL || sk_X509_num(chain) == 0)
    return 0;
  if (!allow_inheritance && v3_addr_inherits(ext))
    return 0;
  return v3_addr_validate_path_internal(NULL, chain, ext);
}

#endif /* OPENSSL_NO_RFC3779 */
