1167612Ssimon/* 2167612Ssimon * Contributed to the OpenSSL Project by the American Registry for 3167612Ssimon * Internet Numbers ("ARIN"). 4167612Ssimon */ 5167612Ssimon/* ==================================================================== 6167612Ssimon * Copyright (c) 2006 The OpenSSL Project. All rights reserved. 7167612Ssimon * 8167612Ssimon * Redistribution and use in source and binary forms, with or without 9167612Ssimon * modification, are permitted provided that the following conditions 10167612Ssimon * are met: 11167612Ssimon * 12167612Ssimon * 1. Redistributions of source code must retain the above copyright 13296465Sdelphij * notice, this list of conditions and the following disclaimer. 14167612Ssimon * 15167612Ssimon * 2. Redistributions in binary form must reproduce the above copyright 16167612Ssimon * notice, this list of conditions and the following disclaimer in 17167612Ssimon * the documentation and/or other materials provided with the 18167612Ssimon * distribution. 19167612Ssimon * 20167612Ssimon * 3. All advertising materials mentioning features or use of this 21167612Ssimon * software must display the following acknowledgment: 22167612Ssimon * "This product includes software developed by the OpenSSL Project 23167612Ssimon * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24167612Ssimon * 25167612Ssimon * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26167612Ssimon * endorse or promote products derived from this software without 27167612Ssimon * prior written permission. For written permission, please contact 28167612Ssimon * licensing@OpenSSL.org. 29167612Ssimon * 30167612Ssimon * 5. Products derived from this software may not be called "OpenSSL" 31167612Ssimon * nor may "OpenSSL" appear in their names without prior written 32167612Ssimon * permission of the OpenSSL Project. 33167612Ssimon * 34167612Ssimon * 6. Redistributions of any form whatsoever must retain the following 35167612Ssimon * acknowledgment: 36167612Ssimon * "This product includes software developed by the OpenSSL Project 37167612Ssimon * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38167612Ssimon * 39167612Ssimon * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40167612Ssimon * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41167612Ssimon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42167612Ssimon * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43167612Ssimon * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44167612Ssimon * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45167612Ssimon * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46167612Ssimon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47167612Ssimon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48167612Ssimon * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49167612Ssimon * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50167612Ssimon * OF THE POSSIBILITY OF SUCH DAMAGE. 51167612Ssimon * ==================================================================== 52167612Ssimon * 53167612Ssimon * This product includes cryptographic software written by Eric Young 54167612Ssimon * (eay@cryptsoft.com). This product includes software written by Tim 55167612Ssimon * Hudson (tjh@cryptsoft.com). 56167612Ssimon */ 57167612Ssimon 58167612Ssimon/* 59167612Ssimon * Implementation of RFC 3779 section 2.2. 60167612Ssimon */ 61167612Ssimon 62167612Ssimon#include <stdio.h> 63167612Ssimon#include <stdlib.h> 64194206Ssimon 65167612Ssimon#include "cryptlib.h" 66167612Ssimon#include <openssl/conf.h> 67167612Ssimon#include <openssl/asn1.h> 68167612Ssimon#include <openssl/asn1t.h> 69167612Ssimon#include <openssl/buffer.h> 70167612Ssimon#include <openssl/x509v3.h> 71167612Ssimon 72167612Ssimon#ifndef OPENSSL_NO_RFC3779 73167612Ssimon 74167612Ssimon/* 75167612Ssimon * OpenSSL ASN.1 template translation of RFC 3779 2.2.3. 76167612Ssimon */ 77167612Ssimon 78167612SsimonASN1_SEQUENCE(IPAddressRange) = { 79167612Ssimon ASN1_SIMPLE(IPAddressRange, min, ASN1_BIT_STRING), 80167612Ssimon ASN1_SIMPLE(IPAddressRange, max, ASN1_BIT_STRING) 81167612Ssimon} ASN1_SEQUENCE_END(IPAddressRange) 82167612Ssimon 83167612SsimonASN1_CHOICE(IPAddressOrRange) = { 84167612Ssimon ASN1_SIMPLE(IPAddressOrRange, u.addressPrefix, ASN1_BIT_STRING), 85167612Ssimon ASN1_SIMPLE(IPAddressOrRange, u.addressRange, IPAddressRange) 86167612Ssimon} ASN1_CHOICE_END(IPAddressOrRange) 87167612Ssimon 88167612SsimonASN1_CHOICE(IPAddressChoice) = { 89167612Ssimon ASN1_SIMPLE(IPAddressChoice, u.inherit, ASN1_NULL), 90167612Ssimon ASN1_SEQUENCE_OF(IPAddressChoice, u.addressesOrRanges, IPAddressOrRange) 91167612Ssimon} ASN1_CHOICE_END(IPAddressChoice) 92167612Ssimon 93167612SsimonASN1_SEQUENCE(IPAddressFamily) = { 94167612Ssimon ASN1_SIMPLE(IPAddressFamily, addressFamily, ASN1_OCTET_STRING), 95167612Ssimon ASN1_SIMPLE(IPAddressFamily, ipAddressChoice, IPAddressChoice) 96167612Ssimon} ASN1_SEQUENCE_END(IPAddressFamily) 97167612Ssimon 98296465SdelphijASN1_ITEM_TEMPLATE(IPAddrBlocks) = 99167612Ssimon ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, 100296465Sdelphij IPAddrBlocks, IPAddressFamily) 101167612SsimonASN1_ITEM_TEMPLATE_END(IPAddrBlocks) 102167612Ssimon 103167612SsimonIMPLEMENT_ASN1_FUNCTIONS(IPAddressRange) 104167612SsimonIMPLEMENT_ASN1_FUNCTIONS(IPAddressOrRange) 105167612SsimonIMPLEMENT_ASN1_FUNCTIONS(IPAddressChoice) 106167612SsimonIMPLEMENT_ASN1_FUNCTIONS(IPAddressFamily) 107167612Ssimon 108167612Ssimon/* 109167612Ssimon * How much buffer space do we need for a raw address? 110167612Ssimon */ 111296465Sdelphij# define ADDR_RAW_BUF_LEN 16 112167612Ssimon 113167612Ssimon/* 114167612Ssimon * What's the address length associated with this AFI? 115167612Ssimon */ 116167612Ssimonstatic int length_from_afi(const unsigned afi) 117167612Ssimon{ 118296465Sdelphij switch (afi) { 119296465Sdelphij case IANA_AFI_IPV4: 120296465Sdelphij return 4; 121296465Sdelphij case IANA_AFI_IPV6: 122296465Sdelphij return 16; 123296465Sdelphij default: 124296465Sdelphij return 0; 125296465Sdelphij } 126167612Ssimon} 127167612Ssimon 128167612Ssimon/* 129167612Ssimon * Extract the AFI from an IPAddressFamily. 130167612Ssimon */ 131194206Ssimonunsigned int v3_addr_get_afi(const IPAddressFamily *f) 132167612Ssimon{ 133296465Sdelphij return ((f != NULL && 134296465Sdelphij f->addressFamily != NULL && f->addressFamily->data != NULL) 135296465Sdelphij ? ((f->addressFamily->data[0] << 8) | (f->addressFamily->data[1])) 136296465Sdelphij : 0); 137167612Ssimon} 138167612Ssimon 139167612Ssimon/* 140167612Ssimon * Expand the bitstring form of an address into a raw byte array. 141167612Ssimon * At the moment this is coded for simplicity, not speed. 142167612Ssimon */ 143237998Sjkimstatic int addr_expand(unsigned char *addr, 144296465Sdelphij const ASN1_BIT_STRING *bs, 145296465Sdelphij const int length, const unsigned char fill) 146167612Ssimon{ 147296465Sdelphij if (bs->length < 0 || bs->length > length) 148296465Sdelphij return 0; 149296465Sdelphij if (bs->length > 0) { 150296465Sdelphij memcpy(addr, bs->data, bs->length); 151296465Sdelphij if ((bs->flags & 7) != 0) { 152296465Sdelphij unsigned char mask = 0xFF >> (8 - (bs->flags & 7)); 153296465Sdelphij if (fill == 0) 154296465Sdelphij addr[bs->length - 1] &= ~mask; 155296465Sdelphij else 156296465Sdelphij addr[bs->length - 1] |= mask; 157296465Sdelphij } 158167612Ssimon } 159296465Sdelphij memset(addr + bs->length, fill, length - bs->length); 160296465Sdelphij return 1; 161167612Ssimon} 162167612Ssimon 163167612Ssimon/* 164167612Ssimon * Extract the prefix length from a bitstring. 165167612Ssimon */ 166296465Sdelphij# define addr_prefixlen(bs) ((int) ((bs)->length * 8 - ((bs)->flags & 7))) 167167612Ssimon 168167612Ssimon/* 169167612Ssimon * i2r handler for one address bitstring. 170167612Ssimon */ 171167612Ssimonstatic int i2r_address(BIO *out, 172296465Sdelphij const unsigned afi, 173296465Sdelphij const unsigned char fill, const ASN1_BIT_STRING *bs) 174167612Ssimon{ 175296465Sdelphij unsigned char addr[ADDR_RAW_BUF_LEN]; 176296465Sdelphij int i, n; 177167612Ssimon 178296465Sdelphij if (bs->length < 0) 179296465Sdelphij return 0; 180296465Sdelphij switch (afi) { 181296465Sdelphij case IANA_AFI_IPV4: 182296465Sdelphij if (!addr_expand(addr, bs, 4, fill)) 183296465Sdelphij return 0; 184296465Sdelphij BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]); 185296465Sdelphij break; 186296465Sdelphij case IANA_AFI_IPV6: 187296465Sdelphij if (!addr_expand(addr, bs, 16, fill)) 188296465Sdelphij return 0; 189296465Sdelphij for (n = 16; n > 1 && addr[n - 1] == 0x00 && addr[n - 2] == 0x00; 190296465Sdelphij n -= 2) ; 191296465Sdelphij for (i = 0; i < n; i += 2) 192296465Sdelphij BIO_printf(out, "%x%s", (addr[i] << 8) | addr[i + 1], 193296465Sdelphij (i < 14 ? ":" : "")); 194296465Sdelphij if (i < 16) 195296465Sdelphij BIO_puts(out, ":"); 196296465Sdelphij if (i == 0) 197296465Sdelphij BIO_puts(out, ":"); 198296465Sdelphij break; 199296465Sdelphij default: 200296465Sdelphij for (i = 0; i < bs->length; i++) 201296465Sdelphij BIO_printf(out, "%s%02x", (i > 0 ? ":" : ""), bs->data[i]); 202296465Sdelphij BIO_printf(out, "[%d]", (int)(bs->flags & 7)); 203296465Sdelphij break; 204296465Sdelphij } 205296465Sdelphij return 1; 206167612Ssimon} 207167612Ssimon 208167612Ssimon/* 209167612Ssimon * i2r handler for a sequence of addresses and ranges. 210167612Ssimon */ 211167612Ssimonstatic int i2r_IPAddressOrRanges(BIO *out, 212296465Sdelphij const int indent, 213296465Sdelphij const IPAddressOrRanges *aors, 214296465Sdelphij const unsigned afi) 215167612Ssimon{ 216296465Sdelphij int i; 217296465Sdelphij for (i = 0; i < sk_IPAddressOrRange_num(aors); i++) { 218296465Sdelphij const IPAddressOrRange *aor = sk_IPAddressOrRange_value(aors, i); 219296465Sdelphij BIO_printf(out, "%*s", indent, ""); 220296465Sdelphij switch (aor->type) { 221296465Sdelphij case IPAddressOrRange_addressPrefix: 222296465Sdelphij if (!i2r_address(out, afi, 0x00, aor->u.addressPrefix)) 223296465Sdelphij return 0; 224296465Sdelphij BIO_printf(out, "/%d\n", addr_prefixlen(aor->u.addressPrefix)); 225296465Sdelphij continue; 226296465Sdelphij case IPAddressOrRange_addressRange: 227296465Sdelphij if (!i2r_address(out, afi, 0x00, aor->u.addressRange->min)) 228296465Sdelphij return 0; 229296465Sdelphij BIO_puts(out, "-"); 230296465Sdelphij if (!i2r_address(out, afi, 0xFF, aor->u.addressRange->max)) 231296465Sdelphij return 0; 232296465Sdelphij BIO_puts(out, "\n"); 233296465Sdelphij continue; 234296465Sdelphij } 235167612Ssimon } 236296465Sdelphij return 1; 237167612Ssimon} 238167612Ssimon 239167612Ssimon/* 240167612Ssimon * i2r handler for an IPAddrBlocks extension. 241167612Ssimon */ 242167612Ssimonstatic int i2r_IPAddrBlocks(X509V3_EXT_METHOD *method, 243296465Sdelphij void *ext, BIO *out, int indent) 244167612Ssimon{ 245296465Sdelphij const IPAddrBlocks *addr = ext; 246296465Sdelphij int i; 247296465Sdelphij for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { 248296465Sdelphij IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); 249296465Sdelphij const unsigned int afi = v3_addr_get_afi(f); 250296465Sdelphij switch (afi) { 251296465Sdelphij case IANA_AFI_IPV4: 252296465Sdelphij BIO_printf(out, "%*sIPv4", indent, ""); 253296465Sdelphij break; 254296465Sdelphij case IANA_AFI_IPV6: 255296465Sdelphij BIO_printf(out, "%*sIPv6", indent, ""); 256296465Sdelphij break; 257296465Sdelphij default: 258296465Sdelphij BIO_printf(out, "%*sUnknown AFI %u", indent, "", afi); 259296465Sdelphij break; 260296465Sdelphij } 261296465Sdelphij if (f->addressFamily->length > 2) { 262296465Sdelphij switch (f->addressFamily->data[2]) { 263296465Sdelphij case 1: 264296465Sdelphij BIO_puts(out, " (Unicast)"); 265296465Sdelphij break; 266296465Sdelphij case 2: 267296465Sdelphij BIO_puts(out, " (Multicast)"); 268296465Sdelphij break; 269296465Sdelphij case 3: 270296465Sdelphij BIO_puts(out, " (Unicast/Multicast)"); 271296465Sdelphij break; 272296465Sdelphij case 4: 273296465Sdelphij BIO_puts(out, " (MPLS)"); 274296465Sdelphij break; 275296465Sdelphij case 64: 276296465Sdelphij BIO_puts(out, " (Tunnel)"); 277296465Sdelphij break; 278296465Sdelphij case 65: 279296465Sdelphij BIO_puts(out, " (VPLS)"); 280296465Sdelphij break; 281296465Sdelphij case 66: 282296465Sdelphij BIO_puts(out, " (BGP MDT)"); 283296465Sdelphij break; 284296465Sdelphij case 128: 285296465Sdelphij BIO_puts(out, " (MPLS-labeled VPN)"); 286296465Sdelphij break; 287296465Sdelphij default: 288296465Sdelphij BIO_printf(out, " (Unknown SAFI %u)", 289296465Sdelphij (unsigned)f->addressFamily->data[2]); 290296465Sdelphij break; 291296465Sdelphij } 292296465Sdelphij } 293296465Sdelphij switch (f->ipAddressChoice->type) { 294296465Sdelphij case IPAddressChoice_inherit: 295296465Sdelphij BIO_puts(out, ": inherit\n"); 296296465Sdelphij break; 297296465Sdelphij case IPAddressChoice_addressesOrRanges: 298296465Sdelphij BIO_puts(out, ":\n"); 299296465Sdelphij if (!i2r_IPAddressOrRanges(out, 300296465Sdelphij indent + 2, 301296465Sdelphij f->ipAddressChoice-> 302296465Sdelphij u.addressesOrRanges, afi)) 303296465Sdelphij return 0; 304296465Sdelphij break; 305296465Sdelphij } 306167612Ssimon } 307296465Sdelphij return 1; 308167612Ssimon} 309167612Ssimon 310167612Ssimon/* 311167612Ssimon * Sort comparison function for a sequence of IPAddressOrRange 312167612Ssimon * elements. 313237998Sjkim * 314237998Sjkim * There's no sane answer we can give if addr_expand() fails, and an 315237998Sjkim * assertion failure on externally supplied data is seriously uncool, 316237998Sjkim * so we just arbitrarily declare that if given invalid inputs this 317237998Sjkim * function returns -1. If this messes up your preferred sort order 318237998Sjkim * for garbage input, tough noogies. 319167612Ssimon */ 320167612Ssimonstatic int IPAddressOrRange_cmp(const IPAddressOrRange *a, 321296465Sdelphij const IPAddressOrRange *b, const int length) 322167612Ssimon{ 323296465Sdelphij unsigned char addr_a[ADDR_RAW_BUF_LEN], addr_b[ADDR_RAW_BUF_LEN]; 324296465Sdelphij int prefixlen_a = 0; 325296465Sdelphij int prefixlen_b = 0; 326296465Sdelphij int r; 327167612Ssimon 328296465Sdelphij switch (a->type) { 329296465Sdelphij case IPAddressOrRange_addressPrefix: 330296465Sdelphij if (!addr_expand(addr_a, a->u.addressPrefix, length, 0x00)) 331296465Sdelphij return -1; 332296465Sdelphij prefixlen_a = addr_prefixlen(a->u.addressPrefix); 333296465Sdelphij break; 334296465Sdelphij case IPAddressOrRange_addressRange: 335296465Sdelphij if (!addr_expand(addr_a, a->u.addressRange->min, length, 0x00)) 336296465Sdelphij return -1; 337296465Sdelphij prefixlen_a = length * 8; 338296465Sdelphij break; 339296465Sdelphij } 340167612Ssimon 341296465Sdelphij switch (b->type) { 342296465Sdelphij case IPAddressOrRange_addressPrefix: 343296465Sdelphij if (!addr_expand(addr_b, b->u.addressPrefix, length, 0x00)) 344296465Sdelphij return -1; 345296465Sdelphij prefixlen_b = addr_prefixlen(b->u.addressPrefix); 346296465Sdelphij break; 347296465Sdelphij case IPAddressOrRange_addressRange: 348296465Sdelphij if (!addr_expand(addr_b, b->u.addressRange->min, length, 0x00)) 349296465Sdelphij return -1; 350296465Sdelphij prefixlen_b = length * 8; 351296465Sdelphij break; 352296465Sdelphij } 353167612Ssimon 354296465Sdelphij if ((r = memcmp(addr_a, addr_b, length)) != 0) 355296465Sdelphij return r; 356296465Sdelphij else 357296465Sdelphij return prefixlen_a - prefixlen_b; 358167612Ssimon} 359167612Ssimon 360167612Ssimon/* 361167612Ssimon * IPv4-specific closure over IPAddressOrRange_cmp, since sk_sort() 362167612Ssimon * comparision routines are only allowed two arguments. 363167612Ssimon */ 364296465Sdelphijstatic int v4IPAddressOrRange_cmp(const IPAddressOrRange *const *a, 365296465Sdelphij const IPAddressOrRange *const *b) 366167612Ssimon{ 367296465Sdelphij return IPAddressOrRange_cmp(*a, *b, 4); 368167612Ssimon} 369167612Ssimon 370167612Ssimon/* 371167612Ssimon * IPv6-specific closure over IPAddressOrRange_cmp, since sk_sort() 372167612Ssimon * comparision routines are only allowed two arguments. 373167612Ssimon */ 374296465Sdelphijstatic int v6IPAddressOrRange_cmp(const IPAddressOrRange *const *a, 375296465Sdelphij const IPAddressOrRange *const *b) 376167612Ssimon{ 377296465Sdelphij return IPAddressOrRange_cmp(*a, *b, 16); 378167612Ssimon} 379167612Ssimon 380167612Ssimon/* 381167612Ssimon * Calculate whether a range collapses to a prefix. 382167612Ssimon * See last paragraph of RFC 3779 2.2.3.7. 383167612Ssimon */ 384167612Ssimonstatic int range_should_be_prefix(const unsigned char *min, 385296465Sdelphij const unsigned char *max, const int length) 386167612Ssimon{ 387296465Sdelphij unsigned char mask; 388296465Sdelphij int i, j; 389167612Ssimon 390296465Sdelphij OPENSSL_assert(memcmp(min, max, length) <= 0); 391296465Sdelphij for (i = 0; i < length && min[i] == max[i]; i++) ; 392296465Sdelphij for (j = length - 1; j >= 0 && min[j] == 0x00 && max[j] == 0xFF; j--) ; 393296465Sdelphij if (i < j) 394296465Sdelphij return -1; 395296465Sdelphij if (i > j) 396296465Sdelphij return i * 8; 397296465Sdelphij mask = min[i] ^ max[i]; 398296465Sdelphij switch (mask) { 399296465Sdelphij case 0x01: 400296465Sdelphij j = 7; 401296465Sdelphij break; 402296465Sdelphij case 0x03: 403296465Sdelphij j = 6; 404296465Sdelphij break; 405296465Sdelphij case 0x07: 406296465Sdelphij j = 5; 407296465Sdelphij break; 408296465Sdelphij case 0x0F: 409296465Sdelphij j = 4; 410296465Sdelphij break; 411296465Sdelphij case 0x1F: 412296465Sdelphij j = 3; 413296465Sdelphij break; 414296465Sdelphij case 0x3F: 415296465Sdelphij j = 2; 416296465Sdelphij break; 417296465Sdelphij case 0x7F: 418296465Sdelphij j = 1; 419296465Sdelphij break; 420296465Sdelphij default: 421296465Sdelphij return -1; 422296465Sdelphij } 423296465Sdelphij if ((min[i] & mask) != 0 || (max[i] & mask) != mask) 424296465Sdelphij return -1; 425296465Sdelphij else 426296465Sdelphij return i * 8 + j; 427167612Ssimon} 428167612Ssimon 429167612Ssimon/* 430167612Ssimon * Construct a prefix. 431167612Ssimon */ 432167612Ssimonstatic int make_addressPrefix(IPAddressOrRange **result, 433296465Sdelphij unsigned char *addr, const int prefixlen) 434167612Ssimon{ 435296465Sdelphij int bytelen = (prefixlen + 7) / 8, bitlen = prefixlen % 8; 436296465Sdelphij IPAddressOrRange *aor = IPAddressOrRange_new(); 437167612Ssimon 438296465Sdelphij if (aor == NULL) 439296465Sdelphij return 0; 440296465Sdelphij aor->type = IPAddressOrRange_addressPrefix; 441296465Sdelphij if (aor->u.addressPrefix == NULL && 442296465Sdelphij (aor->u.addressPrefix = ASN1_BIT_STRING_new()) == NULL) 443296465Sdelphij goto err; 444296465Sdelphij if (!ASN1_BIT_STRING_set(aor->u.addressPrefix, addr, bytelen)) 445296465Sdelphij goto err; 446296465Sdelphij aor->u.addressPrefix->flags &= ~7; 447296465Sdelphij aor->u.addressPrefix->flags |= ASN1_STRING_FLAG_BITS_LEFT; 448296465Sdelphij if (bitlen > 0) { 449296465Sdelphij aor->u.addressPrefix->data[bytelen - 1] &= ~(0xFF >> bitlen); 450296465Sdelphij aor->u.addressPrefix->flags |= 8 - bitlen; 451296465Sdelphij } 452167612Ssimon 453296465Sdelphij *result = aor; 454296465Sdelphij return 1; 455296465Sdelphij 456167612Ssimon err: 457296465Sdelphij IPAddressOrRange_free(aor); 458296465Sdelphij return 0; 459167612Ssimon} 460167612Ssimon 461167612Ssimon/* 462167612Ssimon * Construct a range. If it can be expressed as a prefix, 463167612Ssimon * return a prefix instead. Doing this here simplifies 464167612Ssimon * the rest of the code considerably. 465167612Ssimon */ 466167612Ssimonstatic int make_addressRange(IPAddressOrRange **result, 467296465Sdelphij unsigned char *min, 468296465Sdelphij unsigned char *max, const int length) 469167612Ssimon{ 470296465Sdelphij IPAddressOrRange *aor; 471296465Sdelphij int i, prefixlen; 472167612Ssimon 473296465Sdelphij if ((prefixlen = range_should_be_prefix(min, max, length)) >= 0) 474296465Sdelphij return make_addressPrefix(result, min, prefixlen); 475167612Ssimon 476296465Sdelphij if ((aor = IPAddressOrRange_new()) == NULL) 477296465Sdelphij return 0; 478296465Sdelphij aor->type = IPAddressOrRange_addressRange; 479296465Sdelphij OPENSSL_assert(aor->u.addressRange == NULL); 480296465Sdelphij if ((aor->u.addressRange = IPAddressRange_new()) == NULL) 481296465Sdelphij goto err; 482296465Sdelphij if (aor->u.addressRange->min == NULL && 483296465Sdelphij (aor->u.addressRange->min = ASN1_BIT_STRING_new()) == NULL) 484296465Sdelphij goto err; 485296465Sdelphij if (aor->u.addressRange->max == NULL && 486296465Sdelphij (aor->u.addressRange->max = ASN1_BIT_STRING_new()) == NULL) 487296465Sdelphij goto err; 488167612Ssimon 489296465Sdelphij for (i = length; i > 0 && min[i - 1] == 0x00; --i) ; 490296465Sdelphij if (!ASN1_BIT_STRING_set(aor->u.addressRange->min, min, i)) 491296465Sdelphij goto err; 492296465Sdelphij aor->u.addressRange->min->flags &= ~7; 493296465Sdelphij aor->u.addressRange->min->flags |= ASN1_STRING_FLAG_BITS_LEFT; 494296465Sdelphij if (i > 0) { 495296465Sdelphij unsigned char b = min[i - 1]; 496296465Sdelphij int j = 1; 497296465Sdelphij while ((b & (0xFFU >> j)) != 0) 498296465Sdelphij ++j; 499296465Sdelphij aor->u.addressRange->min->flags |= 8 - j; 500296465Sdelphij } 501167612Ssimon 502296465Sdelphij for (i = length; i > 0 && max[i - 1] == 0xFF; --i) ; 503296465Sdelphij if (!ASN1_BIT_STRING_set(aor->u.addressRange->max, max, i)) 504296465Sdelphij goto err; 505296465Sdelphij aor->u.addressRange->max->flags &= ~7; 506296465Sdelphij aor->u.addressRange->max->flags |= ASN1_STRING_FLAG_BITS_LEFT; 507296465Sdelphij if (i > 0) { 508296465Sdelphij unsigned char b = max[i - 1]; 509296465Sdelphij int j = 1; 510296465Sdelphij while ((b & (0xFFU >> j)) != (0xFFU >> j)) 511296465Sdelphij ++j; 512296465Sdelphij aor->u.addressRange->max->flags |= 8 - j; 513296465Sdelphij } 514167612Ssimon 515296465Sdelphij *result = aor; 516296465Sdelphij return 1; 517167612Ssimon 518167612Ssimon err: 519296465Sdelphij IPAddressOrRange_free(aor); 520296465Sdelphij return 0; 521167612Ssimon} 522167612Ssimon 523167612Ssimon/* 524167612Ssimon * Construct a new address family or find an existing one. 525167612Ssimon */ 526167612Ssimonstatic IPAddressFamily *make_IPAddressFamily(IPAddrBlocks *addr, 527296465Sdelphij const unsigned afi, 528296465Sdelphij const unsigned *safi) 529167612Ssimon{ 530296465Sdelphij IPAddressFamily *f; 531296465Sdelphij unsigned char key[3]; 532296465Sdelphij unsigned keylen; 533296465Sdelphij int i; 534167612Ssimon 535296465Sdelphij key[0] = (afi >> 8) & 0xFF; 536296465Sdelphij key[1] = afi & 0xFF; 537296465Sdelphij if (safi != NULL) { 538296465Sdelphij key[2] = *safi & 0xFF; 539296465Sdelphij keylen = 3; 540296465Sdelphij } else { 541296465Sdelphij keylen = 2; 542296465Sdelphij } 543167612Ssimon 544296465Sdelphij for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { 545296465Sdelphij f = sk_IPAddressFamily_value(addr, i); 546296465Sdelphij OPENSSL_assert(f->addressFamily->data != NULL); 547296465Sdelphij if (f->addressFamily->length == keylen && 548296465Sdelphij !memcmp(f->addressFamily->data, key, keylen)) 549296465Sdelphij return f; 550296465Sdelphij } 551167612Ssimon 552296465Sdelphij if ((f = IPAddressFamily_new()) == NULL) 553296465Sdelphij goto err; 554296465Sdelphij if (f->ipAddressChoice == NULL && 555296465Sdelphij (f->ipAddressChoice = IPAddressChoice_new()) == NULL) 556296465Sdelphij goto err; 557296465Sdelphij if (f->addressFamily == NULL && 558296465Sdelphij (f->addressFamily = ASN1_OCTET_STRING_new()) == NULL) 559296465Sdelphij goto err; 560296465Sdelphij if (!ASN1_OCTET_STRING_set(f->addressFamily, key, keylen)) 561296465Sdelphij goto err; 562296465Sdelphij if (!sk_IPAddressFamily_push(addr, f)) 563296465Sdelphij goto err; 564167612Ssimon 565296465Sdelphij return f; 566167612Ssimon 567167612Ssimon err: 568296465Sdelphij IPAddressFamily_free(f); 569296465Sdelphij return NULL; 570167612Ssimon} 571167612Ssimon 572167612Ssimon/* 573167612Ssimon * Add an inheritance element. 574167612Ssimon */ 575167612Ssimonint v3_addr_add_inherit(IPAddrBlocks *addr, 576296465Sdelphij const unsigned afi, const unsigned *safi) 577167612Ssimon{ 578296465Sdelphij IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi); 579296465Sdelphij if (f == NULL || 580296465Sdelphij f->ipAddressChoice == NULL || 581296465Sdelphij (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges && 582296465Sdelphij f->ipAddressChoice->u.addressesOrRanges != NULL)) 583296465Sdelphij return 0; 584296465Sdelphij if (f->ipAddressChoice->type == IPAddressChoice_inherit && 585296465Sdelphij f->ipAddressChoice->u.inherit != NULL) 586296465Sdelphij return 1; 587296465Sdelphij if (f->ipAddressChoice->u.inherit == NULL && 588296465Sdelphij (f->ipAddressChoice->u.inherit = ASN1_NULL_new()) == NULL) 589296465Sdelphij return 0; 590296465Sdelphij f->ipAddressChoice->type = IPAddressChoice_inherit; 591167612Ssimon return 1; 592167612Ssimon} 593167612Ssimon 594167612Ssimon/* 595167612Ssimon * Construct an IPAddressOrRange sequence, or return an existing one. 596167612Ssimon */ 597167612Ssimonstatic IPAddressOrRanges *make_prefix_or_range(IPAddrBlocks *addr, 598296465Sdelphij const unsigned afi, 599296465Sdelphij const unsigned *safi) 600167612Ssimon{ 601296465Sdelphij IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi); 602296465Sdelphij IPAddressOrRanges *aors = NULL; 603167612Ssimon 604296465Sdelphij if (f == NULL || 605296465Sdelphij f->ipAddressChoice == NULL || 606296465Sdelphij (f->ipAddressChoice->type == IPAddressChoice_inherit && 607296465Sdelphij f->ipAddressChoice->u.inherit != NULL)) 608296465Sdelphij return NULL; 609296465Sdelphij if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges) 610296465Sdelphij aors = f->ipAddressChoice->u.addressesOrRanges; 611296465Sdelphij if (aors != NULL) 612296465Sdelphij return aors; 613296465Sdelphij if ((aors = sk_IPAddressOrRange_new_null()) == NULL) 614296465Sdelphij return NULL; 615296465Sdelphij switch (afi) { 616296465Sdelphij case IANA_AFI_IPV4: 617296465Sdelphij (void)sk_IPAddressOrRange_set_cmp_func(aors, v4IPAddressOrRange_cmp); 618296465Sdelphij break; 619296465Sdelphij case IANA_AFI_IPV6: 620296465Sdelphij (void)sk_IPAddressOrRange_set_cmp_func(aors, v6IPAddressOrRange_cmp); 621296465Sdelphij break; 622296465Sdelphij } 623296465Sdelphij f->ipAddressChoice->type = IPAddressChoice_addressesOrRanges; 624296465Sdelphij f->ipAddressChoice->u.addressesOrRanges = aors; 625167612Ssimon return aors; 626167612Ssimon} 627167612Ssimon 628167612Ssimon/* 629167612Ssimon * Add a prefix. 630167612Ssimon */ 631167612Ssimonint v3_addr_add_prefix(IPAddrBlocks *addr, 632296465Sdelphij const unsigned afi, 633296465Sdelphij const unsigned *safi, 634296465Sdelphij unsigned char *a, const int prefixlen) 635167612Ssimon{ 636296465Sdelphij IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi); 637296465Sdelphij IPAddressOrRange *aor; 638296465Sdelphij if (aors == NULL || !make_addressPrefix(&aor, a, prefixlen)) 639296465Sdelphij return 0; 640296465Sdelphij if (sk_IPAddressOrRange_push(aors, aor)) 641296465Sdelphij return 1; 642296465Sdelphij IPAddressOrRange_free(aor); 643167612Ssimon return 0; 644167612Ssimon} 645167612Ssimon 646167612Ssimon/* 647167612Ssimon * Add a range. 648167612Ssimon */ 649167612Ssimonint v3_addr_add_range(IPAddrBlocks *addr, 650296465Sdelphij const unsigned afi, 651296465Sdelphij const unsigned *safi, 652296465Sdelphij unsigned char *min, unsigned char *max) 653167612Ssimon{ 654296465Sdelphij IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi); 655296465Sdelphij IPAddressOrRange *aor; 656296465Sdelphij int length = length_from_afi(afi); 657296465Sdelphij if (aors == NULL) 658296465Sdelphij return 0; 659296465Sdelphij if (!make_addressRange(&aor, min, max, length)) 660296465Sdelphij return 0; 661296465Sdelphij if (sk_IPAddressOrRange_push(aors, aor)) 662296465Sdelphij return 1; 663296465Sdelphij IPAddressOrRange_free(aor); 664167612Ssimon return 0; 665167612Ssimon} 666167612Ssimon 667167612Ssimon/* 668167612Ssimon * Extract min and max values from an IPAddressOrRange. 669167612Ssimon */ 670237998Sjkimstatic int extract_min_max(IPAddressOrRange *aor, 671296465Sdelphij unsigned char *min, unsigned char *max, int length) 672167612Ssimon{ 673296465Sdelphij if (aor == NULL || min == NULL || max == NULL) 674296465Sdelphij return 0; 675296465Sdelphij switch (aor->type) { 676296465Sdelphij case IPAddressOrRange_addressPrefix: 677296465Sdelphij return (addr_expand(min, aor->u.addressPrefix, length, 0x00) && 678296465Sdelphij addr_expand(max, aor->u.addressPrefix, length, 0xFF)); 679296465Sdelphij case IPAddressOrRange_addressRange: 680296465Sdelphij return (addr_expand(min, aor->u.addressRange->min, length, 0x00) && 681296465Sdelphij addr_expand(max, aor->u.addressRange->max, length, 0xFF)); 682296465Sdelphij } 683237998Sjkim return 0; 684167612Ssimon} 685167612Ssimon 686167612Ssimon/* 687167612Ssimon * Public wrapper for extract_min_max(). 688167612Ssimon */ 689167612Ssimonint v3_addr_get_range(IPAddressOrRange *aor, 690296465Sdelphij const unsigned afi, 691296465Sdelphij unsigned char *min, 692296465Sdelphij unsigned char *max, const int length) 693167612Ssimon{ 694296465Sdelphij int afi_length = length_from_afi(afi); 695296465Sdelphij if (aor == NULL || min == NULL || max == NULL || 696296465Sdelphij afi_length == 0 || length < afi_length || 697296465Sdelphij (aor->type != IPAddressOrRange_addressPrefix && 698296465Sdelphij aor->type != IPAddressOrRange_addressRange) || 699296465Sdelphij !extract_min_max(aor, min, max, afi_length)) 700296465Sdelphij return 0; 701237998Sjkim 702296465Sdelphij return afi_length; 703167612Ssimon} 704167612Ssimon 705167612Ssimon/* 706167612Ssimon * Sort comparision function for a sequence of IPAddressFamily. 707167612Ssimon * 708167612Ssimon * The last paragraph of RFC 3779 2.2.3.3 is slightly ambiguous about 709167612Ssimon * the ordering: I can read it as meaning that IPv6 without a SAFI 710167612Ssimon * comes before IPv4 with a SAFI, which seems pretty weird. The 711167612Ssimon * examples in appendix B suggest that the author intended the 712167612Ssimon * null-SAFI rule to apply only within a single AFI, which is what I 713167612Ssimon * would have expected and is what the following code implements. 714167612Ssimon */ 715296465Sdelphijstatic int IPAddressFamily_cmp(const IPAddressFamily *const *a_, 716296465Sdelphij const IPAddressFamily *const *b_) 717167612Ssimon{ 718296465Sdelphij const ASN1_OCTET_STRING *a = (*a_)->addressFamily; 719296465Sdelphij const ASN1_OCTET_STRING *b = (*b_)->addressFamily; 720296465Sdelphij int len = ((a->length <= b->length) ? a->length : b->length); 721296465Sdelphij int cmp = memcmp(a->data, b->data, len); 722296465Sdelphij return cmp ? cmp : a->length - b->length; 723167612Ssimon} 724167612Ssimon 725167612Ssimon/* 726167612Ssimon * Check whether an IPAddrBLocks is in canonical form. 727167612Ssimon */ 728167612Ssimonint v3_addr_is_canonical(IPAddrBlocks *addr) 729167612Ssimon{ 730296465Sdelphij unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; 731296465Sdelphij unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN]; 732296465Sdelphij IPAddressOrRanges *aors; 733296465Sdelphij int i, j, k; 734167612Ssimon 735296465Sdelphij /* 736296465Sdelphij * Empty extension is cannonical. 737296465Sdelphij */ 738296465Sdelphij if (addr == NULL) 739296465Sdelphij return 1; 740167612Ssimon 741167612Ssimon /* 742296465Sdelphij * Check whether the top-level list is in order. 743167612Ssimon */ 744296465Sdelphij for (i = 0; i < sk_IPAddressFamily_num(addr) - 1; i++) { 745296465Sdelphij const IPAddressFamily *a = sk_IPAddressFamily_value(addr, i); 746296465Sdelphij const IPAddressFamily *b = sk_IPAddressFamily_value(addr, i + 1); 747296465Sdelphij if (IPAddressFamily_cmp(&a, &b) >= 0) 748296465Sdelphij return 0; 749167612Ssimon } 750167612Ssimon 751167612Ssimon /* 752296465Sdelphij * Top level's ok, now check each address family. 753167612Ssimon */ 754296465Sdelphij for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { 755296465Sdelphij IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); 756296465Sdelphij int length = length_from_afi(v3_addr_get_afi(f)); 757167612Ssimon 758296465Sdelphij /* 759296465Sdelphij * Inheritance is canonical. Anything other than inheritance or 760296465Sdelphij * a SEQUENCE OF IPAddressOrRange is an ASN.1 error or something. 761296465Sdelphij */ 762296465Sdelphij if (f == NULL || f->ipAddressChoice == NULL) 763296465Sdelphij return 0; 764296465Sdelphij switch (f->ipAddressChoice->type) { 765296465Sdelphij case IPAddressChoice_inherit: 766296465Sdelphij continue; 767296465Sdelphij case IPAddressChoice_addressesOrRanges: 768296465Sdelphij break; 769296465Sdelphij default: 770296465Sdelphij return 0; 771296465Sdelphij } 772167612Ssimon 773296465Sdelphij /* 774296465Sdelphij * It's an IPAddressOrRanges sequence, check it. 775296465Sdelphij */ 776296465Sdelphij aors = f->ipAddressChoice->u.addressesOrRanges; 777296465Sdelphij if (sk_IPAddressOrRange_num(aors) == 0) 778296465Sdelphij return 0; 779296465Sdelphij for (j = 0; j < sk_IPAddressOrRange_num(aors) - 1; j++) { 780296465Sdelphij IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); 781296465Sdelphij IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, j + 1); 782167612Ssimon 783296465Sdelphij if (!extract_min_max(a, a_min, a_max, length) || 784296465Sdelphij !extract_min_max(b, b_min, b_max, length)) 785296465Sdelphij return 0; 786167612Ssimon 787296465Sdelphij /* 788296465Sdelphij * Punt misordered list, overlapping start, or inverted range. 789296465Sdelphij */ 790296465Sdelphij if (memcmp(a_min, b_min, length) >= 0 || 791296465Sdelphij memcmp(a_min, a_max, length) > 0 || 792296465Sdelphij memcmp(b_min, b_max, length) > 0) 793296465Sdelphij return 0; 794296465Sdelphij 795296465Sdelphij /* 796296465Sdelphij * Punt if adjacent or overlapping. Check for adjacency by 797296465Sdelphij * subtracting one from b_min first. 798296465Sdelphij */ 799296465Sdelphij for (k = length - 1; k >= 0 && b_min[k]-- == 0x00; k--) ; 800296465Sdelphij if (memcmp(a_max, b_min, length) >= 0) 801296465Sdelphij return 0; 802296465Sdelphij 803296465Sdelphij /* 804296465Sdelphij * Check for range that should be expressed as a prefix. 805296465Sdelphij */ 806296465Sdelphij if (a->type == IPAddressOrRange_addressRange && 807296465Sdelphij range_should_be_prefix(a_min, a_max, length) >= 0) 808296465Sdelphij return 0; 809296465Sdelphij } 810296465Sdelphij 811296465Sdelphij /* 812296465Sdelphij * Check range to see if it's inverted or should be a 813296465Sdelphij * prefix. 814296465Sdelphij */ 815296465Sdelphij j = sk_IPAddressOrRange_num(aors) - 1; 816296465Sdelphij { 817296465Sdelphij IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); 818296465Sdelphij if (a != NULL && a->type == IPAddressOrRange_addressRange) { 819296465Sdelphij if (!extract_min_max(a, a_min, a_max, length)) 820296465Sdelphij return 0; 821296465Sdelphij if (memcmp(a_min, a_max, length) > 0 || 822296465Sdelphij range_should_be_prefix(a_min, a_max, length) >= 0) 823296465Sdelphij return 0; 824296465Sdelphij } 825296465Sdelphij } 826167612Ssimon } 827167612Ssimon 828167612Ssimon /* 829296465Sdelphij * If we made it through all that, we're happy. 830167612Ssimon */ 831296465Sdelphij return 1; 832167612Ssimon} 833167612Ssimon 834167612Ssimon/* 835167612Ssimon * Whack an IPAddressOrRanges into canonical form. 836167612Ssimon */ 837167612Ssimonstatic int IPAddressOrRanges_canonize(IPAddressOrRanges *aors, 838296465Sdelphij const unsigned afi) 839167612Ssimon{ 840296465Sdelphij int i, j, length = length_from_afi(afi); 841167612Ssimon 842167612Ssimon /* 843296465Sdelphij * Sort the IPAddressOrRanges sequence. 844237998Sjkim */ 845296465Sdelphij sk_IPAddressOrRange_sort(aors); 846237998Sjkim 847237998Sjkim /* 848296465Sdelphij * Clean up representation issues, punt on duplicates or overlaps. 849167612Ssimon */ 850296465Sdelphij for (i = 0; i < sk_IPAddressOrRange_num(aors) - 1; i++) { 851296465Sdelphij IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, i); 852296465Sdelphij IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, i + 1); 853296465Sdelphij unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; 854296465Sdelphij unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN]; 855167612Ssimon 856296465Sdelphij if (!extract_min_max(a, a_min, a_max, length) || 857296465Sdelphij !extract_min_max(b, b_min, b_max, length)) 858296465Sdelphij return 0; 859296465Sdelphij 860296465Sdelphij /* 861296465Sdelphij * Punt inverted ranges. 862296465Sdelphij */ 863296465Sdelphij if (memcmp(a_min, a_max, length) > 0 || 864296465Sdelphij memcmp(b_min, b_max, length) > 0) 865296465Sdelphij return 0; 866296465Sdelphij 867296465Sdelphij /* 868296465Sdelphij * Punt overlaps. 869296465Sdelphij */ 870296465Sdelphij if (memcmp(a_max, b_min, length) >= 0) 871296465Sdelphij return 0; 872296465Sdelphij 873296465Sdelphij /* 874296465Sdelphij * Merge if a and b are adjacent. We check for 875296465Sdelphij * adjacency by subtracting one from b_min first. 876296465Sdelphij */ 877296465Sdelphij for (j = length - 1; j >= 0 && b_min[j]-- == 0x00; j--) ; 878296465Sdelphij if (memcmp(a_max, b_min, length) == 0) { 879296465Sdelphij IPAddressOrRange *merged; 880296465Sdelphij if (!make_addressRange(&merged, a_min, b_max, length)) 881296465Sdelphij return 0; 882296465Sdelphij sk_IPAddressOrRange_set(aors, i, merged); 883296465Sdelphij (void)sk_IPAddressOrRange_delete(aors, i + 1); 884296465Sdelphij IPAddressOrRange_free(a); 885296465Sdelphij IPAddressOrRange_free(b); 886296465Sdelphij --i; 887296465Sdelphij continue; 888296465Sdelphij } 889296465Sdelphij } 890296465Sdelphij 891167612Ssimon /* 892296465Sdelphij * Check for inverted final range. 893167612Ssimon */ 894296465Sdelphij j = sk_IPAddressOrRange_num(aors) - 1; 895296465Sdelphij { 896296465Sdelphij IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); 897296465Sdelphij if (a != NULL && a->type == IPAddressOrRange_addressRange) { 898296465Sdelphij unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; 899296465Sdelphij extract_min_max(a, a_min, a_max, length); 900296465Sdelphij if (memcmp(a_min, a_max, length) > 0) 901296465Sdelphij return 0; 902296465Sdelphij } 903167612Ssimon } 904167612Ssimon 905296465Sdelphij return 1; 906167612Ssimon} 907167612Ssimon 908167612Ssimon/* 909167612Ssimon * Whack an IPAddrBlocks extension into canonical form. 910167612Ssimon */ 911167612Ssimonint v3_addr_canonize(IPAddrBlocks *addr) 912167612Ssimon{ 913296465Sdelphij int i; 914296465Sdelphij for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { 915296465Sdelphij IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); 916296465Sdelphij if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges && 917296465Sdelphij !IPAddressOrRanges_canonize(f->ipAddressChoice-> 918296465Sdelphij u.addressesOrRanges, 919296465Sdelphij v3_addr_get_afi(f))) 920296465Sdelphij return 0; 921296465Sdelphij } 922296465Sdelphij (void)sk_IPAddressFamily_set_cmp_func(addr, IPAddressFamily_cmp); 923296465Sdelphij sk_IPAddressFamily_sort(addr); 924296465Sdelphij OPENSSL_assert(v3_addr_is_canonical(addr)); 925296465Sdelphij return 1; 926167612Ssimon} 927167612Ssimon 928167612Ssimon/* 929167612Ssimon * v2i handler for the IPAddrBlocks extension. 930167612Ssimon */ 931167612Ssimonstatic void *v2i_IPAddrBlocks(struct v3_ext_method *method, 932296465Sdelphij struct v3_ext_ctx *ctx, 933296465Sdelphij STACK_OF(CONF_VALUE) *values) 934167612Ssimon{ 935296465Sdelphij static const char v4addr_chars[] = "0123456789."; 936296465Sdelphij static const char v6addr_chars[] = "0123456789.:abcdefABCDEF"; 937296465Sdelphij IPAddrBlocks *addr = NULL; 938296465Sdelphij char *s = NULL, *t; 939296465Sdelphij int i; 940167612Ssimon 941296465Sdelphij if ((addr = sk_IPAddressFamily_new(IPAddressFamily_cmp)) == NULL) { 942296465Sdelphij X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); 943296465Sdelphij return NULL; 944167612Ssimon } 945167612Ssimon 946296465Sdelphij for (i = 0; i < sk_CONF_VALUE_num(values); i++) { 947296465Sdelphij CONF_VALUE *val = sk_CONF_VALUE_value(values, i); 948296465Sdelphij unsigned char min[ADDR_RAW_BUF_LEN], max[ADDR_RAW_BUF_LEN]; 949296465Sdelphij unsigned afi, *safi = NULL, safi_; 950296465Sdelphij const char *addr_chars; 951296465Sdelphij int prefixlen, i1, i2, delim, length; 952167612Ssimon 953296465Sdelphij if (!name_cmp(val->name, "IPv4")) { 954296465Sdelphij afi = IANA_AFI_IPV4; 955296465Sdelphij } else if (!name_cmp(val->name, "IPv6")) { 956296465Sdelphij afi = IANA_AFI_IPV6; 957296465Sdelphij } else if (!name_cmp(val->name, "IPv4-SAFI")) { 958296465Sdelphij afi = IANA_AFI_IPV4; 959296465Sdelphij safi = &safi_; 960296465Sdelphij } else if (!name_cmp(val->name, "IPv6-SAFI")) { 961296465Sdelphij afi = IANA_AFI_IPV6; 962296465Sdelphij safi = &safi_; 963296465Sdelphij } else { 964296465Sdelphij X509V3err(X509V3_F_V2I_IPADDRBLOCKS, 965296465Sdelphij X509V3_R_EXTENSION_NAME_ERROR); 966296465Sdelphij X509V3_conf_err(val); 967296465Sdelphij goto err; 968296465Sdelphij } 969167612Ssimon 970296465Sdelphij switch (afi) { 971296465Sdelphij case IANA_AFI_IPV4: 972296465Sdelphij addr_chars = v4addr_chars; 973296465Sdelphij break; 974296465Sdelphij case IANA_AFI_IPV6: 975296465Sdelphij addr_chars = v6addr_chars; 976296465Sdelphij break; 977296465Sdelphij } 978167612Ssimon 979296465Sdelphij length = length_from_afi(afi); 980167612Ssimon 981296465Sdelphij /* 982296465Sdelphij * Handle SAFI, if any, and BUF_strdup() so we can null-terminate 983296465Sdelphij * the other input values. 984296465Sdelphij */ 985296465Sdelphij if (safi != NULL) { 986296465Sdelphij *safi = strtoul(val->value, &t, 0); 987296465Sdelphij t += strspn(t, " \t"); 988296465Sdelphij if (*safi > 0xFF || *t++ != ':') { 989296465Sdelphij X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_SAFI); 990296465Sdelphij X509V3_conf_err(val); 991296465Sdelphij goto err; 992296465Sdelphij } 993296465Sdelphij t += strspn(t, " \t"); 994296465Sdelphij s = BUF_strdup(t); 995296465Sdelphij } else { 996296465Sdelphij s = BUF_strdup(val->value); 997296465Sdelphij } 998296465Sdelphij if (s == NULL) { 999296465Sdelphij X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); 1000296465Sdelphij goto err; 1001296465Sdelphij } 1002167612Ssimon 1003296465Sdelphij /* 1004296465Sdelphij * Check for inheritance. Not worth additional complexity to 1005296465Sdelphij * optimize this (seldom-used) case. 1006296465Sdelphij */ 1007296465Sdelphij if (!strcmp(s, "inherit")) { 1008296465Sdelphij if (!v3_addr_add_inherit(addr, afi, safi)) { 1009296465Sdelphij X509V3err(X509V3_F_V2I_IPADDRBLOCKS, 1010296465Sdelphij X509V3_R_INVALID_INHERITANCE); 1011296465Sdelphij X509V3_conf_err(val); 1012296465Sdelphij goto err; 1013296465Sdelphij } 1014296465Sdelphij OPENSSL_free(s); 1015296465Sdelphij s = NULL; 1016296465Sdelphij continue; 1017296465Sdelphij } 1018167612Ssimon 1019296465Sdelphij i1 = strspn(s, addr_chars); 1020296465Sdelphij i2 = i1 + strspn(s + i1, " \t"); 1021296465Sdelphij delim = s[i2++]; 1022296465Sdelphij s[i1] = '\0'; 1023296465Sdelphij 1024296465Sdelphij if (a2i_ipadd(min, s) != length) { 1025296465Sdelphij X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_IPADDRESS); 1026296465Sdelphij X509V3_conf_err(val); 1027296465Sdelphij goto err; 1028296465Sdelphij } 1029296465Sdelphij 1030296465Sdelphij switch (delim) { 1031296465Sdelphij case '/': 1032296465Sdelphij prefixlen = (int)strtoul(s + i2, &t, 10); 1033296465Sdelphij if (t == s + i2 || *t != '\0') { 1034296465Sdelphij X509V3err(X509V3_F_V2I_IPADDRBLOCKS, 1035296465Sdelphij X509V3_R_EXTENSION_VALUE_ERROR); 1036296465Sdelphij X509V3_conf_err(val); 1037296465Sdelphij goto err; 1038296465Sdelphij } 1039296465Sdelphij if (!v3_addr_add_prefix(addr, afi, safi, min, prefixlen)) { 1040296465Sdelphij X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); 1041296465Sdelphij goto err; 1042296465Sdelphij } 1043296465Sdelphij break; 1044296465Sdelphij case '-': 1045296465Sdelphij i1 = i2 + strspn(s + i2, " \t"); 1046296465Sdelphij i2 = i1 + strspn(s + i1, addr_chars); 1047296465Sdelphij if (i1 == i2 || s[i2] != '\0') { 1048296465Sdelphij X509V3err(X509V3_F_V2I_IPADDRBLOCKS, 1049296465Sdelphij X509V3_R_EXTENSION_VALUE_ERROR); 1050296465Sdelphij X509V3_conf_err(val); 1051296465Sdelphij goto err; 1052296465Sdelphij } 1053296465Sdelphij if (a2i_ipadd(max, s + i1) != length) { 1054296465Sdelphij X509V3err(X509V3_F_V2I_IPADDRBLOCKS, 1055296465Sdelphij X509V3_R_INVALID_IPADDRESS); 1056296465Sdelphij X509V3_conf_err(val); 1057296465Sdelphij goto err; 1058296465Sdelphij } 1059296465Sdelphij if (memcmp(min, max, length_from_afi(afi)) > 0) { 1060296465Sdelphij X509V3err(X509V3_F_V2I_IPADDRBLOCKS, 1061296465Sdelphij X509V3_R_EXTENSION_VALUE_ERROR); 1062296465Sdelphij X509V3_conf_err(val); 1063296465Sdelphij goto err; 1064296465Sdelphij } 1065296465Sdelphij if (!v3_addr_add_range(addr, afi, safi, min, max)) { 1066296465Sdelphij X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); 1067296465Sdelphij goto err; 1068296465Sdelphij } 1069296465Sdelphij break; 1070296465Sdelphij case '\0': 1071296465Sdelphij if (!v3_addr_add_prefix(addr, afi, safi, min, length * 8)) { 1072296465Sdelphij X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); 1073296465Sdelphij goto err; 1074296465Sdelphij } 1075296465Sdelphij break; 1076296465Sdelphij default: 1077296465Sdelphij X509V3err(X509V3_F_V2I_IPADDRBLOCKS, 1078296465Sdelphij X509V3_R_EXTENSION_VALUE_ERROR); 1079296465Sdelphij X509V3_conf_err(val); 1080296465Sdelphij goto err; 1081296465Sdelphij } 1082296465Sdelphij 1083296465Sdelphij OPENSSL_free(s); 1084296465Sdelphij s = NULL; 1085167612Ssimon } 1086167612Ssimon 1087296465Sdelphij /* 1088296465Sdelphij * Canonize the result, then we're done. 1089296465Sdelphij */ 1090296465Sdelphij if (!v3_addr_canonize(addr)) 1091296465Sdelphij goto err; 1092296465Sdelphij return addr; 1093167612Ssimon 1094167612Ssimon err: 1095296465Sdelphij OPENSSL_free(s); 1096296465Sdelphij sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free); 1097296465Sdelphij return NULL; 1098167612Ssimon} 1099167612Ssimon 1100167612Ssimon/* 1101167612Ssimon * OpenSSL dispatch 1102167612Ssimon */ 1103167612Ssimonconst X509V3_EXT_METHOD v3_addr = { 1104296465Sdelphij NID_sbgp_ipAddrBlock, /* nid */ 1105296465Sdelphij 0, /* flags */ 1106296465Sdelphij ASN1_ITEM_ref(IPAddrBlocks), /* template */ 1107296465Sdelphij 0, 0, 0, 0, /* old functions, ignored */ 1108296465Sdelphij 0, /* i2s */ 1109296465Sdelphij 0, /* s2i */ 1110296465Sdelphij 0, /* i2v */ 1111296465Sdelphij v2i_IPAddrBlocks, /* v2i */ 1112296465Sdelphij i2r_IPAddrBlocks, /* i2r */ 1113296465Sdelphij 0, /* r2i */ 1114296465Sdelphij NULL /* extension-specific data */ 1115167612Ssimon}; 1116167612Ssimon 1117167612Ssimon/* 1118167612Ssimon * Figure out whether extension sues inheritance. 1119167612Ssimon */ 1120167612Ssimonint v3_addr_inherits(IPAddrBlocks *addr) 1121167612Ssimon{ 1122296465Sdelphij int i; 1123296465Sdelphij if (addr == NULL) 1124296465Sdelphij return 0; 1125296465Sdelphij for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { 1126296465Sdelphij IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); 1127296465Sdelphij if (f->ipAddressChoice->type == IPAddressChoice_inherit) 1128296465Sdelphij return 1; 1129296465Sdelphij } 1130167612Ssimon return 0; 1131167612Ssimon} 1132167612Ssimon 1133167612Ssimon/* 1134167612Ssimon * Figure out whether parent contains child. 1135167612Ssimon */ 1136167612Ssimonstatic int addr_contains(IPAddressOrRanges *parent, 1137296465Sdelphij IPAddressOrRanges *child, int length) 1138167612Ssimon{ 1139296465Sdelphij unsigned char p_min[ADDR_RAW_BUF_LEN], p_max[ADDR_RAW_BUF_LEN]; 1140296465Sdelphij unsigned char c_min[ADDR_RAW_BUF_LEN], c_max[ADDR_RAW_BUF_LEN]; 1141296465Sdelphij int p, c; 1142167612Ssimon 1143296465Sdelphij if (child == NULL || parent == child) 1144296465Sdelphij return 1; 1145296465Sdelphij if (parent == NULL) 1146296465Sdelphij return 0; 1147167612Ssimon 1148296465Sdelphij p = 0; 1149296465Sdelphij for (c = 0; c < sk_IPAddressOrRange_num(child); c++) { 1150296465Sdelphij if (!extract_min_max(sk_IPAddressOrRange_value(child, c), 1151296465Sdelphij c_min, c_max, length)) 1152296465Sdelphij return -1; 1153296465Sdelphij for (;; p++) { 1154296465Sdelphij if (p >= sk_IPAddressOrRange_num(parent)) 1155296465Sdelphij return 0; 1156296465Sdelphij if (!extract_min_max(sk_IPAddressOrRange_value(parent, p), 1157296465Sdelphij p_min, p_max, length)) 1158296465Sdelphij return 0; 1159296465Sdelphij if (memcmp(p_max, c_max, length) < 0) 1160296465Sdelphij continue; 1161296465Sdelphij if (memcmp(p_min, c_min, length) > 0) 1162296465Sdelphij return 0; 1163296465Sdelphij break; 1164296465Sdelphij } 1165167612Ssimon } 1166167612Ssimon 1167296465Sdelphij return 1; 1168167612Ssimon} 1169167612Ssimon 1170167612Ssimon/* 1171167612Ssimon * Test whether a is a subset of b. 1172167612Ssimon */ 1173167612Ssimonint v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b) 1174167612Ssimon{ 1175296465Sdelphij int i; 1176296465Sdelphij if (a == NULL || a == b) 1177296465Sdelphij return 1; 1178296465Sdelphij if (b == NULL || v3_addr_inherits(a) || v3_addr_inherits(b)) 1179296465Sdelphij return 0; 1180296465Sdelphij (void)sk_IPAddressFamily_set_cmp_func(b, IPAddressFamily_cmp); 1181296465Sdelphij for (i = 0; i < sk_IPAddressFamily_num(a); i++) { 1182296465Sdelphij IPAddressFamily *fa = sk_IPAddressFamily_value(a, i); 1183296465Sdelphij int j = sk_IPAddressFamily_find(b, fa); 1184296465Sdelphij IPAddressFamily *fb; 1185296465Sdelphij fb = sk_IPAddressFamily_value(b, j); 1186296465Sdelphij if (fb == NULL) 1187296465Sdelphij return 0; 1188296465Sdelphij if (!addr_contains(fb->ipAddressChoice->u.addressesOrRanges, 1189296465Sdelphij fa->ipAddressChoice->u.addressesOrRanges, 1190296465Sdelphij length_from_afi(v3_addr_get_afi(fb)))) 1191296465Sdelphij return 0; 1192296465Sdelphij } 1193167612Ssimon return 1; 1194167612Ssimon} 1195167612Ssimon 1196167612Ssimon/* 1197167612Ssimon * Validation error handling via callback. 1198167612Ssimon */ 1199296465Sdelphij# define validation_err(_err_) \ 1200296465Sdelphij do { \ 1201296465Sdelphij if (ctx != NULL) { \ 1202296465Sdelphij ctx->error = _err_; \ 1203296465Sdelphij ctx->error_depth = i; \ 1204296465Sdelphij ctx->current_cert = x; \ 1205296465Sdelphij ret = ctx->verify_cb(0, ctx); \ 1206296465Sdelphij } else { \ 1207296465Sdelphij ret = 0; \ 1208296465Sdelphij } \ 1209296465Sdelphij if (!ret) \ 1210296465Sdelphij goto done; \ 1211167612Ssimon } while (0) 1212167612Ssimon 1213167612Ssimon/* 1214167612Ssimon * Core code for RFC 3779 2.3 path validation. 1215167612Ssimon */ 1216167612Ssimonstatic int v3_addr_validate_path_internal(X509_STORE_CTX *ctx, 1217296465Sdelphij STACK_OF(X509) *chain, 1218296465Sdelphij IPAddrBlocks *ext) 1219167612Ssimon{ 1220296465Sdelphij IPAddrBlocks *child = NULL; 1221296465Sdelphij int i, j, ret = 1; 1222296465Sdelphij X509 *x = NULL; 1223167612Ssimon 1224296465Sdelphij OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0); 1225296465Sdelphij OPENSSL_assert(ctx != NULL || ext != NULL); 1226296465Sdelphij OPENSSL_assert(ctx == NULL || ctx->verify_cb != NULL); 1227167612Ssimon 1228296465Sdelphij /* 1229296465Sdelphij * Figure out where to start. If we don't have an extension to 1230296465Sdelphij * check, we're done. Otherwise, check canonical form and 1231296465Sdelphij * set up for walking up the chain. 1232296465Sdelphij */ 1233296465Sdelphij if (ext != NULL) { 1234296465Sdelphij i = -1; 1235296465Sdelphij } else { 1236296465Sdelphij i = 0; 1237296465Sdelphij x = sk_X509_value(chain, i); 1238296465Sdelphij OPENSSL_assert(x != NULL); 1239296465Sdelphij if ((ext = x->rfc3779_addr) == NULL) 1240296465Sdelphij goto done; 1241167612Ssimon } 1242296465Sdelphij if (!v3_addr_is_canonical(ext)) 1243296465Sdelphij validation_err(X509_V_ERR_INVALID_EXTENSION); 1244296465Sdelphij (void)sk_IPAddressFamily_set_cmp_func(ext, IPAddressFamily_cmp); 1245296465Sdelphij if ((child = sk_IPAddressFamily_dup(ext)) == NULL) { 1246296465Sdelphij X509V3err(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL, 1247296465Sdelphij ERR_R_MALLOC_FAILURE); 1248296465Sdelphij ret = 0; 1249296465Sdelphij goto done; 1250167612Ssimon } 1251167612Ssimon 1252296465Sdelphij /* 1253296465Sdelphij * Now walk up the chain. No cert may list resources that its 1254296465Sdelphij * parent doesn't list. 1255296465Sdelphij */ 1256296465Sdelphij for (i++; i < sk_X509_num(chain); i++) { 1257296465Sdelphij x = sk_X509_value(chain, i); 1258296465Sdelphij OPENSSL_assert(x != NULL); 1259296465Sdelphij if (!v3_addr_is_canonical(x->rfc3779_addr)) 1260296465Sdelphij validation_err(X509_V_ERR_INVALID_EXTENSION); 1261296465Sdelphij if (x->rfc3779_addr == NULL) { 1262296465Sdelphij for (j = 0; j < sk_IPAddressFamily_num(child); j++) { 1263296465Sdelphij IPAddressFamily *fc = sk_IPAddressFamily_value(child, j); 1264296465Sdelphij if (fc->ipAddressChoice->type != IPAddressChoice_inherit) { 1265296465Sdelphij validation_err(X509_V_ERR_UNNESTED_RESOURCE); 1266296465Sdelphij break; 1267296465Sdelphij } 1268296465Sdelphij } 1269296465Sdelphij continue; 1270296465Sdelphij } 1271296465Sdelphij (void)sk_IPAddressFamily_set_cmp_func(x->rfc3779_addr, 1272296465Sdelphij IPAddressFamily_cmp); 1273296465Sdelphij for (j = 0; j < sk_IPAddressFamily_num(child); j++) { 1274296465Sdelphij IPAddressFamily *fc = sk_IPAddressFamily_value(child, j); 1275296465Sdelphij int k = sk_IPAddressFamily_find(x->rfc3779_addr, fc); 1276296465Sdelphij IPAddressFamily *fp = 1277296465Sdelphij sk_IPAddressFamily_value(x->rfc3779_addr, k); 1278296465Sdelphij if (fp == NULL) { 1279296465Sdelphij if (fc->ipAddressChoice->type == 1280296465Sdelphij IPAddressChoice_addressesOrRanges) { 1281296465Sdelphij validation_err(X509_V_ERR_UNNESTED_RESOURCE); 1282296465Sdelphij break; 1283296465Sdelphij } 1284296465Sdelphij continue; 1285296465Sdelphij } 1286296465Sdelphij if (fp->ipAddressChoice->type == 1287296465Sdelphij IPAddressChoice_addressesOrRanges) { 1288296465Sdelphij if (fc->ipAddressChoice->type == IPAddressChoice_inherit 1289296465Sdelphij || addr_contains(fp->ipAddressChoice->u.addressesOrRanges, 1290296465Sdelphij fc->ipAddressChoice->u.addressesOrRanges, 1291296465Sdelphij length_from_afi(v3_addr_get_afi(fc)))) 1292296465Sdelphij sk_IPAddressFamily_set(child, j, fp); 1293296465Sdelphij else 1294296465Sdelphij validation_err(X509_V_ERR_UNNESTED_RESOURCE); 1295296465Sdelphij } 1296296465Sdelphij } 1297167612Ssimon } 1298167612Ssimon 1299296465Sdelphij /* 1300296465Sdelphij * Trust anchor can't inherit. 1301296465Sdelphij */ 1302296465Sdelphij if (x->rfc3779_addr != NULL) { 1303296465Sdelphij for (j = 0; j < sk_IPAddressFamily_num(x->rfc3779_addr); j++) { 1304296465Sdelphij IPAddressFamily *fp = 1305296465Sdelphij sk_IPAddressFamily_value(x->rfc3779_addr, j); 1306296465Sdelphij if (fp->ipAddressChoice->type == IPAddressChoice_inherit 1307296465Sdelphij && sk_IPAddressFamily_find(child, fp) >= 0) 1308296465Sdelphij validation_err(X509_V_ERR_UNNESTED_RESOURCE); 1309296465Sdelphij } 1310296465Sdelphij } 1311296465Sdelphij 1312167612Ssimon done: 1313296465Sdelphij sk_IPAddressFamily_free(child); 1314296465Sdelphij return ret; 1315167612Ssimon} 1316167612Ssimon 1317296465Sdelphij# undef validation_err 1318167612Ssimon 1319167612Ssimon/* 1320167612Ssimon * RFC 3779 2.3 path validation -- called from X509_verify_cert(). 1321167612Ssimon */ 1322167612Ssimonint v3_addr_validate_path(X509_STORE_CTX *ctx) 1323167612Ssimon{ 1324296465Sdelphij return v3_addr_validate_path_internal(ctx, ctx->chain, NULL); 1325167612Ssimon} 1326167612Ssimon 1327167612Ssimon/* 1328167612Ssimon * RFC 3779 2.3 path validation of an extension. 1329167612Ssimon * Test whether chain covers extension. 1330167612Ssimon */ 1331167612Ssimonint v3_addr_validate_resource_set(STACK_OF(X509) *chain, 1332296465Sdelphij IPAddrBlocks *ext, int allow_inheritance) 1333167612Ssimon{ 1334296465Sdelphij if (ext == NULL) 1335296465Sdelphij return 1; 1336296465Sdelphij if (chain == NULL || sk_X509_num(chain) == 0) 1337296465Sdelphij return 0; 1338296465Sdelphij if (!allow_inheritance && v3_addr_inherits(ext)) 1339296465Sdelphij return 0; 1340296465Sdelphij return v3_addr_validate_path_internal(NULL, chain, ext); 1341167612Ssimon} 1342167612Ssimon 1343296465Sdelphij#endif /* OPENSSL_NO_RFC3779 */ 1344