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 13296341Sdelphij * 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 98296341SdelphijASN1_ITEM_TEMPLATE(IPAddrBlocks) = 99167612Ssimon ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, 100296341Sdelphij 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 */ 111296341Sdelphij# 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{ 118296341Sdelphij switch (afi) { 119296341Sdelphij case IANA_AFI_IPV4: 120296341Sdelphij return 4; 121296341Sdelphij case IANA_AFI_IPV6: 122296341Sdelphij return 16; 123296341Sdelphij default: 124296341Sdelphij return 0; 125296341Sdelphij } 126167612Ssimon} 127167612Ssimon 128167612Ssimon/* 129167612Ssimon * Extract the AFI from an IPAddressFamily. 130167612Ssimon */ 131194206Ssimonunsigned int v3_addr_get_afi(const IPAddressFamily *f) 132167612Ssimon{ 133296341Sdelphij return ((f != NULL && 134296341Sdelphij f->addressFamily != NULL && f->addressFamily->data != NULL) 135296341Sdelphij ? ((f->addressFamily->data[0] << 8) | (f->addressFamily->data[1])) 136296341Sdelphij : 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 */ 143237657Sjkimstatic int addr_expand(unsigned char *addr, 144296341Sdelphij const ASN1_BIT_STRING *bs, 145296341Sdelphij const int length, const unsigned char fill) 146167612Ssimon{ 147296341Sdelphij if (bs->length < 0 || bs->length > length) 148296341Sdelphij return 0; 149296341Sdelphij if (bs->length > 0) { 150296341Sdelphij memcpy(addr, bs->data, bs->length); 151296341Sdelphij if ((bs->flags & 7) != 0) { 152296341Sdelphij unsigned char mask = 0xFF >> (8 - (bs->flags & 7)); 153296341Sdelphij if (fill == 0) 154296341Sdelphij addr[bs->length - 1] &= ~mask; 155296341Sdelphij else 156296341Sdelphij addr[bs->length - 1] |= mask; 157296341Sdelphij } 158167612Ssimon } 159296341Sdelphij memset(addr + bs->length, fill, length - bs->length); 160296341Sdelphij return 1; 161167612Ssimon} 162167612Ssimon 163167612Ssimon/* 164167612Ssimon * Extract the prefix length from a bitstring. 165167612Ssimon */ 166296341Sdelphij# 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, 172296341Sdelphij const unsigned afi, 173296341Sdelphij const unsigned char fill, const ASN1_BIT_STRING *bs) 174167612Ssimon{ 175296341Sdelphij unsigned char addr[ADDR_RAW_BUF_LEN]; 176296341Sdelphij int i, n; 177167612Ssimon 178296341Sdelphij if (bs->length < 0) 179296341Sdelphij return 0; 180296341Sdelphij switch (afi) { 181296341Sdelphij case IANA_AFI_IPV4: 182296341Sdelphij if (!addr_expand(addr, bs, 4, fill)) 183296341Sdelphij return 0; 184296341Sdelphij BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]); 185296341Sdelphij break; 186296341Sdelphij case IANA_AFI_IPV6: 187296341Sdelphij if (!addr_expand(addr, bs, 16, fill)) 188296341Sdelphij return 0; 189296341Sdelphij for (n = 16; n > 1 && addr[n - 1] == 0x00 && addr[n - 2] == 0x00; 190296341Sdelphij n -= 2) ; 191296341Sdelphij for (i = 0; i < n; i += 2) 192296341Sdelphij BIO_printf(out, "%x%s", (addr[i] << 8) | addr[i + 1], 193296341Sdelphij (i < 14 ? ":" : "")); 194296341Sdelphij if (i < 16) 195296341Sdelphij BIO_puts(out, ":"); 196296341Sdelphij if (i == 0) 197296341Sdelphij BIO_puts(out, ":"); 198296341Sdelphij break; 199296341Sdelphij default: 200296341Sdelphij for (i = 0; i < bs->length; i++) 201296341Sdelphij BIO_printf(out, "%s%02x", (i > 0 ? ":" : ""), bs->data[i]); 202296341Sdelphij BIO_printf(out, "[%d]", (int)(bs->flags & 7)); 203296341Sdelphij break; 204296341Sdelphij } 205296341Sdelphij return 1; 206167612Ssimon} 207167612Ssimon 208167612Ssimon/* 209167612Ssimon * i2r handler for a sequence of addresses and ranges. 210167612Ssimon */ 211167612Ssimonstatic int i2r_IPAddressOrRanges(BIO *out, 212296341Sdelphij const int indent, 213296341Sdelphij const IPAddressOrRanges *aors, 214296341Sdelphij const unsigned afi) 215167612Ssimon{ 216296341Sdelphij int i; 217296341Sdelphij for (i = 0; i < sk_IPAddressOrRange_num(aors); i++) { 218296341Sdelphij const IPAddressOrRange *aor = sk_IPAddressOrRange_value(aors, i); 219296341Sdelphij BIO_printf(out, "%*s", indent, ""); 220296341Sdelphij switch (aor->type) { 221296341Sdelphij case IPAddressOrRange_addressPrefix: 222296341Sdelphij if (!i2r_address(out, afi, 0x00, aor->u.addressPrefix)) 223296341Sdelphij return 0; 224296341Sdelphij BIO_printf(out, "/%d\n", addr_prefixlen(aor->u.addressPrefix)); 225296341Sdelphij continue; 226296341Sdelphij case IPAddressOrRange_addressRange: 227296341Sdelphij if (!i2r_address(out, afi, 0x00, aor->u.addressRange->min)) 228296341Sdelphij return 0; 229296341Sdelphij BIO_puts(out, "-"); 230296341Sdelphij if (!i2r_address(out, afi, 0xFF, aor->u.addressRange->max)) 231296341Sdelphij return 0; 232296341Sdelphij BIO_puts(out, "\n"); 233296341Sdelphij continue; 234296341Sdelphij } 235167612Ssimon } 236296341Sdelphij return 1; 237167612Ssimon} 238167612Ssimon 239167612Ssimon/* 240167612Ssimon * i2r handler for an IPAddrBlocks extension. 241167612Ssimon */ 242238405Sjkimstatic int i2r_IPAddrBlocks(const X509V3_EXT_METHOD *method, 243296341Sdelphij void *ext, BIO *out, int indent) 244167612Ssimon{ 245296341Sdelphij const IPAddrBlocks *addr = ext; 246296341Sdelphij int i; 247296341Sdelphij for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { 248296341Sdelphij IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); 249296341Sdelphij const unsigned int afi = v3_addr_get_afi(f); 250296341Sdelphij switch (afi) { 251296341Sdelphij case IANA_AFI_IPV4: 252296341Sdelphij BIO_printf(out, "%*sIPv4", indent, ""); 253296341Sdelphij break; 254296341Sdelphij case IANA_AFI_IPV6: 255296341Sdelphij BIO_printf(out, "%*sIPv6", indent, ""); 256296341Sdelphij break; 257296341Sdelphij default: 258296341Sdelphij BIO_printf(out, "%*sUnknown AFI %u", indent, "", afi); 259296341Sdelphij break; 260296341Sdelphij } 261296341Sdelphij if (f->addressFamily->length > 2) { 262296341Sdelphij switch (f->addressFamily->data[2]) { 263296341Sdelphij case 1: 264296341Sdelphij BIO_puts(out, " (Unicast)"); 265296341Sdelphij break; 266296341Sdelphij case 2: 267296341Sdelphij BIO_puts(out, " (Multicast)"); 268296341Sdelphij break; 269296341Sdelphij case 3: 270296341Sdelphij BIO_puts(out, " (Unicast/Multicast)"); 271296341Sdelphij break; 272296341Sdelphij case 4: 273296341Sdelphij BIO_puts(out, " (MPLS)"); 274296341Sdelphij break; 275296341Sdelphij case 64: 276296341Sdelphij BIO_puts(out, " (Tunnel)"); 277296341Sdelphij break; 278296341Sdelphij case 65: 279296341Sdelphij BIO_puts(out, " (VPLS)"); 280296341Sdelphij break; 281296341Sdelphij case 66: 282296341Sdelphij BIO_puts(out, " (BGP MDT)"); 283296341Sdelphij break; 284296341Sdelphij case 128: 285296341Sdelphij BIO_puts(out, " (MPLS-labeled VPN)"); 286296341Sdelphij break; 287296341Sdelphij default: 288296341Sdelphij BIO_printf(out, " (Unknown SAFI %u)", 289296341Sdelphij (unsigned)f->addressFamily->data[2]); 290296341Sdelphij break; 291296341Sdelphij } 292296341Sdelphij } 293296341Sdelphij switch (f->ipAddressChoice->type) { 294296341Sdelphij case IPAddressChoice_inherit: 295296341Sdelphij BIO_puts(out, ": inherit\n"); 296296341Sdelphij break; 297296341Sdelphij case IPAddressChoice_addressesOrRanges: 298296341Sdelphij BIO_puts(out, ":\n"); 299296341Sdelphij if (!i2r_IPAddressOrRanges(out, 300296341Sdelphij indent + 2, 301296341Sdelphij f->ipAddressChoice-> 302296341Sdelphij u.addressesOrRanges, afi)) 303296341Sdelphij return 0; 304296341Sdelphij break; 305296341Sdelphij } 306167612Ssimon } 307296341Sdelphij return 1; 308167612Ssimon} 309167612Ssimon 310167612Ssimon/* 311167612Ssimon * Sort comparison function for a sequence of IPAddressOrRange 312167612Ssimon * elements. 313237657Sjkim * 314237657Sjkim * There's no sane answer we can give if addr_expand() fails, and an 315237657Sjkim * assertion failure on externally supplied data is seriously uncool, 316237657Sjkim * so we just arbitrarily declare that if given invalid inputs this 317237657Sjkim * function returns -1. If this messes up your preferred sort order 318237657Sjkim * for garbage input, tough noogies. 319167612Ssimon */ 320167612Ssimonstatic int IPAddressOrRange_cmp(const IPAddressOrRange *a, 321296341Sdelphij const IPAddressOrRange *b, const int length) 322167612Ssimon{ 323296341Sdelphij unsigned char addr_a[ADDR_RAW_BUF_LEN], addr_b[ADDR_RAW_BUF_LEN]; 324296341Sdelphij int prefixlen_a = 0, prefixlen_b = 0; 325296341Sdelphij int r; 326167612Ssimon 327296341Sdelphij switch (a->type) { 328296341Sdelphij case IPAddressOrRange_addressPrefix: 329296341Sdelphij if (!addr_expand(addr_a, a->u.addressPrefix, length, 0x00)) 330296341Sdelphij return -1; 331296341Sdelphij prefixlen_a = addr_prefixlen(a->u.addressPrefix); 332296341Sdelphij break; 333296341Sdelphij case IPAddressOrRange_addressRange: 334296341Sdelphij if (!addr_expand(addr_a, a->u.addressRange->min, length, 0x00)) 335296341Sdelphij return -1; 336296341Sdelphij prefixlen_a = length * 8; 337296341Sdelphij break; 338296341Sdelphij } 339167612Ssimon 340296341Sdelphij switch (b->type) { 341296341Sdelphij case IPAddressOrRange_addressPrefix: 342296341Sdelphij if (!addr_expand(addr_b, b->u.addressPrefix, length, 0x00)) 343296341Sdelphij return -1; 344296341Sdelphij prefixlen_b = addr_prefixlen(b->u.addressPrefix); 345296341Sdelphij break; 346296341Sdelphij case IPAddressOrRange_addressRange: 347296341Sdelphij if (!addr_expand(addr_b, b->u.addressRange->min, length, 0x00)) 348296341Sdelphij return -1; 349296341Sdelphij prefixlen_b = length * 8; 350296341Sdelphij break; 351296341Sdelphij } 352167612Ssimon 353296341Sdelphij if ((r = memcmp(addr_a, addr_b, length)) != 0) 354296341Sdelphij return r; 355296341Sdelphij else 356296341Sdelphij return prefixlen_a - prefixlen_b; 357167612Ssimon} 358167612Ssimon 359167612Ssimon/* 360167612Ssimon * IPv4-specific closure over IPAddressOrRange_cmp, since sk_sort() 361167612Ssimon * comparision routines are only allowed two arguments. 362167612Ssimon */ 363296341Sdelphijstatic int v4IPAddressOrRange_cmp(const IPAddressOrRange *const *a, 364296341Sdelphij const IPAddressOrRange *const *b) 365167612Ssimon{ 366296341Sdelphij return IPAddressOrRange_cmp(*a, *b, 4); 367167612Ssimon} 368167612Ssimon 369167612Ssimon/* 370167612Ssimon * IPv6-specific closure over IPAddressOrRange_cmp, since sk_sort() 371167612Ssimon * comparision routines are only allowed two arguments. 372167612Ssimon */ 373296341Sdelphijstatic int v6IPAddressOrRange_cmp(const IPAddressOrRange *const *a, 374296341Sdelphij const IPAddressOrRange *const *b) 375167612Ssimon{ 376296341Sdelphij return IPAddressOrRange_cmp(*a, *b, 16); 377167612Ssimon} 378167612Ssimon 379167612Ssimon/* 380167612Ssimon * Calculate whether a range collapses to a prefix. 381167612Ssimon * See last paragraph of RFC 3779 2.2.3.7. 382167612Ssimon */ 383167612Ssimonstatic int range_should_be_prefix(const unsigned char *min, 384296341Sdelphij const unsigned char *max, const int length) 385167612Ssimon{ 386296341Sdelphij unsigned char mask; 387296341Sdelphij int i, j; 388167612Ssimon 389296341Sdelphij OPENSSL_assert(memcmp(min, max, length) <= 0); 390296341Sdelphij for (i = 0; i < length && min[i] == max[i]; i++) ; 391296341Sdelphij for (j = length - 1; j >= 0 && min[j] == 0x00 && max[j] == 0xFF; j--) ; 392296341Sdelphij if (i < j) 393296341Sdelphij return -1; 394296341Sdelphij if (i > j) 395296341Sdelphij return i * 8; 396296341Sdelphij mask = min[i] ^ max[i]; 397296341Sdelphij switch (mask) { 398296341Sdelphij case 0x01: 399296341Sdelphij j = 7; 400296341Sdelphij break; 401296341Sdelphij case 0x03: 402296341Sdelphij j = 6; 403296341Sdelphij break; 404296341Sdelphij case 0x07: 405296341Sdelphij j = 5; 406296341Sdelphij break; 407296341Sdelphij case 0x0F: 408296341Sdelphij j = 4; 409296341Sdelphij break; 410296341Sdelphij case 0x1F: 411296341Sdelphij j = 3; 412296341Sdelphij break; 413296341Sdelphij case 0x3F: 414296341Sdelphij j = 2; 415296341Sdelphij break; 416296341Sdelphij case 0x7F: 417296341Sdelphij j = 1; 418296341Sdelphij break; 419296341Sdelphij default: 420296341Sdelphij return -1; 421296341Sdelphij } 422296341Sdelphij if ((min[i] & mask) != 0 || (max[i] & mask) != mask) 423296341Sdelphij return -1; 424296341Sdelphij else 425296341Sdelphij return i * 8 + j; 426167612Ssimon} 427167612Ssimon 428167612Ssimon/* 429167612Ssimon * Construct a prefix. 430167612Ssimon */ 431167612Ssimonstatic int make_addressPrefix(IPAddressOrRange **result, 432296341Sdelphij unsigned char *addr, const int prefixlen) 433167612Ssimon{ 434296341Sdelphij int bytelen = (prefixlen + 7) / 8, bitlen = prefixlen % 8; 435296341Sdelphij IPAddressOrRange *aor = IPAddressOrRange_new(); 436167612Ssimon 437296341Sdelphij if (aor == NULL) 438296341Sdelphij return 0; 439296341Sdelphij aor->type = IPAddressOrRange_addressPrefix; 440296341Sdelphij if (aor->u.addressPrefix == NULL && 441296341Sdelphij (aor->u.addressPrefix = ASN1_BIT_STRING_new()) == NULL) 442296341Sdelphij goto err; 443296341Sdelphij if (!ASN1_BIT_STRING_set(aor->u.addressPrefix, addr, bytelen)) 444296341Sdelphij goto err; 445296341Sdelphij aor->u.addressPrefix->flags &= ~7; 446296341Sdelphij aor->u.addressPrefix->flags |= ASN1_STRING_FLAG_BITS_LEFT; 447296341Sdelphij if (bitlen > 0) { 448296341Sdelphij aor->u.addressPrefix->data[bytelen - 1] &= ~(0xFF >> bitlen); 449296341Sdelphij aor->u.addressPrefix->flags |= 8 - bitlen; 450296341Sdelphij } 451167612Ssimon 452296341Sdelphij *result = aor; 453296341Sdelphij return 1; 454296341Sdelphij 455167612Ssimon err: 456296341Sdelphij IPAddressOrRange_free(aor); 457296341Sdelphij return 0; 458167612Ssimon} 459167612Ssimon 460167612Ssimon/* 461167612Ssimon * Construct a range. If it can be expressed as a prefix, 462167612Ssimon * return a prefix instead. Doing this here simplifies 463167612Ssimon * the rest of the code considerably. 464167612Ssimon */ 465167612Ssimonstatic int make_addressRange(IPAddressOrRange **result, 466296341Sdelphij unsigned char *min, 467296341Sdelphij unsigned char *max, const int length) 468167612Ssimon{ 469296341Sdelphij IPAddressOrRange *aor; 470296341Sdelphij int i, prefixlen; 471167612Ssimon 472296341Sdelphij if ((prefixlen = range_should_be_prefix(min, max, length)) >= 0) 473296341Sdelphij return make_addressPrefix(result, min, prefixlen); 474167612Ssimon 475296341Sdelphij if ((aor = IPAddressOrRange_new()) == NULL) 476296341Sdelphij return 0; 477296341Sdelphij aor->type = IPAddressOrRange_addressRange; 478296341Sdelphij OPENSSL_assert(aor->u.addressRange == NULL); 479296341Sdelphij if ((aor->u.addressRange = IPAddressRange_new()) == NULL) 480296341Sdelphij goto err; 481296341Sdelphij if (aor->u.addressRange->min == NULL && 482296341Sdelphij (aor->u.addressRange->min = ASN1_BIT_STRING_new()) == NULL) 483296341Sdelphij goto err; 484296341Sdelphij if (aor->u.addressRange->max == NULL && 485296341Sdelphij (aor->u.addressRange->max = ASN1_BIT_STRING_new()) == NULL) 486296341Sdelphij goto err; 487167612Ssimon 488296341Sdelphij for (i = length; i > 0 && min[i - 1] == 0x00; --i) ; 489296341Sdelphij if (!ASN1_BIT_STRING_set(aor->u.addressRange->min, min, i)) 490296341Sdelphij goto err; 491296341Sdelphij aor->u.addressRange->min->flags &= ~7; 492296341Sdelphij aor->u.addressRange->min->flags |= ASN1_STRING_FLAG_BITS_LEFT; 493296341Sdelphij if (i > 0) { 494296341Sdelphij unsigned char b = min[i - 1]; 495296341Sdelphij int j = 1; 496296341Sdelphij while ((b & (0xFFU >> j)) != 0) 497296341Sdelphij ++j; 498296341Sdelphij aor->u.addressRange->min->flags |= 8 - j; 499296341Sdelphij } 500167612Ssimon 501296341Sdelphij for (i = length; i > 0 && max[i - 1] == 0xFF; --i) ; 502296341Sdelphij if (!ASN1_BIT_STRING_set(aor->u.addressRange->max, max, i)) 503296341Sdelphij goto err; 504296341Sdelphij aor->u.addressRange->max->flags &= ~7; 505296341Sdelphij aor->u.addressRange->max->flags |= ASN1_STRING_FLAG_BITS_LEFT; 506296341Sdelphij if (i > 0) { 507296341Sdelphij unsigned char b = max[i - 1]; 508296341Sdelphij int j = 1; 509296341Sdelphij while ((b & (0xFFU >> j)) != (0xFFU >> j)) 510296341Sdelphij ++j; 511296341Sdelphij aor->u.addressRange->max->flags |= 8 - j; 512296341Sdelphij } 513167612Ssimon 514296341Sdelphij *result = aor; 515296341Sdelphij return 1; 516167612Ssimon 517167612Ssimon err: 518296341Sdelphij IPAddressOrRange_free(aor); 519296341Sdelphij return 0; 520167612Ssimon} 521167612Ssimon 522167612Ssimon/* 523167612Ssimon * Construct a new address family or find an existing one. 524167612Ssimon */ 525167612Ssimonstatic IPAddressFamily *make_IPAddressFamily(IPAddrBlocks *addr, 526296341Sdelphij const unsigned afi, 527296341Sdelphij const unsigned *safi) 528167612Ssimon{ 529296341Sdelphij IPAddressFamily *f; 530296341Sdelphij unsigned char key[3]; 531296341Sdelphij unsigned keylen; 532296341Sdelphij int i; 533167612Ssimon 534296341Sdelphij key[0] = (afi >> 8) & 0xFF; 535296341Sdelphij key[1] = afi & 0xFF; 536296341Sdelphij if (safi != NULL) { 537296341Sdelphij key[2] = *safi & 0xFF; 538296341Sdelphij keylen = 3; 539296341Sdelphij } else { 540296341Sdelphij keylen = 2; 541296341Sdelphij } 542167612Ssimon 543296341Sdelphij for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { 544296341Sdelphij f = sk_IPAddressFamily_value(addr, i); 545296341Sdelphij OPENSSL_assert(f->addressFamily->data != NULL); 546296341Sdelphij if (f->addressFamily->length == keylen && 547296341Sdelphij !memcmp(f->addressFamily->data, key, keylen)) 548296341Sdelphij return f; 549296341Sdelphij } 550167612Ssimon 551296341Sdelphij if ((f = IPAddressFamily_new()) == NULL) 552296341Sdelphij goto err; 553296341Sdelphij if (f->ipAddressChoice == NULL && 554296341Sdelphij (f->ipAddressChoice = IPAddressChoice_new()) == NULL) 555296341Sdelphij goto err; 556296341Sdelphij if (f->addressFamily == NULL && 557296341Sdelphij (f->addressFamily = ASN1_OCTET_STRING_new()) == NULL) 558296341Sdelphij goto err; 559296341Sdelphij if (!ASN1_OCTET_STRING_set(f->addressFamily, key, keylen)) 560296341Sdelphij goto err; 561296341Sdelphij if (!sk_IPAddressFamily_push(addr, f)) 562296341Sdelphij goto err; 563167612Ssimon 564296341Sdelphij return f; 565167612Ssimon 566167612Ssimon err: 567296341Sdelphij IPAddressFamily_free(f); 568296341Sdelphij return NULL; 569167612Ssimon} 570167612Ssimon 571167612Ssimon/* 572167612Ssimon * Add an inheritance element. 573167612Ssimon */ 574167612Ssimonint v3_addr_add_inherit(IPAddrBlocks *addr, 575296341Sdelphij const unsigned afi, const unsigned *safi) 576167612Ssimon{ 577296341Sdelphij IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi); 578296341Sdelphij if (f == NULL || 579296341Sdelphij f->ipAddressChoice == NULL || 580296341Sdelphij (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges && 581296341Sdelphij f->ipAddressChoice->u.addressesOrRanges != NULL)) 582296341Sdelphij return 0; 583296341Sdelphij if (f->ipAddressChoice->type == IPAddressChoice_inherit && 584296341Sdelphij f->ipAddressChoice->u.inherit != NULL) 585296341Sdelphij return 1; 586296341Sdelphij if (f->ipAddressChoice->u.inherit == NULL && 587296341Sdelphij (f->ipAddressChoice->u.inherit = ASN1_NULL_new()) == NULL) 588296341Sdelphij return 0; 589296341Sdelphij f->ipAddressChoice->type = IPAddressChoice_inherit; 590167612Ssimon return 1; 591167612Ssimon} 592167612Ssimon 593167612Ssimon/* 594167612Ssimon * Construct an IPAddressOrRange sequence, or return an existing one. 595167612Ssimon */ 596167612Ssimonstatic IPAddressOrRanges *make_prefix_or_range(IPAddrBlocks *addr, 597296341Sdelphij const unsigned afi, 598296341Sdelphij const unsigned *safi) 599167612Ssimon{ 600296341Sdelphij IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi); 601296341Sdelphij IPAddressOrRanges *aors = NULL; 602167612Ssimon 603296341Sdelphij if (f == NULL || 604296341Sdelphij f->ipAddressChoice == NULL || 605296341Sdelphij (f->ipAddressChoice->type == IPAddressChoice_inherit && 606296341Sdelphij f->ipAddressChoice->u.inherit != NULL)) 607296341Sdelphij return NULL; 608296341Sdelphij if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges) 609296341Sdelphij aors = f->ipAddressChoice->u.addressesOrRanges; 610296341Sdelphij if (aors != NULL) 611296341Sdelphij return aors; 612296341Sdelphij if ((aors = sk_IPAddressOrRange_new_null()) == NULL) 613296341Sdelphij return NULL; 614296341Sdelphij switch (afi) { 615296341Sdelphij case IANA_AFI_IPV4: 616296341Sdelphij (void)sk_IPAddressOrRange_set_cmp_func(aors, v4IPAddressOrRange_cmp); 617296341Sdelphij break; 618296341Sdelphij case IANA_AFI_IPV6: 619296341Sdelphij (void)sk_IPAddressOrRange_set_cmp_func(aors, v6IPAddressOrRange_cmp); 620296341Sdelphij break; 621296341Sdelphij } 622296341Sdelphij f->ipAddressChoice->type = IPAddressChoice_addressesOrRanges; 623296341Sdelphij f->ipAddressChoice->u.addressesOrRanges = aors; 624167612Ssimon return aors; 625167612Ssimon} 626167612Ssimon 627167612Ssimon/* 628167612Ssimon * Add a prefix. 629167612Ssimon */ 630167612Ssimonint v3_addr_add_prefix(IPAddrBlocks *addr, 631296341Sdelphij const unsigned afi, 632296341Sdelphij const unsigned *safi, 633296341Sdelphij unsigned char *a, const int prefixlen) 634167612Ssimon{ 635296341Sdelphij IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi); 636296341Sdelphij IPAddressOrRange *aor; 637296341Sdelphij if (aors == NULL || !make_addressPrefix(&aor, a, prefixlen)) 638296341Sdelphij return 0; 639296341Sdelphij if (sk_IPAddressOrRange_push(aors, aor)) 640296341Sdelphij return 1; 641296341Sdelphij IPAddressOrRange_free(aor); 642167612Ssimon return 0; 643167612Ssimon} 644167612Ssimon 645167612Ssimon/* 646167612Ssimon * Add a range. 647167612Ssimon */ 648167612Ssimonint v3_addr_add_range(IPAddrBlocks *addr, 649296341Sdelphij const unsigned afi, 650296341Sdelphij const unsigned *safi, 651296341Sdelphij unsigned char *min, unsigned char *max) 652167612Ssimon{ 653296341Sdelphij IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi); 654296341Sdelphij IPAddressOrRange *aor; 655296341Sdelphij int length = length_from_afi(afi); 656296341Sdelphij if (aors == NULL) 657296341Sdelphij return 0; 658296341Sdelphij if (!make_addressRange(&aor, min, max, length)) 659296341Sdelphij return 0; 660296341Sdelphij if (sk_IPAddressOrRange_push(aors, aor)) 661296341Sdelphij return 1; 662296341Sdelphij IPAddressOrRange_free(aor); 663167612Ssimon return 0; 664167612Ssimon} 665167612Ssimon 666167612Ssimon/* 667167612Ssimon * Extract min and max values from an IPAddressOrRange. 668167612Ssimon */ 669237657Sjkimstatic int extract_min_max(IPAddressOrRange *aor, 670296341Sdelphij unsigned char *min, unsigned char *max, int length) 671167612Ssimon{ 672296341Sdelphij if (aor == NULL || min == NULL || max == NULL) 673296341Sdelphij return 0; 674296341Sdelphij switch (aor->type) { 675296341Sdelphij case IPAddressOrRange_addressPrefix: 676296341Sdelphij return (addr_expand(min, aor->u.addressPrefix, length, 0x00) && 677296341Sdelphij addr_expand(max, aor->u.addressPrefix, length, 0xFF)); 678296341Sdelphij case IPAddressOrRange_addressRange: 679296341Sdelphij return (addr_expand(min, aor->u.addressRange->min, length, 0x00) && 680296341Sdelphij addr_expand(max, aor->u.addressRange->max, length, 0xFF)); 681296341Sdelphij } 682237657Sjkim return 0; 683167612Ssimon} 684167612Ssimon 685167612Ssimon/* 686167612Ssimon * Public wrapper for extract_min_max(). 687167612Ssimon */ 688167612Ssimonint v3_addr_get_range(IPAddressOrRange *aor, 689296341Sdelphij const unsigned afi, 690296341Sdelphij unsigned char *min, 691296341Sdelphij unsigned char *max, const int length) 692167612Ssimon{ 693296341Sdelphij int afi_length = length_from_afi(afi); 694296341Sdelphij if (aor == NULL || min == NULL || max == NULL || 695296341Sdelphij afi_length == 0 || length < afi_length || 696296341Sdelphij (aor->type != IPAddressOrRange_addressPrefix && 697296341Sdelphij aor->type != IPAddressOrRange_addressRange) || 698296341Sdelphij !extract_min_max(aor, min, max, afi_length)) 699296341Sdelphij return 0; 700237657Sjkim 701296341Sdelphij return afi_length; 702167612Ssimon} 703167612Ssimon 704167612Ssimon/* 705167612Ssimon * Sort comparision function for a sequence of IPAddressFamily. 706167612Ssimon * 707167612Ssimon * The last paragraph of RFC 3779 2.2.3.3 is slightly ambiguous about 708167612Ssimon * the ordering: I can read it as meaning that IPv6 without a SAFI 709167612Ssimon * comes before IPv4 with a SAFI, which seems pretty weird. The 710167612Ssimon * examples in appendix B suggest that the author intended the 711167612Ssimon * null-SAFI rule to apply only within a single AFI, which is what I 712167612Ssimon * would have expected and is what the following code implements. 713167612Ssimon */ 714296341Sdelphijstatic int IPAddressFamily_cmp(const IPAddressFamily *const *a_, 715296341Sdelphij const IPAddressFamily *const *b_) 716167612Ssimon{ 717296341Sdelphij const ASN1_OCTET_STRING *a = (*a_)->addressFamily; 718296341Sdelphij const ASN1_OCTET_STRING *b = (*b_)->addressFamily; 719296341Sdelphij int len = ((a->length <= b->length) ? a->length : b->length); 720296341Sdelphij int cmp = memcmp(a->data, b->data, len); 721296341Sdelphij return cmp ? cmp : a->length - b->length; 722167612Ssimon} 723167612Ssimon 724167612Ssimon/* 725167612Ssimon * Check whether an IPAddrBLocks is in canonical form. 726167612Ssimon */ 727167612Ssimonint v3_addr_is_canonical(IPAddrBlocks *addr) 728167612Ssimon{ 729296341Sdelphij unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; 730296341Sdelphij unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN]; 731296341Sdelphij IPAddressOrRanges *aors; 732296341Sdelphij int i, j, k; 733167612Ssimon 734296341Sdelphij /* 735296341Sdelphij * Empty extension is cannonical. 736296341Sdelphij */ 737296341Sdelphij if (addr == NULL) 738296341Sdelphij return 1; 739167612Ssimon 740167612Ssimon /* 741296341Sdelphij * Check whether the top-level list is in order. 742167612Ssimon */ 743296341Sdelphij for (i = 0; i < sk_IPAddressFamily_num(addr) - 1; i++) { 744296341Sdelphij const IPAddressFamily *a = sk_IPAddressFamily_value(addr, i); 745296341Sdelphij const IPAddressFamily *b = sk_IPAddressFamily_value(addr, i + 1); 746296341Sdelphij if (IPAddressFamily_cmp(&a, &b) >= 0) 747296341Sdelphij return 0; 748167612Ssimon } 749167612Ssimon 750167612Ssimon /* 751296341Sdelphij * Top level's ok, now check each address family. 752167612Ssimon */ 753296341Sdelphij for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { 754296341Sdelphij IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); 755296341Sdelphij int length = length_from_afi(v3_addr_get_afi(f)); 756167612Ssimon 757296341Sdelphij /* 758296341Sdelphij * Inheritance is canonical. Anything other than inheritance or 759296341Sdelphij * a SEQUENCE OF IPAddressOrRange is an ASN.1 error or something. 760296341Sdelphij */ 761296341Sdelphij if (f == NULL || f->ipAddressChoice == NULL) 762296341Sdelphij return 0; 763296341Sdelphij switch (f->ipAddressChoice->type) { 764296341Sdelphij case IPAddressChoice_inherit: 765296341Sdelphij continue; 766296341Sdelphij case IPAddressChoice_addressesOrRanges: 767296341Sdelphij break; 768296341Sdelphij default: 769296341Sdelphij return 0; 770296341Sdelphij } 771167612Ssimon 772296341Sdelphij /* 773296341Sdelphij * It's an IPAddressOrRanges sequence, check it. 774296341Sdelphij */ 775296341Sdelphij aors = f->ipAddressChoice->u.addressesOrRanges; 776296341Sdelphij if (sk_IPAddressOrRange_num(aors) == 0) 777296341Sdelphij return 0; 778296341Sdelphij for (j = 0; j < sk_IPAddressOrRange_num(aors) - 1; j++) { 779296341Sdelphij IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); 780296341Sdelphij IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, j + 1); 781167612Ssimon 782296341Sdelphij if (!extract_min_max(a, a_min, a_max, length) || 783296341Sdelphij !extract_min_max(b, b_min, b_max, length)) 784296341Sdelphij return 0; 785167612Ssimon 786296341Sdelphij /* 787296341Sdelphij * Punt misordered list, overlapping start, or inverted range. 788296341Sdelphij */ 789296341Sdelphij if (memcmp(a_min, b_min, length) >= 0 || 790296341Sdelphij memcmp(a_min, a_max, length) > 0 || 791296341Sdelphij memcmp(b_min, b_max, length) > 0) 792296341Sdelphij return 0; 793296341Sdelphij 794296341Sdelphij /* 795296341Sdelphij * Punt if adjacent or overlapping. Check for adjacency by 796296341Sdelphij * subtracting one from b_min first. 797296341Sdelphij */ 798296341Sdelphij for (k = length - 1; k >= 0 && b_min[k]-- == 0x00; k--) ; 799296341Sdelphij if (memcmp(a_max, b_min, length) >= 0) 800296341Sdelphij return 0; 801296341Sdelphij 802296341Sdelphij /* 803296341Sdelphij * Check for range that should be expressed as a prefix. 804296341Sdelphij */ 805296341Sdelphij if (a->type == IPAddressOrRange_addressRange && 806296341Sdelphij range_should_be_prefix(a_min, a_max, length) >= 0) 807296341Sdelphij return 0; 808296341Sdelphij } 809296341Sdelphij 810296341Sdelphij /* 811296341Sdelphij * Check range to see if it's inverted or should be a 812296341Sdelphij * prefix. 813296341Sdelphij */ 814296341Sdelphij j = sk_IPAddressOrRange_num(aors) - 1; 815296341Sdelphij { 816296341Sdelphij IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); 817296341Sdelphij if (a != NULL && a->type == IPAddressOrRange_addressRange) { 818296341Sdelphij if (!extract_min_max(a, a_min, a_max, length)) 819296341Sdelphij return 0; 820296341Sdelphij if (memcmp(a_min, a_max, length) > 0 || 821296341Sdelphij range_should_be_prefix(a_min, a_max, length) >= 0) 822296341Sdelphij return 0; 823296341Sdelphij } 824296341Sdelphij } 825167612Ssimon } 826167612Ssimon 827167612Ssimon /* 828296341Sdelphij * If we made it through all that, we're happy. 829167612Ssimon */ 830296341Sdelphij return 1; 831167612Ssimon} 832167612Ssimon 833167612Ssimon/* 834167612Ssimon * Whack an IPAddressOrRanges into canonical form. 835167612Ssimon */ 836167612Ssimonstatic int IPAddressOrRanges_canonize(IPAddressOrRanges *aors, 837296341Sdelphij const unsigned afi) 838167612Ssimon{ 839296341Sdelphij int i, j, length = length_from_afi(afi); 840167612Ssimon 841167612Ssimon /* 842296341Sdelphij * Sort the IPAddressOrRanges sequence. 843237657Sjkim */ 844296341Sdelphij sk_IPAddressOrRange_sort(aors); 845237657Sjkim 846237657Sjkim /* 847296341Sdelphij * Clean up representation issues, punt on duplicates or overlaps. 848167612Ssimon */ 849296341Sdelphij for (i = 0; i < sk_IPAddressOrRange_num(aors) - 1; i++) { 850296341Sdelphij IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, i); 851296341Sdelphij IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, i + 1); 852296341Sdelphij unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; 853296341Sdelphij unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN]; 854167612Ssimon 855296341Sdelphij if (!extract_min_max(a, a_min, a_max, length) || 856296341Sdelphij !extract_min_max(b, b_min, b_max, length)) 857296341Sdelphij return 0; 858296341Sdelphij 859296341Sdelphij /* 860296341Sdelphij * Punt inverted ranges. 861296341Sdelphij */ 862296341Sdelphij if (memcmp(a_min, a_max, length) > 0 || 863296341Sdelphij memcmp(b_min, b_max, length) > 0) 864296341Sdelphij return 0; 865296341Sdelphij 866296341Sdelphij /* 867296341Sdelphij * Punt overlaps. 868296341Sdelphij */ 869296341Sdelphij if (memcmp(a_max, b_min, length) >= 0) 870296341Sdelphij return 0; 871296341Sdelphij 872296341Sdelphij /* 873296341Sdelphij * Merge if a and b are adjacent. We check for 874296341Sdelphij * adjacency by subtracting one from b_min first. 875296341Sdelphij */ 876296341Sdelphij for (j = length - 1; j >= 0 && b_min[j]-- == 0x00; j--) ; 877296341Sdelphij if (memcmp(a_max, b_min, length) == 0) { 878296341Sdelphij IPAddressOrRange *merged; 879296341Sdelphij if (!make_addressRange(&merged, a_min, b_max, length)) 880296341Sdelphij return 0; 881296341Sdelphij (void)sk_IPAddressOrRange_set(aors, i, merged); 882296341Sdelphij (void)sk_IPAddressOrRange_delete(aors, i + 1); 883296341Sdelphij IPAddressOrRange_free(a); 884296341Sdelphij IPAddressOrRange_free(b); 885296341Sdelphij --i; 886296341Sdelphij continue; 887296341Sdelphij } 888296341Sdelphij } 889296341Sdelphij 890167612Ssimon /* 891296341Sdelphij * Check for inverted final range. 892167612Ssimon */ 893296341Sdelphij j = sk_IPAddressOrRange_num(aors) - 1; 894296341Sdelphij { 895296341Sdelphij IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); 896296341Sdelphij if (a != NULL && a->type == IPAddressOrRange_addressRange) { 897296341Sdelphij unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; 898296341Sdelphij extract_min_max(a, a_min, a_max, length); 899296341Sdelphij if (memcmp(a_min, a_max, length) > 0) 900296341Sdelphij return 0; 901296341Sdelphij } 902167612Ssimon } 903167612Ssimon 904296341Sdelphij return 1; 905167612Ssimon} 906167612Ssimon 907167612Ssimon/* 908167612Ssimon * Whack an IPAddrBlocks extension into canonical form. 909167612Ssimon */ 910167612Ssimonint v3_addr_canonize(IPAddrBlocks *addr) 911167612Ssimon{ 912296341Sdelphij int i; 913296341Sdelphij for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { 914296341Sdelphij IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); 915296341Sdelphij if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges && 916296341Sdelphij !IPAddressOrRanges_canonize(f->ipAddressChoice-> 917296341Sdelphij u.addressesOrRanges, 918296341Sdelphij v3_addr_get_afi(f))) 919296341Sdelphij return 0; 920296341Sdelphij } 921296341Sdelphij (void)sk_IPAddressFamily_set_cmp_func(addr, IPAddressFamily_cmp); 922296341Sdelphij sk_IPAddressFamily_sort(addr); 923296341Sdelphij OPENSSL_assert(v3_addr_is_canonical(addr)); 924296341Sdelphij return 1; 925167612Ssimon} 926167612Ssimon 927167612Ssimon/* 928167612Ssimon * v2i handler for the IPAddrBlocks extension. 929167612Ssimon */ 930238405Sjkimstatic void *v2i_IPAddrBlocks(const struct v3_ext_method *method, 931296341Sdelphij struct v3_ext_ctx *ctx, 932296341Sdelphij STACK_OF(CONF_VALUE) *values) 933167612Ssimon{ 934296341Sdelphij static const char v4addr_chars[] = "0123456789."; 935296341Sdelphij static const char v6addr_chars[] = "0123456789.:abcdefABCDEF"; 936296341Sdelphij IPAddrBlocks *addr = NULL; 937296341Sdelphij char *s = NULL, *t; 938296341Sdelphij int i; 939167612Ssimon 940296341Sdelphij if ((addr = sk_IPAddressFamily_new(IPAddressFamily_cmp)) == NULL) { 941296341Sdelphij X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); 942296341Sdelphij return NULL; 943167612Ssimon } 944167612Ssimon 945296341Sdelphij for (i = 0; i < sk_CONF_VALUE_num(values); i++) { 946296341Sdelphij CONF_VALUE *val = sk_CONF_VALUE_value(values, i); 947296341Sdelphij unsigned char min[ADDR_RAW_BUF_LEN], max[ADDR_RAW_BUF_LEN]; 948296341Sdelphij unsigned afi, *safi = NULL, safi_; 949296341Sdelphij const char *addr_chars; 950296341Sdelphij int prefixlen, i1, i2, delim, length; 951167612Ssimon 952296341Sdelphij if (!name_cmp(val->name, "IPv4")) { 953296341Sdelphij afi = IANA_AFI_IPV4; 954296341Sdelphij } else if (!name_cmp(val->name, "IPv6")) { 955296341Sdelphij afi = IANA_AFI_IPV6; 956296341Sdelphij } else if (!name_cmp(val->name, "IPv4-SAFI")) { 957296341Sdelphij afi = IANA_AFI_IPV4; 958296341Sdelphij safi = &safi_; 959296341Sdelphij } else if (!name_cmp(val->name, "IPv6-SAFI")) { 960296341Sdelphij afi = IANA_AFI_IPV6; 961296341Sdelphij safi = &safi_; 962296341Sdelphij } else { 963296341Sdelphij X509V3err(X509V3_F_V2I_IPADDRBLOCKS, 964296341Sdelphij X509V3_R_EXTENSION_NAME_ERROR); 965296341Sdelphij X509V3_conf_err(val); 966296341Sdelphij goto err; 967296341Sdelphij } 968167612Ssimon 969296341Sdelphij switch (afi) { 970296341Sdelphij case IANA_AFI_IPV4: 971296341Sdelphij addr_chars = v4addr_chars; 972296341Sdelphij break; 973296341Sdelphij case IANA_AFI_IPV6: 974296341Sdelphij addr_chars = v6addr_chars; 975296341Sdelphij break; 976296341Sdelphij } 977167612Ssimon 978296341Sdelphij length = length_from_afi(afi); 979167612Ssimon 980296341Sdelphij /* 981296341Sdelphij * Handle SAFI, if any, and BUF_strdup() so we can null-terminate 982296341Sdelphij * the other input values. 983296341Sdelphij */ 984296341Sdelphij if (safi != NULL) { 985296341Sdelphij *safi = strtoul(val->value, &t, 0); 986296341Sdelphij t += strspn(t, " \t"); 987296341Sdelphij if (*safi > 0xFF || *t++ != ':') { 988296341Sdelphij X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_SAFI); 989296341Sdelphij X509V3_conf_err(val); 990296341Sdelphij goto err; 991296341Sdelphij } 992296341Sdelphij t += strspn(t, " \t"); 993296341Sdelphij s = BUF_strdup(t); 994296341Sdelphij } else { 995296341Sdelphij s = BUF_strdup(val->value); 996296341Sdelphij } 997296341Sdelphij if (s == NULL) { 998296341Sdelphij X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); 999296341Sdelphij goto err; 1000296341Sdelphij } 1001167612Ssimon 1002296341Sdelphij /* 1003296341Sdelphij * Check for inheritance. Not worth additional complexity to 1004296341Sdelphij * optimize this (seldom-used) case. 1005296341Sdelphij */ 1006296341Sdelphij if (!strcmp(s, "inherit")) { 1007296341Sdelphij if (!v3_addr_add_inherit(addr, afi, safi)) { 1008296341Sdelphij X509V3err(X509V3_F_V2I_IPADDRBLOCKS, 1009296341Sdelphij X509V3_R_INVALID_INHERITANCE); 1010296341Sdelphij X509V3_conf_err(val); 1011296341Sdelphij goto err; 1012296341Sdelphij } 1013296341Sdelphij OPENSSL_free(s); 1014296341Sdelphij s = NULL; 1015296341Sdelphij continue; 1016296341Sdelphij } 1017167612Ssimon 1018296341Sdelphij i1 = strspn(s, addr_chars); 1019296341Sdelphij i2 = i1 + strspn(s + i1, " \t"); 1020296341Sdelphij delim = s[i2++]; 1021296341Sdelphij s[i1] = '\0'; 1022296341Sdelphij 1023296341Sdelphij if (a2i_ipadd(min, s) != length) { 1024296341Sdelphij X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_IPADDRESS); 1025296341Sdelphij X509V3_conf_err(val); 1026296341Sdelphij goto err; 1027296341Sdelphij } 1028296341Sdelphij 1029296341Sdelphij switch (delim) { 1030296341Sdelphij case '/': 1031296341Sdelphij prefixlen = (int)strtoul(s + i2, &t, 10); 1032296341Sdelphij if (t == s + i2 || *t != '\0') { 1033296341Sdelphij X509V3err(X509V3_F_V2I_IPADDRBLOCKS, 1034296341Sdelphij X509V3_R_EXTENSION_VALUE_ERROR); 1035296341Sdelphij X509V3_conf_err(val); 1036296341Sdelphij goto err; 1037296341Sdelphij } 1038296341Sdelphij if (!v3_addr_add_prefix(addr, afi, safi, min, prefixlen)) { 1039296341Sdelphij X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); 1040296341Sdelphij goto err; 1041296341Sdelphij } 1042296341Sdelphij break; 1043296341Sdelphij case '-': 1044296341Sdelphij i1 = i2 + strspn(s + i2, " \t"); 1045296341Sdelphij i2 = i1 + strspn(s + i1, addr_chars); 1046296341Sdelphij if (i1 == i2 || s[i2] != '\0') { 1047296341Sdelphij X509V3err(X509V3_F_V2I_IPADDRBLOCKS, 1048296341Sdelphij X509V3_R_EXTENSION_VALUE_ERROR); 1049296341Sdelphij X509V3_conf_err(val); 1050296341Sdelphij goto err; 1051296341Sdelphij } 1052296341Sdelphij if (a2i_ipadd(max, s + i1) != length) { 1053296341Sdelphij X509V3err(X509V3_F_V2I_IPADDRBLOCKS, 1054296341Sdelphij X509V3_R_INVALID_IPADDRESS); 1055296341Sdelphij X509V3_conf_err(val); 1056296341Sdelphij goto err; 1057296341Sdelphij } 1058296341Sdelphij if (memcmp(min, max, length_from_afi(afi)) > 0) { 1059296341Sdelphij X509V3err(X509V3_F_V2I_IPADDRBLOCKS, 1060296341Sdelphij X509V3_R_EXTENSION_VALUE_ERROR); 1061296341Sdelphij X509V3_conf_err(val); 1062296341Sdelphij goto err; 1063296341Sdelphij } 1064296341Sdelphij if (!v3_addr_add_range(addr, afi, safi, min, max)) { 1065296341Sdelphij X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); 1066296341Sdelphij goto err; 1067296341Sdelphij } 1068296341Sdelphij break; 1069296341Sdelphij case '\0': 1070296341Sdelphij if (!v3_addr_add_prefix(addr, afi, safi, min, length * 8)) { 1071296341Sdelphij X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); 1072296341Sdelphij goto err; 1073296341Sdelphij } 1074296341Sdelphij break; 1075296341Sdelphij default: 1076296341Sdelphij X509V3err(X509V3_F_V2I_IPADDRBLOCKS, 1077296341Sdelphij X509V3_R_EXTENSION_VALUE_ERROR); 1078296341Sdelphij X509V3_conf_err(val); 1079296341Sdelphij goto err; 1080296341Sdelphij } 1081296341Sdelphij 1082296341Sdelphij OPENSSL_free(s); 1083296341Sdelphij s = NULL; 1084167612Ssimon } 1085167612Ssimon 1086296341Sdelphij /* 1087296341Sdelphij * Canonize the result, then we're done. 1088296341Sdelphij */ 1089296341Sdelphij if (!v3_addr_canonize(addr)) 1090296341Sdelphij goto err; 1091296341Sdelphij return addr; 1092167612Ssimon 1093167612Ssimon err: 1094296341Sdelphij OPENSSL_free(s); 1095296341Sdelphij sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free); 1096296341Sdelphij return NULL; 1097167612Ssimon} 1098167612Ssimon 1099167612Ssimon/* 1100167612Ssimon * OpenSSL dispatch 1101167612Ssimon */ 1102167612Ssimonconst X509V3_EXT_METHOD v3_addr = { 1103296341Sdelphij NID_sbgp_ipAddrBlock, /* nid */ 1104296341Sdelphij 0, /* flags */ 1105296341Sdelphij ASN1_ITEM_ref(IPAddrBlocks), /* template */ 1106296341Sdelphij 0, 0, 0, 0, /* old functions, ignored */ 1107296341Sdelphij 0, /* i2s */ 1108296341Sdelphij 0, /* s2i */ 1109296341Sdelphij 0, /* i2v */ 1110296341Sdelphij v2i_IPAddrBlocks, /* v2i */ 1111296341Sdelphij i2r_IPAddrBlocks, /* i2r */ 1112296341Sdelphij 0, /* r2i */ 1113296341Sdelphij NULL /* extension-specific data */ 1114167612Ssimon}; 1115167612Ssimon 1116167612Ssimon/* 1117167612Ssimon * Figure out whether extension sues inheritance. 1118167612Ssimon */ 1119167612Ssimonint v3_addr_inherits(IPAddrBlocks *addr) 1120167612Ssimon{ 1121296341Sdelphij int i; 1122296341Sdelphij if (addr == NULL) 1123296341Sdelphij return 0; 1124296341Sdelphij for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { 1125296341Sdelphij IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); 1126296341Sdelphij if (f->ipAddressChoice->type == IPAddressChoice_inherit) 1127296341Sdelphij return 1; 1128296341Sdelphij } 1129167612Ssimon return 0; 1130167612Ssimon} 1131167612Ssimon 1132167612Ssimon/* 1133167612Ssimon * Figure out whether parent contains child. 1134167612Ssimon */ 1135167612Ssimonstatic int addr_contains(IPAddressOrRanges *parent, 1136296341Sdelphij IPAddressOrRanges *child, int length) 1137167612Ssimon{ 1138296341Sdelphij unsigned char p_min[ADDR_RAW_BUF_LEN], p_max[ADDR_RAW_BUF_LEN]; 1139296341Sdelphij unsigned char c_min[ADDR_RAW_BUF_LEN], c_max[ADDR_RAW_BUF_LEN]; 1140296341Sdelphij int p, c; 1141167612Ssimon 1142296341Sdelphij if (child == NULL || parent == child) 1143296341Sdelphij return 1; 1144296341Sdelphij if (parent == NULL) 1145296341Sdelphij return 0; 1146167612Ssimon 1147296341Sdelphij p = 0; 1148296341Sdelphij for (c = 0; c < sk_IPAddressOrRange_num(child); c++) { 1149296341Sdelphij if (!extract_min_max(sk_IPAddressOrRange_value(child, c), 1150296341Sdelphij c_min, c_max, length)) 1151296341Sdelphij return -1; 1152296341Sdelphij for (;; p++) { 1153296341Sdelphij if (p >= sk_IPAddressOrRange_num(parent)) 1154296341Sdelphij return 0; 1155296341Sdelphij if (!extract_min_max(sk_IPAddressOrRange_value(parent, p), 1156296341Sdelphij p_min, p_max, length)) 1157296341Sdelphij return 0; 1158296341Sdelphij if (memcmp(p_max, c_max, length) < 0) 1159296341Sdelphij continue; 1160296341Sdelphij if (memcmp(p_min, c_min, length) > 0) 1161296341Sdelphij return 0; 1162296341Sdelphij break; 1163296341Sdelphij } 1164167612Ssimon } 1165167612Ssimon 1166296341Sdelphij return 1; 1167167612Ssimon} 1168167612Ssimon 1169167612Ssimon/* 1170167612Ssimon * Test whether a is a subset of b. 1171167612Ssimon */ 1172167612Ssimonint v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b) 1173167612Ssimon{ 1174296341Sdelphij int i; 1175296341Sdelphij if (a == NULL || a == b) 1176296341Sdelphij return 1; 1177296341Sdelphij if (b == NULL || v3_addr_inherits(a) || v3_addr_inherits(b)) 1178296341Sdelphij return 0; 1179296341Sdelphij (void)sk_IPAddressFamily_set_cmp_func(b, IPAddressFamily_cmp); 1180296341Sdelphij for (i = 0; i < sk_IPAddressFamily_num(a); i++) { 1181296341Sdelphij IPAddressFamily *fa = sk_IPAddressFamily_value(a, i); 1182296341Sdelphij int j = sk_IPAddressFamily_find(b, fa); 1183296341Sdelphij IPAddressFamily *fb; 1184296341Sdelphij fb = sk_IPAddressFamily_value(b, j); 1185296341Sdelphij if (fb == NULL) 1186296341Sdelphij return 0; 1187296341Sdelphij if (!addr_contains(fb->ipAddressChoice->u.addressesOrRanges, 1188296341Sdelphij fa->ipAddressChoice->u.addressesOrRanges, 1189296341Sdelphij length_from_afi(v3_addr_get_afi(fb)))) 1190296341Sdelphij return 0; 1191296341Sdelphij } 1192167612Ssimon return 1; 1193167612Ssimon} 1194167612Ssimon 1195167612Ssimon/* 1196167612Ssimon * Validation error handling via callback. 1197167612Ssimon */ 1198296341Sdelphij# define validation_err(_err_) \ 1199296341Sdelphij do { \ 1200296341Sdelphij if (ctx != NULL) { \ 1201296341Sdelphij ctx->error = _err_; \ 1202296341Sdelphij ctx->error_depth = i; \ 1203296341Sdelphij ctx->current_cert = x; \ 1204296341Sdelphij ret = ctx->verify_cb(0, ctx); \ 1205296341Sdelphij } else { \ 1206296341Sdelphij ret = 0; \ 1207296341Sdelphij } \ 1208296341Sdelphij if (!ret) \ 1209296341Sdelphij goto done; \ 1210167612Ssimon } while (0) 1211167612Ssimon 1212167612Ssimon/* 1213167612Ssimon * Core code for RFC 3779 2.3 path validation. 1214167612Ssimon */ 1215167612Ssimonstatic int v3_addr_validate_path_internal(X509_STORE_CTX *ctx, 1216296341Sdelphij STACK_OF(X509) *chain, 1217296341Sdelphij IPAddrBlocks *ext) 1218167612Ssimon{ 1219296341Sdelphij IPAddrBlocks *child = NULL; 1220296341Sdelphij int i, j, ret = 1; 1221296341Sdelphij X509 *x; 1222167612Ssimon 1223296341Sdelphij OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0); 1224296341Sdelphij OPENSSL_assert(ctx != NULL || ext != NULL); 1225296341Sdelphij OPENSSL_assert(ctx == NULL || ctx->verify_cb != NULL); 1226167612Ssimon 1227296341Sdelphij /* 1228296341Sdelphij * Figure out where to start. If we don't have an extension to 1229296341Sdelphij * check, we're done. Otherwise, check canonical form and 1230296341Sdelphij * set up for walking up the chain. 1231296341Sdelphij */ 1232296341Sdelphij if (ext != NULL) { 1233296341Sdelphij i = -1; 1234296341Sdelphij x = NULL; 1235296341Sdelphij } else { 1236296341Sdelphij i = 0; 1237296341Sdelphij x = sk_X509_value(chain, i); 1238296341Sdelphij OPENSSL_assert(x != NULL); 1239296341Sdelphij if ((ext = x->rfc3779_addr) == NULL) 1240296341Sdelphij goto done; 1241167612Ssimon } 1242296341Sdelphij if (!v3_addr_is_canonical(ext)) 1243296341Sdelphij validation_err(X509_V_ERR_INVALID_EXTENSION); 1244296341Sdelphij (void)sk_IPAddressFamily_set_cmp_func(ext, IPAddressFamily_cmp); 1245296341Sdelphij if ((child = sk_IPAddressFamily_dup(ext)) == NULL) { 1246296341Sdelphij X509V3err(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL, 1247296341Sdelphij ERR_R_MALLOC_FAILURE); 1248296341Sdelphij ret = 0; 1249296341Sdelphij goto done; 1250167612Ssimon } 1251167612Ssimon 1252296341Sdelphij /* 1253296341Sdelphij * Now walk up the chain. No cert may list resources that its 1254296341Sdelphij * parent doesn't list. 1255296341Sdelphij */ 1256296341Sdelphij for (i++; i < sk_X509_num(chain); i++) { 1257296341Sdelphij x = sk_X509_value(chain, i); 1258296341Sdelphij OPENSSL_assert(x != NULL); 1259296341Sdelphij if (!v3_addr_is_canonical(x->rfc3779_addr)) 1260296341Sdelphij validation_err(X509_V_ERR_INVALID_EXTENSION); 1261296341Sdelphij if (x->rfc3779_addr == NULL) { 1262296341Sdelphij for (j = 0; j < sk_IPAddressFamily_num(child); j++) { 1263296341Sdelphij IPAddressFamily *fc = sk_IPAddressFamily_value(child, j); 1264296341Sdelphij if (fc->ipAddressChoice->type != IPAddressChoice_inherit) { 1265296341Sdelphij validation_err(X509_V_ERR_UNNESTED_RESOURCE); 1266296341Sdelphij break; 1267296341Sdelphij } 1268296341Sdelphij } 1269296341Sdelphij continue; 1270296341Sdelphij } 1271296341Sdelphij (void)sk_IPAddressFamily_set_cmp_func(x->rfc3779_addr, 1272296341Sdelphij IPAddressFamily_cmp); 1273296341Sdelphij for (j = 0; j < sk_IPAddressFamily_num(child); j++) { 1274296341Sdelphij IPAddressFamily *fc = sk_IPAddressFamily_value(child, j); 1275296341Sdelphij int k = sk_IPAddressFamily_find(x->rfc3779_addr, fc); 1276296341Sdelphij IPAddressFamily *fp = 1277296341Sdelphij sk_IPAddressFamily_value(x->rfc3779_addr, k); 1278296341Sdelphij if (fp == NULL) { 1279296341Sdelphij if (fc->ipAddressChoice->type == 1280296341Sdelphij IPAddressChoice_addressesOrRanges) { 1281296341Sdelphij validation_err(X509_V_ERR_UNNESTED_RESOURCE); 1282296341Sdelphij break; 1283296341Sdelphij } 1284296341Sdelphij continue; 1285296341Sdelphij } 1286296341Sdelphij if (fp->ipAddressChoice->type == 1287296341Sdelphij IPAddressChoice_addressesOrRanges) { 1288296341Sdelphij if (fc->ipAddressChoice->type == IPAddressChoice_inherit 1289296341Sdelphij || addr_contains(fp->ipAddressChoice->u.addressesOrRanges, 1290296341Sdelphij fc->ipAddressChoice->u.addressesOrRanges, 1291296341Sdelphij length_from_afi(v3_addr_get_afi(fc)))) 1292296341Sdelphij sk_IPAddressFamily_set(child, j, fp); 1293296341Sdelphij else 1294296341Sdelphij validation_err(X509_V_ERR_UNNESTED_RESOURCE); 1295296341Sdelphij } 1296296341Sdelphij } 1297167612Ssimon } 1298167612Ssimon 1299296341Sdelphij /* 1300296341Sdelphij * Trust anchor can't inherit. 1301296341Sdelphij */ 1302296341Sdelphij OPENSSL_assert(x != NULL); 1303296341Sdelphij if (x->rfc3779_addr != NULL) { 1304296341Sdelphij for (j = 0; j < sk_IPAddressFamily_num(x->rfc3779_addr); j++) { 1305296341Sdelphij IPAddressFamily *fp = 1306296341Sdelphij sk_IPAddressFamily_value(x->rfc3779_addr, j); 1307296341Sdelphij if (fp->ipAddressChoice->type == IPAddressChoice_inherit 1308296341Sdelphij && sk_IPAddressFamily_find(child, fp) >= 0) 1309296341Sdelphij validation_err(X509_V_ERR_UNNESTED_RESOURCE); 1310296341Sdelphij } 1311296341Sdelphij } 1312296341Sdelphij 1313167612Ssimon done: 1314296341Sdelphij sk_IPAddressFamily_free(child); 1315296341Sdelphij return ret; 1316167612Ssimon} 1317167612Ssimon 1318296341Sdelphij# undef validation_err 1319167612Ssimon 1320167612Ssimon/* 1321167612Ssimon * RFC 3779 2.3 path validation -- called from X509_verify_cert(). 1322167612Ssimon */ 1323167612Ssimonint v3_addr_validate_path(X509_STORE_CTX *ctx) 1324167612Ssimon{ 1325296341Sdelphij return v3_addr_validate_path_internal(ctx, ctx->chain, NULL); 1326167612Ssimon} 1327167612Ssimon 1328167612Ssimon/* 1329167612Ssimon * RFC 3779 2.3 path validation of an extension. 1330167612Ssimon * Test whether chain covers extension. 1331167612Ssimon */ 1332167612Ssimonint v3_addr_validate_resource_set(STACK_OF(X509) *chain, 1333296341Sdelphij IPAddrBlocks *ext, int allow_inheritance) 1334167612Ssimon{ 1335296341Sdelphij if (ext == NULL) 1336296341Sdelphij return 1; 1337296341Sdelphij if (chain == NULL || sk_X509_num(chain) == 0) 1338296341Sdelphij return 0; 1339296341Sdelphij if (!allow_inheritance && v3_addr_inherits(ext)) 1340296341Sdelphij return 0; 1341296341Sdelphij return v3_addr_validate_path_internal(NULL, chain, ext); 1342167612Ssimon} 1343167612Ssimon 1344296341Sdelphij#endif /* OPENSSL_NO_RFC3779 */ 1345