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 13280297Sjkim * 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 98280297SjkimASN1_ITEM_TEMPLATE(IPAddrBlocks) = 99167612Ssimon ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, 100280297Sjkim 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 */ 111280297Sjkim# 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{ 118280297Sjkim switch (afi) { 119280297Sjkim case IANA_AFI_IPV4: 120280297Sjkim return 4; 121280297Sjkim case IANA_AFI_IPV6: 122280297Sjkim return 16; 123280297Sjkim default: 124280297Sjkim return 0; 125280297Sjkim } 126167612Ssimon} 127167612Ssimon 128167612Ssimon/* 129167612Ssimon * Extract the AFI from an IPAddressFamily. 130167612Ssimon */ 131194206Ssimonunsigned int v3_addr_get_afi(const IPAddressFamily *f) 132167612Ssimon{ 133325337Sjkim if (f == NULL 134325337Sjkim || f->addressFamily == NULL 135325337Sjkim || f->addressFamily->data == NULL 136325337Sjkim || f->addressFamily->length < 2) 137325337Sjkim return 0; 138325337Sjkim return (f->addressFamily->data[0] << 8) | f->addressFamily->data[1]; 139167612Ssimon} 140167612Ssimon 141167612Ssimon/* 142167612Ssimon * Expand the bitstring form of an address into a raw byte array. 143167612Ssimon * At the moment this is coded for simplicity, not speed. 144167612Ssimon */ 145237657Sjkimstatic int addr_expand(unsigned char *addr, 146280297Sjkim const ASN1_BIT_STRING *bs, 147280297Sjkim const int length, const unsigned char fill) 148167612Ssimon{ 149280297Sjkim if (bs->length < 0 || bs->length > length) 150280297Sjkim return 0; 151280297Sjkim if (bs->length > 0) { 152280297Sjkim memcpy(addr, bs->data, bs->length); 153280297Sjkim if ((bs->flags & 7) != 0) { 154280297Sjkim unsigned char mask = 0xFF >> (8 - (bs->flags & 7)); 155280297Sjkim if (fill == 0) 156280297Sjkim addr[bs->length - 1] &= ~mask; 157280297Sjkim else 158280297Sjkim addr[bs->length - 1] |= mask; 159280297Sjkim } 160167612Ssimon } 161280297Sjkim memset(addr + bs->length, fill, length - bs->length); 162280297Sjkim return 1; 163167612Ssimon} 164167612Ssimon 165167612Ssimon/* 166167612Ssimon * Extract the prefix length from a bitstring. 167167612Ssimon */ 168280297Sjkim# define addr_prefixlen(bs) ((int) ((bs)->length * 8 - ((bs)->flags & 7))) 169167612Ssimon 170167612Ssimon/* 171167612Ssimon * i2r handler for one address bitstring. 172167612Ssimon */ 173167612Ssimonstatic int i2r_address(BIO *out, 174280297Sjkim const unsigned afi, 175280297Sjkim const unsigned char fill, const ASN1_BIT_STRING *bs) 176167612Ssimon{ 177280297Sjkim unsigned char addr[ADDR_RAW_BUF_LEN]; 178280297Sjkim int i, n; 179167612Ssimon 180280297Sjkim if (bs->length < 0) 181280297Sjkim return 0; 182280297Sjkim switch (afi) { 183280297Sjkim case IANA_AFI_IPV4: 184280297Sjkim if (!addr_expand(addr, bs, 4, fill)) 185280297Sjkim return 0; 186280297Sjkim BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]); 187280297Sjkim break; 188280297Sjkim case IANA_AFI_IPV6: 189280297Sjkim if (!addr_expand(addr, bs, 16, fill)) 190280297Sjkim return 0; 191280297Sjkim for (n = 16; n > 1 && addr[n - 1] == 0x00 && addr[n - 2] == 0x00; 192280297Sjkim n -= 2) ; 193280297Sjkim for (i = 0; i < n; i += 2) 194280297Sjkim BIO_printf(out, "%x%s", (addr[i] << 8) | addr[i + 1], 195280297Sjkim (i < 14 ? ":" : "")); 196280297Sjkim if (i < 16) 197280297Sjkim BIO_puts(out, ":"); 198280297Sjkim if (i == 0) 199280297Sjkim BIO_puts(out, ":"); 200280297Sjkim break; 201280297Sjkim default: 202280297Sjkim for (i = 0; i < bs->length; i++) 203280297Sjkim BIO_printf(out, "%s%02x", (i > 0 ? ":" : ""), bs->data[i]); 204280297Sjkim BIO_printf(out, "[%d]", (int)(bs->flags & 7)); 205280297Sjkim break; 206280297Sjkim } 207280297Sjkim return 1; 208167612Ssimon} 209167612Ssimon 210167612Ssimon/* 211167612Ssimon * i2r handler for a sequence of addresses and ranges. 212167612Ssimon */ 213167612Ssimonstatic int i2r_IPAddressOrRanges(BIO *out, 214280297Sjkim const int indent, 215280297Sjkim const IPAddressOrRanges *aors, 216280297Sjkim const unsigned afi) 217167612Ssimon{ 218280297Sjkim int i; 219280297Sjkim for (i = 0; i < sk_IPAddressOrRange_num(aors); i++) { 220280297Sjkim const IPAddressOrRange *aor = sk_IPAddressOrRange_value(aors, i); 221280297Sjkim BIO_printf(out, "%*s", indent, ""); 222280297Sjkim switch (aor->type) { 223280297Sjkim case IPAddressOrRange_addressPrefix: 224280297Sjkim if (!i2r_address(out, afi, 0x00, aor->u.addressPrefix)) 225280297Sjkim return 0; 226280297Sjkim BIO_printf(out, "/%d\n", addr_prefixlen(aor->u.addressPrefix)); 227280297Sjkim continue; 228280297Sjkim case IPAddressOrRange_addressRange: 229280297Sjkim if (!i2r_address(out, afi, 0x00, aor->u.addressRange->min)) 230280297Sjkim return 0; 231280297Sjkim BIO_puts(out, "-"); 232280297Sjkim if (!i2r_address(out, afi, 0xFF, aor->u.addressRange->max)) 233280297Sjkim return 0; 234280297Sjkim BIO_puts(out, "\n"); 235280297Sjkim continue; 236280297Sjkim } 237167612Ssimon } 238280297Sjkim return 1; 239167612Ssimon} 240167612Ssimon 241167612Ssimon/* 242167612Ssimon * i2r handler for an IPAddrBlocks extension. 243167612Ssimon */ 244238405Sjkimstatic int i2r_IPAddrBlocks(const X509V3_EXT_METHOD *method, 245280297Sjkim void *ext, BIO *out, int indent) 246167612Ssimon{ 247280297Sjkim const IPAddrBlocks *addr = ext; 248280297Sjkim int i; 249280297Sjkim for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { 250280297Sjkim IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); 251280297Sjkim const unsigned int afi = v3_addr_get_afi(f); 252280297Sjkim switch (afi) { 253280297Sjkim case IANA_AFI_IPV4: 254280297Sjkim BIO_printf(out, "%*sIPv4", indent, ""); 255280297Sjkim break; 256280297Sjkim case IANA_AFI_IPV6: 257280297Sjkim BIO_printf(out, "%*sIPv6", indent, ""); 258280297Sjkim break; 259280297Sjkim default: 260280297Sjkim BIO_printf(out, "%*sUnknown AFI %u", indent, "", afi); 261280297Sjkim break; 262280297Sjkim } 263280297Sjkim if (f->addressFamily->length > 2) { 264280297Sjkim switch (f->addressFamily->data[2]) { 265280297Sjkim case 1: 266280297Sjkim BIO_puts(out, " (Unicast)"); 267280297Sjkim break; 268280297Sjkim case 2: 269280297Sjkim BIO_puts(out, " (Multicast)"); 270280297Sjkim break; 271280297Sjkim case 3: 272280297Sjkim BIO_puts(out, " (Unicast/Multicast)"); 273280297Sjkim break; 274280297Sjkim case 4: 275280297Sjkim BIO_puts(out, " (MPLS)"); 276280297Sjkim break; 277280297Sjkim case 64: 278280297Sjkim BIO_puts(out, " (Tunnel)"); 279280297Sjkim break; 280280297Sjkim case 65: 281280297Sjkim BIO_puts(out, " (VPLS)"); 282280297Sjkim break; 283280297Sjkim case 66: 284280297Sjkim BIO_puts(out, " (BGP MDT)"); 285280297Sjkim break; 286280297Sjkim case 128: 287280297Sjkim BIO_puts(out, " (MPLS-labeled VPN)"); 288280297Sjkim break; 289280297Sjkim default: 290280297Sjkim BIO_printf(out, " (Unknown SAFI %u)", 291280297Sjkim (unsigned)f->addressFamily->data[2]); 292280297Sjkim break; 293280297Sjkim } 294280297Sjkim } 295280297Sjkim switch (f->ipAddressChoice->type) { 296280297Sjkim case IPAddressChoice_inherit: 297280297Sjkim BIO_puts(out, ": inherit\n"); 298280297Sjkim break; 299280297Sjkim case IPAddressChoice_addressesOrRanges: 300280297Sjkim BIO_puts(out, ":\n"); 301280297Sjkim if (!i2r_IPAddressOrRanges(out, 302280297Sjkim indent + 2, 303280297Sjkim f->ipAddressChoice-> 304280297Sjkim u.addressesOrRanges, afi)) 305280297Sjkim return 0; 306280297Sjkim break; 307280297Sjkim } 308167612Ssimon } 309280297Sjkim return 1; 310167612Ssimon} 311167612Ssimon 312167612Ssimon/* 313167612Ssimon * Sort comparison function for a sequence of IPAddressOrRange 314167612Ssimon * elements. 315237657Sjkim * 316237657Sjkim * There's no sane answer we can give if addr_expand() fails, and an 317237657Sjkim * assertion failure on externally supplied data is seriously uncool, 318237657Sjkim * so we just arbitrarily declare that if given invalid inputs this 319237657Sjkim * function returns -1. If this messes up your preferred sort order 320237657Sjkim * for garbage input, tough noogies. 321167612Ssimon */ 322167612Ssimonstatic int IPAddressOrRange_cmp(const IPAddressOrRange *a, 323280297Sjkim const IPAddressOrRange *b, const int length) 324167612Ssimon{ 325280297Sjkim unsigned char addr_a[ADDR_RAW_BUF_LEN], addr_b[ADDR_RAW_BUF_LEN]; 326280297Sjkim int prefixlen_a = 0, prefixlen_b = 0; 327280297Sjkim int r; 328167612Ssimon 329280297Sjkim switch (a->type) { 330280297Sjkim case IPAddressOrRange_addressPrefix: 331280297Sjkim if (!addr_expand(addr_a, a->u.addressPrefix, length, 0x00)) 332280297Sjkim return -1; 333280297Sjkim prefixlen_a = addr_prefixlen(a->u.addressPrefix); 334280297Sjkim break; 335280297Sjkim case IPAddressOrRange_addressRange: 336280297Sjkim if (!addr_expand(addr_a, a->u.addressRange->min, length, 0x00)) 337280297Sjkim return -1; 338280297Sjkim prefixlen_a = length * 8; 339280297Sjkim break; 340280297Sjkim } 341167612Ssimon 342280297Sjkim switch (b->type) { 343280297Sjkim case IPAddressOrRange_addressPrefix: 344280297Sjkim if (!addr_expand(addr_b, b->u.addressPrefix, length, 0x00)) 345280297Sjkim return -1; 346280297Sjkim prefixlen_b = addr_prefixlen(b->u.addressPrefix); 347280297Sjkim break; 348280297Sjkim case IPAddressOrRange_addressRange: 349280297Sjkim if (!addr_expand(addr_b, b->u.addressRange->min, length, 0x00)) 350280297Sjkim return -1; 351280297Sjkim prefixlen_b = length * 8; 352280297Sjkim break; 353280297Sjkim } 354167612Ssimon 355280297Sjkim if ((r = memcmp(addr_a, addr_b, length)) != 0) 356280297Sjkim return r; 357280297Sjkim else 358280297Sjkim return prefixlen_a - prefixlen_b; 359167612Ssimon} 360167612Ssimon 361167612Ssimon/* 362167612Ssimon * IPv4-specific closure over IPAddressOrRange_cmp, since sk_sort() 363167612Ssimon * comparision routines are only allowed two arguments. 364167612Ssimon */ 365280297Sjkimstatic int v4IPAddressOrRange_cmp(const IPAddressOrRange *const *a, 366280297Sjkim const IPAddressOrRange *const *b) 367167612Ssimon{ 368280297Sjkim return IPAddressOrRange_cmp(*a, *b, 4); 369167612Ssimon} 370167612Ssimon 371167612Ssimon/* 372167612Ssimon * IPv6-specific closure over IPAddressOrRange_cmp, since sk_sort() 373167612Ssimon * comparision routines are only allowed two arguments. 374167612Ssimon */ 375280297Sjkimstatic int v6IPAddressOrRange_cmp(const IPAddressOrRange *const *a, 376280297Sjkim const IPAddressOrRange *const *b) 377167612Ssimon{ 378280297Sjkim return IPAddressOrRange_cmp(*a, *b, 16); 379167612Ssimon} 380167612Ssimon 381167612Ssimon/* 382167612Ssimon * Calculate whether a range collapses to a prefix. 383167612Ssimon * See last paragraph of RFC 3779 2.2.3.7. 384167612Ssimon */ 385167612Ssimonstatic int range_should_be_prefix(const unsigned char *min, 386280297Sjkim const unsigned char *max, const int length) 387167612Ssimon{ 388280297Sjkim unsigned char mask; 389280297Sjkim int i, j; 390167612Ssimon 391280297Sjkim OPENSSL_assert(memcmp(min, max, length) <= 0); 392280297Sjkim for (i = 0; i < length && min[i] == max[i]; i++) ; 393280297Sjkim for (j = length - 1; j >= 0 && min[j] == 0x00 && max[j] == 0xFF; j--) ; 394280297Sjkim if (i < j) 395280297Sjkim return -1; 396280297Sjkim if (i > j) 397280297Sjkim return i * 8; 398280297Sjkim mask = min[i] ^ max[i]; 399280297Sjkim switch (mask) { 400280297Sjkim case 0x01: 401280297Sjkim j = 7; 402280297Sjkim break; 403280297Sjkim case 0x03: 404280297Sjkim j = 6; 405280297Sjkim break; 406280297Sjkim case 0x07: 407280297Sjkim j = 5; 408280297Sjkim break; 409280297Sjkim case 0x0F: 410280297Sjkim j = 4; 411280297Sjkim break; 412280297Sjkim case 0x1F: 413280297Sjkim j = 3; 414280297Sjkim break; 415280297Sjkim case 0x3F: 416280297Sjkim j = 2; 417280297Sjkim break; 418280297Sjkim case 0x7F: 419280297Sjkim j = 1; 420280297Sjkim break; 421280297Sjkim default: 422280297Sjkim return -1; 423280297Sjkim } 424280297Sjkim if ((min[i] & mask) != 0 || (max[i] & mask) != mask) 425280297Sjkim return -1; 426280297Sjkim else 427280297Sjkim return i * 8 + j; 428167612Ssimon} 429167612Ssimon 430167612Ssimon/* 431167612Ssimon * Construct a prefix. 432167612Ssimon */ 433167612Ssimonstatic int make_addressPrefix(IPAddressOrRange **result, 434280297Sjkim unsigned char *addr, const int prefixlen) 435167612Ssimon{ 436280297Sjkim int bytelen = (prefixlen + 7) / 8, bitlen = prefixlen % 8; 437280297Sjkim IPAddressOrRange *aor = IPAddressOrRange_new(); 438167612Ssimon 439280297Sjkim if (aor == NULL) 440280297Sjkim return 0; 441280297Sjkim aor->type = IPAddressOrRange_addressPrefix; 442280297Sjkim if (aor->u.addressPrefix == NULL && 443280297Sjkim (aor->u.addressPrefix = ASN1_BIT_STRING_new()) == NULL) 444280297Sjkim goto err; 445280297Sjkim if (!ASN1_BIT_STRING_set(aor->u.addressPrefix, addr, bytelen)) 446280297Sjkim goto err; 447280297Sjkim aor->u.addressPrefix->flags &= ~7; 448280297Sjkim aor->u.addressPrefix->flags |= ASN1_STRING_FLAG_BITS_LEFT; 449280297Sjkim if (bitlen > 0) { 450280297Sjkim aor->u.addressPrefix->data[bytelen - 1] &= ~(0xFF >> bitlen); 451280297Sjkim aor->u.addressPrefix->flags |= 8 - bitlen; 452280297Sjkim } 453167612Ssimon 454280297Sjkim *result = aor; 455280297Sjkim return 1; 456280297Sjkim 457167612Ssimon err: 458280297Sjkim IPAddressOrRange_free(aor); 459280297Sjkim return 0; 460167612Ssimon} 461167612Ssimon 462167612Ssimon/* 463167612Ssimon * Construct a range. If it can be expressed as a prefix, 464167612Ssimon * return a prefix instead. Doing this here simplifies 465167612Ssimon * the rest of the code considerably. 466167612Ssimon */ 467167612Ssimonstatic int make_addressRange(IPAddressOrRange **result, 468280297Sjkim unsigned char *min, 469280297Sjkim unsigned char *max, const int length) 470167612Ssimon{ 471280297Sjkim IPAddressOrRange *aor; 472280297Sjkim int i, prefixlen; 473167612Ssimon 474280297Sjkim if ((prefixlen = range_should_be_prefix(min, max, length)) >= 0) 475280297Sjkim return make_addressPrefix(result, min, prefixlen); 476167612Ssimon 477280297Sjkim if ((aor = IPAddressOrRange_new()) == NULL) 478280297Sjkim return 0; 479280297Sjkim aor->type = IPAddressOrRange_addressRange; 480280297Sjkim OPENSSL_assert(aor->u.addressRange == NULL); 481280297Sjkim if ((aor->u.addressRange = IPAddressRange_new()) == NULL) 482280297Sjkim goto err; 483280297Sjkim if (aor->u.addressRange->min == NULL && 484280297Sjkim (aor->u.addressRange->min = ASN1_BIT_STRING_new()) == NULL) 485280297Sjkim goto err; 486280297Sjkim if (aor->u.addressRange->max == NULL && 487280297Sjkim (aor->u.addressRange->max = ASN1_BIT_STRING_new()) == NULL) 488280297Sjkim goto err; 489167612Ssimon 490280297Sjkim for (i = length; i > 0 && min[i - 1] == 0x00; --i) ; 491280297Sjkim if (!ASN1_BIT_STRING_set(aor->u.addressRange->min, min, i)) 492280297Sjkim goto err; 493280297Sjkim aor->u.addressRange->min->flags &= ~7; 494280297Sjkim aor->u.addressRange->min->flags |= ASN1_STRING_FLAG_BITS_LEFT; 495280297Sjkim if (i > 0) { 496280297Sjkim unsigned char b = min[i - 1]; 497280297Sjkim int j = 1; 498280297Sjkim while ((b & (0xFFU >> j)) != 0) 499280297Sjkim ++j; 500280297Sjkim aor->u.addressRange->min->flags |= 8 - j; 501280297Sjkim } 502167612Ssimon 503280297Sjkim for (i = length; i > 0 && max[i - 1] == 0xFF; --i) ; 504280297Sjkim if (!ASN1_BIT_STRING_set(aor->u.addressRange->max, max, i)) 505280297Sjkim goto err; 506280297Sjkim aor->u.addressRange->max->flags &= ~7; 507280297Sjkim aor->u.addressRange->max->flags |= ASN1_STRING_FLAG_BITS_LEFT; 508280297Sjkim if (i > 0) { 509280297Sjkim unsigned char b = max[i - 1]; 510280297Sjkim int j = 1; 511280297Sjkim while ((b & (0xFFU >> j)) != (0xFFU >> j)) 512280297Sjkim ++j; 513280297Sjkim aor->u.addressRange->max->flags |= 8 - j; 514280297Sjkim } 515167612Ssimon 516280297Sjkim *result = aor; 517280297Sjkim return 1; 518167612Ssimon 519167612Ssimon err: 520280297Sjkim IPAddressOrRange_free(aor); 521280297Sjkim return 0; 522167612Ssimon} 523167612Ssimon 524167612Ssimon/* 525167612Ssimon * Construct a new address family or find an existing one. 526167612Ssimon */ 527167612Ssimonstatic IPAddressFamily *make_IPAddressFamily(IPAddrBlocks *addr, 528280297Sjkim const unsigned afi, 529280297Sjkim const unsigned *safi) 530167612Ssimon{ 531280297Sjkim IPAddressFamily *f; 532280297Sjkim unsigned char key[3]; 533280297Sjkim unsigned keylen; 534280297Sjkim int i; 535167612Ssimon 536280297Sjkim key[0] = (afi >> 8) & 0xFF; 537280297Sjkim key[1] = afi & 0xFF; 538280297Sjkim if (safi != NULL) { 539280297Sjkim key[2] = *safi & 0xFF; 540280297Sjkim keylen = 3; 541280297Sjkim } else { 542280297Sjkim keylen = 2; 543280297Sjkim } 544167612Ssimon 545280297Sjkim for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { 546280297Sjkim f = sk_IPAddressFamily_value(addr, i); 547280297Sjkim OPENSSL_assert(f->addressFamily->data != NULL); 548280297Sjkim if (f->addressFamily->length == keylen && 549280297Sjkim !memcmp(f->addressFamily->data, key, keylen)) 550280297Sjkim return f; 551280297Sjkim } 552167612Ssimon 553280297Sjkim if ((f = IPAddressFamily_new()) == NULL) 554280297Sjkim goto err; 555280297Sjkim if (f->ipAddressChoice == NULL && 556280297Sjkim (f->ipAddressChoice = IPAddressChoice_new()) == NULL) 557280297Sjkim goto err; 558280297Sjkim if (f->addressFamily == NULL && 559280297Sjkim (f->addressFamily = ASN1_OCTET_STRING_new()) == NULL) 560280297Sjkim goto err; 561280297Sjkim if (!ASN1_OCTET_STRING_set(f->addressFamily, key, keylen)) 562280297Sjkim goto err; 563280297Sjkim if (!sk_IPAddressFamily_push(addr, f)) 564280297Sjkim goto err; 565167612Ssimon 566280297Sjkim return f; 567167612Ssimon 568167612Ssimon err: 569280297Sjkim IPAddressFamily_free(f); 570280297Sjkim return NULL; 571167612Ssimon} 572167612Ssimon 573167612Ssimon/* 574167612Ssimon * Add an inheritance element. 575167612Ssimon */ 576167612Ssimonint v3_addr_add_inherit(IPAddrBlocks *addr, 577280297Sjkim const unsigned afi, const unsigned *safi) 578167612Ssimon{ 579280297Sjkim IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi); 580280297Sjkim if (f == NULL || 581280297Sjkim f->ipAddressChoice == NULL || 582280297Sjkim (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges && 583280297Sjkim f->ipAddressChoice->u.addressesOrRanges != NULL)) 584280297Sjkim return 0; 585280297Sjkim if (f->ipAddressChoice->type == IPAddressChoice_inherit && 586280297Sjkim f->ipAddressChoice->u.inherit != NULL) 587280297Sjkim return 1; 588280297Sjkim if (f->ipAddressChoice->u.inherit == NULL && 589280297Sjkim (f->ipAddressChoice->u.inherit = ASN1_NULL_new()) == NULL) 590280297Sjkim return 0; 591280297Sjkim f->ipAddressChoice->type = IPAddressChoice_inherit; 592167612Ssimon return 1; 593167612Ssimon} 594167612Ssimon 595167612Ssimon/* 596167612Ssimon * Construct an IPAddressOrRange sequence, or return an existing one. 597167612Ssimon */ 598167612Ssimonstatic IPAddressOrRanges *make_prefix_or_range(IPAddrBlocks *addr, 599280297Sjkim const unsigned afi, 600280297Sjkim const unsigned *safi) 601167612Ssimon{ 602280297Sjkim IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi); 603280297Sjkim IPAddressOrRanges *aors = NULL; 604167612Ssimon 605280297Sjkim if (f == NULL || 606280297Sjkim f->ipAddressChoice == NULL || 607280297Sjkim (f->ipAddressChoice->type == IPAddressChoice_inherit && 608280297Sjkim f->ipAddressChoice->u.inherit != NULL)) 609280297Sjkim return NULL; 610280297Sjkim if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges) 611280297Sjkim aors = f->ipAddressChoice->u.addressesOrRanges; 612280297Sjkim if (aors != NULL) 613280297Sjkim return aors; 614280297Sjkim if ((aors = sk_IPAddressOrRange_new_null()) == NULL) 615280297Sjkim return NULL; 616280297Sjkim switch (afi) { 617280297Sjkim case IANA_AFI_IPV4: 618280297Sjkim (void)sk_IPAddressOrRange_set_cmp_func(aors, v4IPAddressOrRange_cmp); 619280297Sjkim break; 620280297Sjkim case IANA_AFI_IPV6: 621280297Sjkim (void)sk_IPAddressOrRange_set_cmp_func(aors, v6IPAddressOrRange_cmp); 622280297Sjkim break; 623280297Sjkim } 624280297Sjkim f->ipAddressChoice->type = IPAddressChoice_addressesOrRanges; 625280297Sjkim f->ipAddressChoice->u.addressesOrRanges = aors; 626167612Ssimon return aors; 627167612Ssimon} 628167612Ssimon 629167612Ssimon/* 630167612Ssimon * Add a prefix. 631167612Ssimon */ 632167612Ssimonint v3_addr_add_prefix(IPAddrBlocks *addr, 633280297Sjkim const unsigned afi, 634280297Sjkim const unsigned *safi, 635280297Sjkim unsigned char *a, const int prefixlen) 636167612Ssimon{ 637280297Sjkim IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi); 638280297Sjkim IPAddressOrRange *aor; 639280297Sjkim if (aors == NULL || !make_addressPrefix(&aor, a, prefixlen)) 640280297Sjkim return 0; 641280297Sjkim if (sk_IPAddressOrRange_push(aors, aor)) 642280297Sjkim return 1; 643280297Sjkim IPAddressOrRange_free(aor); 644167612Ssimon return 0; 645167612Ssimon} 646167612Ssimon 647167612Ssimon/* 648167612Ssimon * Add a range. 649167612Ssimon */ 650167612Ssimonint v3_addr_add_range(IPAddrBlocks *addr, 651280297Sjkim const unsigned afi, 652280297Sjkim const unsigned *safi, 653280297Sjkim unsigned char *min, unsigned char *max) 654167612Ssimon{ 655280297Sjkim IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi); 656280297Sjkim IPAddressOrRange *aor; 657280297Sjkim int length = length_from_afi(afi); 658280297Sjkim if (aors == NULL) 659280297Sjkim return 0; 660280297Sjkim if (!make_addressRange(&aor, min, max, length)) 661280297Sjkim return 0; 662280297Sjkim if (sk_IPAddressOrRange_push(aors, aor)) 663280297Sjkim return 1; 664280297Sjkim IPAddressOrRange_free(aor); 665167612Ssimon return 0; 666167612Ssimon} 667167612Ssimon 668167612Ssimon/* 669167612Ssimon * Extract min and max values from an IPAddressOrRange. 670167612Ssimon */ 671237657Sjkimstatic int extract_min_max(IPAddressOrRange *aor, 672280297Sjkim unsigned char *min, unsigned char *max, int length) 673167612Ssimon{ 674280297Sjkim if (aor == NULL || min == NULL || max == NULL) 675280297Sjkim return 0; 676280297Sjkim switch (aor->type) { 677280297Sjkim case IPAddressOrRange_addressPrefix: 678280297Sjkim return (addr_expand(min, aor->u.addressPrefix, length, 0x00) && 679280297Sjkim addr_expand(max, aor->u.addressPrefix, length, 0xFF)); 680280297Sjkim case IPAddressOrRange_addressRange: 681280297Sjkim return (addr_expand(min, aor->u.addressRange->min, length, 0x00) && 682280297Sjkim addr_expand(max, aor->u.addressRange->max, length, 0xFF)); 683280297Sjkim } 684237657Sjkim return 0; 685167612Ssimon} 686167612Ssimon 687167612Ssimon/* 688167612Ssimon * Public wrapper for extract_min_max(). 689167612Ssimon */ 690167612Ssimonint v3_addr_get_range(IPAddressOrRange *aor, 691280297Sjkim const unsigned afi, 692280297Sjkim unsigned char *min, 693280297Sjkim unsigned char *max, const int length) 694167612Ssimon{ 695280297Sjkim int afi_length = length_from_afi(afi); 696280297Sjkim if (aor == NULL || min == NULL || max == NULL || 697280297Sjkim afi_length == 0 || length < afi_length || 698280297Sjkim (aor->type != IPAddressOrRange_addressPrefix && 699280297Sjkim aor->type != IPAddressOrRange_addressRange) || 700280297Sjkim !extract_min_max(aor, min, max, afi_length)) 701280297Sjkim return 0; 702237657Sjkim 703280297Sjkim return afi_length; 704167612Ssimon} 705167612Ssimon 706167612Ssimon/* 707167612Ssimon * Sort comparision function for a sequence of IPAddressFamily. 708167612Ssimon * 709167612Ssimon * The last paragraph of RFC 3779 2.2.3.3 is slightly ambiguous about 710167612Ssimon * the ordering: I can read it as meaning that IPv6 without a SAFI 711167612Ssimon * comes before IPv4 with a SAFI, which seems pretty weird. The 712167612Ssimon * examples in appendix B suggest that the author intended the 713167612Ssimon * null-SAFI rule to apply only within a single AFI, which is what I 714167612Ssimon * would have expected and is what the following code implements. 715167612Ssimon */ 716280297Sjkimstatic int IPAddressFamily_cmp(const IPAddressFamily *const *a_, 717280297Sjkim const IPAddressFamily *const *b_) 718167612Ssimon{ 719280297Sjkim const ASN1_OCTET_STRING *a = (*a_)->addressFamily; 720280297Sjkim const ASN1_OCTET_STRING *b = (*b_)->addressFamily; 721280297Sjkim int len = ((a->length <= b->length) ? a->length : b->length); 722280297Sjkim int cmp = memcmp(a->data, b->data, len); 723280297Sjkim return cmp ? cmp : a->length - b->length; 724167612Ssimon} 725167612Ssimon 726167612Ssimon/* 727167612Ssimon * Check whether an IPAddrBLocks is in canonical form. 728167612Ssimon */ 729167612Ssimonint v3_addr_is_canonical(IPAddrBlocks *addr) 730167612Ssimon{ 731280297Sjkim unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; 732280297Sjkim unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN]; 733280297Sjkim IPAddressOrRanges *aors; 734280297Sjkim int i, j, k; 735167612Ssimon 736280297Sjkim /* 737280297Sjkim * Empty extension is cannonical. 738280297Sjkim */ 739280297Sjkim if (addr == NULL) 740280297Sjkim return 1; 741167612Ssimon 742167612Ssimon /* 743280297Sjkim * Check whether the top-level list is in order. 744167612Ssimon */ 745280297Sjkim for (i = 0; i < sk_IPAddressFamily_num(addr) - 1; i++) { 746280297Sjkim const IPAddressFamily *a = sk_IPAddressFamily_value(addr, i); 747280297Sjkim const IPAddressFamily *b = sk_IPAddressFamily_value(addr, i + 1); 748280297Sjkim if (IPAddressFamily_cmp(&a, &b) >= 0) 749280297Sjkim return 0; 750167612Ssimon } 751167612Ssimon 752167612Ssimon /* 753280297Sjkim * Top level's ok, now check each address family. 754167612Ssimon */ 755280297Sjkim for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { 756280297Sjkim IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); 757280297Sjkim int length = length_from_afi(v3_addr_get_afi(f)); 758167612Ssimon 759280297Sjkim /* 760280297Sjkim * Inheritance is canonical. Anything other than inheritance or 761280297Sjkim * a SEQUENCE OF IPAddressOrRange is an ASN.1 error or something. 762280297Sjkim */ 763280297Sjkim if (f == NULL || f->ipAddressChoice == NULL) 764280297Sjkim return 0; 765280297Sjkim switch (f->ipAddressChoice->type) { 766280297Sjkim case IPAddressChoice_inherit: 767280297Sjkim continue; 768280297Sjkim case IPAddressChoice_addressesOrRanges: 769280297Sjkim break; 770280297Sjkim default: 771280297Sjkim return 0; 772280297Sjkim } 773167612Ssimon 774280297Sjkim /* 775280297Sjkim * It's an IPAddressOrRanges sequence, check it. 776280297Sjkim */ 777280297Sjkim aors = f->ipAddressChoice->u.addressesOrRanges; 778280297Sjkim if (sk_IPAddressOrRange_num(aors) == 0) 779280297Sjkim return 0; 780280297Sjkim for (j = 0; j < sk_IPAddressOrRange_num(aors) - 1; j++) { 781280297Sjkim IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); 782280297Sjkim IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, j + 1); 783167612Ssimon 784280297Sjkim if (!extract_min_max(a, a_min, a_max, length) || 785280297Sjkim !extract_min_max(b, b_min, b_max, length)) 786280297Sjkim return 0; 787167612Ssimon 788280297Sjkim /* 789280297Sjkim * Punt misordered list, overlapping start, or inverted range. 790280297Sjkim */ 791280297Sjkim if (memcmp(a_min, b_min, length) >= 0 || 792280297Sjkim memcmp(a_min, a_max, length) > 0 || 793280297Sjkim memcmp(b_min, b_max, length) > 0) 794280297Sjkim return 0; 795280297Sjkim 796280297Sjkim /* 797280297Sjkim * Punt if adjacent or overlapping. Check for adjacency by 798280297Sjkim * subtracting one from b_min first. 799280297Sjkim */ 800280297Sjkim for (k = length - 1; k >= 0 && b_min[k]-- == 0x00; k--) ; 801280297Sjkim if (memcmp(a_max, b_min, length) >= 0) 802280297Sjkim return 0; 803280297Sjkim 804280297Sjkim /* 805280297Sjkim * Check for range that should be expressed as a prefix. 806280297Sjkim */ 807280297Sjkim if (a->type == IPAddressOrRange_addressRange && 808280297Sjkim range_should_be_prefix(a_min, a_max, length) >= 0) 809280297Sjkim return 0; 810280297Sjkim } 811280297Sjkim 812280297Sjkim /* 813280297Sjkim * Check range to see if it's inverted or should be a 814280297Sjkim * prefix. 815280297Sjkim */ 816280297Sjkim j = sk_IPAddressOrRange_num(aors) - 1; 817280297Sjkim { 818280297Sjkim IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); 819280297Sjkim if (a != NULL && a->type == IPAddressOrRange_addressRange) { 820280297Sjkim if (!extract_min_max(a, a_min, a_max, length)) 821280297Sjkim return 0; 822280297Sjkim if (memcmp(a_min, a_max, length) > 0 || 823280297Sjkim range_should_be_prefix(a_min, a_max, length) >= 0) 824280297Sjkim return 0; 825280297Sjkim } 826280297Sjkim } 827167612Ssimon } 828167612Ssimon 829167612Ssimon /* 830280297Sjkim * If we made it through all that, we're happy. 831167612Ssimon */ 832280297Sjkim return 1; 833167612Ssimon} 834167612Ssimon 835167612Ssimon/* 836167612Ssimon * Whack an IPAddressOrRanges into canonical form. 837167612Ssimon */ 838167612Ssimonstatic int IPAddressOrRanges_canonize(IPAddressOrRanges *aors, 839280297Sjkim const unsigned afi) 840167612Ssimon{ 841280297Sjkim int i, j, length = length_from_afi(afi); 842167612Ssimon 843167612Ssimon /* 844280297Sjkim * Sort the IPAddressOrRanges sequence. 845237657Sjkim */ 846280297Sjkim sk_IPAddressOrRange_sort(aors); 847237657Sjkim 848237657Sjkim /* 849280297Sjkim * Clean up representation issues, punt on duplicates or overlaps. 850167612Ssimon */ 851280297Sjkim for (i = 0; i < sk_IPAddressOrRange_num(aors) - 1; i++) { 852280297Sjkim IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, i); 853280297Sjkim IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, i + 1); 854280297Sjkim unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; 855280297Sjkim unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN]; 856167612Ssimon 857280297Sjkim if (!extract_min_max(a, a_min, a_max, length) || 858280297Sjkim !extract_min_max(b, b_min, b_max, length)) 859280297Sjkim return 0; 860280297Sjkim 861280297Sjkim /* 862280297Sjkim * Punt inverted ranges. 863280297Sjkim */ 864280297Sjkim if (memcmp(a_min, a_max, length) > 0 || 865280297Sjkim memcmp(b_min, b_max, length) > 0) 866280297Sjkim return 0; 867280297Sjkim 868280297Sjkim /* 869280297Sjkim * Punt overlaps. 870280297Sjkim */ 871280297Sjkim if (memcmp(a_max, b_min, length) >= 0) 872280297Sjkim return 0; 873280297Sjkim 874280297Sjkim /* 875280297Sjkim * Merge if a and b are adjacent. We check for 876280297Sjkim * adjacency by subtracting one from b_min first. 877280297Sjkim */ 878280297Sjkim for (j = length - 1; j >= 0 && b_min[j]-- == 0x00; j--) ; 879280297Sjkim if (memcmp(a_max, b_min, length) == 0) { 880280297Sjkim IPAddressOrRange *merged; 881280297Sjkim if (!make_addressRange(&merged, a_min, b_max, length)) 882280297Sjkim return 0; 883280297Sjkim (void)sk_IPAddressOrRange_set(aors, i, merged); 884280297Sjkim (void)sk_IPAddressOrRange_delete(aors, i + 1); 885280297Sjkim IPAddressOrRange_free(a); 886280297Sjkim IPAddressOrRange_free(b); 887280297Sjkim --i; 888280297Sjkim continue; 889280297Sjkim } 890280297Sjkim } 891280297Sjkim 892167612Ssimon /* 893280297Sjkim * Check for inverted final range. 894167612Ssimon */ 895280297Sjkim j = sk_IPAddressOrRange_num(aors) - 1; 896280297Sjkim { 897280297Sjkim IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); 898280297Sjkim if (a != NULL && a->type == IPAddressOrRange_addressRange) { 899280297Sjkim unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; 900280297Sjkim extract_min_max(a, a_min, a_max, length); 901280297Sjkim if (memcmp(a_min, a_max, length) > 0) 902280297Sjkim return 0; 903280297Sjkim } 904167612Ssimon } 905167612Ssimon 906280297Sjkim return 1; 907167612Ssimon} 908167612Ssimon 909167612Ssimon/* 910167612Ssimon * Whack an IPAddrBlocks extension into canonical form. 911167612Ssimon */ 912167612Ssimonint v3_addr_canonize(IPAddrBlocks *addr) 913167612Ssimon{ 914280297Sjkim int i; 915280297Sjkim for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { 916280297Sjkim IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); 917280297Sjkim if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges && 918280297Sjkim !IPAddressOrRanges_canonize(f->ipAddressChoice-> 919280297Sjkim u.addressesOrRanges, 920280297Sjkim v3_addr_get_afi(f))) 921280297Sjkim return 0; 922280297Sjkim } 923280297Sjkim (void)sk_IPAddressFamily_set_cmp_func(addr, IPAddressFamily_cmp); 924280297Sjkim sk_IPAddressFamily_sort(addr); 925280297Sjkim OPENSSL_assert(v3_addr_is_canonical(addr)); 926280297Sjkim return 1; 927167612Ssimon} 928167612Ssimon 929167612Ssimon/* 930167612Ssimon * v2i handler for the IPAddrBlocks extension. 931167612Ssimon */ 932238405Sjkimstatic void *v2i_IPAddrBlocks(const struct v3_ext_method *method, 933280297Sjkim struct v3_ext_ctx *ctx, 934280297Sjkim STACK_OF(CONF_VALUE) *values) 935167612Ssimon{ 936280297Sjkim static const char v4addr_chars[] = "0123456789."; 937280297Sjkim static const char v6addr_chars[] = "0123456789.:abcdefABCDEF"; 938280297Sjkim IPAddrBlocks *addr = NULL; 939280297Sjkim char *s = NULL, *t; 940280297Sjkim int i; 941167612Ssimon 942280297Sjkim if ((addr = sk_IPAddressFamily_new(IPAddressFamily_cmp)) == NULL) { 943280297Sjkim X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); 944280297Sjkim return NULL; 945167612Ssimon } 946167612Ssimon 947280297Sjkim for (i = 0; i < sk_CONF_VALUE_num(values); i++) { 948280297Sjkim CONF_VALUE *val = sk_CONF_VALUE_value(values, i); 949280297Sjkim unsigned char min[ADDR_RAW_BUF_LEN], max[ADDR_RAW_BUF_LEN]; 950280297Sjkim unsigned afi, *safi = NULL, safi_; 951280297Sjkim const char *addr_chars; 952280297Sjkim int prefixlen, i1, i2, delim, length; 953167612Ssimon 954280297Sjkim if (!name_cmp(val->name, "IPv4")) { 955280297Sjkim afi = IANA_AFI_IPV4; 956280297Sjkim } else if (!name_cmp(val->name, "IPv6")) { 957280297Sjkim afi = IANA_AFI_IPV6; 958280297Sjkim } else if (!name_cmp(val->name, "IPv4-SAFI")) { 959280297Sjkim afi = IANA_AFI_IPV4; 960280297Sjkim safi = &safi_; 961280297Sjkim } else if (!name_cmp(val->name, "IPv6-SAFI")) { 962280297Sjkim afi = IANA_AFI_IPV6; 963280297Sjkim safi = &safi_; 964280297Sjkim } else { 965280297Sjkim X509V3err(X509V3_F_V2I_IPADDRBLOCKS, 966280297Sjkim X509V3_R_EXTENSION_NAME_ERROR); 967280297Sjkim X509V3_conf_err(val); 968280297Sjkim goto err; 969280297Sjkim } 970167612Ssimon 971280297Sjkim switch (afi) { 972280297Sjkim case IANA_AFI_IPV4: 973280297Sjkim addr_chars = v4addr_chars; 974280297Sjkim break; 975280297Sjkim case IANA_AFI_IPV6: 976280297Sjkim addr_chars = v6addr_chars; 977280297Sjkim break; 978280297Sjkim } 979167612Ssimon 980280297Sjkim length = length_from_afi(afi); 981167612Ssimon 982280297Sjkim /* 983280297Sjkim * Handle SAFI, if any, and BUF_strdup() so we can null-terminate 984280297Sjkim * the other input values. 985280297Sjkim */ 986280297Sjkim if (safi != NULL) { 987280297Sjkim *safi = strtoul(val->value, &t, 0); 988280297Sjkim t += strspn(t, " \t"); 989280297Sjkim if (*safi > 0xFF || *t++ != ':') { 990280297Sjkim X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_SAFI); 991280297Sjkim X509V3_conf_err(val); 992280297Sjkim goto err; 993280297Sjkim } 994280297Sjkim t += strspn(t, " \t"); 995280297Sjkim s = BUF_strdup(t); 996280297Sjkim } else { 997280297Sjkim s = BUF_strdup(val->value); 998280297Sjkim } 999280297Sjkim if (s == NULL) { 1000280297Sjkim X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); 1001280297Sjkim goto err; 1002280297Sjkim } 1003167612Ssimon 1004280297Sjkim /* 1005280297Sjkim * Check for inheritance. Not worth additional complexity to 1006280297Sjkim * optimize this (seldom-used) case. 1007280297Sjkim */ 1008280297Sjkim if (!strcmp(s, "inherit")) { 1009280297Sjkim if (!v3_addr_add_inherit(addr, afi, safi)) { 1010280297Sjkim X509V3err(X509V3_F_V2I_IPADDRBLOCKS, 1011280297Sjkim X509V3_R_INVALID_INHERITANCE); 1012280297Sjkim X509V3_conf_err(val); 1013280297Sjkim goto err; 1014280297Sjkim } 1015280297Sjkim OPENSSL_free(s); 1016280297Sjkim s = NULL; 1017280297Sjkim continue; 1018280297Sjkim } 1019167612Ssimon 1020280297Sjkim i1 = strspn(s, addr_chars); 1021280297Sjkim i2 = i1 + strspn(s + i1, " \t"); 1022280297Sjkim delim = s[i2++]; 1023280297Sjkim s[i1] = '\0'; 1024280297Sjkim 1025280297Sjkim if (a2i_ipadd(min, s) != length) { 1026280297Sjkim X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_IPADDRESS); 1027280297Sjkim X509V3_conf_err(val); 1028280297Sjkim goto err; 1029280297Sjkim } 1030280297Sjkim 1031280297Sjkim switch (delim) { 1032280297Sjkim case '/': 1033280297Sjkim prefixlen = (int)strtoul(s + i2, &t, 10); 1034280297Sjkim if (t == s + i2 || *t != '\0') { 1035280297Sjkim X509V3err(X509V3_F_V2I_IPADDRBLOCKS, 1036280297Sjkim X509V3_R_EXTENSION_VALUE_ERROR); 1037280297Sjkim X509V3_conf_err(val); 1038280297Sjkim goto err; 1039280297Sjkim } 1040280297Sjkim if (!v3_addr_add_prefix(addr, afi, safi, min, prefixlen)) { 1041280297Sjkim X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); 1042280297Sjkim goto err; 1043280297Sjkim } 1044280297Sjkim break; 1045280297Sjkim case '-': 1046280297Sjkim i1 = i2 + strspn(s + i2, " \t"); 1047280297Sjkim i2 = i1 + strspn(s + i1, addr_chars); 1048280297Sjkim if (i1 == i2 || s[i2] != '\0') { 1049280297Sjkim X509V3err(X509V3_F_V2I_IPADDRBLOCKS, 1050280297Sjkim X509V3_R_EXTENSION_VALUE_ERROR); 1051280297Sjkim X509V3_conf_err(val); 1052280297Sjkim goto err; 1053280297Sjkim } 1054280297Sjkim if (a2i_ipadd(max, s + i1) != length) { 1055280297Sjkim X509V3err(X509V3_F_V2I_IPADDRBLOCKS, 1056280297Sjkim X509V3_R_INVALID_IPADDRESS); 1057280297Sjkim X509V3_conf_err(val); 1058280297Sjkim goto err; 1059280297Sjkim } 1060280297Sjkim if (memcmp(min, max, length_from_afi(afi)) > 0) { 1061280297Sjkim X509V3err(X509V3_F_V2I_IPADDRBLOCKS, 1062280297Sjkim X509V3_R_EXTENSION_VALUE_ERROR); 1063280297Sjkim X509V3_conf_err(val); 1064280297Sjkim goto err; 1065280297Sjkim } 1066280297Sjkim if (!v3_addr_add_range(addr, afi, safi, min, max)) { 1067280297Sjkim X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); 1068280297Sjkim goto err; 1069280297Sjkim } 1070280297Sjkim break; 1071280297Sjkim case '\0': 1072280297Sjkim if (!v3_addr_add_prefix(addr, afi, safi, min, length * 8)) { 1073280297Sjkim X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); 1074280297Sjkim goto err; 1075280297Sjkim } 1076280297Sjkim break; 1077280297Sjkim default: 1078280297Sjkim X509V3err(X509V3_F_V2I_IPADDRBLOCKS, 1079280297Sjkim X509V3_R_EXTENSION_VALUE_ERROR); 1080280297Sjkim X509V3_conf_err(val); 1081280297Sjkim goto err; 1082280297Sjkim } 1083280297Sjkim 1084280297Sjkim OPENSSL_free(s); 1085280297Sjkim s = NULL; 1086167612Ssimon } 1087167612Ssimon 1088280297Sjkim /* 1089280297Sjkim * Canonize the result, then we're done. 1090280297Sjkim */ 1091280297Sjkim if (!v3_addr_canonize(addr)) 1092280297Sjkim goto err; 1093280297Sjkim return addr; 1094167612Ssimon 1095167612Ssimon err: 1096280297Sjkim OPENSSL_free(s); 1097280297Sjkim sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free); 1098280297Sjkim return NULL; 1099167612Ssimon} 1100167612Ssimon 1101167612Ssimon/* 1102167612Ssimon * OpenSSL dispatch 1103167612Ssimon */ 1104167612Ssimonconst X509V3_EXT_METHOD v3_addr = { 1105280297Sjkim NID_sbgp_ipAddrBlock, /* nid */ 1106280297Sjkim 0, /* flags */ 1107280297Sjkim ASN1_ITEM_ref(IPAddrBlocks), /* template */ 1108280297Sjkim 0, 0, 0, 0, /* old functions, ignored */ 1109280297Sjkim 0, /* i2s */ 1110280297Sjkim 0, /* s2i */ 1111280297Sjkim 0, /* i2v */ 1112280297Sjkim v2i_IPAddrBlocks, /* v2i */ 1113280297Sjkim i2r_IPAddrBlocks, /* i2r */ 1114280297Sjkim 0, /* r2i */ 1115280297Sjkim NULL /* extension-specific data */ 1116167612Ssimon}; 1117167612Ssimon 1118167612Ssimon/* 1119167612Ssimon * Figure out whether extension sues inheritance. 1120167612Ssimon */ 1121167612Ssimonint v3_addr_inherits(IPAddrBlocks *addr) 1122167612Ssimon{ 1123280297Sjkim int i; 1124280297Sjkim if (addr == NULL) 1125280297Sjkim return 0; 1126280297Sjkim for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { 1127280297Sjkim IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); 1128280297Sjkim if (f->ipAddressChoice->type == IPAddressChoice_inherit) 1129280297Sjkim return 1; 1130280297Sjkim } 1131167612Ssimon return 0; 1132167612Ssimon} 1133167612Ssimon 1134167612Ssimon/* 1135167612Ssimon * Figure out whether parent contains child. 1136167612Ssimon */ 1137167612Ssimonstatic int addr_contains(IPAddressOrRanges *parent, 1138280297Sjkim IPAddressOrRanges *child, int length) 1139167612Ssimon{ 1140280297Sjkim unsigned char p_min[ADDR_RAW_BUF_LEN], p_max[ADDR_RAW_BUF_LEN]; 1141280297Sjkim unsigned char c_min[ADDR_RAW_BUF_LEN], c_max[ADDR_RAW_BUF_LEN]; 1142280297Sjkim int p, c; 1143167612Ssimon 1144280297Sjkim if (child == NULL || parent == child) 1145280297Sjkim return 1; 1146280297Sjkim if (parent == NULL) 1147280297Sjkim return 0; 1148167612Ssimon 1149280297Sjkim p = 0; 1150280297Sjkim for (c = 0; c < sk_IPAddressOrRange_num(child); c++) { 1151280297Sjkim if (!extract_min_max(sk_IPAddressOrRange_value(child, c), 1152280297Sjkim c_min, c_max, length)) 1153280297Sjkim return -1; 1154280297Sjkim for (;; p++) { 1155280297Sjkim if (p >= sk_IPAddressOrRange_num(parent)) 1156280297Sjkim return 0; 1157280297Sjkim if (!extract_min_max(sk_IPAddressOrRange_value(parent, p), 1158280297Sjkim p_min, p_max, length)) 1159280297Sjkim return 0; 1160280297Sjkim if (memcmp(p_max, c_max, length) < 0) 1161280297Sjkim continue; 1162280297Sjkim if (memcmp(p_min, c_min, length) > 0) 1163280297Sjkim return 0; 1164280297Sjkim break; 1165280297Sjkim } 1166167612Ssimon } 1167167612Ssimon 1168280297Sjkim return 1; 1169167612Ssimon} 1170167612Ssimon 1171167612Ssimon/* 1172167612Ssimon * Test whether a is a subset of b. 1173167612Ssimon */ 1174167612Ssimonint v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b) 1175167612Ssimon{ 1176280297Sjkim int i; 1177280297Sjkim if (a == NULL || a == b) 1178280297Sjkim return 1; 1179280297Sjkim if (b == NULL || v3_addr_inherits(a) || v3_addr_inherits(b)) 1180280297Sjkim return 0; 1181280297Sjkim (void)sk_IPAddressFamily_set_cmp_func(b, IPAddressFamily_cmp); 1182280297Sjkim for (i = 0; i < sk_IPAddressFamily_num(a); i++) { 1183280297Sjkim IPAddressFamily *fa = sk_IPAddressFamily_value(a, i); 1184280297Sjkim int j = sk_IPAddressFamily_find(b, fa); 1185280297Sjkim IPAddressFamily *fb; 1186280297Sjkim fb = sk_IPAddressFamily_value(b, j); 1187280297Sjkim if (fb == NULL) 1188280297Sjkim return 0; 1189280297Sjkim if (!addr_contains(fb->ipAddressChoice->u.addressesOrRanges, 1190280297Sjkim fa->ipAddressChoice->u.addressesOrRanges, 1191280297Sjkim length_from_afi(v3_addr_get_afi(fb)))) 1192280297Sjkim return 0; 1193280297Sjkim } 1194167612Ssimon return 1; 1195167612Ssimon} 1196167612Ssimon 1197167612Ssimon/* 1198167612Ssimon * Validation error handling via callback. 1199167612Ssimon */ 1200280297Sjkim# define validation_err(_err_) \ 1201280297Sjkim do { \ 1202280297Sjkim if (ctx != NULL) { \ 1203280297Sjkim ctx->error = _err_; \ 1204280297Sjkim ctx->error_depth = i; \ 1205280297Sjkim ctx->current_cert = x; \ 1206280297Sjkim ret = ctx->verify_cb(0, ctx); \ 1207280297Sjkim } else { \ 1208280297Sjkim ret = 0; \ 1209280297Sjkim } \ 1210280297Sjkim if (!ret) \ 1211280297Sjkim goto done; \ 1212167612Ssimon } while (0) 1213167612Ssimon 1214167612Ssimon/* 1215167612Ssimon * Core code for RFC 3779 2.3 path validation. 1216306195Sjkim * 1217306195Sjkim * Returns 1 for success, 0 on error. 1218306195Sjkim * 1219306195Sjkim * When returning 0, ctx->error MUST be set to an appropriate value other than 1220306195Sjkim * X509_V_OK. 1221167612Ssimon */ 1222167612Ssimonstatic int v3_addr_validate_path_internal(X509_STORE_CTX *ctx, 1223280297Sjkim STACK_OF(X509) *chain, 1224280297Sjkim IPAddrBlocks *ext) 1225167612Ssimon{ 1226280297Sjkim IPAddrBlocks *child = NULL; 1227280297Sjkim int i, j, ret = 1; 1228280297Sjkim X509 *x; 1229167612Ssimon 1230280297Sjkim OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0); 1231280297Sjkim OPENSSL_assert(ctx != NULL || ext != NULL); 1232280297Sjkim OPENSSL_assert(ctx == NULL || ctx->verify_cb != NULL); 1233167612Ssimon 1234280297Sjkim /* 1235280297Sjkim * Figure out where to start. If we don't have an extension to 1236280297Sjkim * check, we're done. Otherwise, check canonical form and 1237280297Sjkim * set up for walking up the chain. 1238280297Sjkim */ 1239280297Sjkim if (ext != NULL) { 1240280297Sjkim i = -1; 1241280297Sjkim x = NULL; 1242280297Sjkim } else { 1243280297Sjkim i = 0; 1244280297Sjkim x = sk_X509_value(chain, i); 1245280297Sjkim OPENSSL_assert(x != NULL); 1246280297Sjkim if ((ext = x->rfc3779_addr) == NULL) 1247280297Sjkim goto done; 1248167612Ssimon } 1249280297Sjkim if (!v3_addr_is_canonical(ext)) 1250280297Sjkim validation_err(X509_V_ERR_INVALID_EXTENSION); 1251280297Sjkim (void)sk_IPAddressFamily_set_cmp_func(ext, IPAddressFamily_cmp); 1252280297Sjkim if ((child = sk_IPAddressFamily_dup(ext)) == NULL) { 1253280297Sjkim X509V3err(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL, 1254280297Sjkim ERR_R_MALLOC_FAILURE); 1255306195Sjkim ctx->error = X509_V_ERR_OUT_OF_MEM; 1256280297Sjkim ret = 0; 1257280297Sjkim goto done; 1258167612Ssimon } 1259167612Ssimon 1260280297Sjkim /* 1261280297Sjkim * Now walk up the chain. No cert may list resources that its 1262280297Sjkim * parent doesn't list. 1263280297Sjkim */ 1264280297Sjkim for (i++; i < sk_X509_num(chain); i++) { 1265280297Sjkim x = sk_X509_value(chain, i); 1266280297Sjkim OPENSSL_assert(x != NULL); 1267280297Sjkim if (!v3_addr_is_canonical(x->rfc3779_addr)) 1268280297Sjkim validation_err(X509_V_ERR_INVALID_EXTENSION); 1269280297Sjkim if (x->rfc3779_addr == NULL) { 1270280297Sjkim for (j = 0; j < sk_IPAddressFamily_num(child); j++) { 1271280297Sjkim IPAddressFamily *fc = sk_IPAddressFamily_value(child, j); 1272280297Sjkim if (fc->ipAddressChoice->type != IPAddressChoice_inherit) { 1273280297Sjkim validation_err(X509_V_ERR_UNNESTED_RESOURCE); 1274280297Sjkim break; 1275280297Sjkim } 1276280297Sjkim } 1277280297Sjkim continue; 1278280297Sjkim } 1279280297Sjkim (void)sk_IPAddressFamily_set_cmp_func(x->rfc3779_addr, 1280280297Sjkim IPAddressFamily_cmp); 1281280297Sjkim for (j = 0; j < sk_IPAddressFamily_num(child); j++) { 1282280297Sjkim IPAddressFamily *fc = sk_IPAddressFamily_value(child, j); 1283280297Sjkim int k = sk_IPAddressFamily_find(x->rfc3779_addr, fc); 1284280297Sjkim IPAddressFamily *fp = 1285280297Sjkim sk_IPAddressFamily_value(x->rfc3779_addr, k); 1286280297Sjkim if (fp == NULL) { 1287280297Sjkim if (fc->ipAddressChoice->type == 1288280297Sjkim IPAddressChoice_addressesOrRanges) { 1289280297Sjkim validation_err(X509_V_ERR_UNNESTED_RESOURCE); 1290280297Sjkim break; 1291280297Sjkim } 1292280297Sjkim continue; 1293280297Sjkim } 1294280297Sjkim if (fp->ipAddressChoice->type == 1295280297Sjkim IPAddressChoice_addressesOrRanges) { 1296280297Sjkim if (fc->ipAddressChoice->type == IPAddressChoice_inherit 1297280297Sjkim || addr_contains(fp->ipAddressChoice->u.addressesOrRanges, 1298280297Sjkim fc->ipAddressChoice->u.addressesOrRanges, 1299280297Sjkim length_from_afi(v3_addr_get_afi(fc)))) 1300280297Sjkim sk_IPAddressFamily_set(child, j, fp); 1301280297Sjkim else 1302280297Sjkim validation_err(X509_V_ERR_UNNESTED_RESOURCE); 1303280297Sjkim } 1304280297Sjkim } 1305167612Ssimon } 1306167612Ssimon 1307280297Sjkim /* 1308280297Sjkim * Trust anchor can't inherit. 1309280297Sjkim */ 1310280297Sjkim OPENSSL_assert(x != NULL); 1311280297Sjkim if (x->rfc3779_addr != NULL) { 1312280297Sjkim for (j = 0; j < sk_IPAddressFamily_num(x->rfc3779_addr); j++) { 1313280297Sjkim IPAddressFamily *fp = 1314280297Sjkim sk_IPAddressFamily_value(x->rfc3779_addr, j); 1315280297Sjkim if (fp->ipAddressChoice->type == IPAddressChoice_inherit 1316280297Sjkim && sk_IPAddressFamily_find(child, fp) >= 0) 1317280297Sjkim validation_err(X509_V_ERR_UNNESTED_RESOURCE); 1318280297Sjkim } 1319280297Sjkim } 1320280297Sjkim 1321167612Ssimon done: 1322280297Sjkim sk_IPAddressFamily_free(child); 1323280297Sjkim return ret; 1324167612Ssimon} 1325167612Ssimon 1326280297Sjkim# undef validation_err 1327167612Ssimon 1328167612Ssimon/* 1329167612Ssimon * RFC 3779 2.3 path validation -- called from X509_verify_cert(). 1330167612Ssimon */ 1331167612Ssimonint v3_addr_validate_path(X509_STORE_CTX *ctx) 1332167612Ssimon{ 1333280297Sjkim return v3_addr_validate_path_internal(ctx, ctx->chain, NULL); 1334167612Ssimon} 1335167612Ssimon 1336167612Ssimon/* 1337167612Ssimon * RFC 3779 2.3 path validation of an extension. 1338167612Ssimon * Test whether chain covers extension. 1339167612Ssimon */ 1340167612Ssimonint v3_addr_validate_resource_set(STACK_OF(X509) *chain, 1341280297Sjkim IPAddrBlocks *ext, int allow_inheritance) 1342167612Ssimon{ 1343280297Sjkim if (ext == NULL) 1344280297Sjkim return 1; 1345280297Sjkim if (chain == NULL || sk_X509_num(chain) == 0) 1346280297Sjkim return 0; 1347280297Sjkim if (!allow_inheritance && v3_addr_inherits(ext)) 1348280297Sjkim return 0; 1349280297Sjkim return v3_addr_validate_path_internal(NULL, chain, ext); 1350167612Ssimon} 1351167612Ssimon 1352280297Sjkim#endif /* OPENSSL_NO_RFC3779 */ 1353