1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Contributed to the OpenSSL Project by the American Registry for 3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Internet Numbers ("ARIN"). 4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ==================================================================== 6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright (c) 2006 The OpenSSL Project. All rights reserved. 7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without 9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions 10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met: 11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the above copyright 13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * notice, this list of conditions and the following disclaimer. 14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * notice, this list of conditions and the following disclaimer in 17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the documentation and/or other materials provided with the 18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * distribution. 19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this 21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * software must display the following acknowledgment: 22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * "This product includes software developed by the OpenSSL Project 23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * endorse or promote products derived from this software without 27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * prior written permission. For written permission, please contact 28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * licensing@OpenSSL.org. 29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 5. Products derived from this software may not be called "OpenSSL" 31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * nor may "OpenSSL" appear in their names without prior written 32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * permission of the OpenSSL Project. 33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 6. Redistributions of any form whatsoever must retain the following 35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * acknowledgment: 36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * "This product includes software developed by the OpenSSL Project 37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OF THE POSSIBILITY OF SUCH DAMAGE. 51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ==================================================================== 52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This product includes cryptographic software written by Eric Young 54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (eay@cryptsoft.com). This product includes software written by Tim 55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Hudson (tjh@cryptsoft.com). 56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Implementation of RFC 3779 section 2.2. 60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <stdio.h> 63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <stdlib.h> 64e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "cryptlib.h" 66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/conf.h> 67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/asn1.h> 68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/asn1t.h> 69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/buffer.h> 70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/x509v3.h> 71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_RFC3779 73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OpenSSL ASN.1 template translation of RFC 3779 2.2.3. 76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectASN1_SEQUENCE(IPAddressRange) = { 79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ASN1_SIMPLE(IPAddressRange, min, ASN1_BIT_STRING), 80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ASN1_SIMPLE(IPAddressRange, max, ASN1_BIT_STRING) 81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} ASN1_SEQUENCE_END(IPAddressRange) 82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectASN1_CHOICE(IPAddressOrRange) = { 84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ASN1_SIMPLE(IPAddressOrRange, u.addressPrefix, ASN1_BIT_STRING), 85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ASN1_SIMPLE(IPAddressOrRange, u.addressRange, IPAddressRange) 86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} ASN1_CHOICE_END(IPAddressOrRange) 87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectASN1_CHOICE(IPAddressChoice) = { 89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ASN1_SIMPLE(IPAddressChoice, u.inherit, ASN1_NULL), 90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ASN1_SEQUENCE_OF(IPAddressChoice, u.addressesOrRanges, IPAddressOrRange) 91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} ASN1_CHOICE_END(IPAddressChoice) 92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectASN1_SEQUENCE(IPAddressFamily) = { 94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ASN1_SIMPLE(IPAddressFamily, addressFamily, ASN1_OCTET_STRING), 95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ASN1_SIMPLE(IPAddressFamily, ipAddressChoice, IPAddressChoice) 96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} ASN1_SEQUENCE_END(IPAddressFamily) 97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectASN1_ITEM_TEMPLATE(IPAddrBlocks) = 99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, 100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddrBlocks, IPAddressFamily) 101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectASN1_ITEM_TEMPLATE_END(IPAddrBlocks) 102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectIMPLEMENT_ASN1_FUNCTIONS(IPAddressRange) 104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectIMPLEMENT_ASN1_FUNCTIONS(IPAddressOrRange) 105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectIMPLEMENT_ASN1_FUNCTIONS(IPAddressChoice) 106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectIMPLEMENT_ASN1_FUNCTIONS(IPAddressFamily) 107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * How much buffer space do we need for a raw address? 110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define ADDR_RAW_BUF_LEN 16 112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * What's the address length associated with this AFI? 115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int length_from_afi(const unsigned afi) 117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project switch (afi) { 119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case IANA_AFI_IPV4: 120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 4; 121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case IANA_AFI_IPV6: 122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 16; 123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project default: 124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Extract the AFI from an IPAddressFamily. 130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 131e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modaduguunsigned int v3_addr_get_afi(const IPAddressFamily *f) 132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return ((f != NULL && 134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project f->addressFamily != NULL && 135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project f->addressFamily->data != NULL) 136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ? ((f->addressFamily->data[0] << 8) | 137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project (f->addressFamily->data[1])) 138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project : 0); 139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Expand the bitstring form of an address into a raw byte array. 143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * At the moment this is coded for simplicity, not speed. 144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 1457b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstromstatic int addr_expand(unsigned char *addr, 146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const ASN1_BIT_STRING *bs, 147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const int length, 148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const unsigned char fill) 149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 1507b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom if (bs->length < 0 || bs->length > length) 1517b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom return 0; 152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (bs->length > 0) { 153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project memcpy(addr, bs->data, bs->length); 154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((bs->flags & 7) != 0) { 155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned char mask = 0xFF >> (8 - (bs->flags & 7)); 156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (fill == 0) 157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project addr[bs->length - 1] &= ~mask; 158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project addr[bs->length - 1] |= mask; 160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project memset(addr + bs->length, fill, length - bs->length); 1637b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom return 1; 164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Extract the prefix length from a bitstring. 168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define addr_prefixlen(bs) ((int) ((bs)->length * 8 - ((bs)->flags & 7))) 170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * i2r handler for one address bitstring. 173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int i2r_address(BIO *out, 175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const unsigned afi, 176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const unsigned char fill, 177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const ASN1_BIT_STRING *bs) 178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned char addr[ADDR_RAW_BUF_LEN]; 180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i, n; 181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 18281c4de7869b646592127e952cda763abf8305069Brian Carlstrom if (bs->length < 0) 18381c4de7869b646592127e952cda763abf8305069Brian Carlstrom return 0; 184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project switch (afi) { 185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case IANA_AFI_IPV4: 1867b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom if (!addr_expand(addr, bs, 4, fill)) 18781c4de7869b646592127e952cda763abf8305069Brian Carlstrom return 0; 188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]); 189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case IANA_AFI_IPV6: 1917b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom if (!addr_expand(addr, bs, 16, fill)) 19281c4de7869b646592127e952cda763abf8305069Brian Carlstrom return 0; 193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (n = 16; n > 1 && addr[n-1] == 0x00 && addr[n-2] == 0x00; n -= 2) 194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ; 195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (i = 0; i < n; i += 2) 196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_printf(out, "%x%s", (addr[i] << 8) | addr[i+1], (i < 14 ? ":" : "")); 197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (i < 16) 198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_puts(out, ":"); 199e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu if (i == 0) 200e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BIO_puts(out, ":"); 201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project default: 203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (i = 0; i < bs->length; i++) 204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_printf(out, "%s%02x", (i > 0 ? ":" : ""), bs->data[i]); 205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_printf(out, "[%d]", (int) (bs->flags & 7)); 206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * i2r handler for a sequence of addresses and ranges. 213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int i2r_IPAddressOrRanges(BIO *out, 215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const int indent, 216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const IPAddressOrRanges *aors, 217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const unsigned afi) 218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i; 220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (i = 0; i < sk_IPAddressOrRange_num(aors); i++) { 221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const IPAddressOrRange *aor = sk_IPAddressOrRange_value(aors, i); 222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_printf(out, "%*s", indent, ""); 223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project switch (aor->type) { 224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case IPAddressOrRange_addressPrefix: 225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!i2r_address(out, afi, 0x00, aor->u.addressPrefix)) 226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_printf(out, "/%d\n", addr_prefixlen(aor->u.addressPrefix)); 228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project continue; 229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case IPAddressOrRange_addressRange: 230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!i2r_address(out, afi, 0x00, aor->u.addressRange->min)) 231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_puts(out, "-"); 233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!i2r_address(out, afi, 0xFF, aor->u.addressRange->max)) 234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_puts(out, "\n"); 236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project continue; 237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * i2r handler for an IPAddrBlocks extension. 244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 245221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int i2r_IPAddrBlocks(const X509V3_EXT_METHOD *method, 246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project void *ext, 247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO *out, 248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int indent) 249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const IPAddrBlocks *addr = ext; 251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i; 252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { 253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); 254e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu const unsigned int afi = v3_addr_get_afi(f); 255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project switch (afi) { 256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case IANA_AFI_IPV4: 257656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_printf(out, "%*sIPv4", indent, ""); 258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case IANA_AFI_IPV6: 260656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_printf(out, "%*sIPv6", indent, ""); 261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 262656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project default: 263656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_printf(out, "%*sUnknown AFI %u", indent, "", afi); 264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 265656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (f->addressFamily->length > 2) { 267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project switch (f->addressFamily->data[2]) { 268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case 1: 269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_puts(out, " (Unicast)"); 270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case 2: 272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_puts(out, " (Multicast)"); 273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case 3: 275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_puts(out, " (Unicast/Multicast)"); 276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case 4: 278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_puts(out, " (MPLS)"); 279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case 64: 281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_puts(out, " (Tunnel)"); 282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 283656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case 65: 284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_puts(out, " (VPLS)"); 285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case 66: 287656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_puts(out, " (BGP MDT)"); 288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case 128: 290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_puts(out, " (MPLS-labeled VPN)"); 291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project default: 293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_printf(out, " (Unknown SAFI %u)", 294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project (unsigned) f->addressFamily->data[2]); 295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project switch (f->ipAddressChoice->type) { 299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case IPAddressChoice_inherit: 300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_puts(out, ": inherit\n"); 301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case IPAddressChoice_addressesOrRanges: 303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_puts(out, ":\n"); 304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!i2r_IPAddressOrRanges(out, 305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project indent + 2, 306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project f->ipAddressChoice->u.addressesOrRanges, 307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project afi)) 308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 314656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 316656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Sort comparison function for a sequence of IPAddressOrRange 317656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * elements. 3187b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom * 3197b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom * There's no sane answer we can give if addr_expand() fails, and an 3207b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom * assertion failure on externally supplied data is seriously uncool, 3217b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom * so we just arbitrarily declare that if given invalid inputs this 3227b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom * function returns -1. If this messes up your preferred sort order 3237b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom * for garbage input, tough noogies. 324656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int IPAddressOrRange_cmp(const IPAddressOrRange *a, 326656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const IPAddressOrRange *b, 327656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const int length) 328656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 329656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned char addr_a[ADDR_RAW_BUF_LEN], addr_b[ADDR_RAW_BUF_LEN]; 330221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom int prefixlen_a = 0, prefixlen_b = 0; 331656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int r; 332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 333656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project switch (a->type) { 334656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case IPAddressOrRange_addressPrefix: 3357b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom if (!addr_expand(addr_a, a->u.addressPrefix, length, 0x00)) 3367b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom return -1; 337656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project prefixlen_a = addr_prefixlen(a->u.addressPrefix); 338656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 339656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case IPAddressOrRange_addressRange: 3407b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom if (!addr_expand(addr_a, a->u.addressRange->min, length, 0x00)) 3417b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom return -1; 342656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project prefixlen_a = length * 8; 343656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 344656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 345656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 346656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project switch (b->type) { 347656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case IPAddressOrRange_addressPrefix: 3487b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom if (!addr_expand(addr_b, b->u.addressPrefix, length, 0x00)) 3497b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom return -1; 350656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project prefixlen_b = addr_prefixlen(b->u.addressPrefix); 351656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 352656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case IPAddressOrRange_addressRange: 3537b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom if (!addr_expand(addr_b, b->u.addressRange->min, length, 0x00)) 3547b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom return -1; 355656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project prefixlen_b = length * 8; 356656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 357656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 358656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 359656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((r = memcmp(addr_a, addr_b, length)) != 0) 360656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return r; 361656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 362656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return prefixlen_a - prefixlen_b; 363656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 364656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 365656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 366656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IPv4-specific closure over IPAddressOrRange_cmp, since sk_sort() 367656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * comparision routines are only allowed two arguments. 368656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 369656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int v4IPAddressOrRange_cmp(const IPAddressOrRange * const *a, 370656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const IPAddressOrRange * const *b) 371656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 372656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return IPAddressOrRange_cmp(*a, *b, 4); 373656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 374656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 375656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 376656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IPv6-specific closure over IPAddressOrRange_cmp, since sk_sort() 377656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * comparision routines are only allowed two arguments. 378656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 379656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int v6IPAddressOrRange_cmp(const IPAddressOrRange * const *a, 380656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const IPAddressOrRange * const *b) 381656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 382656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return IPAddressOrRange_cmp(*a, *b, 16); 383656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 384656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 385656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 386656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Calculate whether a range collapses to a prefix. 387656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * See last paragraph of RFC 3779 2.2.3.7. 388656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 389656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int range_should_be_prefix(const unsigned char *min, 390656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const unsigned char *max, 391656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const int length) 392656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 393656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned char mask; 394656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i, j; 395656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 3967b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom OPENSSL_assert(memcmp(min, max, length) <= 0); 397656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (i = 0; i < length && min[i] == max[i]; i++) 398656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ; 399656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (j = length - 1; j >= 0 && min[j] == 0x00 && max[j] == 0xFF; j--) 400656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ; 401656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (i < j) 402656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return -1; 403656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (i > j) 404656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return i * 8; 405656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project mask = min[i] ^ max[i]; 406656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project switch (mask) { 407656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case 0x01: j = 7; break; 408656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case 0x03: j = 6; break; 409656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case 0x07: j = 5; break; 410656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case 0x0F: j = 4; break; 411656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case 0x1F: j = 3; break; 412656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case 0x3F: j = 2; break; 413656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case 0x7F: j = 1; break; 414656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project default: return -1; 415656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 416656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((min[i] & mask) != 0 || (max[i] & mask) != mask) 417656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return -1; 418656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 419656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return i * 8 + j; 420656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 421656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 422656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 423656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Construct a prefix. 424656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 425656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int make_addressPrefix(IPAddressOrRange **result, 426656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned char *addr, 427656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const int prefixlen) 428656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 429656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int bytelen = (prefixlen + 7) / 8, bitlen = prefixlen % 8; 430656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddressOrRange *aor = IPAddressOrRange_new(); 431656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 432656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (aor == NULL) 433656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 434656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project aor->type = IPAddressOrRange_addressPrefix; 435656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (aor->u.addressPrefix == NULL && 436656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project (aor->u.addressPrefix = ASN1_BIT_STRING_new()) == NULL) 437656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 438656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!ASN1_BIT_STRING_set(aor->u.addressPrefix, addr, bytelen)) 439656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 440656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project aor->u.addressPrefix->flags &= ~7; 441656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project aor->u.addressPrefix->flags |= ASN1_STRING_FLAG_BITS_LEFT; 442656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (bitlen > 0) { 443656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project aor->u.addressPrefix->data[bytelen - 1] &= ~(0xFF >> bitlen); 444656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project aor->u.addressPrefix->flags |= 8 - bitlen; 445656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 446656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 447656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *result = aor; 448656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 449656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 450656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project err: 451656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddressOrRange_free(aor); 452656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 453656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 454656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 455656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 456656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Construct a range. If it can be expressed as a prefix, 457656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * return a prefix instead. Doing this here simplifies 458656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the rest of the code considerably. 459656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 460656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int make_addressRange(IPAddressOrRange **result, 461656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned char *min, 462656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned char *max, 463656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const int length) 464656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 465656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddressOrRange *aor; 466656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i, prefixlen; 467656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 468656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((prefixlen = range_should_be_prefix(min, max, length)) >= 0) 469656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return make_addressPrefix(result, min, prefixlen); 470656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 471656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((aor = IPAddressOrRange_new()) == NULL) 472656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 473656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project aor->type = IPAddressOrRange_addressRange; 474e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu OPENSSL_assert(aor->u.addressRange == NULL); 475656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((aor->u.addressRange = IPAddressRange_new()) == NULL) 476656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 477656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (aor->u.addressRange->min == NULL && 478656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project (aor->u.addressRange->min = ASN1_BIT_STRING_new()) == NULL) 479656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 480656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (aor->u.addressRange->max == NULL && 481656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project (aor->u.addressRange->max = ASN1_BIT_STRING_new()) == NULL) 482656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 483656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 484656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (i = length; i > 0 && min[i - 1] == 0x00; --i) 485656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ; 486656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!ASN1_BIT_STRING_set(aor->u.addressRange->min, min, i)) 487656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 488656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project aor->u.addressRange->min->flags &= ~7; 489656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project aor->u.addressRange->min->flags |= ASN1_STRING_FLAG_BITS_LEFT; 490656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (i > 0) { 491656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned char b = min[i - 1]; 492656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int j = 1; 493656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project while ((b & (0xFFU >> j)) != 0) 494656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ++j; 495656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project aor->u.addressRange->min->flags |= 8 - j; 496656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 497656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 498656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (i = length; i > 0 && max[i - 1] == 0xFF; --i) 499656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ; 500656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!ASN1_BIT_STRING_set(aor->u.addressRange->max, max, i)) 501656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 502656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project aor->u.addressRange->max->flags &= ~7; 503656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project aor->u.addressRange->max->flags |= ASN1_STRING_FLAG_BITS_LEFT; 504656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (i > 0) { 505656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned char b = max[i - 1]; 506656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int j = 1; 507656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project while ((b & (0xFFU >> j)) != (0xFFU >> j)) 508656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ++j; 509656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project aor->u.addressRange->max->flags |= 8 - j; 510656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 511656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 512656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *result = aor; 513656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 514656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 515656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project err: 516656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddressOrRange_free(aor); 517656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 518656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 519656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 520656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 521656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Construct a new address family or find an existing one. 522656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 523656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic IPAddressFamily *make_IPAddressFamily(IPAddrBlocks *addr, 524656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const unsigned afi, 525656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const unsigned *safi) 526656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 527656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddressFamily *f; 528656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned char key[3]; 529656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned keylen; 530656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i; 531656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 532656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project key[0] = (afi >> 8) & 0xFF; 533656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project key[1] = afi & 0xFF; 534656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (safi != NULL) { 535656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project key[2] = *safi & 0xFF; 536656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project keylen = 3; 537656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } else { 538656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project keylen = 2; 539656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 540656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 541656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { 542656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project f = sk_IPAddressFamily_value(addr, i); 543e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu OPENSSL_assert(f->addressFamily->data != NULL); 544656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (f->addressFamily->length == keylen && 545656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project !memcmp(f->addressFamily->data, key, keylen)) 546656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return f; 547656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 548656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 549656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((f = IPAddressFamily_new()) == NULL) 550656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 551656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (f->ipAddressChoice == NULL && 552656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project (f->ipAddressChoice = IPAddressChoice_new()) == NULL) 553656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 554656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (f->addressFamily == NULL && 555656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project (f->addressFamily = ASN1_OCTET_STRING_new()) == NULL) 556656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 557656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!ASN1_OCTET_STRING_set(f->addressFamily, key, keylen)) 558656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 559656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!sk_IPAddressFamily_push(addr, f)) 560656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 561656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 562656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return f; 563656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 564656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project err: 565656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddressFamily_free(f); 566656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return NULL; 567656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 568656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 569656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 570656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Add an inheritance element. 571656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 572656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint v3_addr_add_inherit(IPAddrBlocks *addr, 573656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const unsigned afi, 574656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const unsigned *safi) 575656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 576656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi); 577656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (f == NULL || 578656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project f->ipAddressChoice == NULL || 579656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges && 580656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project f->ipAddressChoice->u.addressesOrRanges != NULL)) 581656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 582656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (f->ipAddressChoice->type == IPAddressChoice_inherit && 583656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project f->ipAddressChoice->u.inherit != NULL) 584656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 585656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (f->ipAddressChoice->u.inherit == NULL && 586656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project (f->ipAddressChoice->u.inherit = ASN1_NULL_new()) == NULL) 587656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 588656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project f->ipAddressChoice->type = IPAddressChoice_inherit; 589656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 590656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 591656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 592656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 593656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Construct an IPAddressOrRange sequence, or return an existing one. 594656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 595656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic IPAddressOrRanges *make_prefix_or_range(IPAddrBlocks *addr, 596656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const unsigned afi, 597656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const unsigned *safi) 598656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 599656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi); 600656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddressOrRanges *aors = NULL; 601656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 602656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (f == NULL || 603656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project f->ipAddressChoice == NULL || 604656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project (f->ipAddressChoice->type == IPAddressChoice_inherit && 605656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project f->ipAddressChoice->u.inherit != NULL)) 606656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return NULL; 607656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges) 608656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project aors = f->ipAddressChoice->u.addressesOrRanges; 609656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (aors != NULL) 610656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return aors; 611656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((aors = sk_IPAddressOrRange_new_null()) == NULL) 612656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return NULL; 613656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project switch (afi) { 614656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case IANA_AFI_IPV4: 6157b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom (void) sk_IPAddressOrRange_set_cmp_func(aors, v4IPAddressOrRange_cmp); 616656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 617656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case IANA_AFI_IPV6: 6187b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom (void) sk_IPAddressOrRange_set_cmp_func(aors, v6IPAddressOrRange_cmp); 619656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 620656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 621656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project f->ipAddressChoice->type = IPAddressChoice_addressesOrRanges; 622656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project f->ipAddressChoice->u.addressesOrRanges = aors; 623656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return aors; 624656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 625656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 626656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 627656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Add a prefix. 628656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 629656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint v3_addr_add_prefix(IPAddrBlocks *addr, 630656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const unsigned afi, 631656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const unsigned *safi, 632656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned char *a, 633656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const int prefixlen) 634656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 635656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi); 636656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddressOrRange *aor; 637656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (aors == NULL || !make_addressPrefix(&aor, a, prefixlen)) 638656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 639656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (sk_IPAddressOrRange_push(aors, aor)) 640656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 641656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddressOrRange_free(aor); 642656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 643656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 644656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 645656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 646656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Add a range. 647656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 648656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint v3_addr_add_range(IPAddrBlocks *addr, 649656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const unsigned afi, 650656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const unsigned *safi, 651656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned char *min, 652656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned char *max) 653656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 654656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi); 655656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddressOrRange *aor; 656656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int length = length_from_afi(afi); 657656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (aors == NULL) 658656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 659656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!make_addressRange(&aor, min, max, length)) 660656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 661656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (sk_IPAddressOrRange_push(aors, aor)) 662656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 663656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddressOrRange_free(aor); 664656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 665656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 666656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 667656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 668656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Extract min and max values from an IPAddressOrRange. 669656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 6707b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstromstatic int extract_min_max(IPAddressOrRange *aor, 671656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned char *min, 672656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned char *max, 673656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int length) 674656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 6757b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom if (aor == NULL || min == NULL || max == NULL) 6767b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom return 0; 677656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project switch (aor->type) { 678656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case IPAddressOrRange_addressPrefix: 6797b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom return (addr_expand(min, aor->u.addressPrefix, length, 0x00) && 6807b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom addr_expand(max, aor->u.addressPrefix, length, 0xFF)); 681656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case IPAddressOrRange_addressRange: 6827b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom return (addr_expand(min, aor->u.addressRange->min, length, 0x00) && 6837b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom addr_expand(max, aor->u.addressRange->max, length, 0xFF)); 684656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 6857b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom return 0; 686656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 687656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 688656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 689656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Public wrapper for extract_min_max(). 690656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 691656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint v3_addr_get_range(IPAddressOrRange *aor, 692656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const unsigned afi, 693656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned char *min, 694656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned char *max, 695656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const int length) 696656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 697656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int afi_length = length_from_afi(afi); 698656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (aor == NULL || min == NULL || max == NULL || 699656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project afi_length == 0 || length < afi_length || 700656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project (aor->type != IPAddressOrRange_addressPrefix && 7017b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom aor->type != IPAddressOrRange_addressRange) || 7027b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom !extract_min_max(aor, min, max, afi_length)) 703656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 7047b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom 705656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return afi_length; 706656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 707656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 708656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 709656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Sort comparision function for a sequence of IPAddressFamily. 710656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 711656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * The last paragraph of RFC 3779 2.2.3.3 is slightly ambiguous about 712656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the ordering: I can read it as meaning that IPv6 without a SAFI 713656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * comes before IPv4 with a SAFI, which seems pretty weird. The 714656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * examples in appendix B suggest that the author intended the 715656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * null-SAFI rule to apply only within a single AFI, which is what I 716656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * would have expected and is what the following code implements. 717656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 718656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int IPAddressFamily_cmp(const IPAddressFamily * const *a_, 719656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const IPAddressFamily * const *b_) 720656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 721656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const ASN1_OCTET_STRING *a = (*a_)->addressFamily; 722656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const ASN1_OCTET_STRING *b = (*b_)->addressFamily; 723656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int len = ((a->length <= b->length) ? a->length : b->length); 724656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int cmp = memcmp(a->data, b->data, len); 725656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return cmp ? cmp : a->length - b->length; 726656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 727656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 728656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 729656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Check whether an IPAddrBLocks is in canonical form. 730656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 731656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint v3_addr_is_canonical(IPAddrBlocks *addr) 732656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 733656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; 734656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN]; 735656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddressOrRanges *aors; 736656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i, j, k; 737656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 738656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* 739656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Empty extension is cannonical. 740656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 741656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (addr == NULL) 742656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 743656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 744656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* 745656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Check whether the top-level list is in order. 746656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 747656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (i = 0; i < sk_IPAddressFamily_num(addr) - 1; i++) { 748656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const IPAddressFamily *a = sk_IPAddressFamily_value(addr, i); 749656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const IPAddressFamily *b = sk_IPAddressFamily_value(addr, i + 1); 750656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (IPAddressFamily_cmp(&a, &b) >= 0) 751656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 752656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 753656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 754656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* 755656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Top level's ok, now check each address family. 756656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 757656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { 758656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); 759656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int length = length_from_afi(v3_addr_get_afi(f)); 760656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 761656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* 762656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Inheritance is canonical. Anything other than inheritance or 763656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * a SEQUENCE OF IPAddressOrRange is an ASN.1 error or something. 764656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 765656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (f == NULL || f->ipAddressChoice == NULL) 766656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 767656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project switch (f->ipAddressChoice->type) { 768656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case IPAddressChoice_inherit: 769656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project continue; 770656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case IPAddressChoice_addressesOrRanges: 771656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 772656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project default: 773656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 774656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 775656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 776656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* 777656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * It's an IPAddressOrRanges sequence, check it. 778656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 779656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project aors = f->ipAddressChoice->u.addressesOrRanges; 780656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (sk_IPAddressOrRange_num(aors) == 0) 781656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 782656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (j = 0; j < sk_IPAddressOrRange_num(aors) - 1; j++) { 783656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); 784656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, j + 1); 785656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 7867b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom if (!extract_min_max(a, a_min, a_max, length) || 7877b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom !extract_min_max(b, b_min, b_max, length)) 7887b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom return 0; 789656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 790656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* 791656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Punt misordered list, overlapping start, or inverted range. 792656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 793656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (memcmp(a_min, b_min, length) >= 0 || 794656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project memcmp(a_min, a_max, length) > 0 || 795656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project memcmp(b_min, b_max, length) > 0) 796656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 797656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 798656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* 799656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Punt if adjacent or overlapping. Check for adjacency by 800656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * subtracting one from b_min first. 801656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 802656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (k = length - 1; k >= 0 && b_min[k]-- == 0x00; k--) 803656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ; 804656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (memcmp(a_max, b_min, length) >= 0) 805656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 806656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 807656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* 808656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Check for range that should be expressed as a prefix. 809656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 810656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (a->type == IPAddressOrRange_addressRange && 811656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project range_should_be_prefix(a_min, a_max, length) >= 0) 812656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 813656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 814656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 815656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* 8167b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom * Check range to see if it's inverted or should be a 8177b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom * prefix. 818656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 819656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project j = sk_IPAddressOrRange_num(aors) - 1; 820656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 821656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); 8227b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom if (a != NULL && a->type == IPAddressOrRange_addressRange) { 8237b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom if (!extract_min_max(a, a_min, a_max, length)) 8247b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom return 0; 8257b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom if (memcmp(a_min, a_max, length) > 0 || 8267b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom range_should_be_prefix(a_min, a_max, length) >= 0) 827656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 828656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 829656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 830656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 831656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 832656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* 833656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * If we made it through all that, we're happy. 834656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 835656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 836656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 837656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 838656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 839656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Whack an IPAddressOrRanges into canonical form. 840656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 841656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int IPAddressOrRanges_canonize(IPAddressOrRanges *aors, 842656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const unsigned afi) 843656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 844656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i, j, length = length_from_afi(afi); 845656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 846656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* 847656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Sort the IPAddressOrRanges sequence. 848656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 849656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project sk_IPAddressOrRange_sort(aors); 850656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 851656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* 852656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Clean up representation issues, punt on duplicates or overlaps. 853656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 854656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (i = 0; i < sk_IPAddressOrRange_num(aors) - 1; i++) { 855656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, i); 856656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, i + 1); 857656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; 858656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN]; 859656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 8607b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom if (!extract_min_max(a, a_min, a_max, length) || 8617b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom !extract_min_max(b, b_min, b_max, length)) 8627b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom return 0; 8637b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom 8647b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom /* 8657b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom * Punt inverted ranges. 8667b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom */ 8677b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom if (memcmp(a_min, a_max, length) > 0 || 8687b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom memcmp(b_min, b_max, length) > 0) 8697b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom return 0; 870656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 871656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* 872656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Punt overlaps. 873656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 874656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (memcmp(a_max, b_min, length) >= 0) 875656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 876656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 877656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* 878656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Merge if a and b are adjacent. We check for 879656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * adjacency by subtracting one from b_min first. 880656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 881656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (j = length - 1; j >= 0 && b_min[j]-- == 0x00; j--) 882656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ; 883656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (memcmp(a_max, b_min, length) == 0) { 884656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddressOrRange *merged; 885656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!make_addressRange(&merged, a_min, b_max, length)) 886656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 8877b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom (void) sk_IPAddressOrRange_set(aors, i, merged); 8887b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom (void) sk_IPAddressOrRange_delete(aors, i + 1); 889656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddressOrRange_free(a); 890656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddressOrRange_free(b); 891656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project --i; 892656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project continue; 893656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 894656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 895656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 8967b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom /* 8977b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom * Check for inverted final range. 8987b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom */ 8997b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom j = sk_IPAddressOrRange_num(aors) - 1; 9007b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom { 9017b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); 9027b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom if (a != NULL && a->type == IPAddressOrRange_addressRange) { 9037b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; 9047b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom extract_min_max(a, a_min, a_max, length); 9057b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom if (memcmp(a_min, a_max, length) > 0) 9067b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom return 0; 9077b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom } 9087b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom } 9097b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom 910656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 911656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 912656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 913656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 914656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Whack an IPAddrBlocks extension into canonical form. 915656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 916656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint v3_addr_canonize(IPAddrBlocks *addr) 917656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 918656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i; 919656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { 920656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); 921656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges && 922656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project !IPAddressOrRanges_canonize(f->ipAddressChoice->u.addressesOrRanges, 923656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project v3_addr_get_afi(f))) 924656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 925656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 9267b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom (void) sk_IPAddressFamily_set_cmp_func(addr, IPAddressFamily_cmp); 927656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project sk_IPAddressFamily_sort(addr); 928e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu OPENSSL_assert(v3_addr_is_canonical(addr)); 929656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 930656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 931656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 932656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 933656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * v2i handler for the IPAddrBlocks extension. 934656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 935221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void *v2i_IPAddrBlocks(const struct v3_ext_method *method, 936656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project struct v3_ext_ctx *ctx, 937656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project STACK_OF(CONF_VALUE) *values) 938656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 939656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project static const char v4addr_chars[] = "0123456789."; 940656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project static const char v6addr_chars[] = "0123456789.:abcdefABCDEF"; 941656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddrBlocks *addr = NULL; 942656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project char *s = NULL, *t; 943656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i; 944656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 945656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((addr = sk_IPAddressFamily_new(IPAddressFamily_cmp)) == NULL) { 946656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); 947656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return NULL; 948656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 949656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 950656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (i = 0; i < sk_CONF_VALUE_num(values); i++) { 951656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project CONF_VALUE *val = sk_CONF_VALUE_value(values, i); 952656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned char min[ADDR_RAW_BUF_LEN], max[ADDR_RAW_BUF_LEN]; 953656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned afi, *safi = NULL, safi_; 954656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const char *addr_chars; 955656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int prefixlen, i1, i2, delim, length; 956656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 957656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ( !name_cmp(val->name, "IPv4")) { 958656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project afi = IANA_AFI_IPV4; 959656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } else if (!name_cmp(val->name, "IPv6")) { 960656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project afi = IANA_AFI_IPV6; 961656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } else if (!name_cmp(val->name, "IPv4-SAFI")) { 962656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project afi = IANA_AFI_IPV4; 963656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project safi = &safi_; 964656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } else if (!name_cmp(val->name, "IPv6-SAFI")) { 965656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project afi = IANA_AFI_IPV6; 966656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project safi = &safi_; 967656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } else { 968656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_NAME_ERROR); 969656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509V3_conf_err(val); 970656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 971656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 972656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 973656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project switch (afi) { 974656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case IANA_AFI_IPV4: 975656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project addr_chars = v4addr_chars; 976656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 977656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case IANA_AFI_IPV6: 978656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project addr_chars = v6addr_chars; 979656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 980656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 981656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 982656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project length = length_from_afi(afi); 983656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 984656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* 985656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Handle SAFI, if any, and BUF_strdup() so we can null-terminate 986656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the other input values. 987656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 988656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (safi != NULL) { 989656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *safi = strtoul(val->value, &t, 0); 990656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project t += strspn(t, " \t"); 991656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (*safi > 0xFF || *t++ != ':') { 992656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_SAFI); 993656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509V3_conf_err(val); 994656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 995656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 996656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project t += strspn(t, " \t"); 997656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project s = BUF_strdup(t); 998656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } else { 999656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project s = BUF_strdup(val->value); 1000656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 1001656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (s == NULL) { 1002656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); 1003656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 1004656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 1005656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 1006656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* 1007656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Check for inheritance. Not worth additional complexity to 1008656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * optimize this (seldom-used) case. 1009656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 1010656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!strcmp(s, "inherit")) { 1011656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!v3_addr_add_inherit(addr, afi, safi)) { 1012656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_INHERITANCE); 1013656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509V3_conf_err(val); 1014656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 1015656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 1016656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project OPENSSL_free(s); 1017656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project s = NULL; 1018656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project continue; 1019656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 1020656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 1021656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project i1 = strspn(s, addr_chars); 1022656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project i2 = i1 + strspn(s + i1, " \t"); 1023656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project delim = s[i2++]; 1024656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project s[i1] = '\0'; 1025656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 1026656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (a2i_ipadd(min, s) != length) { 1027656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_IPADDRESS); 1028656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509V3_conf_err(val); 1029656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 1030656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 1031656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 1032656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project switch (delim) { 1033656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case '/': 1034656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project prefixlen = (int) strtoul(s + i2, &t, 10); 1035656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (t == s + i2 || *t != '\0') { 1036656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR); 1037656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509V3_conf_err(val); 1038656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 1039656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 1040656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!v3_addr_add_prefix(addr, afi, safi, min, prefixlen)) { 1041656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); 1042656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 1043656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 1044656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 1045656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case '-': 1046656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project i1 = i2 + strspn(s + i2, " \t"); 1047656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project i2 = i1 + strspn(s + i1, addr_chars); 1048656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (i1 == i2 || s[i2] != '\0') { 1049656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR); 1050656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509V3_conf_err(val); 1051656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 1052656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 1053656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (a2i_ipadd(max, s + i1) != length) { 1054656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_IPADDRESS); 1055656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509V3_conf_err(val); 1056656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 1057656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 10587b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom if (memcmp(min, max, length_from_afi(afi)) > 0) { 10597b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR); 10607b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom X509V3_conf_err(val); 10617b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom goto err; 10627b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom } 1063656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!v3_addr_add_range(addr, afi, safi, min, max)) { 1064656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); 1065656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 1066656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 1067656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 1068656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case '\0': 1069656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!v3_addr_add_prefix(addr, afi, safi, min, length * 8)) { 1070656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); 1071656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 1072656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 1073656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 1074656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project default: 1075656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR); 1076656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509V3_conf_err(val); 1077656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 1078656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 1079656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 1080656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project OPENSSL_free(s); 1081656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project s = NULL; 1082656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 1083656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 1084656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* 1085656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Canonize the result, then we're done. 1086656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 1087656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!v3_addr_canonize(addr)) 1088656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 1089656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return addr; 1090656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 1091656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project err: 1092656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project OPENSSL_free(s); 1093656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free); 1094656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return NULL; 1095656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 1096656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 1097656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 1098656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OpenSSL dispatch 1099656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 1100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectconst X509V3_EXT_METHOD v3_addr = { 1101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project NID_sbgp_ipAddrBlock, /* nid */ 1102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 0, /* flags */ 1103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ASN1_ITEM_ref(IPAddrBlocks), /* template */ 1104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 0, 0, 0, 0, /* old functions, ignored */ 1105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 0, /* i2s */ 1106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 0, /* s2i */ 1107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 0, /* i2v */ 1108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project v2i_IPAddrBlocks, /* v2i */ 1109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project i2r_IPAddrBlocks, /* i2r */ 1110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 0, /* r2i */ 1111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project NULL /* extension-specific data */ 1112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}; 1113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 1114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 1115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Figure out whether extension sues inheritance. 1116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 1117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint v3_addr_inherits(IPAddrBlocks *addr) 1118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 1119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i; 1120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (addr == NULL) 1121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 1122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { 1123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); 1124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (f->ipAddressChoice->type == IPAddressChoice_inherit) 1125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 1126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 1127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 1128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 1129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 1130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 1131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Figure out whether parent contains child. 1132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 1133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int addr_contains(IPAddressOrRanges *parent, 1134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddressOrRanges *child, 1135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int length) 1136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 1137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned char p_min[ADDR_RAW_BUF_LEN], p_max[ADDR_RAW_BUF_LEN]; 1138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned char c_min[ADDR_RAW_BUF_LEN], c_max[ADDR_RAW_BUF_LEN]; 1139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int p, c; 1140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 1141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (child == NULL || parent == child) 1142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 1143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (parent == NULL) 1144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 1145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 1146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project p = 0; 1147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (c = 0; c < sk_IPAddressOrRange_num(child); c++) { 11487b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom if (!extract_min_max(sk_IPAddressOrRange_value(child, c), 11497b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom c_min, c_max, length)) 11507b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom return -1; 1151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (;; p++) { 1152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (p >= sk_IPAddressOrRange_num(parent)) 1153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 11547b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom if (!extract_min_max(sk_IPAddressOrRange_value(parent, p), 11557b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom p_min, p_max, length)) 11567b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom return 0; 1157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (memcmp(p_max, c_max, length) < 0) 1158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project continue; 1159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (memcmp(p_min, c_min, length) > 0) 1160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 1161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 1162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 1163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 1164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 1165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 1166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 1167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 1168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 1169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Test whether a is a subset of b. 1170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 1171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b) 1172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 1173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i; 1174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (a == NULL || a == b) 1175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 1176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (b == NULL || v3_addr_inherits(a) || v3_addr_inherits(b)) 1177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 11787b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom (void) sk_IPAddressFamily_set_cmp_func(b, IPAddressFamily_cmp); 1179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (i = 0; i < sk_IPAddressFamily_num(a); i++) { 1180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddressFamily *fa = sk_IPAddressFamily_value(a, i); 1181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int j = sk_IPAddressFamily_find(b, fa); 1182e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu IPAddressFamily *fb; 1183e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu fb = sk_IPAddressFamily_value(b, j); 1184e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu if (fb == NULL) 1185e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu return 0; 1186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!addr_contains(fb->ipAddressChoice->u.addressesOrRanges, 1187656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project fa->ipAddressChoice->u.addressesOrRanges, 1188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project length_from_afi(v3_addr_get_afi(fb)))) 1189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 1190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 1191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 1192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 1193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 1194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 1195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Validation error handling via callback. 1196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 1197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define validation_err(_err_) \ 1198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project do { \ 1199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ctx != NULL) { \ 1200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ctx->error = _err_; \ 1201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ctx->error_depth = i; \ 1202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ctx->current_cert = x; \ 1203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = ctx->verify_cb(0, ctx); \ 1204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } else { \ 1205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = 0; \ 1206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } \ 1207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!ret) \ 1208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto done; \ 1209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } while (0) 1210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 1211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 1212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Core code for RFC 3779 2.3 path validation. 1213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 1214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int v3_addr_validate_path_internal(X509_STORE_CTX *ctx, 1215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project STACK_OF(X509) *chain, 1216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddrBlocks *ext) 1217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 1218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddrBlocks *child = NULL; 1219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i, j, ret = 1; 1220221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom X509 *x; 1221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 1222e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0); 1223e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu OPENSSL_assert(ctx != NULL || ext != NULL); 1224e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu OPENSSL_assert(ctx == NULL || ctx->verify_cb != NULL); 1225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 1226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* 1227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Figure out where to start. If we don't have an extension to 1228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * check, we're done. Otherwise, check canonical form and 1229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * set up for walking up the chain. 1230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 1231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ext != NULL) { 1232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project i = -1; 1233221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom x = NULL; 1234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } else { 1235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project i = 0; 1236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project x = sk_X509_value(chain, i); 1237e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu OPENSSL_assert(x != NULL); 1238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((ext = x->rfc3779_addr) == NULL) 1239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto done; 1240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 1241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!v3_addr_is_canonical(ext)) 1242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project validation_err(X509_V_ERR_INVALID_EXTENSION); 12437b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom (void) sk_IPAddressFamily_set_cmp_func(ext, IPAddressFamily_cmp); 1244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((child = sk_IPAddressFamily_dup(ext)) == NULL) { 1245656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509V3err(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL, ERR_R_MALLOC_FAILURE); 1246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = 0; 1247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto done; 1248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 1249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 1250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* 1251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Now walk up the chain. No cert may list resources that its 1252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * parent doesn't list. 1253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 1254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (i++; i < sk_X509_num(chain); i++) { 1255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project x = sk_X509_value(chain, i); 1256e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu OPENSSL_assert(x != NULL); 1257656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!v3_addr_is_canonical(x->rfc3779_addr)) 1258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project validation_err(X509_V_ERR_INVALID_EXTENSION); 1259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (x->rfc3779_addr == NULL) { 1260656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (j = 0; j < sk_IPAddressFamily_num(child); j++) { 1261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddressFamily *fc = sk_IPAddressFamily_value(child, j); 1262656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (fc->ipAddressChoice->type != IPAddressChoice_inherit) { 1263656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project validation_err(X509_V_ERR_UNNESTED_RESOURCE); 1264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 1265656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 1266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 1267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project continue; 1268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 12697b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom (void) sk_IPAddressFamily_set_cmp_func(x->rfc3779_addr, IPAddressFamily_cmp); 1270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (j = 0; j < sk_IPAddressFamily_num(child); j++) { 1271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddressFamily *fc = sk_IPAddressFamily_value(child, j); 1272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int k = sk_IPAddressFamily_find(x->rfc3779_addr, fc); 1273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddressFamily *fp = sk_IPAddressFamily_value(x->rfc3779_addr, k); 1274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (fp == NULL) { 1275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (fc->ipAddressChoice->type == IPAddressChoice_addressesOrRanges) { 1276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project validation_err(X509_V_ERR_UNNESTED_RESOURCE); 1277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 1278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 1279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project continue; 1280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 1281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (fp->ipAddressChoice->type == IPAddressChoice_addressesOrRanges) { 1282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (fc->ipAddressChoice->type == IPAddressChoice_inherit || 1283656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project addr_contains(fp->ipAddressChoice->u.addressesOrRanges, 1284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project fc->ipAddressChoice->u.addressesOrRanges, 1285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project length_from_afi(v3_addr_get_afi(fc)))) 1286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project sk_IPAddressFamily_set(child, j, fp); 1287656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 1288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project validation_err(X509_V_ERR_UNNESTED_RESOURCE); 1289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 1290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 1291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 1292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 1293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* 1294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Trust anchor can't inherit. 1295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 1296221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom OPENSSL_assert(x != NULL); 1297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (x->rfc3779_addr != NULL) { 1298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (j = 0; j < sk_IPAddressFamily_num(x->rfc3779_addr); j++) { 1299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddressFamily *fp = sk_IPAddressFamily_value(x->rfc3779_addr, j); 1300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (fp->ipAddressChoice->type == IPAddressChoice_inherit && 1301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project sk_IPAddressFamily_find(child, fp) >= 0) 1302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project validation_err(X509_V_ERR_UNNESTED_RESOURCE); 1303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 1304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 1305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 1306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project done: 1307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project sk_IPAddressFamily_free(child); 1308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return ret; 1309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 1310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 1311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#undef validation_err 1312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 1313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 1314656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * RFC 3779 2.3 path validation -- called from X509_verify_cert(). 1315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 1316656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint v3_addr_validate_path(X509_STORE_CTX *ctx) 1317656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 1318656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return v3_addr_validate_path_internal(ctx, ctx->chain, NULL); 1319656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 1320656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 1321656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 1322656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * RFC 3779 2.3 path validation of an extension. 1323656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Test whether chain covers extension. 1324656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 1325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint v3_addr_validate_resource_set(STACK_OF(X509) *chain, 1326656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project IPAddrBlocks *ext, 1327656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int allow_inheritance) 1328656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 1329656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ext == NULL) 1330656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 1331656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (chain == NULL || sk_X509_num(chain) == 0) 1332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 1333656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!allow_inheritance && v3_addr_inherits(ext)) 1334656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 1335656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return v3_addr_validate_path_internal(NULL, chain, ext); 1336656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 1337656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 1338656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif /* OPENSSL_NO_RFC3779 */ 1339