os/ossrv/ssl/libcrypto/src/crypto/x509v3/v3_addr.c
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/*
sl@0
     2
 * Contributed to the OpenSSL Project by the American Registry for
sl@0
     3
 * Internet Numbers ("ARIN").
sl@0
     4
 */
sl@0
     5
/* ====================================================================
sl@0
     6
 * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
sl@0
     7
 *
sl@0
     8
 * Redistribution and use in source and binary forms, with or without
sl@0
     9
 * modification, are permitted provided that the following conditions
sl@0
    10
 * are met:
sl@0
    11
 *
sl@0
    12
 * 1. Redistributions of source code must retain the above copyright
sl@0
    13
 *    notice, this list of conditions and the following disclaimer. 
sl@0
    14
 *
sl@0
    15
 * 2. Redistributions in binary form must reproduce the above copyright
sl@0
    16
 *    notice, this list of conditions and the following disclaimer in
sl@0
    17
 *    the documentation and/or other materials provided with the
sl@0
    18
 *    distribution.
sl@0
    19
 *
sl@0
    20
 * 3. All advertising materials mentioning features or use of this
sl@0
    21
 *    software must display the following acknowledgment:
sl@0
    22
 *    "This product includes software developed by the OpenSSL Project
sl@0
    23
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
sl@0
    24
 *
sl@0
    25
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
sl@0
    26
 *    endorse or promote products derived from this software without
sl@0
    27
 *    prior written permission. For written permission, please contact
sl@0
    28
 *    licensing@OpenSSL.org.
sl@0
    29
 *
sl@0
    30
 * 5. Products derived from this software may not be called "OpenSSL"
sl@0
    31
 *    nor may "OpenSSL" appear in their names without prior written
sl@0
    32
 *    permission of the OpenSSL Project.
sl@0
    33
 *
sl@0
    34
 * 6. Redistributions of any form whatsoever must retain the following
sl@0
    35
 *    acknowledgment:
sl@0
    36
 *    "This product includes software developed by the OpenSSL Project
sl@0
    37
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
sl@0
    38
 *
sl@0
    39
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
sl@0
    40
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
sl@0
    41
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
sl@0
    42
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
sl@0
    43
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
sl@0
    44
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
sl@0
    45
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
sl@0
    46
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
sl@0
    47
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
sl@0
    48
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
sl@0
    49
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
sl@0
    50
 * OF THE POSSIBILITY OF SUCH DAMAGE.
sl@0
    51
 * ====================================================================
sl@0
    52
 *
sl@0
    53
 * This product includes cryptographic software written by Eric Young
sl@0
    54
 * (eay@cryptsoft.com).  This product includes software written by Tim
sl@0
    55
 * Hudson (tjh@cryptsoft.com).
sl@0
    56
 */
sl@0
    57
sl@0
    58
/*
sl@0
    59
 * Implementation of RFC 3779 section 2.2.
sl@0
    60
 */
sl@0
    61
sl@0
    62
#include <stdio.h>
sl@0
    63
#include <stdlib.h>
sl@0
    64
#include <assert.h>
sl@0
    65
#include "cryptlib.h"
sl@0
    66
#include <openssl/conf.h>
sl@0
    67
#include <openssl/asn1.h>
sl@0
    68
#include <openssl/asn1t.h>
sl@0
    69
#include <openssl/buffer.h>
sl@0
    70
#include <openssl/x509v3.h>
sl@0
    71
sl@0
    72
#ifndef OPENSSL_NO_RFC3779
sl@0
    73
sl@0
    74
/*
sl@0
    75
 * OpenSSL ASN.1 template translation of RFC 3779 2.2.3.
sl@0
    76
 */
sl@0
    77
sl@0
    78
ASN1_SEQUENCE(IPAddressRange) = {
sl@0
    79
  ASN1_SIMPLE(IPAddressRange, min, ASN1_BIT_STRING),
sl@0
    80
  ASN1_SIMPLE(IPAddressRange, max, ASN1_BIT_STRING)
sl@0
    81
} ASN1_SEQUENCE_END(IPAddressRange)
sl@0
    82
sl@0
    83
ASN1_CHOICE(IPAddressOrRange) = {
sl@0
    84
  ASN1_SIMPLE(IPAddressOrRange, u.addressPrefix, ASN1_BIT_STRING),
sl@0
    85
  ASN1_SIMPLE(IPAddressOrRange, u.addressRange,  IPAddressRange)
sl@0
    86
} ASN1_CHOICE_END(IPAddressOrRange)
sl@0
    87
sl@0
    88
ASN1_CHOICE(IPAddressChoice) = {
sl@0
    89
  ASN1_SIMPLE(IPAddressChoice,      u.inherit,           ASN1_NULL),
sl@0
    90
  ASN1_SEQUENCE_OF(IPAddressChoice, u.addressesOrRanges, IPAddressOrRange)
sl@0
    91
} ASN1_CHOICE_END(IPAddressChoice)
sl@0
    92
sl@0
    93
ASN1_SEQUENCE(IPAddressFamily) = {
sl@0
    94
  ASN1_SIMPLE(IPAddressFamily, addressFamily,   ASN1_OCTET_STRING),
sl@0
    95
  ASN1_SIMPLE(IPAddressFamily, ipAddressChoice, IPAddressChoice)
sl@0
    96
} ASN1_SEQUENCE_END(IPAddressFamily)
sl@0
    97
sl@0
    98
ASN1_ITEM_TEMPLATE(IPAddrBlocks) = 
sl@0
    99
  ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0,
sl@0
   100
			IPAddrBlocks, IPAddressFamily)
sl@0
   101
ASN1_ITEM_TEMPLATE_END(IPAddrBlocks)
sl@0
   102
sl@0
   103
IMPLEMENT_ASN1_FUNCTIONS(IPAddressRange)
sl@0
   104
IMPLEMENT_ASN1_FUNCTIONS(IPAddressOrRange)
sl@0
   105
IMPLEMENT_ASN1_FUNCTIONS(IPAddressChoice)
sl@0
   106
IMPLEMENT_ASN1_FUNCTIONS(IPAddressFamily)
sl@0
   107
sl@0
   108
/*
sl@0
   109
 * How much buffer space do we need for a raw address?
sl@0
   110
 */
sl@0
   111
#define ADDR_RAW_BUF_LEN	16
sl@0
   112
sl@0
   113
/*
sl@0
   114
 * What's the address length associated with this AFI?
sl@0
   115
 */
sl@0
   116
static int length_from_afi(const unsigned afi)
sl@0
   117
{
sl@0
   118
  switch (afi) {
sl@0
   119
  case IANA_AFI_IPV4:
sl@0
   120
    return 4;
sl@0
   121
  case IANA_AFI_IPV6:
sl@0
   122
    return 16;
sl@0
   123
  default:
sl@0
   124
    return 0;
sl@0
   125
  }
sl@0
   126
}
sl@0
   127
sl@0
   128
/*
sl@0
   129
 * Extract the AFI from an IPAddressFamily.
sl@0
   130
 */
sl@0
   131
unsigned v3_addr_get_afi(const IPAddressFamily *f)
sl@0
   132
{
sl@0
   133
  return ((f != NULL &&
sl@0
   134
	   f->addressFamily != NULL &&
sl@0
   135
	   f->addressFamily->data != NULL)
sl@0
   136
	  ? ((f->addressFamily->data[0] << 8) |
sl@0
   137
	     (f->addressFamily->data[1]))
sl@0
   138
	  : 0);
sl@0
   139
}
sl@0
   140
sl@0
   141
/*
sl@0
   142
 * Expand the bitstring form of an address into a raw byte array.
sl@0
   143
 * At the moment this is coded for simplicity, not speed.
sl@0
   144
 */
sl@0
   145
static void addr_expand(unsigned char *addr,
sl@0
   146
			const ASN1_BIT_STRING *bs,
sl@0
   147
			const int length,
sl@0
   148
			const unsigned char fill)
sl@0
   149
{
sl@0
   150
  assert(bs->length >= 0 && bs->length <= length);
sl@0
   151
  if (bs->length > 0) {
sl@0
   152
    memcpy(addr, bs->data, bs->length);
sl@0
   153
    if ((bs->flags & 7) != 0) {
sl@0
   154
      unsigned char mask = 0xFF >> (8 - (bs->flags & 7));
sl@0
   155
      if (fill == 0)
sl@0
   156
	addr[bs->length - 1] &= ~mask;
sl@0
   157
      else
sl@0
   158
	addr[bs->length - 1] |= mask;
sl@0
   159
    }
sl@0
   160
  }
sl@0
   161
  memset(addr + bs->length, fill, length - bs->length);
sl@0
   162
}
sl@0
   163
sl@0
   164
/*
sl@0
   165
 * Extract the prefix length from a bitstring.
sl@0
   166
 */
sl@0
   167
#define addr_prefixlen(bs) ((int) ((bs)->length * 8 - ((bs)->flags & 7)))
sl@0
   168
sl@0
   169
/*
sl@0
   170
 * i2r handler for one address bitstring.
sl@0
   171
 */
sl@0
   172
static int i2r_address(BIO *out,
sl@0
   173
		       const unsigned afi,
sl@0
   174
		       const unsigned char fill,
sl@0
   175
		       const ASN1_BIT_STRING *bs)
sl@0
   176
{
sl@0
   177
  unsigned char addr[ADDR_RAW_BUF_LEN];
sl@0
   178
  int i, n;
sl@0
   179
sl@0
   180
  switch (afi) {
sl@0
   181
  case IANA_AFI_IPV4:
sl@0
   182
    addr_expand(addr, bs, 4, fill);
sl@0
   183
    BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
sl@0
   184
    break;
sl@0
   185
  case IANA_AFI_IPV6:
sl@0
   186
    addr_expand(addr, bs, 16, fill);
sl@0
   187
    for (n = 16; n > 1 && addr[n-1] == 0x00 && addr[n-2] == 0x00; n -= 2)
sl@0
   188
      ;
sl@0
   189
    for (i = 0; i < n; i += 2)
sl@0
   190
      BIO_printf(out, "%x%s", (addr[i] << 8) | addr[i+1], (i < 14 ? ":" : ""));
sl@0
   191
    if (i < 16)
sl@0
   192
      BIO_puts(out, ":");
sl@0
   193
    break;
sl@0
   194
  default:
sl@0
   195
    for (i = 0; i < bs->length; i++)
sl@0
   196
      BIO_printf(out, "%s%02x", (i > 0 ? ":" : ""), bs->data[i]);
sl@0
   197
    BIO_printf(out, "[%d]", (int) (bs->flags & 7));
sl@0
   198
    break;
sl@0
   199
  }
sl@0
   200
  return 1;
sl@0
   201
}
sl@0
   202
sl@0
   203
/*
sl@0
   204
 * i2r handler for a sequence of addresses and ranges.
sl@0
   205
 */
sl@0
   206
static int i2r_IPAddressOrRanges(BIO *out,
sl@0
   207
				 const int indent,
sl@0
   208
				 const IPAddressOrRanges *aors,
sl@0
   209
				 const unsigned afi)
sl@0
   210
{
sl@0
   211
  int i;
sl@0
   212
  for (i = 0; i < sk_IPAddressOrRange_num(aors); i++) {
sl@0
   213
    const IPAddressOrRange *aor = sk_IPAddressOrRange_value(aors, i);
sl@0
   214
    BIO_printf(out, "%*s", indent, "");
sl@0
   215
    switch (aor->type) {
sl@0
   216
    case IPAddressOrRange_addressPrefix:
sl@0
   217
      if (!i2r_address(out, afi, 0x00, aor->u.addressPrefix))
sl@0
   218
	return 0;
sl@0
   219
      BIO_printf(out, "/%d\n", addr_prefixlen(aor->u.addressPrefix));
sl@0
   220
      continue;
sl@0
   221
    case IPAddressOrRange_addressRange:
sl@0
   222
      if (!i2r_address(out, afi, 0x00, aor->u.addressRange->min))
sl@0
   223
	return 0;
sl@0
   224
      BIO_puts(out, "-");
sl@0
   225
      if (!i2r_address(out, afi, 0xFF, aor->u.addressRange->max))
sl@0
   226
	return 0;
sl@0
   227
      BIO_puts(out, "\n");
sl@0
   228
      continue;
sl@0
   229
    }
sl@0
   230
  }
sl@0
   231
  return 1;
sl@0
   232
}
sl@0
   233
sl@0
   234
/*
sl@0
   235
 * i2r handler for an IPAddrBlocks extension.
sl@0
   236
 */
sl@0
   237
static int i2r_IPAddrBlocks(X509V3_EXT_METHOD *method,
sl@0
   238
			    void *ext,
sl@0
   239
			    BIO *out,
sl@0
   240
			    int indent)
sl@0
   241
{
sl@0
   242
  const IPAddrBlocks *addr = ext;
sl@0
   243
  int i;
sl@0
   244
  for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
sl@0
   245
    IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
sl@0
   246
    const unsigned afi = v3_addr_get_afi(f);
sl@0
   247
    switch (afi) {
sl@0
   248
    case IANA_AFI_IPV4:
sl@0
   249
      BIO_printf(out, "%*sIPv4", indent, "");
sl@0
   250
      break;
sl@0
   251
    case IANA_AFI_IPV6:
sl@0
   252
      BIO_printf(out, "%*sIPv6", indent, "");
sl@0
   253
      break;
sl@0
   254
    default:
sl@0
   255
      BIO_printf(out, "%*sUnknown AFI %u", indent, "", afi);
sl@0
   256
      break;
sl@0
   257
    }
sl@0
   258
    if (f->addressFamily->length > 2) {
sl@0
   259
      switch (f->addressFamily->data[2]) {
sl@0
   260
      case   1:
sl@0
   261
	BIO_puts(out, " (Unicast)");
sl@0
   262
	break;
sl@0
   263
      case   2:
sl@0
   264
	BIO_puts(out, " (Multicast)");
sl@0
   265
	break;
sl@0
   266
      case   3:
sl@0
   267
	BIO_puts(out, " (Unicast/Multicast)");
sl@0
   268
	break;
sl@0
   269
      case   4:
sl@0
   270
	BIO_puts(out, " (MPLS)");
sl@0
   271
	break;
sl@0
   272
      case  64:
sl@0
   273
	BIO_puts(out, " (Tunnel)");
sl@0
   274
	break;
sl@0
   275
      case  65:
sl@0
   276
	BIO_puts(out, " (VPLS)");
sl@0
   277
	break;
sl@0
   278
      case  66:
sl@0
   279
	BIO_puts(out, " (BGP MDT)");
sl@0
   280
	break;
sl@0
   281
      case 128:
sl@0
   282
	BIO_puts(out, " (MPLS-labeled VPN)");
sl@0
   283
	break;
sl@0
   284
      default:  
sl@0
   285
	BIO_printf(out, " (Unknown SAFI %u)",
sl@0
   286
		   (unsigned) f->addressFamily->data[2]);
sl@0
   287
	break;
sl@0
   288
      }
sl@0
   289
    }
sl@0
   290
    switch (f->ipAddressChoice->type) {
sl@0
   291
    case IPAddressChoice_inherit:
sl@0
   292
      BIO_puts(out, ": inherit\n");
sl@0
   293
      break;
sl@0
   294
    case IPAddressChoice_addressesOrRanges:
sl@0
   295
      BIO_puts(out, ":\n");
sl@0
   296
      if (!i2r_IPAddressOrRanges(out,
sl@0
   297
				 indent + 2,
sl@0
   298
				 f->ipAddressChoice->u.addressesOrRanges,
sl@0
   299
				 afi))
sl@0
   300
	return 0;
sl@0
   301
      break;
sl@0
   302
    }
sl@0
   303
  }
sl@0
   304
  return 1;
sl@0
   305
}
sl@0
   306
sl@0
   307
/*
sl@0
   308
 * Sort comparison function for a sequence of IPAddressOrRange
sl@0
   309
 * elements.
sl@0
   310
 */
sl@0
   311
static int IPAddressOrRange_cmp(const IPAddressOrRange *a,
sl@0
   312
				const IPAddressOrRange *b,
sl@0
   313
				const int length)
sl@0
   314
{
sl@0
   315
  unsigned char addr_a[ADDR_RAW_BUF_LEN], addr_b[ADDR_RAW_BUF_LEN];
sl@0
   316
  int prefixlen_a = 0;
sl@0
   317
  int prefixlen_b = 0;
sl@0
   318
  int r;
sl@0
   319
sl@0
   320
  switch (a->type) {
sl@0
   321
  case IPAddressOrRange_addressPrefix:
sl@0
   322
    addr_expand(addr_a, a->u.addressPrefix, length, 0x00);
sl@0
   323
    prefixlen_a = addr_prefixlen(a->u.addressPrefix);
sl@0
   324
    break;
sl@0
   325
  case IPAddressOrRange_addressRange:
sl@0
   326
    addr_expand(addr_a, a->u.addressRange->min, length, 0x00);
sl@0
   327
    prefixlen_a = length * 8;
sl@0
   328
    break;
sl@0
   329
  }
sl@0
   330
sl@0
   331
  switch (b->type) {
sl@0
   332
  case IPAddressOrRange_addressPrefix:
sl@0
   333
    addr_expand(addr_b, b->u.addressPrefix, length, 0x00);
sl@0
   334
    prefixlen_b = addr_prefixlen(b->u.addressPrefix);
sl@0
   335
    break;
sl@0
   336
  case IPAddressOrRange_addressRange:
sl@0
   337
    addr_expand(addr_b, b->u.addressRange->min, length, 0x00);
sl@0
   338
    prefixlen_b = length * 8;
sl@0
   339
    break;
sl@0
   340
  }
sl@0
   341
sl@0
   342
  if ((r = memcmp(addr_a, addr_b, length)) != 0)
sl@0
   343
    return r;
sl@0
   344
  else
sl@0
   345
    return prefixlen_a - prefixlen_b;
sl@0
   346
}
sl@0
   347
sl@0
   348
/*
sl@0
   349
 * IPv4-specific closure over IPAddressOrRange_cmp, since sk_sort()
sl@0
   350
 * comparision routines are only allowed two arguments.
sl@0
   351
 */
sl@0
   352
static int v4IPAddressOrRange_cmp(const IPAddressOrRange * const *a,
sl@0
   353
				  const IPAddressOrRange * const *b)
sl@0
   354
{
sl@0
   355
  return IPAddressOrRange_cmp(*a, *b, 4);
sl@0
   356
}
sl@0
   357
sl@0
   358
/*
sl@0
   359
 * IPv6-specific closure over IPAddressOrRange_cmp, since sk_sort()
sl@0
   360
 * comparision routines are only allowed two arguments.
sl@0
   361
 */
sl@0
   362
static int v6IPAddressOrRange_cmp(const IPAddressOrRange * const *a,
sl@0
   363
				  const IPAddressOrRange * const *b)
sl@0
   364
{
sl@0
   365
  return IPAddressOrRange_cmp(*a, *b, 16);
sl@0
   366
}
sl@0
   367
sl@0
   368
/*
sl@0
   369
 * Calculate whether a range collapses to a prefix.
sl@0
   370
 * See last paragraph of RFC 3779 2.2.3.7.
sl@0
   371
 */
sl@0
   372
static int range_should_be_prefix(const unsigned char *min,
sl@0
   373
				  const unsigned char *max,
sl@0
   374
				  const int length)
sl@0
   375
{
sl@0
   376
  unsigned char mask;
sl@0
   377
  int i, j;
sl@0
   378
sl@0
   379
  for (i = 0; i < length && min[i] == max[i]; i++)
sl@0
   380
    ;
sl@0
   381
  for (j = length - 1; j >= 0 && min[j] == 0x00 && max[j] == 0xFF; j--)
sl@0
   382
    ;
sl@0
   383
  if (i < j)
sl@0
   384
    return -1;
sl@0
   385
  if (i > j)
sl@0
   386
    return i * 8;
sl@0
   387
  mask = min[i] ^ max[i];
sl@0
   388
  switch (mask) {
sl@0
   389
  case 0x01: j = 7; break;
sl@0
   390
  case 0x03: j = 6; break;
sl@0
   391
  case 0x07: j = 5; break;
sl@0
   392
  case 0x0F: j = 4; break;
sl@0
   393
  case 0x1F: j = 3; break;
sl@0
   394
  case 0x3F: j = 2; break;
sl@0
   395
  case 0x7F: j = 1; break;
sl@0
   396
  default:   return -1;
sl@0
   397
  }
sl@0
   398
  if ((min[i] & mask) != 0 || (max[i] & mask) != mask)
sl@0
   399
    return -1;
sl@0
   400
  else
sl@0
   401
    return i * 8 + j;
sl@0
   402
}
sl@0
   403
sl@0
   404
/*
sl@0
   405
 * Construct a prefix.
sl@0
   406
 */
sl@0
   407
static int make_addressPrefix(IPAddressOrRange **result,
sl@0
   408
			      unsigned char *addr,
sl@0
   409
			      const int prefixlen)
sl@0
   410
{
sl@0
   411
  int bytelen = (prefixlen + 7) / 8, bitlen = prefixlen % 8;
sl@0
   412
  IPAddressOrRange *aor = IPAddressOrRange_new();
sl@0
   413
sl@0
   414
  if (aor == NULL)
sl@0
   415
    return 0;
sl@0
   416
  aor->type = IPAddressOrRange_addressPrefix;
sl@0
   417
  if (aor->u.addressPrefix == NULL &&
sl@0
   418
      (aor->u.addressPrefix = ASN1_BIT_STRING_new()) == NULL)
sl@0
   419
    goto err;
sl@0
   420
  if (!ASN1_BIT_STRING_set(aor->u.addressPrefix, addr, bytelen))
sl@0
   421
    goto err;
sl@0
   422
  aor->u.addressPrefix->flags &= ~7;
sl@0
   423
  aor->u.addressPrefix->flags |= ASN1_STRING_FLAG_BITS_LEFT;
sl@0
   424
  if (bitlen > 0) {
sl@0
   425
    aor->u.addressPrefix->data[bytelen - 1] &= ~(0xFF >> bitlen);
sl@0
   426
    aor->u.addressPrefix->flags |= 8 - bitlen;
sl@0
   427
  }
sl@0
   428
  
sl@0
   429
  *result = aor;
sl@0
   430
  return 1;
sl@0
   431
sl@0
   432
 err:
sl@0
   433
  IPAddressOrRange_free(aor);
sl@0
   434
  return 0;
sl@0
   435
}
sl@0
   436
sl@0
   437
/*
sl@0
   438
 * Construct a range.  If it can be expressed as a prefix,
sl@0
   439
 * return a prefix instead.  Doing this here simplifies
sl@0
   440
 * the rest of the code considerably.
sl@0
   441
 */
sl@0
   442
static int make_addressRange(IPAddressOrRange **result,
sl@0
   443
			     unsigned char *min,
sl@0
   444
			     unsigned char *max,
sl@0
   445
			     const int length)
sl@0
   446
{
sl@0
   447
  IPAddressOrRange *aor;
sl@0
   448
  int i, prefixlen;
sl@0
   449
sl@0
   450
  if ((prefixlen = range_should_be_prefix(min, max, length)) >= 0)
sl@0
   451
    return make_addressPrefix(result, min, prefixlen);
sl@0
   452
sl@0
   453
  if ((aor = IPAddressOrRange_new()) == NULL)
sl@0
   454
    return 0;
sl@0
   455
  aor->type = IPAddressOrRange_addressRange;
sl@0
   456
  assert(aor->u.addressRange == NULL);
sl@0
   457
  if ((aor->u.addressRange = IPAddressRange_new()) == NULL)
sl@0
   458
    goto err;
sl@0
   459
  if (aor->u.addressRange->min == NULL &&
sl@0
   460
      (aor->u.addressRange->min = ASN1_BIT_STRING_new()) == NULL)
sl@0
   461
    goto err;
sl@0
   462
  if (aor->u.addressRange->max == NULL &&
sl@0
   463
      (aor->u.addressRange->max = ASN1_BIT_STRING_new()) == NULL)
sl@0
   464
    goto err;
sl@0
   465
sl@0
   466
  for (i = length; i > 0 && min[i - 1] == 0x00; --i)
sl@0
   467
    ;
sl@0
   468
  if (!ASN1_BIT_STRING_set(aor->u.addressRange->min, min, i))
sl@0
   469
    goto err;
sl@0
   470
  aor->u.addressRange->min->flags &= ~7;
sl@0
   471
  aor->u.addressRange->min->flags |= ASN1_STRING_FLAG_BITS_LEFT;
sl@0
   472
  if (i > 0) {
sl@0
   473
    unsigned char b = min[i - 1];
sl@0
   474
    int j = 1;
sl@0
   475
    while ((b & (0xFFU >> j)) != 0) 
sl@0
   476
      ++j;
sl@0
   477
    aor->u.addressRange->min->flags |= 8 - j;
sl@0
   478
  }
sl@0
   479
sl@0
   480
  for (i = length; i > 0 && max[i - 1] == 0xFF; --i)
sl@0
   481
    ;
sl@0
   482
  if (!ASN1_BIT_STRING_set(aor->u.addressRange->max, max, i))
sl@0
   483
    goto err;
sl@0
   484
  aor->u.addressRange->max->flags &= ~7;
sl@0
   485
  aor->u.addressRange->max->flags |= ASN1_STRING_FLAG_BITS_LEFT;
sl@0
   486
  if (i > 0) {
sl@0
   487
    unsigned char b = max[i - 1];
sl@0
   488
    int j = 1;
sl@0
   489
    while ((b & (0xFFU >> j)) != (0xFFU >> j))
sl@0
   490
      ++j;
sl@0
   491
    aor->u.addressRange->max->flags |= 8 - j;
sl@0
   492
  }
sl@0
   493
sl@0
   494
  *result = aor;
sl@0
   495
  return 1;
sl@0
   496
sl@0
   497
 err:
sl@0
   498
  IPAddressOrRange_free(aor);
sl@0
   499
  return 0;
sl@0
   500
}
sl@0
   501
sl@0
   502
/*
sl@0
   503
 * Construct a new address family or find an existing one.
sl@0
   504
 */
sl@0
   505
static IPAddressFamily *make_IPAddressFamily(IPAddrBlocks *addr,
sl@0
   506
					     const unsigned afi,
sl@0
   507
					     const unsigned *safi)
sl@0
   508
{
sl@0
   509
  IPAddressFamily *f;
sl@0
   510
  unsigned char key[3];
sl@0
   511
  unsigned keylen;
sl@0
   512
  int i;
sl@0
   513
sl@0
   514
  key[0] = (afi >> 8) & 0xFF;
sl@0
   515
  key[1] = afi & 0xFF;
sl@0
   516
  if (safi != NULL) {
sl@0
   517
    key[2] = *safi & 0xFF;
sl@0
   518
    keylen = 3;
sl@0
   519
  } else {
sl@0
   520
    keylen = 2;
sl@0
   521
  }
sl@0
   522
sl@0
   523
  for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
sl@0
   524
    f = sk_IPAddressFamily_value(addr, i);
sl@0
   525
    assert(f->addressFamily->data != NULL);
sl@0
   526
    if (f->addressFamily->length == keylen &&
sl@0
   527
	!memcmp(f->addressFamily->data, key, keylen))
sl@0
   528
      return f;
sl@0
   529
  }
sl@0
   530
sl@0
   531
  if ((f = IPAddressFamily_new()) == NULL)
sl@0
   532
    goto err;
sl@0
   533
  if (f->ipAddressChoice == NULL &&
sl@0
   534
      (f->ipAddressChoice = IPAddressChoice_new()) == NULL)
sl@0
   535
    goto err;
sl@0
   536
  if (f->addressFamily == NULL && 
sl@0
   537
      (f->addressFamily = ASN1_OCTET_STRING_new()) == NULL)
sl@0
   538
    goto err;
sl@0
   539
  if (!ASN1_OCTET_STRING_set(f->addressFamily, key, keylen))
sl@0
   540
    goto err;
sl@0
   541
  if (!sk_IPAddressFamily_push(addr, f))
sl@0
   542
    goto err;
sl@0
   543
sl@0
   544
  return f;
sl@0
   545
sl@0
   546
 err:
sl@0
   547
  IPAddressFamily_free(f);
sl@0
   548
  return NULL;
sl@0
   549
}
sl@0
   550
sl@0
   551
/*
sl@0
   552
 * Add an inheritance element.
sl@0
   553
 */
sl@0
   554
int v3_addr_add_inherit(IPAddrBlocks *addr,
sl@0
   555
			const unsigned afi,
sl@0
   556
			const unsigned *safi)
sl@0
   557
{
sl@0
   558
  IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi);
sl@0
   559
  if (f == NULL ||
sl@0
   560
      f->ipAddressChoice == NULL ||
sl@0
   561
      (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges &&
sl@0
   562
       f->ipAddressChoice->u.addressesOrRanges != NULL))
sl@0
   563
    return 0;
sl@0
   564
  if (f->ipAddressChoice->type == IPAddressChoice_inherit &&
sl@0
   565
      f->ipAddressChoice->u.inherit != NULL)
sl@0
   566
    return 1;
sl@0
   567
  if (f->ipAddressChoice->u.inherit == NULL &&
sl@0
   568
      (f->ipAddressChoice->u.inherit = ASN1_NULL_new()) == NULL)
sl@0
   569
    return 0;
sl@0
   570
  f->ipAddressChoice->type = IPAddressChoice_inherit;
sl@0
   571
  return 1;
sl@0
   572
}
sl@0
   573
sl@0
   574
/*
sl@0
   575
 * Construct an IPAddressOrRange sequence, or return an existing one.
sl@0
   576
 */
sl@0
   577
static IPAddressOrRanges *make_prefix_or_range(IPAddrBlocks *addr,
sl@0
   578
					       const unsigned afi,
sl@0
   579
					       const unsigned *safi)
sl@0
   580
{
sl@0
   581
  IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi);
sl@0
   582
  IPAddressOrRanges *aors = NULL;
sl@0
   583
sl@0
   584
  if (f == NULL ||
sl@0
   585
      f->ipAddressChoice == NULL ||
sl@0
   586
      (f->ipAddressChoice->type == IPAddressChoice_inherit &&
sl@0
   587
       f->ipAddressChoice->u.inherit != NULL))
sl@0
   588
    return NULL;
sl@0
   589
  if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges)
sl@0
   590
    aors = f->ipAddressChoice->u.addressesOrRanges;
sl@0
   591
  if (aors != NULL)
sl@0
   592
    return aors;
sl@0
   593
  if ((aors = sk_IPAddressOrRange_new_null()) == NULL)
sl@0
   594
    return NULL;
sl@0
   595
  switch (afi) {
sl@0
   596
  case IANA_AFI_IPV4:
sl@0
   597
    sk_IPAddressOrRange_set_cmp_func(aors, v4IPAddressOrRange_cmp);
sl@0
   598
    break;
sl@0
   599
  case IANA_AFI_IPV6:
sl@0
   600
    sk_IPAddressOrRange_set_cmp_func(aors, v6IPAddressOrRange_cmp);
sl@0
   601
    break;
sl@0
   602
  }
sl@0
   603
  f->ipAddressChoice->type = IPAddressChoice_addressesOrRanges;
sl@0
   604
  f->ipAddressChoice->u.addressesOrRanges = aors;
sl@0
   605
  return aors;
sl@0
   606
}
sl@0
   607
sl@0
   608
/*
sl@0
   609
 * Add a prefix.
sl@0
   610
 */
sl@0
   611
int v3_addr_add_prefix(IPAddrBlocks *addr,
sl@0
   612
		       const unsigned afi,
sl@0
   613
		       const unsigned *safi,
sl@0
   614
		       unsigned char *a,
sl@0
   615
		       const int prefixlen)
sl@0
   616
{
sl@0
   617
  IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi);
sl@0
   618
  IPAddressOrRange *aor;
sl@0
   619
  if (aors == NULL || !make_addressPrefix(&aor, a, prefixlen))
sl@0
   620
    return 0;
sl@0
   621
  if (sk_IPAddressOrRange_push(aors, aor))
sl@0
   622
    return 1;
sl@0
   623
  IPAddressOrRange_free(aor);
sl@0
   624
  return 0;
sl@0
   625
}
sl@0
   626
sl@0
   627
/*
sl@0
   628
 * Add a range.
sl@0
   629
 */
sl@0
   630
int v3_addr_add_range(IPAddrBlocks *addr,
sl@0
   631
		      const unsigned afi,
sl@0
   632
		      const unsigned *safi,
sl@0
   633
		      unsigned char *min,
sl@0
   634
		      unsigned char *max)
sl@0
   635
{
sl@0
   636
  IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi);
sl@0
   637
  IPAddressOrRange *aor;
sl@0
   638
  int length = length_from_afi(afi);
sl@0
   639
  if (aors == NULL)
sl@0
   640
    return 0;
sl@0
   641
  if (!make_addressRange(&aor, min, max, length))
sl@0
   642
    return 0;
sl@0
   643
  if (sk_IPAddressOrRange_push(aors, aor))
sl@0
   644
    return 1;
sl@0
   645
  IPAddressOrRange_free(aor);
sl@0
   646
  return 0;
sl@0
   647
}
sl@0
   648
sl@0
   649
/*
sl@0
   650
 * Extract min and max values from an IPAddressOrRange.
sl@0
   651
 */
sl@0
   652
static void extract_min_max(IPAddressOrRange *aor,
sl@0
   653
			    unsigned char *min,
sl@0
   654
			    unsigned char *max,
sl@0
   655
			    int length)
sl@0
   656
{
sl@0
   657
  assert(aor != NULL && min != NULL && max != NULL);
sl@0
   658
  switch (aor->type) {
sl@0
   659
  case IPAddressOrRange_addressPrefix:
sl@0
   660
    addr_expand(min, aor->u.addressPrefix, length, 0x00);
sl@0
   661
    addr_expand(max, aor->u.addressPrefix, length, 0xFF);
sl@0
   662
    return;
sl@0
   663
  case IPAddressOrRange_addressRange:
sl@0
   664
    addr_expand(min, aor->u.addressRange->min, length, 0x00);
sl@0
   665
    addr_expand(max, aor->u.addressRange->max, length, 0xFF);
sl@0
   666
    return;
sl@0
   667
  }
sl@0
   668
}
sl@0
   669
sl@0
   670
/*
sl@0
   671
 * Public wrapper for extract_min_max().
sl@0
   672
 */
sl@0
   673
int v3_addr_get_range(IPAddressOrRange *aor,
sl@0
   674
		      const unsigned afi,
sl@0
   675
		      unsigned char *min,
sl@0
   676
		      unsigned char *max,
sl@0
   677
		      const int length)
sl@0
   678
{
sl@0
   679
  int afi_length = length_from_afi(afi);
sl@0
   680
  if (aor == NULL || min == NULL || max == NULL ||
sl@0
   681
      afi_length == 0 || length < afi_length ||
sl@0
   682
      (aor->type != IPAddressOrRange_addressPrefix &&
sl@0
   683
       aor->type != IPAddressOrRange_addressRange))
sl@0
   684
    return 0;
sl@0
   685
  extract_min_max(aor, min, max, afi_length);
sl@0
   686
  return afi_length;
sl@0
   687
}
sl@0
   688
sl@0
   689
/*
sl@0
   690
 * Sort comparision function for a sequence of IPAddressFamily.
sl@0
   691
 *
sl@0
   692
 * The last paragraph of RFC 3779 2.2.3.3 is slightly ambiguous about
sl@0
   693
 * the ordering: I can read it as meaning that IPv6 without a SAFI
sl@0
   694
 * comes before IPv4 with a SAFI, which seems pretty weird.  The
sl@0
   695
 * examples in appendix B suggest that the author intended the
sl@0
   696
 * null-SAFI rule to apply only within a single AFI, which is what I
sl@0
   697
 * would have expected and is what the following code implements.
sl@0
   698
 */
sl@0
   699
static int IPAddressFamily_cmp(const IPAddressFamily * const *a_,
sl@0
   700
			       const IPAddressFamily * const *b_)
sl@0
   701
{
sl@0
   702
  const ASN1_OCTET_STRING *a = (*a_)->addressFamily;
sl@0
   703
  const ASN1_OCTET_STRING *b = (*b_)->addressFamily;
sl@0
   704
  int len = ((a->length <= b->length) ? a->length : b->length);
sl@0
   705
  int cmp = memcmp(a->data, b->data, len);
sl@0
   706
  return cmp ? cmp : a->length - b->length;
sl@0
   707
}
sl@0
   708
sl@0
   709
/*
sl@0
   710
 * Check whether an IPAddrBLocks is in canonical form.
sl@0
   711
 */
sl@0
   712
int v3_addr_is_canonical(IPAddrBlocks *addr)
sl@0
   713
{
sl@0
   714
  unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
sl@0
   715
  unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN];
sl@0
   716
  IPAddressOrRanges *aors;
sl@0
   717
  int i, j, k;
sl@0
   718
sl@0
   719
  /*
sl@0
   720
   * Empty extension is cannonical.
sl@0
   721
   */
sl@0
   722
  if (addr == NULL)
sl@0
   723
    return 1;
sl@0
   724
sl@0
   725
  /*
sl@0
   726
   * Check whether the top-level list is in order.
sl@0
   727
   */
sl@0
   728
  for (i = 0; i < sk_IPAddressFamily_num(addr) - 1; i++) {
sl@0
   729
    const IPAddressFamily *a = sk_IPAddressFamily_value(addr, i);
sl@0
   730
    const IPAddressFamily *b = sk_IPAddressFamily_value(addr, i + 1);
sl@0
   731
    if (IPAddressFamily_cmp(&a, &b) >= 0)
sl@0
   732
      return 0;
sl@0
   733
  }
sl@0
   734
sl@0
   735
  /*
sl@0
   736
   * Top level's ok, now check each address family.
sl@0
   737
   */
sl@0
   738
  for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
sl@0
   739
    IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
sl@0
   740
    int length = length_from_afi(v3_addr_get_afi(f));
sl@0
   741
sl@0
   742
    /*
sl@0
   743
     * Inheritance is canonical.  Anything other than inheritance or
sl@0
   744
     * a SEQUENCE OF IPAddressOrRange is an ASN.1 error or something.
sl@0
   745
     */
sl@0
   746
    if (f == NULL || f->ipAddressChoice == NULL)
sl@0
   747
      return 0;
sl@0
   748
    switch (f->ipAddressChoice->type) {
sl@0
   749
    case IPAddressChoice_inherit:
sl@0
   750
      continue;
sl@0
   751
    case IPAddressChoice_addressesOrRanges:
sl@0
   752
      break;
sl@0
   753
    default:
sl@0
   754
      return 0;
sl@0
   755
    }
sl@0
   756
sl@0
   757
    /*
sl@0
   758
     * It's an IPAddressOrRanges sequence, check it.
sl@0
   759
     */
sl@0
   760
    aors = f->ipAddressChoice->u.addressesOrRanges;
sl@0
   761
    if (sk_IPAddressOrRange_num(aors) == 0)
sl@0
   762
      return 0;
sl@0
   763
    for (j = 0; j < sk_IPAddressOrRange_num(aors) - 1; j++) {
sl@0
   764
      IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
sl@0
   765
      IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, j + 1);
sl@0
   766
sl@0
   767
      extract_min_max(a, a_min, a_max, length);
sl@0
   768
      extract_min_max(b, b_min, b_max, length);
sl@0
   769
sl@0
   770
      /*
sl@0
   771
       * Punt misordered list, overlapping start, or inverted range.
sl@0
   772
       */
sl@0
   773
      if (memcmp(a_min, b_min, length) >= 0 ||
sl@0
   774
	  memcmp(a_min, a_max, length) > 0 ||
sl@0
   775
	  memcmp(b_min, b_max, length) > 0)
sl@0
   776
	return 0;
sl@0
   777
sl@0
   778
      /*
sl@0
   779
       * Punt if adjacent or overlapping.  Check for adjacency by
sl@0
   780
       * subtracting one from b_min first.
sl@0
   781
       */
sl@0
   782
      for (k = length - 1; k >= 0 && b_min[k]-- == 0x00; k--)
sl@0
   783
	;
sl@0
   784
      if (memcmp(a_max, b_min, length) >= 0)
sl@0
   785
	return 0;
sl@0
   786
sl@0
   787
      /*
sl@0
   788
       * Check for range that should be expressed as a prefix.
sl@0
   789
       */
sl@0
   790
      if (a->type == IPAddressOrRange_addressRange &&
sl@0
   791
	  range_should_be_prefix(a_min, a_max, length) >= 0)
sl@0
   792
	return 0;
sl@0
   793
    }
sl@0
   794
sl@0
   795
    /*
sl@0
   796
     * Check final range to see if it should be a prefix.
sl@0
   797
     */
sl@0
   798
    j = sk_IPAddressOrRange_num(aors) - 1;
sl@0
   799
    {
sl@0
   800
      IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
sl@0
   801
      if (a->type == IPAddressOrRange_addressRange) {
sl@0
   802
	extract_min_max(a, a_min, a_max, length);
sl@0
   803
	if (range_should_be_prefix(a_min, a_max, length) >= 0)
sl@0
   804
	  return 0;
sl@0
   805
      }
sl@0
   806
    }
sl@0
   807
  }
sl@0
   808
sl@0
   809
  /*
sl@0
   810
   * If we made it through all that, we're happy.
sl@0
   811
   */
sl@0
   812
  return 1;
sl@0
   813
}
sl@0
   814
sl@0
   815
/*
sl@0
   816
 * Whack an IPAddressOrRanges into canonical form.
sl@0
   817
 */
sl@0
   818
static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors,
sl@0
   819
				      const unsigned afi)
sl@0
   820
{
sl@0
   821
  int i, j, length = length_from_afi(afi);
sl@0
   822
sl@0
   823
  /*
sl@0
   824
   * Sort the IPAddressOrRanges sequence.
sl@0
   825
   */
sl@0
   826
  sk_IPAddressOrRange_sort(aors);
sl@0
   827
sl@0
   828
  /*
sl@0
   829
   * Clean up representation issues, punt on duplicates or overlaps.
sl@0
   830
   */
sl@0
   831
  for (i = 0; i < sk_IPAddressOrRange_num(aors) - 1; i++) {
sl@0
   832
    IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, i);
sl@0
   833
    IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, i + 1);
sl@0
   834
    unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
sl@0
   835
    unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN];
sl@0
   836
sl@0
   837
    extract_min_max(a, a_min, a_max, length);
sl@0
   838
    extract_min_max(b, b_min, b_max, length);
sl@0
   839
sl@0
   840
    /*
sl@0
   841
     * Punt overlaps.
sl@0
   842
     */
sl@0
   843
    if (memcmp(a_max, b_min, length) >= 0)
sl@0
   844
      return 0;
sl@0
   845
sl@0
   846
    /*
sl@0
   847
     * Merge if a and b are adjacent.  We check for
sl@0
   848
     * adjacency by subtracting one from b_min first.
sl@0
   849
     */
sl@0
   850
    for (j = length - 1; j >= 0 && b_min[j]-- == 0x00; j--)
sl@0
   851
      ;
sl@0
   852
    if (memcmp(a_max, b_min, length) == 0) {
sl@0
   853
      IPAddressOrRange *merged;
sl@0
   854
      if (!make_addressRange(&merged, a_min, b_max, length))
sl@0
   855
	return 0;
sl@0
   856
      sk_IPAddressOrRange_set(aors, i, merged);
sl@0
   857
      sk_IPAddressOrRange_delete(aors, i + 1);
sl@0
   858
      IPAddressOrRange_free(a);
sl@0
   859
      IPAddressOrRange_free(b);
sl@0
   860
      --i;
sl@0
   861
      continue;
sl@0
   862
    }
sl@0
   863
  }
sl@0
   864
sl@0
   865
  return 1;
sl@0
   866
}
sl@0
   867
sl@0
   868
/*
sl@0
   869
 * Whack an IPAddrBlocks extension into canonical form.
sl@0
   870
 */
sl@0
   871
int v3_addr_canonize(IPAddrBlocks *addr)
sl@0
   872
{
sl@0
   873
  int i;
sl@0
   874
  for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
sl@0
   875
    IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
sl@0
   876
    if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges &&
sl@0
   877
	!IPAddressOrRanges_canonize(f->ipAddressChoice->u.addressesOrRanges,
sl@0
   878
				    v3_addr_get_afi(f)))
sl@0
   879
      return 0;
sl@0
   880
  }
sl@0
   881
  sk_IPAddressFamily_sort(addr);
sl@0
   882
  assert(v3_addr_is_canonical(addr));
sl@0
   883
  return 1;
sl@0
   884
}
sl@0
   885
sl@0
   886
/*
sl@0
   887
 * v2i handler for the IPAddrBlocks extension.
sl@0
   888
 */
sl@0
   889
static void *v2i_IPAddrBlocks(struct v3_ext_method *method,
sl@0
   890
			      struct v3_ext_ctx *ctx,
sl@0
   891
			      STACK_OF(CONF_VALUE) *values)
sl@0
   892
{
sl@0
   893
  static const char v4addr_chars[] = "0123456789.";
sl@0
   894
  static const char v6addr_chars[] = "0123456789.:abcdefABCDEF";
sl@0
   895
  IPAddrBlocks *addr = NULL;
sl@0
   896
  char *s = NULL, *t;
sl@0
   897
  int i;
sl@0
   898
  
sl@0
   899
  if ((addr = sk_IPAddressFamily_new(IPAddressFamily_cmp)) == NULL) {
sl@0
   900
    X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
sl@0
   901
    return NULL;
sl@0
   902
  }
sl@0
   903
sl@0
   904
  for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
sl@0
   905
    CONF_VALUE *val = sk_CONF_VALUE_value(values, i);
sl@0
   906
    unsigned char min[ADDR_RAW_BUF_LEN], max[ADDR_RAW_BUF_LEN];
sl@0
   907
    unsigned afi, *safi = NULL, safi_;
sl@0
   908
    const char *addr_chars;
sl@0
   909
    int prefixlen, i1, i2, delim, length;
sl@0
   910
sl@0
   911
    if (       !name_cmp(val->name, "IPv4")) {
sl@0
   912
      afi = IANA_AFI_IPV4;
sl@0
   913
    } else if (!name_cmp(val->name, "IPv6")) {
sl@0
   914
      afi = IANA_AFI_IPV6;
sl@0
   915
    } else if (!name_cmp(val->name, "IPv4-SAFI")) {
sl@0
   916
      afi = IANA_AFI_IPV4;
sl@0
   917
      safi = &safi_;
sl@0
   918
    } else if (!name_cmp(val->name, "IPv6-SAFI")) {
sl@0
   919
      afi = IANA_AFI_IPV6;
sl@0
   920
      safi = &safi_;
sl@0
   921
    } else {
sl@0
   922
      X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_NAME_ERROR);
sl@0
   923
      X509V3_conf_err(val);
sl@0
   924
      goto err;
sl@0
   925
    }
sl@0
   926
sl@0
   927
    switch (afi) {
sl@0
   928
    case IANA_AFI_IPV4:
sl@0
   929
      addr_chars = v4addr_chars;
sl@0
   930
      break;
sl@0
   931
    case IANA_AFI_IPV6:
sl@0
   932
      addr_chars = v6addr_chars;
sl@0
   933
      break;
sl@0
   934
    }
sl@0
   935
sl@0
   936
    length = length_from_afi(afi);
sl@0
   937
sl@0
   938
    /*
sl@0
   939
     * Handle SAFI, if any, and BUF_strdup() so we can null-terminate
sl@0
   940
     * the other input values.
sl@0
   941
     */
sl@0
   942
    if (safi != NULL) {
sl@0
   943
      *safi = strtoul(val->value, &t, 0);
sl@0
   944
      t += strspn(t, " \t");
sl@0
   945
      if (*safi > 0xFF || *t++ != ':') {
sl@0
   946
	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_SAFI);
sl@0
   947
	X509V3_conf_err(val);
sl@0
   948
	goto err;
sl@0
   949
      }
sl@0
   950
      t += strspn(t, " \t");
sl@0
   951
      s = BUF_strdup(t);
sl@0
   952
    } else {
sl@0
   953
      s = BUF_strdup(val->value);
sl@0
   954
    }
sl@0
   955
    if (s == NULL) {
sl@0
   956
      X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
sl@0
   957
      goto err;
sl@0
   958
    }
sl@0
   959
sl@0
   960
    /*
sl@0
   961
     * Check for inheritance.  Not worth additional complexity to
sl@0
   962
     * optimize this (seldom-used) case.
sl@0
   963
     */
sl@0
   964
    if (!strcmp(s, "inherit")) {
sl@0
   965
      if (!v3_addr_add_inherit(addr, afi, safi)) {
sl@0
   966
	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_INHERITANCE);
sl@0
   967
	X509V3_conf_err(val);
sl@0
   968
	goto err;
sl@0
   969
      }
sl@0
   970
      OPENSSL_free(s);
sl@0
   971
      s = NULL;
sl@0
   972
      continue;
sl@0
   973
    }
sl@0
   974
sl@0
   975
    i1 = strspn(s, addr_chars);
sl@0
   976
    i2 = i1 + strspn(s + i1, " \t");
sl@0
   977
    delim = s[i2++];
sl@0
   978
    s[i1] = '\0';
sl@0
   979
sl@0
   980
    if (a2i_ipadd(min, s) != length) {
sl@0
   981
      X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_IPADDRESS);
sl@0
   982
      X509V3_conf_err(val);
sl@0
   983
      goto err;
sl@0
   984
    }
sl@0
   985
sl@0
   986
    switch (delim) {
sl@0
   987
    case '/':
sl@0
   988
      prefixlen = (int) strtoul(s + i2, &t, 10);
sl@0
   989
      if (t == s + i2 || *t != '\0') {
sl@0
   990
	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR);
sl@0
   991
	X509V3_conf_err(val);
sl@0
   992
	goto err;
sl@0
   993
      }
sl@0
   994
      if (!v3_addr_add_prefix(addr, afi, safi, min, prefixlen)) {
sl@0
   995
	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
sl@0
   996
	goto err;
sl@0
   997
      }
sl@0
   998
      break;
sl@0
   999
    case '-':
sl@0
  1000
      i1 = i2 + strspn(s + i2, " \t");
sl@0
  1001
      i2 = i1 + strspn(s + i1, addr_chars);
sl@0
  1002
      if (i1 == i2 || s[i2] != '\0') {
sl@0
  1003
	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR);
sl@0
  1004
	X509V3_conf_err(val);
sl@0
  1005
	goto err;
sl@0
  1006
      }
sl@0
  1007
      if (a2i_ipadd(max, s + i1) != length) {
sl@0
  1008
	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_IPADDRESS);
sl@0
  1009
	X509V3_conf_err(val);
sl@0
  1010
	goto err;
sl@0
  1011
      }
sl@0
  1012
      if (!v3_addr_add_range(addr, afi, safi, min, max)) {
sl@0
  1013
	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
sl@0
  1014
	goto err;
sl@0
  1015
      }
sl@0
  1016
      break;
sl@0
  1017
    case '\0':
sl@0
  1018
      if (!v3_addr_add_prefix(addr, afi, safi, min, length * 8)) {
sl@0
  1019
	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
sl@0
  1020
	goto err;
sl@0
  1021
      }
sl@0
  1022
      break;
sl@0
  1023
    default:
sl@0
  1024
      X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR);
sl@0
  1025
      X509V3_conf_err(val);
sl@0
  1026
      goto err;
sl@0
  1027
    }
sl@0
  1028
sl@0
  1029
    OPENSSL_free(s);
sl@0
  1030
    s = NULL;
sl@0
  1031
  }
sl@0
  1032
sl@0
  1033
  /*
sl@0
  1034
   * Canonize the result, then we're done.
sl@0
  1035
   */
sl@0
  1036
  if (!v3_addr_canonize(addr))
sl@0
  1037
    goto err;    
sl@0
  1038
  return addr;
sl@0
  1039
sl@0
  1040
 err:
sl@0
  1041
  OPENSSL_free(s);
sl@0
  1042
  sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free);
sl@0
  1043
  return NULL;
sl@0
  1044
}
sl@0
  1045
sl@0
  1046
/*
sl@0
  1047
 * OpenSSL dispatch
sl@0
  1048
 */
sl@0
  1049
const X509V3_EXT_METHOD v3_addr = {
sl@0
  1050
  NID_sbgp_ipAddrBlock,		/* nid */
sl@0
  1051
  0,				/* flags */
sl@0
  1052
  ASN1_ITEM_ref(IPAddrBlocks),	/* template */
sl@0
  1053
  0, 0, 0, 0,			/* old functions, ignored */
sl@0
  1054
  0,				/* i2s */
sl@0
  1055
  0,				/* s2i */
sl@0
  1056
  0,				/* i2v */
sl@0
  1057
  v2i_IPAddrBlocks,		/* v2i */
sl@0
  1058
  i2r_IPAddrBlocks,		/* i2r */
sl@0
  1059
  0,				/* r2i */
sl@0
  1060
  NULL				/* extension-specific data */
sl@0
  1061
};
sl@0
  1062
sl@0
  1063
/*
sl@0
  1064
 * Figure out whether extension sues inheritance.
sl@0
  1065
 */
sl@0
  1066
int v3_addr_inherits(IPAddrBlocks *addr)
sl@0
  1067
{
sl@0
  1068
  int i;
sl@0
  1069
  if (addr == NULL)
sl@0
  1070
    return 0;
sl@0
  1071
  for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
sl@0
  1072
    IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
sl@0
  1073
    if (f->ipAddressChoice->type == IPAddressChoice_inherit)
sl@0
  1074
      return 1;
sl@0
  1075
  }
sl@0
  1076
  return 0;
sl@0
  1077
}
sl@0
  1078
sl@0
  1079
/*
sl@0
  1080
 * Figure out whether parent contains child.
sl@0
  1081
 */
sl@0
  1082
static int addr_contains(IPAddressOrRanges *parent,
sl@0
  1083
			 IPAddressOrRanges *child,
sl@0
  1084
			 int length)
sl@0
  1085
{
sl@0
  1086
  unsigned char p_min[ADDR_RAW_BUF_LEN], p_max[ADDR_RAW_BUF_LEN];
sl@0
  1087
  unsigned char c_min[ADDR_RAW_BUF_LEN], c_max[ADDR_RAW_BUF_LEN];
sl@0
  1088
  int p, c;
sl@0
  1089
sl@0
  1090
  if (child == NULL || parent == child)
sl@0
  1091
    return 1;
sl@0
  1092
  if (parent == NULL)
sl@0
  1093
    return 0;
sl@0
  1094
sl@0
  1095
  p = 0;
sl@0
  1096
  for (c = 0; c < sk_IPAddressOrRange_num(child); c++) {
sl@0
  1097
    extract_min_max(sk_IPAddressOrRange_value(child, c),
sl@0
  1098
		    c_min, c_max, length);
sl@0
  1099
    for (;; p++) {
sl@0
  1100
      if (p >= sk_IPAddressOrRange_num(parent))
sl@0
  1101
	return 0;
sl@0
  1102
      extract_min_max(sk_IPAddressOrRange_value(parent, p),
sl@0
  1103
		      p_min, p_max, length);
sl@0
  1104
      if (memcmp(p_max, c_max, length) < 0)
sl@0
  1105
	continue;
sl@0
  1106
      if (memcmp(p_min, c_min, length) > 0)
sl@0
  1107
	return 0;
sl@0
  1108
      break;
sl@0
  1109
    }
sl@0
  1110
  }
sl@0
  1111
sl@0
  1112
  return 1;
sl@0
  1113
}
sl@0
  1114
sl@0
  1115
/*
sl@0
  1116
 * Test whether a is a subset of b.
sl@0
  1117
 */
sl@0
  1118
int v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b)
sl@0
  1119
{
sl@0
  1120
  int i;
sl@0
  1121
  if (a == NULL || a == b)
sl@0
  1122
    return 1;
sl@0
  1123
  if (b == NULL || v3_addr_inherits(a) || v3_addr_inherits(b))
sl@0
  1124
    return 0;
sl@0
  1125
  sk_IPAddressFamily_set_cmp_func(b, IPAddressFamily_cmp);
sl@0
  1126
  for (i = 0; i < sk_IPAddressFamily_num(a); i++) {
sl@0
  1127
    IPAddressFamily *fa = sk_IPAddressFamily_value(a, i);
sl@0
  1128
    int j = sk_IPAddressFamily_find(b, fa);
sl@0
  1129
    IPAddressFamily *fb = sk_IPAddressFamily_value(b, j);
sl@0
  1130
    if (!addr_contains(fb->ipAddressChoice->u.addressesOrRanges, 
sl@0
  1131
		       fa->ipAddressChoice->u.addressesOrRanges,
sl@0
  1132
		       length_from_afi(v3_addr_get_afi(fb))))
sl@0
  1133
      return 0;
sl@0
  1134
  }
sl@0
  1135
  return 1;
sl@0
  1136
}
sl@0
  1137
sl@0
  1138
/*
sl@0
  1139
 * Validation error handling via callback.
sl@0
  1140
 */
sl@0
  1141
#define validation_err(_err_)		\
sl@0
  1142
  do {					\
sl@0
  1143
    if (ctx != NULL) {			\
sl@0
  1144
      ctx->error = _err_;		\
sl@0
  1145
      ctx->error_depth = i;		\
sl@0
  1146
      ctx->current_cert = x;		\
sl@0
  1147
      ret = ctx->verify_cb(0, ctx);	\
sl@0
  1148
    } else {				\
sl@0
  1149
      ret = 0;				\
sl@0
  1150
    }					\
sl@0
  1151
    if (!ret)				\
sl@0
  1152
      goto done;			\
sl@0
  1153
  } while (0)
sl@0
  1154
sl@0
  1155
/*
sl@0
  1156
 * Core code for RFC 3779 2.3 path validation.
sl@0
  1157
 */
sl@0
  1158
static int v3_addr_validate_path_internal(X509_STORE_CTX *ctx,
sl@0
  1159
					  STACK_OF(X509) *chain,
sl@0
  1160
					  IPAddrBlocks *ext)
sl@0
  1161
{
sl@0
  1162
  IPAddrBlocks *child = NULL;
sl@0
  1163
  int i, j, ret = 1;
sl@0
  1164
  X509 *x = NULL;
sl@0
  1165
sl@0
  1166
  assert(chain != NULL && sk_X509_num(chain) > 0);
sl@0
  1167
  assert(ctx != NULL || ext != NULL);
sl@0
  1168
  assert(ctx == NULL || ctx->verify_cb != NULL);
sl@0
  1169
sl@0
  1170
  /*
sl@0
  1171
   * Figure out where to start.  If we don't have an extension to
sl@0
  1172
   * check, we're done.  Otherwise, check canonical form and
sl@0
  1173
   * set up for walking up the chain.
sl@0
  1174
   */
sl@0
  1175
  if (ext != NULL) {
sl@0
  1176
    i = -1;
sl@0
  1177
  } else {
sl@0
  1178
    i = 0;
sl@0
  1179
    x = sk_X509_value(chain, i);
sl@0
  1180
    assert(x != NULL);
sl@0
  1181
    if ((ext = x->rfc3779_addr) == NULL)
sl@0
  1182
      goto done;
sl@0
  1183
  }
sl@0
  1184
  if (!v3_addr_is_canonical(ext))
sl@0
  1185
    validation_err(X509_V_ERR_INVALID_EXTENSION);
sl@0
  1186
  sk_IPAddressFamily_set_cmp_func(ext, IPAddressFamily_cmp);
sl@0
  1187
  if ((child = sk_IPAddressFamily_dup(ext)) == NULL) {
sl@0
  1188
    X509V3err(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL, ERR_R_MALLOC_FAILURE);
sl@0
  1189
    ret = 0;
sl@0
  1190
    goto done;
sl@0
  1191
  }
sl@0
  1192
sl@0
  1193
  /*
sl@0
  1194
   * Now walk up the chain.  No cert may list resources that its
sl@0
  1195
   * parent doesn't list.
sl@0
  1196
   */
sl@0
  1197
  for (i++; i < sk_X509_num(chain); i++) {
sl@0
  1198
    x = sk_X509_value(chain, i);
sl@0
  1199
    assert(x != NULL);
sl@0
  1200
    if (!v3_addr_is_canonical(x->rfc3779_addr))
sl@0
  1201
      validation_err(X509_V_ERR_INVALID_EXTENSION);
sl@0
  1202
    if (x->rfc3779_addr == NULL) {
sl@0
  1203
      for (j = 0; j < sk_IPAddressFamily_num(child); j++) {
sl@0
  1204
	IPAddressFamily *fc = sk_IPAddressFamily_value(child, j);
sl@0
  1205
	if (fc->ipAddressChoice->type != IPAddressChoice_inherit) {
sl@0
  1206
	  validation_err(X509_V_ERR_UNNESTED_RESOURCE);
sl@0
  1207
	  break;
sl@0
  1208
	}
sl@0
  1209
      }
sl@0
  1210
      continue;
sl@0
  1211
    }
sl@0
  1212
    sk_IPAddressFamily_set_cmp_func(x->rfc3779_addr, IPAddressFamily_cmp);
sl@0
  1213
    for (j = 0; j < sk_IPAddressFamily_num(child); j++) {
sl@0
  1214
      IPAddressFamily *fc = sk_IPAddressFamily_value(child, j);
sl@0
  1215
      int k = sk_IPAddressFamily_find(x->rfc3779_addr, fc);
sl@0
  1216
      IPAddressFamily *fp = sk_IPAddressFamily_value(x->rfc3779_addr, k);
sl@0
  1217
      if (fp == NULL) {
sl@0
  1218
	if (fc->ipAddressChoice->type == IPAddressChoice_addressesOrRanges) {
sl@0
  1219
	  validation_err(X509_V_ERR_UNNESTED_RESOURCE);
sl@0
  1220
	  break;
sl@0
  1221
	}
sl@0
  1222
	continue;
sl@0
  1223
      }
sl@0
  1224
      if (fp->ipAddressChoice->type == IPAddressChoice_addressesOrRanges) {
sl@0
  1225
	if (fc->ipAddressChoice->type == IPAddressChoice_inherit ||
sl@0
  1226
	    addr_contains(fp->ipAddressChoice->u.addressesOrRanges, 
sl@0
  1227
			  fc->ipAddressChoice->u.addressesOrRanges,
sl@0
  1228
			  length_from_afi(v3_addr_get_afi(fc))))
sl@0
  1229
	  sk_IPAddressFamily_set(child, j, fp);
sl@0
  1230
	else
sl@0
  1231
	  validation_err(X509_V_ERR_UNNESTED_RESOURCE);
sl@0
  1232
      }
sl@0
  1233
    }
sl@0
  1234
  }
sl@0
  1235
sl@0
  1236
  /*
sl@0
  1237
   * Trust anchor can't inherit.
sl@0
  1238
   */
sl@0
  1239
  if (x->rfc3779_addr != NULL) {
sl@0
  1240
    for (j = 0; j < sk_IPAddressFamily_num(x->rfc3779_addr); j++) {
sl@0
  1241
      IPAddressFamily *fp = sk_IPAddressFamily_value(x->rfc3779_addr, j);
sl@0
  1242
      if (fp->ipAddressChoice->type == IPAddressChoice_inherit &&
sl@0
  1243
	  sk_IPAddressFamily_find(child, fp) >= 0)
sl@0
  1244
	validation_err(X509_V_ERR_UNNESTED_RESOURCE);
sl@0
  1245
    }
sl@0
  1246
  }
sl@0
  1247
sl@0
  1248
 done:
sl@0
  1249
  sk_IPAddressFamily_free(child);
sl@0
  1250
  return ret;
sl@0
  1251
}
sl@0
  1252
sl@0
  1253
#undef validation_err
sl@0
  1254
sl@0
  1255
/*
sl@0
  1256
 * RFC 3779 2.3 path validation -- called from X509_verify_cert().
sl@0
  1257
 */
sl@0
  1258
int v3_addr_validate_path(X509_STORE_CTX *ctx)
sl@0
  1259
{
sl@0
  1260
  return v3_addr_validate_path_internal(ctx, ctx->chain, NULL);
sl@0
  1261
}
sl@0
  1262
sl@0
  1263
/*
sl@0
  1264
 * RFC 3779 2.3 path validation of an extension.
sl@0
  1265
 * Test whether chain covers extension.
sl@0
  1266
 */
sl@0
  1267
int v3_addr_validate_resource_set(STACK_OF(X509) *chain,
sl@0
  1268
				  IPAddrBlocks *ext,
sl@0
  1269
				  int allow_inheritance)
sl@0
  1270
{
sl@0
  1271
  if (ext == NULL)
sl@0
  1272
    return 1;
sl@0
  1273
  if (chain == NULL || sk_X509_num(chain) == 0)
sl@0
  1274
    return 0;
sl@0
  1275
  if (!allow_inheritance && v3_addr_inherits(ext))
sl@0
  1276
    return 0;
sl@0
  1277
  return v3_addr_validate_path_internal(NULL, chain, ext);
sl@0
  1278
}
sl@0
  1279
sl@0
  1280
#endif /* OPENSSL_NO_RFC3779 */