1*de0e0e4dSAntonio Huete Jimenez /* $OpenBSD: x509_addr.c,v 1.83 2022/05/25 17:10:30 tb Exp $ */ 2*de0e0e4dSAntonio Huete Jimenez /* 3*de0e0e4dSAntonio Huete Jimenez * Contributed to the OpenSSL Project by the American Registry for 4*de0e0e4dSAntonio Huete Jimenez * Internet Numbers ("ARIN"). 5*de0e0e4dSAntonio Huete Jimenez */ 6*de0e0e4dSAntonio Huete Jimenez /* ==================================================================== 7*de0e0e4dSAntonio Huete Jimenez * Copyright (c) 2006-2016 The OpenSSL Project. All rights reserved. 8*de0e0e4dSAntonio Huete Jimenez * 9*de0e0e4dSAntonio Huete Jimenez * Redistribution and use in source and binary forms, with or without 10*de0e0e4dSAntonio Huete Jimenez * modification, are permitted provided that the following conditions 11*de0e0e4dSAntonio Huete Jimenez * are met: 12*de0e0e4dSAntonio Huete Jimenez * 13*de0e0e4dSAntonio Huete Jimenez * 1. Redistributions of source code must retain the above copyright 14*de0e0e4dSAntonio Huete Jimenez * notice, this list of conditions and the following disclaimer. 15*de0e0e4dSAntonio Huete Jimenez * 16*de0e0e4dSAntonio Huete Jimenez * 2. Redistributions in binary form must reproduce the above copyright 17*de0e0e4dSAntonio Huete Jimenez * notice, this list of conditions and the following disclaimer in 18*de0e0e4dSAntonio Huete Jimenez * the documentation and/or other materials provided with the 19*de0e0e4dSAntonio Huete Jimenez * distribution. 20*de0e0e4dSAntonio Huete Jimenez * 21*de0e0e4dSAntonio Huete Jimenez * 3. All advertising materials mentioning features or use of this 22*de0e0e4dSAntonio Huete Jimenez * software must display the following acknowledgment: 23*de0e0e4dSAntonio Huete Jimenez * "This product includes software developed by the OpenSSL Project 24*de0e0e4dSAntonio Huete Jimenez * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 25*de0e0e4dSAntonio Huete Jimenez * 26*de0e0e4dSAntonio Huete Jimenez * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 27*de0e0e4dSAntonio Huete Jimenez * endorse or promote products derived from this software without 28*de0e0e4dSAntonio Huete Jimenez * prior written permission. For written permission, please contact 29*de0e0e4dSAntonio Huete Jimenez * licensing@OpenSSL.org. 30*de0e0e4dSAntonio Huete Jimenez * 31*de0e0e4dSAntonio Huete Jimenez * 5. Products derived from this software may not be called "OpenSSL" 32*de0e0e4dSAntonio Huete Jimenez * nor may "OpenSSL" appear in their names without prior written 33*de0e0e4dSAntonio Huete Jimenez * permission of the OpenSSL Project. 34*de0e0e4dSAntonio Huete Jimenez * 35*de0e0e4dSAntonio Huete Jimenez * 6. Redistributions of any form whatsoever must retain the following 36*de0e0e4dSAntonio Huete Jimenez * acknowledgment: 37*de0e0e4dSAntonio Huete Jimenez * "This product includes software developed by the OpenSSL Project 38*de0e0e4dSAntonio Huete Jimenez * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 39*de0e0e4dSAntonio Huete Jimenez * 40*de0e0e4dSAntonio Huete Jimenez * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 41*de0e0e4dSAntonio Huete Jimenez * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42*de0e0e4dSAntonio Huete Jimenez * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43*de0e0e4dSAntonio Huete Jimenez * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 44*de0e0e4dSAntonio Huete Jimenez * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45*de0e0e4dSAntonio Huete Jimenez * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46*de0e0e4dSAntonio Huete Jimenez * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47*de0e0e4dSAntonio Huete Jimenez * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48*de0e0e4dSAntonio Huete Jimenez * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 49*de0e0e4dSAntonio Huete Jimenez * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50*de0e0e4dSAntonio Huete Jimenez * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51*de0e0e4dSAntonio Huete Jimenez * OF THE POSSIBILITY OF SUCH DAMAGE. 52*de0e0e4dSAntonio Huete Jimenez * ==================================================================== 53*de0e0e4dSAntonio Huete Jimenez * 54*de0e0e4dSAntonio Huete Jimenez * This product includes cryptographic software written by Eric Young 55*de0e0e4dSAntonio Huete Jimenez * (eay@cryptsoft.com). This product includes software written by Tim 56*de0e0e4dSAntonio Huete Jimenez * Hudson (tjh@cryptsoft.com). 57*de0e0e4dSAntonio Huete Jimenez */ 58*de0e0e4dSAntonio Huete Jimenez 59*de0e0e4dSAntonio Huete Jimenez /* 60*de0e0e4dSAntonio Huete Jimenez * Implementation of RFC 3779 section 2.2. 61*de0e0e4dSAntonio Huete Jimenez */ 62*de0e0e4dSAntonio Huete Jimenez 63*de0e0e4dSAntonio Huete Jimenez #include <limits.h> 64*de0e0e4dSAntonio Huete Jimenez #include <stdio.h> 65*de0e0e4dSAntonio Huete Jimenez #include <stdlib.h> 66*de0e0e4dSAntonio Huete Jimenez #include <string.h> 67*de0e0e4dSAntonio Huete Jimenez 68*de0e0e4dSAntonio Huete Jimenez #include <openssl/asn1.h> 69*de0e0e4dSAntonio Huete Jimenez #include <openssl/asn1t.h> 70*de0e0e4dSAntonio Huete Jimenez #include <openssl/buffer.h> 71*de0e0e4dSAntonio Huete Jimenez #include <openssl/conf.h> 72*de0e0e4dSAntonio Huete Jimenez #include <openssl/err.h> 73*de0e0e4dSAntonio Huete Jimenez #include <openssl/x509.h> 74*de0e0e4dSAntonio Huete Jimenez #include <openssl/x509v3.h> 75*de0e0e4dSAntonio Huete Jimenez 76*de0e0e4dSAntonio Huete Jimenez #include "asn1_locl.h" 77*de0e0e4dSAntonio Huete Jimenez #include "bytestring.h" 78*de0e0e4dSAntonio Huete Jimenez #include "x509_lcl.h" 79*de0e0e4dSAntonio Huete Jimenez 80*de0e0e4dSAntonio Huete Jimenez #ifndef OPENSSL_NO_RFC3779 81*de0e0e4dSAntonio Huete Jimenez 82*de0e0e4dSAntonio Huete Jimenez /* 83*de0e0e4dSAntonio Huete Jimenez * OpenSSL ASN.1 template translation of RFC 3779 2.2.3. 84*de0e0e4dSAntonio Huete Jimenez */ 85*de0e0e4dSAntonio Huete Jimenez 86*de0e0e4dSAntonio Huete Jimenez static const ASN1_TEMPLATE IPAddressRange_seq_tt[] = { 87*de0e0e4dSAntonio Huete Jimenez { 88*de0e0e4dSAntonio Huete Jimenez .flags = 0, 89*de0e0e4dSAntonio Huete Jimenez .tag = 0, 90*de0e0e4dSAntonio Huete Jimenez .offset = offsetof(IPAddressRange, min), 91*de0e0e4dSAntonio Huete Jimenez .field_name = "min", 92*de0e0e4dSAntonio Huete Jimenez .item = &ASN1_BIT_STRING_it, 93*de0e0e4dSAntonio Huete Jimenez }, 94*de0e0e4dSAntonio Huete Jimenez { 95*de0e0e4dSAntonio Huete Jimenez .flags = 0, 96*de0e0e4dSAntonio Huete Jimenez .tag = 0, 97*de0e0e4dSAntonio Huete Jimenez .offset = offsetof(IPAddressRange, max), 98*de0e0e4dSAntonio Huete Jimenez .field_name = "max", 99*de0e0e4dSAntonio Huete Jimenez .item = &ASN1_BIT_STRING_it, 100*de0e0e4dSAntonio Huete Jimenez }, 101*de0e0e4dSAntonio Huete Jimenez }; 102*de0e0e4dSAntonio Huete Jimenez 103*de0e0e4dSAntonio Huete Jimenez const ASN1_ITEM IPAddressRange_it = { 104*de0e0e4dSAntonio Huete Jimenez .itype = ASN1_ITYPE_SEQUENCE, 105*de0e0e4dSAntonio Huete Jimenez .utype = V_ASN1_SEQUENCE, 106*de0e0e4dSAntonio Huete Jimenez .templates = IPAddressRange_seq_tt, 107*de0e0e4dSAntonio Huete Jimenez .tcount = sizeof(IPAddressRange_seq_tt) / sizeof(ASN1_TEMPLATE), 108*de0e0e4dSAntonio Huete Jimenez .funcs = NULL, 109*de0e0e4dSAntonio Huete Jimenez .size = sizeof(IPAddressRange), 110*de0e0e4dSAntonio Huete Jimenez .sname = "IPAddressRange", 111*de0e0e4dSAntonio Huete Jimenez }; 112*de0e0e4dSAntonio Huete Jimenez 113*de0e0e4dSAntonio Huete Jimenez static const ASN1_TEMPLATE IPAddressOrRange_ch_tt[] = { 114*de0e0e4dSAntonio Huete Jimenez { 115*de0e0e4dSAntonio Huete Jimenez .flags = 0, 116*de0e0e4dSAntonio Huete Jimenez .tag = 0, 117*de0e0e4dSAntonio Huete Jimenez .offset = offsetof(IPAddressOrRange, u.addressPrefix), 118*de0e0e4dSAntonio Huete Jimenez .field_name = "u.addressPrefix", 119*de0e0e4dSAntonio Huete Jimenez .item = &ASN1_BIT_STRING_it, 120*de0e0e4dSAntonio Huete Jimenez }, 121*de0e0e4dSAntonio Huete Jimenez { 122*de0e0e4dSAntonio Huete Jimenez .flags = 0, 123*de0e0e4dSAntonio Huete Jimenez .tag = 0, 124*de0e0e4dSAntonio Huete Jimenez .offset = offsetof(IPAddressOrRange, u.addressRange), 125*de0e0e4dSAntonio Huete Jimenez .field_name = "u.addressRange", 126*de0e0e4dSAntonio Huete Jimenez .item = &IPAddressRange_it, 127*de0e0e4dSAntonio Huete Jimenez }, 128*de0e0e4dSAntonio Huete Jimenez }; 129*de0e0e4dSAntonio Huete Jimenez 130*de0e0e4dSAntonio Huete Jimenez const ASN1_ITEM IPAddressOrRange_it = { 131*de0e0e4dSAntonio Huete Jimenez .itype = ASN1_ITYPE_CHOICE, 132*de0e0e4dSAntonio Huete Jimenez .utype = offsetof(IPAddressOrRange, type), 133*de0e0e4dSAntonio Huete Jimenez .templates = IPAddressOrRange_ch_tt, 134*de0e0e4dSAntonio Huete Jimenez .tcount = sizeof(IPAddressOrRange_ch_tt) / sizeof(ASN1_TEMPLATE), 135*de0e0e4dSAntonio Huete Jimenez .funcs = NULL, 136*de0e0e4dSAntonio Huete Jimenez .size = sizeof(IPAddressOrRange), 137*de0e0e4dSAntonio Huete Jimenez .sname = "IPAddressOrRange", 138*de0e0e4dSAntonio Huete Jimenez }; 139*de0e0e4dSAntonio Huete Jimenez 140*de0e0e4dSAntonio Huete Jimenez static const ASN1_TEMPLATE IPAddressChoice_ch_tt[] = { 141*de0e0e4dSAntonio Huete Jimenez { 142*de0e0e4dSAntonio Huete Jimenez .flags = 0, 143*de0e0e4dSAntonio Huete Jimenez .tag = 0, 144*de0e0e4dSAntonio Huete Jimenez .offset = offsetof(IPAddressChoice, u.inherit), 145*de0e0e4dSAntonio Huete Jimenez .field_name = "u.inherit", 146*de0e0e4dSAntonio Huete Jimenez .item = &ASN1_NULL_it, 147*de0e0e4dSAntonio Huete Jimenez }, 148*de0e0e4dSAntonio Huete Jimenez { 149*de0e0e4dSAntonio Huete Jimenez .flags = ASN1_TFLG_SEQUENCE_OF, 150*de0e0e4dSAntonio Huete Jimenez .tag = 0, 151*de0e0e4dSAntonio Huete Jimenez .offset = offsetof(IPAddressChoice, u.addressesOrRanges), 152*de0e0e4dSAntonio Huete Jimenez .field_name = "u.addressesOrRanges", 153*de0e0e4dSAntonio Huete Jimenez .item = &IPAddressOrRange_it, 154*de0e0e4dSAntonio Huete Jimenez }, 155*de0e0e4dSAntonio Huete Jimenez }; 156*de0e0e4dSAntonio Huete Jimenez 157*de0e0e4dSAntonio Huete Jimenez const ASN1_ITEM IPAddressChoice_it = { 158*de0e0e4dSAntonio Huete Jimenez .itype = ASN1_ITYPE_CHOICE, 159*de0e0e4dSAntonio Huete Jimenez .utype = offsetof(IPAddressChoice, type), 160*de0e0e4dSAntonio Huete Jimenez .templates = IPAddressChoice_ch_tt, 161*de0e0e4dSAntonio Huete Jimenez .tcount = sizeof(IPAddressChoice_ch_tt) / sizeof(ASN1_TEMPLATE), 162*de0e0e4dSAntonio Huete Jimenez .funcs = NULL, 163*de0e0e4dSAntonio Huete Jimenez .size = sizeof(IPAddressChoice), 164*de0e0e4dSAntonio Huete Jimenez .sname = "IPAddressChoice", 165*de0e0e4dSAntonio Huete Jimenez }; 166*de0e0e4dSAntonio Huete Jimenez 167*de0e0e4dSAntonio Huete Jimenez static const ASN1_TEMPLATE IPAddressFamily_seq_tt[] = { 168*de0e0e4dSAntonio Huete Jimenez { 169*de0e0e4dSAntonio Huete Jimenez .flags = 0, 170*de0e0e4dSAntonio Huete Jimenez .tag = 0, 171*de0e0e4dSAntonio Huete Jimenez .offset = offsetof(IPAddressFamily, addressFamily), 172*de0e0e4dSAntonio Huete Jimenez .field_name = "addressFamily", 173*de0e0e4dSAntonio Huete Jimenez .item = &ASN1_OCTET_STRING_it, 174*de0e0e4dSAntonio Huete Jimenez }, 175*de0e0e4dSAntonio Huete Jimenez { 176*de0e0e4dSAntonio Huete Jimenez .flags = 0, 177*de0e0e4dSAntonio Huete Jimenez .tag = 0, 178*de0e0e4dSAntonio Huete Jimenez .offset = offsetof(IPAddressFamily, ipAddressChoice), 179*de0e0e4dSAntonio Huete Jimenez .field_name = "ipAddressChoice", 180*de0e0e4dSAntonio Huete Jimenez .item = &IPAddressChoice_it, 181*de0e0e4dSAntonio Huete Jimenez }, 182*de0e0e4dSAntonio Huete Jimenez }; 183*de0e0e4dSAntonio Huete Jimenez 184*de0e0e4dSAntonio Huete Jimenez const ASN1_ITEM IPAddressFamily_it = { 185*de0e0e4dSAntonio Huete Jimenez .itype = ASN1_ITYPE_SEQUENCE, 186*de0e0e4dSAntonio Huete Jimenez .utype = V_ASN1_SEQUENCE, 187*de0e0e4dSAntonio Huete Jimenez .templates = IPAddressFamily_seq_tt, 188*de0e0e4dSAntonio Huete Jimenez .tcount = sizeof(IPAddressFamily_seq_tt) / sizeof(ASN1_TEMPLATE), 189*de0e0e4dSAntonio Huete Jimenez .funcs = NULL, 190*de0e0e4dSAntonio Huete Jimenez .size = sizeof(IPAddressFamily), 191*de0e0e4dSAntonio Huete Jimenez .sname = "IPAddressFamily", 192*de0e0e4dSAntonio Huete Jimenez }; 193*de0e0e4dSAntonio Huete Jimenez 194*de0e0e4dSAntonio Huete Jimenez static const ASN1_TEMPLATE IPAddrBlocks_item_tt = { 195*de0e0e4dSAntonio Huete Jimenez .flags = ASN1_TFLG_SEQUENCE_OF, 196*de0e0e4dSAntonio Huete Jimenez .tag = 0, 197*de0e0e4dSAntonio Huete Jimenez .offset = 0, 198*de0e0e4dSAntonio Huete Jimenez .field_name = "IPAddrBlocks", 199*de0e0e4dSAntonio Huete Jimenez .item = &IPAddressFamily_it, 200*de0e0e4dSAntonio Huete Jimenez }; 201*de0e0e4dSAntonio Huete Jimenez 202*de0e0e4dSAntonio Huete Jimenez static const ASN1_ITEM IPAddrBlocks_it = { 203*de0e0e4dSAntonio Huete Jimenez .itype = ASN1_ITYPE_PRIMITIVE, 204*de0e0e4dSAntonio Huete Jimenez .utype = -1, 205*de0e0e4dSAntonio Huete Jimenez .templates = &IPAddrBlocks_item_tt, 206*de0e0e4dSAntonio Huete Jimenez .tcount = 0, 207*de0e0e4dSAntonio Huete Jimenez .funcs = NULL, 208*de0e0e4dSAntonio Huete Jimenez .size = 0, 209*de0e0e4dSAntonio Huete Jimenez .sname = "IPAddrBlocks", 210*de0e0e4dSAntonio Huete Jimenez }; 211*de0e0e4dSAntonio Huete Jimenez 212*de0e0e4dSAntonio Huete Jimenez IPAddressRange * 213*de0e0e4dSAntonio Huete Jimenez d2i_IPAddressRange(IPAddressRange **a, const unsigned char **in, long len) 214*de0e0e4dSAntonio Huete Jimenez { 215*de0e0e4dSAntonio Huete Jimenez return (IPAddressRange *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, 216*de0e0e4dSAntonio Huete Jimenez &IPAddressRange_it); 217*de0e0e4dSAntonio Huete Jimenez } 218*de0e0e4dSAntonio Huete Jimenez 219*de0e0e4dSAntonio Huete Jimenez int 220*de0e0e4dSAntonio Huete Jimenez i2d_IPAddressRange(IPAddressRange *a, unsigned char **out) 221*de0e0e4dSAntonio Huete Jimenez { 222*de0e0e4dSAntonio Huete Jimenez return ASN1_item_i2d((ASN1_VALUE *)a, out, &IPAddressRange_it); 223*de0e0e4dSAntonio Huete Jimenez } 224*de0e0e4dSAntonio Huete Jimenez 225*de0e0e4dSAntonio Huete Jimenez IPAddressRange * 226*de0e0e4dSAntonio Huete Jimenez IPAddressRange_new(void) 227*de0e0e4dSAntonio Huete Jimenez { 228*de0e0e4dSAntonio Huete Jimenez return (IPAddressRange *)ASN1_item_new(&IPAddressRange_it); 229*de0e0e4dSAntonio Huete Jimenez } 230*de0e0e4dSAntonio Huete Jimenez 231*de0e0e4dSAntonio Huete Jimenez void 232*de0e0e4dSAntonio Huete Jimenez IPAddressRange_free(IPAddressRange *a) 233*de0e0e4dSAntonio Huete Jimenez { 234*de0e0e4dSAntonio Huete Jimenez ASN1_item_free((ASN1_VALUE *)a, &IPAddressRange_it); 235*de0e0e4dSAntonio Huete Jimenez } 236*de0e0e4dSAntonio Huete Jimenez 237*de0e0e4dSAntonio Huete Jimenez IPAddressOrRange * 238*de0e0e4dSAntonio Huete Jimenez d2i_IPAddressOrRange(IPAddressOrRange **a, const unsigned char **in, long len) 239*de0e0e4dSAntonio Huete Jimenez { 240*de0e0e4dSAntonio Huete Jimenez return (IPAddressOrRange *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, 241*de0e0e4dSAntonio Huete Jimenez &IPAddressOrRange_it); 242*de0e0e4dSAntonio Huete Jimenez } 243*de0e0e4dSAntonio Huete Jimenez 244*de0e0e4dSAntonio Huete Jimenez int 245*de0e0e4dSAntonio Huete Jimenez i2d_IPAddressOrRange(IPAddressOrRange *a, unsigned char **out) 246*de0e0e4dSAntonio Huete Jimenez { 247*de0e0e4dSAntonio Huete Jimenez return ASN1_item_i2d((ASN1_VALUE *)a, out, &IPAddressOrRange_it); 248*de0e0e4dSAntonio Huete Jimenez } 249*de0e0e4dSAntonio Huete Jimenez 250*de0e0e4dSAntonio Huete Jimenez IPAddressOrRange * 251*de0e0e4dSAntonio Huete Jimenez IPAddressOrRange_new(void) 252*de0e0e4dSAntonio Huete Jimenez { 253*de0e0e4dSAntonio Huete Jimenez return (IPAddressOrRange *)ASN1_item_new(&IPAddressOrRange_it); 254*de0e0e4dSAntonio Huete Jimenez } 255*de0e0e4dSAntonio Huete Jimenez 256*de0e0e4dSAntonio Huete Jimenez void 257*de0e0e4dSAntonio Huete Jimenez IPAddressOrRange_free(IPAddressOrRange *a) 258*de0e0e4dSAntonio Huete Jimenez { 259*de0e0e4dSAntonio Huete Jimenez ASN1_item_free((ASN1_VALUE *)a, &IPAddressOrRange_it); 260*de0e0e4dSAntonio Huete Jimenez } 261*de0e0e4dSAntonio Huete Jimenez 262*de0e0e4dSAntonio Huete Jimenez IPAddressChoice * 263*de0e0e4dSAntonio Huete Jimenez d2i_IPAddressChoice(IPAddressChoice **a, const unsigned char **in, long len) 264*de0e0e4dSAntonio Huete Jimenez { 265*de0e0e4dSAntonio Huete Jimenez return (IPAddressChoice *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, 266*de0e0e4dSAntonio Huete Jimenez &IPAddressChoice_it); 267*de0e0e4dSAntonio Huete Jimenez } 268*de0e0e4dSAntonio Huete Jimenez 269*de0e0e4dSAntonio Huete Jimenez int 270*de0e0e4dSAntonio Huete Jimenez i2d_IPAddressChoice(IPAddressChoice *a, unsigned char **out) 271*de0e0e4dSAntonio Huete Jimenez { 272*de0e0e4dSAntonio Huete Jimenez return ASN1_item_i2d((ASN1_VALUE *)a, out, &IPAddressChoice_it); 273*de0e0e4dSAntonio Huete Jimenez } 274*de0e0e4dSAntonio Huete Jimenez 275*de0e0e4dSAntonio Huete Jimenez IPAddressChoice * 276*de0e0e4dSAntonio Huete Jimenez IPAddressChoice_new(void) 277*de0e0e4dSAntonio Huete Jimenez { 278*de0e0e4dSAntonio Huete Jimenez return (IPAddressChoice *)ASN1_item_new(&IPAddressChoice_it); 279*de0e0e4dSAntonio Huete Jimenez } 280*de0e0e4dSAntonio Huete Jimenez 281*de0e0e4dSAntonio Huete Jimenez void 282*de0e0e4dSAntonio Huete Jimenez IPAddressChoice_free(IPAddressChoice *a) 283*de0e0e4dSAntonio Huete Jimenez { 284*de0e0e4dSAntonio Huete Jimenez ASN1_item_free((ASN1_VALUE *)a, &IPAddressChoice_it); 285*de0e0e4dSAntonio Huete Jimenez } 286*de0e0e4dSAntonio Huete Jimenez 287*de0e0e4dSAntonio Huete Jimenez IPAddressFamily * 288*de0e0e4dSAntonio Huete Jimenez d2i_IPAddressFamily(IPAddressFamily **a, const unsigned char **in, long len) 289*de0e0e4dSAntonio Huete Jimenez { 290*de0e0e4dSAntonio Huete Jimenez return (IPAddressFamily *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, 291*de0e0e4dSAntonio Huete Jimenez &IPAddressFamily_it); 292*de0e0e4dSAntonio Huete Jimenez } 293*de0e0e4dSAntonio Huete Jimenez 294*de0e0e4dSAntonio Huete Jimenez int 295*de0e0e4dSAntonio Huete Jimenez i2d_IPAddressFamily(IPAddressFamily *a, unsigned char **out) 296*de0e0e4dSAntonio Huete Jimenez { 297*de0e0e4dSAntonio Huete Jimenez return ASN1_item_i2d((ASN1_VALUE *)a, out, &IPAddressFamily_it); 298*de0e0e4dSAntonio Huete Jimenez } 299*de0e0e4dSAntonio Huete Jimenez 300*de0e0e4dSAntonio Huete Jimenez IPAddressFamily * 301*de0e0e4dSAntonio Huete Jimenez IPAddressFamily_new(void) 302*de0e0e4dSAntonio Huete Jimenez { 303*de0e0e4dSAntonio Huete Jimenez return (IPAddressFamily *)ASN1_item_new(&IPAddressFamily_it); 304*de0e0e4dSAntonio Huete Jimenez } 305*de0e0e4dSAntonio Huete Jimenez 306*de0e0e4dSAntonio Huete Jimenez void 307*de0e0e4dSAntonio Huete Jimenez IPAddressFamily_free(IPAddressFamily *a) 308*de0e0e4dSAntonio Huete Jimenez { 309*de0e0e4dSAntonio Huete Jimenez ASN1_item_free((ASN1_VALUE *)a, &IPAddressFamily_it); 310*de0e0e4dSAntonio Huete Jimenez } 311*de0e0e4dSAntonio Huete Jimenez 312*de0e0e4dSAntonio Huete Jimenez /* 313*de0e0e4dSAntonio Huete Jimenez * Convenience accessors for IPAddressFamily. 314*de0e0e4dSAntonio Huete Jimenez */ 315*de0e0e4dSAntonio Huete Jimenez 316*de0e0e4dSAntonio Huete Jimenez static int 317*de0e0e4dSAntonio Huete Jimenez IPAddressFamily_type(IPAddressFamily *af) 318*de0e0e4dSAntonio Huete Jimenez { 319*de0e0e4dSAntonio Huete Jimenez /* XXX - can af->ipAddressChoice == NULL actually happen? */ 320*de0e0e4dSAntonio Huete Jimenez if (af == NULL || af->ipAddressChoice == NULL) 321*de0e0e4dSAntonio Huete Jimenez return -1; 322*de0e0e4dSAntonio Huete Jimenez 323*de0e0e4dSAntonio Huete Jimenez switch (af->ipAddressChoice->type) { 324*de0e0e4dSAntonio Huete Jimenez case IPAddressChoice_inherit: 325*de0e0e4dSAntonio Huete Jimenez case IPAddressChoice_addressesOrRanges: 326*de0e0e4dSAntonio Huete Jimenez return af->ipAddressChoice->type; 327*de0e0e4dSAntonio Huete Jimenez default: 328*de0e0e4dSAntonio Huete Jimenez return -1; 329*de0e0e4dSAntonio Huete Jimenez } 330*de0e0e4dSAntonio Huete Jimenez } 331*de0e0e4dSAntonio Huete Jimenez 332*de0e0e4dSAntonio Huete Jimenez static IPAddressOrRanges * 333*de0e0e4dSAntonio Huete Jimenez IPAddressFamily_addressesOrRanges(IPAddressFamily *af) 334*de0e0e4dSAntonio Huete Jimenez { 335*de0e0e4dSAntonio Huete Jimenez if (IPAddressFamily_type(af) == IPAddressChoice_addressesOrRanges) 336*de0e0e4dSAntonio Huete Jimenez return af->ipAddressChoice->u.addressesOrRanges; 337*de0e0e4dSAntonio Huete Jimenez 338*de0e0e4dSAntonio Huete Jimenez return NULL; 339*de0e0e4dSAntonio Huete Jimenez } 340*de0e0e4dSAntonio Huete Jimenez 341*de0e0e4dSAntonio Huete Jimenez static ASN1_NULL * 342*de0e0e4dSAntonio Huete Jimenez IPAddressFamily_inheritance(IPAddressFamily *af) 343*de0e0e4dSAntonio Huete Jimenez { 344*de0e0e4dSAntonio Huete Jimenez if (IPAddressFamily_type(af) == IPAddressChoice_inherit) 345*de0e0e4dSAntonio Huete Jimenez return af->ipAddressChoice->u.inherit; 346*de0e0e4dSAntonio Huete Jimenez 347*de0e0e4dSAntonio Huete Jimenez return NULL; 348*de0e0e4dSAntonio Huete Jimenez } 349*de0e0e4dSAntonio Huete Jimenez 350*de0e0e4dSAntonio Huete Jimenez static int 351*de0e0e4dSAntonio Huete Jimenez IPAddressFamily_set_inheritance(IPAddressFamily *af) 352*de0e0e4dSAntonio Huete Jimenez { 353*de0e0e4dSAntonio Huete Jimenez if (IPAddressFamily_addressesOrRanges(af) != NULL) 354*de0e0e4dSAntonio Huete Jimenez return 0; 355*de0e0e4dSAntonio Huete Jimenez 356*de0e0e4dSAntonio Huete Jimenez if (IPAddressFamily_inheritance(af) != NULL) 357*de0e0e4dSAntonio Huete Jimenez return 1; 358*de0e0e4dSAntonio Huete Jimenez 359*de0e0e4dSAntonio Huete Jimenez if ((af->ipAddressChoice->u.inherit = ASN1_NULL_new()) == NULL) 360*de0e0e4dSAntonio Huete Jimenez return 0; 361*de0e0e4dSAntonio Huete Jimenez af->ipAddressChoice->type = IPAddressChoice_inherit; 362*de0e0e4dSAntonio Huete Jimenez 363*de0e0e4dSAntonio Huete Jimenez return 1; 364*de0e0e4dSAntonio Huete Jimenez } 365*de0e0e4dSAntonio Huete Jimenez 366*de0e0e4dSAntonio Huete Jimenez /* 367*de0e0e4dSAntonio Huete Jimenez * How much buffer space do we need for a raw address? 368*de0e0e4dSAntonio Huete Jimenez */ 369*de0e0e4dSAntonio Huete Jimenez #define ADDR_RAW_BUF_LEN 16 370*de0e0e4dSAntonio Huete Jimenez 371*de0e0e4dSAntonio Huete Jimenez /* 372*de0e0e4dSAntonio Huete Jimenez * What's the address length associated with this AFI? 373*de0e0e4dSAntonio Huete Jimenez */ 374*de0e0e4dSAntonio Huete Jimenez static int 375*de0e0e4dSAntonio Huete Jimenez length_from_afi(const unsigned afi) 376*de0e0e4dSAntonio Huete Jimenez { 377*de0e0e4dSAntonio Huete Jimenez switch (afi) { 378*de0e0e4dSAntonio Huete Jimenez case IANA_AFI_IPV4: 379*de0e0e4dSAntonio Huete Jimenez return 4; 380*de0e0e4dSAntonio Huete Jimenez case IANA_AFI_IPV6: 381*de0e0e4dSAntonio Huete Jimenez return 16; 382*de0e0e4dSAntonio Huete Jimenez default: 383*de0e0e4dSAntonio Huete Jimenez return 0; 384*de0e0e4dSAntonio Huete Jimenez } 385*de0e0e4dSAntonio Huete Jimenez } 386*de0e0e4dSAntonio Huete Jimenez 387*de0e0e4dSAntonio Huete Jimenez /* 388*de0e0e4dSAntonio Huete Jimenez * Get AFI and optional SAFI from an IPAddressFamily. All three out arguments 389*de0e0e4dSAntonio Huete Jimenez * are optional; if |out_safi| is non-NULL, |safi_is_set| must be non-NULL. 390*de0e0e4dSAntonio Huete Jimenez */ 391*de0e0e4dSAntonio Huete Jimenez static int 392*de0e0e4dSAntonio Huete Jimenez IPAddressFamily_afi_safi(const IPAddressFamily *af, uint16_t *out_afi, 393*de0e0e4dSAntonio Huete Jimenez uint8_t *out_safi, int *safi_is_set) 394*de0e0e4dSAntonio Huete Jimenez { 395*de0e0e4dSAntonio Huete Jimenez CBS cbs; 396*de0e0e4dSAntonio Huete Jimenez uint16_t afi; 397*de0e0e4dSAntonio Huete Jimenez uint8_t safi = 0; 398*de0e0e4dSAntonio Huete Jimenez int got_safi = 0; 399*de0e0e4dSAntonio Huete Jimenez 400*de0e0e4dSAntonio Huete Jimenez CBS_init(&cbs, af->addressFamily->data, af->addressFamily->length); 401*de0e0e4dSAntonio Huete Jimenez 402*de0e0e4dSAntonio Huete Jimenez if (!CBS_get_u16(&cbs, &afi)) 403*de0e0e4dSAntonio Huete Jimenez return 0; 404*de0e0e4dSAntonio Huete Jimenez 405*de0e0e4dSAntonio Huete Jimenez /* Fetch the optional SAFI. */ 406*de0e0e4dSAntonio Huete Jimenez if (CBS_len(&cbs) != 0) { 407*de0e0e4dSAntonio Huete Jimenez if (!CBS_get_u8(&cbs, &safi)) 408*de0e0e4dSAntonio Huete Jimenez return 0; 409*de0e0e4dSAntonio Huete Jimenez got_safi = 1; 410*de0e0e4dSAntonio Huete Jimenez } 411*de0e0e4dSAntonio Huete Jimenez 412*de0e0e4dSAntonio Huete Jimenez /* If there's anything left, it's garbage. */ 413*de0e0e4dSAntonio Huete Jimenez if (CBS_len(&cbs) != 0) 414*de0e0e4dSAntonio Huete Jimenez return 0; 415*de0e0e4dSAntonio Huete Jimenez 416*de0e0e4dSAntonio Huete Jimenez /* XXX - error on reserved AFI/SAFI? */ 417*de0e0e4dSAntonio Huete Jimenez 418*de0e0e4dSAntonio Huete Jimenez if (out_afi != NULL) 419*de0e0e4dSAntonio Huete Jimenez *out_afi = afi; 420*de0e0e4dSAntonio Huete Jimenez 421*de0e0e4dSAntonio Huete Jimenez if (out_safi != NULL) { 422*de0e0e4dSAntonio Huete Jimenez *out_safi = safi; 423*de0e0e4dSAntonio Huete Jimenez *safi_is_set = got_safi; 424*de0e0e4dSAntonio Huete Jimenez } 425*de0e0e4dSAntonio Huete Jimenez 426*de0e0e4dSAntonio Huete Jimenez return 1; 427*de0e0e4dSAntonio Huete Jimenez } 428*de0e0e4dSAntonio Huete Jimenez 429*de0e0e4dSAntonio Huete Jimenez static int 430*de0e0e4dSAntonio Huete Jimenez IPAddressFamily_afi(const IPAddressFamily *af, uint16_t *out_afi) 431*de0e0e4dSAntonio Huete Jimenez { 432*de0e0e4dSAntonio Huete Jimenez return IPAddressFamily_afi_safi(af, out_afi, NULL, NULL); 433*de0e0e4dSAntonio Huete Jimenez } 434*de0e0e4dSAntonio Huete Jimenez 435*de0e0e4dSAntonio Huete Jimenez static int 436*de0e0e4dSAntonio Huete Jimenez IPAddressFamily_afi_is_valid(const IPAddressFamily *af) 437*de0e0e4dSAntonio Huete Jimenez { 438*de0e0e4dSAntonio Huete Jimenez return IPAddressFamily_afi_safi(af, NULL, NULL, NULL); 439*de0e0e4dSAntonio Huete Jimenez } 440*de0e0e4dSAntonio Huete Jimenez 441*de0e0e4dSAntonio Huete Jimenez static int 442*de0e0e4dSAntonio Huete Jimenez IPAddressFamily_afi_length(const IPAddressFamily *af, int *out_length) 443*de0e0e4dSAntonio Huete Jimenez { 444*de0e0e4dSAntonio Huete Jimenez uint16_t afi; 445*de0e0e4dSAntonio Huete Jimenez 446*de0e0e4dSAntonio Huete Jimenez *out_length = 0; 447*de0e0e4dSAntonio Huete Jimenez 448*de0e0e4dSAntonio Huete Jimenez if (!IPAddressFamily_afi(af, &afi)) 449*de0e0e4dSAntonio Huete Jimenez return 0; 450*de0e0e4dSAntonio Huete Jimenez 451*de0e0e4dSAntonio Huete Jimenez *out_length = length_from_afi(afi); 452*de0e0e4dSAntonio Huete Jimenez 453*de0e0e4dSAntonio Huete Jimenez return 1; 454*de0e0e4dSAntonio Huete Jimenez } 455*de0e0e4dSAntonio Huete Jimenez 456*de0e0e4dSAntonio Huete Jimenez #define MINIMUM(a, b) (((a) < (b)) ? (a) : (b)) 457*de0e0e4dSAntonio Huete Jimenez 458*de0e0e4dSAntonio Huete Jimenez /* 459*de0e0e4dSAntonio Huete Jimenez * Sort comparison function for a sequence of IPAddressFamily. 460*de0e0e4dSAntonio Huete Jimenez * 461*de0e0e4dSAntonio Huete Jimenez * The last paragraph of RFC 3779 2.2.3.3 is slightly ambiguous about 462*de0e0e4dSAntonio Huete Jimenez * the ordering: I can read it as meaning that IPv6 without a SAFI 463*de0e0e4dSAntonio Huete Jimenez * comes before IPv4 with a SAFI, which seems pretty weird. The 464*de0e0e4dSAntonio Huete Jimenez * examples in appendix B suggest that the author intended the 465*de0e0e4dSAntonio Huete Jimenez * null-SAFI rule to apply only within a single AFI, which is what I 466*de0e0e4dSAntonio Huete Jimenez * would have expected and is what the following code implements. 467*de0e0e4dSAntonio Huete Jimenez */ 468*de0e0e4dSAntonio Huete Jimenez static int 469*de0e0e4dSAntonio Huete Jimenez IPAddressFamily_cmp(const IPAddressFamily *const *a_, 470*de0e0e4dSAntonio Huete Jimenez const IPAddressFamily *const *b_) 471*de0e0e4dSAntonio Huete Jimenez { 472*de0e0e4dSAntonio Huete Jimenez const ASN1_OCTET_STRING *a = (*a_)->addressFamily; 473*de0e0e4dSAntonio Huete Jimenez const ASN1_OCTET_STRING *b = (*b_)->addressFamily; 474*de0e0e4dSAntonio Huete Jimenez int len, cmp; 475*de0e0e4dSAntonio Huete Jimenez 476*de0e0e4dSAntonio Huete Jimenez len = MINIMUM(a->length, b->length); 477*de0e0e4dSAntonio Huete Jimenez 478*de0e0e4dSAntonio Huete Jimenez if ((cmp = memcmp(a->data, b->data, len)) != 0) 479*de0e0e4dSAntonio Huete Jimenez return cmp; 480*de0e0e4dSAntonio Huete Jimenez 481*de0e0e4dSAntonio Huete Jimenez return a->length - b->length; 482*de0e0e4dSAntonio Huete Jimenez } 483*de0e0e4dSAntonio Huete Jimenez 484*de0e0e4dSAntonio Huete Jimenez static IPAddressFamily * 485*de0e0e4dSAntonio Huete Jimenez IPAddressFamily_find_in_parent(IPAddrBlocks *parent, IPAddressFamily *child_af) 486*de0e0e4dSAntonio Huete Jimenez { 487*de0e0e4dSAntonio Huete Jimenez int index; 488*de0e0e4dSAntonio Huete Jimenez 489*de0e0e4dSAntonio Huete Jimenez (void)sk_IPAddressFamily_set_cmp_func(parent, IPAddressFamily_cmp); 490*de0e0e4dSAntonio Huete Jimenez 491*de0e0e4dSAntonio Huete Jimenez if ((index = sk_IPAddressFamily_find(parent, child_af)) < 0) 492*de0e0e4dSAntonio Huete Jimenez return NULL; 493*de0e0e4dSAntonio Huete Jimenez 494*de0e0e4dSAntonio Huete Jimenez return sk_IPAddressFamily_value(parent, index); 495*de0e0e4dSAntonio Huete Jimenez } 496*de0e0e4dSAntonio Huete Jimenez 497*de0e0e4dSAntonio Huete Jimenez /* 498*de0e0e4dSAntonio Huete Jimenez * Extract the AFI from an IPAddressFamily. 499*de0e0e4dSAntonio Huete Jimenez * 500*de0e0e4dSAntonio Huete Jimenez * This is public API. It uses the reserved AFI 0 as an in-band error 501*de0e0e4dSAntonio Huete Jimenez * while it doesn't care about the reserved AFI 65535... 502*de0e0e4dSAntonio Huete Jimenez */ 503*de0e0e4dSAntonio Huete Jimenez unsigned int 504*de0e0e4dSAntonio Huete Jimenez X509v3_addr_get_afi(const IPAddressFamily *af) 505*de0e0e4dSAntonio Huete Jimenez { 506*de0e0e4dSAntonio Huete Jimenez uint16_t afi; 507*de0e0e4dSAntonio Huete Jimenez 508*de0e0e4dSAntonio Huete Jimenez /* 509*de0e0e4dSAntonio Huete Jimenez * XXX are these NULL checks really sensible? If af is non-NULL, it 510*de0e0e4dSAntonio Huete Jimenez * should have both addressFamily and ipAddressChoice... 511*de0e0e4dSAntonio Huete Jimenez */ 512*de0e0e4dSAntonio Huete Jimenez if (af == NULL || af->addressFamily == NULL || 513*de0e0e4dSAntonio Huete Jimenez af->addressFamily->data == NULL) 514*de0e0e4dSAntonio Huete Jimenez return 0; 515*de0e0e4dSAntonio Huete Jimenez 516*de0e0e4dSAntonio Huete Jimenez if (!IPAddressFamily_afi(af, &afi)) 517*de0e0e4dSAntonio Huete Jimenez return 0; 518*de0e0e4dSAntonio Huete Jimenez 519*de0e0e4dSAntonio Huete Jimenez return afi; 520*de0e0e4dSAntonio Huete Jimenez } 521*de0e0e4dSAntonio Huete Jimenez 522*de0e0e4dSAntonio Huete Jimenez /* 523*de0e0e4dSAntonio Huete Jimenez * Expand the bitstring form (RFC 3779, section 2.1.2) of an address into 524*de0e0e4dSAntonio Huete Jimenez * a raw byte array. At the moment this is coded for simplicity, not speed. 525*de0e0e4dSAntonio Huete Jimenez * 526*de0e0e4dSAntonio Huete Jimenez * Unused bits in the last octet of |bs| and all bits in subsequent bytes 527*de0e0e4dSAntonio Huete Jimenez * of |addr| are set to 0 or 1 depending on whether |fill| is 0 or not. 528*de0e0e4dSAntonio Huete Jimenez */ 529*de0e0e4dSAntonio Huete Jimenez static int 530*de0e0e4dSAntonio Huete Jimenez addr_expand(unsigned char *addr, const ASN1_BIT_STRING *bs, const int length, 531*de0e0e4dSAntonio Huete Jimenez uint8_t fill) 532*de0e0e4dSAntonio Huete Jimenez { 533*de0e0e4dSAntonio Huete Jimenez if (bs->length < 0 || bs->length > length) 534*de0e0e4dSAntonio Huete Jimenez return 0; 535*de0e0e4dSAntonio Huete Jimenez 536*de0e0e4dSAntonio Huete Jimenez if (fill != 0) 537*de0e0e4dSAntonio Huete Jimenez fill = 0xff; 538*de0e0e4dSAntonio Huete Jimenez 539*de0e0e4dSAntonio Huete Jimenez if (bs->length > 0) { 540*de0e0e4dSAntonio Huete Jimenez /* XXX - shouldn't this check ASN1_STRING_FLAG_BITS_LEFT? */ 541*de0e0e4dSAntonio Huete Jimenez uint8_t unused_bits = bs->flags & 7; 542*de0e0e4dSAntonio Huete Jimenez uint8_t mask = (1 << unused_bits) - 1; 543*de0e0e4dSAntonio Huete Jimenez 544*de0e0e4dSAntonio Huete Jimenez memcpy(addr, bs->data, bs->length); 545*de0e0e4dSAntonio Huete Jimenez 546*de0e0e4dSAntonio Huete Jimenez if (fill == 0) 547*de0e0e4dSAntonio Huete Jimenez addr[bs->length - 1] &= ~mask; 548*de0e0e4dSAntonio Huete Jimenez else 549*de0e0e4dSAntonio Huete Jimenez addr[bs->length - 1] |= mask; 550*de0e0e4dSAntonio Huete Jimenez } 551*de0e0e4dSAntonio Huete Jimenez 552*de0e0e4dSAntonio Huete Jimenez memset(addr + bs->length, fill, length - bs->length); 553*de0e0e4dSAntonio Huete Jimenez 554*de0e0e4dSAntonio Huete Jimenez return 1; 555*de0e0e4dSAntonio Huete Jimenez } 556*de0e0e4dSAntonio Huete Jimenez 557*de0e0e4dSAntonio Huete Jimenez /* 558*de0e0e4dSAntonio Huete Jimenez * Extract the prefix length from a bitstring: 8 * length - unused bits. 559*de0e0e4dSAntonio Huete Jimenez */ 560*de0e0e4dSAntonio Huete Jimenez #define addr_prefix_len(bs) ((int) ((bs)->length * 8 - ((bs)->flags & 7))) 561*de0e0e4dSAntonio Huete Jimenez 562*de0e0e4dSAntonio Huete Jimenez /* 563*de0e0e4dSAntonio Huete Jimenez * i2r handler for one address bitstring. 564*de0e0e4dSAntonio Huete Jimenez */ 565*de0e0e4dSAntonio Huete Jimenez static int 566*de0e0e4dSAntonio Huete Jimenez i2r_address(BIO *out, const unsigned afi, const unsigned char fill, 567*de0e0e4dSAntonio Huete Jimenez const ASN1_BIT_STRING *bs) 568*de0e0e4dSAntonio Huete Jimenez { 569*de0e0e4dSAntonio Huete Jimenez unsigned char addr[ADDR_RAW_BUF_LEN]; 570*de0e0e4dSAntonio Huete Jimenez int i, n; 571*de0e0e4dSAntonio Huete Jimenez 572*de0e0e4dSAntonio Huete Jimenez if (bs->length < 0) 573*de0e0e4dSAntonio Huete Jimenez return 0; 574*de0e0e4dSAntonio Huete Jimenez switch (afi) { 575*de0e0e4dSAntonio Huete Jimenez case IANA_AFI_IPV4: 576*de0e0e4dSAntonio Huete Jimenez if (!addr_expand(addr, bs, 4, fill)) 577*de0e0e4dSAntonio Huete Jimenez return 0; 578*de0e0e4dSAntonio Huete Jimenez BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], 579*de0e0e4dSAntonio Huete Jimenez addr[3]); 580*de0e0e4dSAntonio Huete Jimenez break; 581*de0e0e4dSAntonio Huete Jimenez case IANA_AFI_IPV6: 582*de0e0e4dSAntonio Huete Jimenez if (!addr_expand(addr, bs, 16, fill)) 583*de0e0e4dSAntonio Huete Jimenez return 0; 584*de0e0e4dSAntonio Huete Jimenez for (n = 16; 585*de0e0e4dSAntonio Huete Jimenez n > 1 && addr[n - 1] == 0x00 && addr[n - 2] == 0x00; n -= 2) 586*de0e0e4dSAntonio Huete Jimenez continue; 587*de0e0e4dSAntonio Huete Jimenez for (i = 0; i < n; i += 2) 588*de0e0e4dSAntonio Huete Jimenez BIO_printf(out, "%x%s", (addr[i] << 8) | addr[i + 1], 589*de0e0e4dSAntonio Huete Jimenez (i < 14 ? ":" : "")); 590*de0e0e4dSAntonio Huete Jimenez if (i < 16) 591*de0e0e4dSAntonio Huete Jimenez BIO_puts(out, ":"); 592*de0e0e4dSAntonio Huete Jimenez if (i == 0) 593*de0e0e4dSAntonio Huete Jimenez BIO_puts(out, ":"); 594*de0e0e4dSAntonio Huete Jimenez break; 595*de0e0e4dSAntonio Huete Jimenez default: 596*de0e0e4dSAntonio Huete Jimenez for (i = 0; i < bs->length; i++) 597*de0e0e4dSAntonio Huete Jimenez BIO_printf(out, "%s%02x", (i > 0 ? ":" : ""), 598*de0e0e4dSAntonio Huete Jimenez bs->data[i]); 599*de0e0e4dSAntonio Huete Jimenez BIO_printf(out, "[%d]", (int)(bs->flags & 7)); 600*de0e0e4dSAntonio Huete Jimenez break; 601*de0e0e4dSAntonio Huete Jimenez } 602*de0e0e4dSAntonio Huete Jimenez return 1; 603*de0e0e4dSAntonio Huete Jimenez } 604*de0e0e4dSAntonio Huete Jimenez 605*de0e0e4dSAntonio Huete Jimenez /* 606*de0e0e4dSAntonio Huete Jimenez * i2r handler for a sequence of addresses and ranges. 607*de0e0e4dSAntonio Huete Jimenez */ 608*de0e0e4dSAntonio Huete Jimenez static int 609*de0e0e4dSAntonio Huete Jimenez i2r_IPAddressOrRanges(BIO *out, const int indent, 610*de0e0e4dSAntonio Huete Jimenez const IPAddressOrRanges *aors, const unsigned afi) 611*de0e0e4dSAntonio Huete Jimenez { 612*de0e0e4dSAntonio Huete Jimenez const IPAddressOrRange *aor; 613*de0e0e4dSAntonio Huete Jimenez const ASN1_BIT_STRING *prefix; 614*de0e0e4dSAntonio Huete Jimenez const IPAddressRange *range; 615*de0e0e4dSAntonio Huete Jimenez int i; 616*de0e0e4dSAntonio Huete Jimenez 617*de0e0e4dSAntonio Huete Jimenez for (i = 0; i < sk_IPAddressOrRange_num(aors); i++) { 618*de0e0e4dSAntonio Huete Jimenez aor = sk_IPAddressOrRange_value(aors, i); 619*de0e0e4dSAntonio Huete Jimenez 620*de0e0e4dSAntonio Huete Jimenez BIO_printf(out, "%*s", indent, ""); 621*de0e0e4dSAntonio Huete Jimenez 622*de0e0e4dSAntonio Huete Jimenez switch (aor->type) { 623*de0e0e4dSAntonio Huete Jimenez case IPAddressOrRange_addressPrefix: 624*de0e0e4dSAntonio Huete Jimenez prefix = aor->u.addressPrefix; 625*de0e0e4dSAntonio Huete Jimenez 626*de0e0e4dSAntonio Huete Jimenez if (!i2r_address(out, afi, 0x00, prefix)) 627*de0e0e4dSAntonio Huete Jimenez return 0; 628*de0e0e4dSAntonio Huete Jimenez BIO_printf(out, "/%d\n", addr_prefix_len(prefix)); 629*de0e0e4dSAntonio Huete Jimenez continue; 630*de0e0e4dSAntonio Huete Jimenez case IPAddressOrRange_addressRange: 631*de0e0e4dSAntonio Huete Jimenez range = aor->u.addressRange; 632*de0e0e4dSAntonio Huete Jimenez 633*de0e0e4dSAntonio Huete Jimenez if (!i2r_address(out, afi, 0x00, range->min)) 634*de0e0e4dSAntonio Huete Jimenez return 0; 635*de0e0e4dSAntonio Huete Jimenez BIO_puts(out, "-"); 636*de0e0e4dSAntonio Huete Jimenez if (!i2r_address(out, afi, 0xff, range->max)) 637*de0e0e4dSAntonio Huete Jimenez return 0; 638*de0e0e4dSAntonio Huete Jimenez BIO_puts(out, "\n"); 639*de0e0e4dSAntonio Huete Jimenez continue; 640*de0e0e4dSAntonio Huete Jimenez } 641*de0e0e4dSAntonio Huete Jimenez } 642*de0e0e4dSAntonio Huete Jimenez 643*de0e0e4dSAntonio Huete Jimenez return 1; 644*de0e0e4dSAntonio Huete Jimenez } 645*de0e0e4dSAntonio Huete Jimenez 646*de0e0e4dSAntonio Huete Jimenez /* 647*de0e0e4dSAntonio Huete Jimenez * i2r handler for an IPAddrBlocks extension. 648*de0e0e4dSAntonio Huete Jimenez */ 649*de0e0e4dSAntonio Huete Jimenez static int 650*de0e0e4dSAntonio Huete Jimenez i2r_IPAddrBlocks(const X509V3_EXT_METHOD *method, void *ext, BIO *out, 651*de0e0e4dSAntonio Huete Jimenez int indent) 652*de0e0e4dSAntonio Huete Jimenez { 653*de0e0e4dSAntonio Huete Jimenez const IPAddrBlocks *addr = ext; 654*de0e0e4dSAntonio Huete Jimenez IPAddressFamily *af; 655*de0e0e4dSAntonio Huete Jimenez uint16_t afi; 656*de0e0e4dSAntonio Huete Jimenez uint8_t safi; 657*de0e0e4dSAntonio Huete Jimenez int i, safi_is_set; 658*de0e0e4dSAntonio Huete Jimenez 659*de0e0e4dSAntonio Huete Jimenez for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { 660*de0e0e4dSAntonio Huete Jimenez af = sk_IPAddressFamily_value(addr, i); 661*de0e0e4dSAntonio Huete Jimenez 662*de0e0e4dSAntonio Huete Jimenez if (!IPAddressFamily_afi_safi(af, &afi, &safi, &safi_is_set)) 663*de0e0e4dSAntonio Huete Jimenez goto print_addresses; 664*de0e0e4dSAntonio Huete Jimenez 665*de0e0e4dSAntonio Huete Jimenez switch (afi) { 666*de0e0e4dSAntonio Huete Jimenez case IANA_AFI_IPV4: 667*de0e0e4dSAntonio Huete Jimenez BIO_printf(out, "%*sIPv4", indent, ""); 668*de0e0e4dSAntonio Huete Jimenez break; 669*de0e0e4dSAntonio Huete Jimenez case IANA_AFI_IPV6: 670*de0e0e4dSAntonio Huete Jimenez BIO_printf(out, "%*sIPv6", indent, ""); 671*de0e0e4dSAntonio Huete Jimenez break; 672*de0e0e4dSAntonio Huete Jimenez default: 673*de0e0e4dSAntonio Huete Jimenez BIO_printf(out, "%*sUnknown AFI %u", indent, "", afi); 674*de0e0e4dSAntonio Huete Jimenez break; 675*de0e0e4dSAntonio Huete Jimenez } 676*de0e0e4dSAntonio Huete Jimenez if (safi_is_set) { 677*de0e0e4dSAntonio Huete Jimenez switch (safi) { 678*de0e0e4dSAntonio Huete Jimenez case 1: 679*de0e0e4dSAntonio Huete Jimenez BIO_puts(out, " (Unicast)"); 680*de0e0e4dSAntonio Huete Jimenez break; 681*de0e0e4dSAntonio Huete Jimenez case 2: 682*de0e0e4dSAntonio Huete Jimenez BIO_puts(out, " (Multicast)"); 683*de0e0e4dSAntonio Huete Jimenez break; 684*de0e0e4dSAntonio Huete Jimenez case 3: 685*de0e0e4dSAntonio Huete Jimenez BIO_puts(out, " (Unicast/Multicast)"); 686*de0e0e4dSAntonio Huete Jimenez break; 687*de0e0e4dSAntonio Huete Jimenez case 4: 688*de0e0e4dSAntonio Huete Jimenez BIO_puts(out, " (MPLS)"); 689*de0e0e4dSAntonio Huete Jimenez break; 690*de0e0e4dSAntonio Huete Jimenez case 64: 691*de0e0e4dSAntonio Huete Jimenez BIO_puts(out, " (Tunnel)"); 692*de0e0e4dSAntonio Huete Jimenez break; 693*de0e0e4dSAntonio Huete Jimenez case 65: 694*de0e0e4dSAntonio Huete Jimenez BIO_puts(out, " (VPLS)"); 695*de0e0e4dSAntonio Huete Jimenez break; 696*de0e0e4dSAntonio Huete Jimenez case 66: 697*de0e0e4dSAntonio Huete Jimenez BIO_puts(out, " (BGP MDT)"); 698*de0e0e4dSAntonio Huete Jimenez break; 699*de0e0e4dSAntonio Huete Jimenez case 128: 700*de0e0e4dSAntonio Huete Jimenez BIO_puts(out, " (MPLS-labeled VPN)"); 701*de0e0e4dSAntonio Huete Jimenez break; 702*de0e0e4dSAntonio Huete Jimenez default: 703*de0e0e4dSAntonio Huete Jimenez BIO_printf(out, " (Unknown SAFI %u)", safi); 704*de0e0e4dSAntonio Huete Jimenez break; 705*de0e0e4dSAntonio Huete Jimenez } 706*de0e0e4dSAntonio Huete Jimenez } 707*de0e0e4dSAntonio Huete Jimenez 708*de0e0e4dSAntonio Huete Jimenez print_addresses: 709*de0e0e4dSAntonio Huete Jimenez switch (IPAddressFamily_type(af)) { 710*de0e0e4dSAntonio Huete Jimenez case IPAddressChoice_inherit: 711*de0e0e4dSAntonio Huete Jimenez BIO_puts(out, ": inherit\n"); 712*de0e0e4dSAntonio Huete Jimenez break; 713*de0e0e4dSAntonio Huete Jimenez case IPAddressChoice_addressesOrRanges: 714*de0e0e4dSAntonio Huete Jimenez BIO_puts(out, ":\n"); 715*de0e0e4dSAntonio Huete Jimenez if (!i2r_IPAddressOrRanges(out, indent + 2, 716*de0e0e4dSAntonio Huete Jimenez IPAddressFamily_addressesOrRanges(af), afi)) 717*de0e0e4dSAntonio Huete Jimenez return 0; 718*de0e0e4dSAntonio Huete Jimenez break; 719*de0e0e4dSAntonio Huete Jimenez /* XXX - how should we handle -1 here? */ 720*de0e0e4dSAntonio Huete Jimenez } 721*de0e0e4dSAntonio Huete Jimenez } 722*de0e0e4dSAntonio Huete Jimenez return 1; 723*de0e0e4dSAntonio Huete Jimenez } 724*de0e0e4dSAntonio Huete Jimenez 725*de0e0e4dSAntonio Huete Jimenez /* 726*de0e0e4dSAntonio Huete Jimenez * Sort comparison function for a sequence of IPAddressOrRange 727*de0e0e4dSAntonio Huete Jimenez * elements. 728*de0e0e4dSAntonio Huete Jimenez * 729*de0e0e4dSAntonio Huete Jimenez * There's no sane answer we can give if addr_expand() fails, and an 730*de0e0e4dSAntonio Huete Jimenez * assertion failure on externally supplied data is seriously uncool, 731*de0e0e4dSAntonio Huete Jimenez * so we just arbitrarily declare that if given invalid inputs this 732*de0e0e4dSAntonio Huete Jimenez * function returns -1. If this messes up your preferred sort order 733*de0e0e4dSAntonio Huete Jimenez * for garbage input, tough noogies. 734*de0e0e4dSAntonio Huete Jimenez */ 735*de0e0e4dSAntonio Huete Jimenez static int 736*de0e0e4dSAntonio Huete Jimenez IPAddressOrRange_cmp(const IPAddressOrRange *a, const IPAddressOrRange *b, 737*de0e0e4dSAntonio Huete Jimenez const int length) 738*de0e0e4dSAntonio Huete Jimenez { 739*de0e0e4dSAntonio Huete Jimenez unsigned char addr_a[ADDR_RAW_BUF_LEN], addr_b[ADDR_RAW_BUF_LEN]; 740*de0e0e4dSAntonio Huete Jimenez int prefix_len_a = 0, prefix_len_b = 0; 741*de0e0e4dSAntonio Huete Jimenez int r; 742*de0e0e4dSAntonio Huete Jimenez 743*de0e0e4dSAntonio Huete Jimenez switch (a->type) { 744*de0e0e4dSAntonio Huete Jimenez case IPAddressOrRange_addressPrefix: 745*de0e0e4dSAntonio Huete Jimenez if (!addr_expand(addr_a, a->u.addressPrefix, length, 0x00)) 746*de0e0e4dSAntonio Huete Jimenez return -1; 747*de0e0e4dSAntonio Huete Jimenez prefix_len_a = addr_prefix_len(a->u.addressPrefix); 748*de0e0e4dSAntonio Huete Jimenez break; 749*de0e0e4dSAntonio Huete Jimenez case IPAddressOrRange_addressRange: 750*de0e0e4dSAntonio Huete Jimenez if (!addr_expand(addr_a, a->u.addressRange->min, length, 0x00)) 751*de0e0e4dSAntonio Huete Jimenez return -1; 752*de0e0e4dSAntonio Huete Jimenez prefix_len_a = length * 8; 753*de0e0e4dSAntonio Huete Jimenez break; 754*de0e0e4dSAntonio Huete Jimenez } 755*de0e0e4dSAntonio Huete Jimenez 756*de0e0e4dSAntonio Huete Jimenez switch (b->type) { 757*de0e0e4dSAntonio Huete Jimenez case IPAddressOrRange_addressPrefix: 758*de0e0e4dSAntonio Huete Jimenez if (!addr_expand(addr_b, b->u.addressPrefix, length, 0x00)) 759*de0e0e4dSAntonio Huete Jimenez return -1; 760*de0e0e4dSAntonio Huete Jimenez prefix_len_b = addr_prefix_len(b->u.addressPrefix); 761*de0e0e4dSAntonio Huete Jimenez break; 762*de0e0e4dSAntonio Huete Jimenez case IPAddressOrRange_addressRange: 763*de0e0e4dSAntonio Huete Jimenez if (!addr_expand(addr_b, b->u.addressRange->min, length, 0x00)) 764*de0e0e4dSAntonio Huete Jimenez return -1; 765*de0e0e4dSAntonio Huete Jimenez prefix_len_b = length * 8; 766*de0e0e4dSAntonio Huete Jimenez break; 767*de0e0e4dSAntonio Huete Jimenez } 768*de0e0e4dSAntonio Huete Jimenez 769*de0e0e4dSAntonio Huete Jimenez if ((r = memcmp(addr_a, addr_b, length)) != 0) 770*de0e0e4dSAntonio Huete Jimenez return r; 771*de0e0e4dSAntonio Huete Jimenez else 772*de0e0e4dSAntonio Huete Jimenez return prefix_len_a - prefix_len_b; 773*de0e0e4dSAntonio Huete Jimenez } 774*de0e0e4dSAntonio Huete Jimenez 775*de0e0e4dSAntonio Huete Jimenez /* 776*de0e0e4dSAntonio Huete Jimenez * IPv4-specific closure over IPAddressOrRange_cmp, since sk_sort() 777*de0e0e4dSAntonio Huete Jimenez * comparison routines are only allowed two arguments. 778*de0e0e4dSAntonio Huete Jimenez */ 779*de0e0e4dSAntonio Huete Jimenez static int 780*de0e0e4dSAntonio Huete Jimenez v4IPAddressOrRange_cmp(const IPAddressOrRange *const *a, 781*de0e0e4dSAntonio Huete Jimenez const IPAddressOrRange *const *b) 782*de0e0e4dSAntonio Huete Jimenez { 783*de0e0e4dSAntonio Huete Jimenez return IPAddressOrRange_cmp(*a, *b, 4); 784*de0e0e4dSAntonio Huete Jimenez } 785*de0e0e4dSAntonio Huete Jimenez 786*de0e0e4dSAntonio Huete Jimenez /* 787*de0e0e4dSAntonio Huete Jimenez * IPv6-specific closure over IPAddressOrRange_cmp, since sk_sort() 788*de0e0e4dSAntonio Huete Jimenez * comparison routines are only allowed two arguments. 789*de0e0e4dSAntonio Huete Jimenez */ 790*de0e0e4dSAntonio Huete Jimenez static int 791*de0e0e4dSAntonio Huete Jimenez v6IPAddressOrRange_cmp(const IPAddressOrRange *const *a, 792*de0e0e4dSAntonio Huete Jimenez const IPAddressOrRange *const *b) 793*de0e0e4dSAntonio Huete Jimenez { 794*de0e0e4dSAntonio Huete Jimenez return IPAddressOrRange_cmp(*a, *b, 16); 795*de0e0e4dSAntonio Huete Jimenez } 796*de0e0e4dSAntonio Huete Jimenez 797*de0e0e4dSAntonio Huete Jimenez /* 798*de0e0e4dSAntonio Huete Jimenez * Calculate whether a range collapses to a prefix. 799*de0e0e4dSAntonio Huete Jimenez * See last paragraph of RFC 3779 2.2.3.7. 800*de0e0e4dSAntonio Huete Jimenez * 801*de0e0e4dSAntonio Huete Jimenez * It's the caller's responsibility to ensure that min <= max. 802*de0e0e4dSAntonio Huete Jimenez */ 803*de0e0e4dSAntonio Huete Jimenez static int 804*de0e0e4dSAntonio Huete Jimenez range_should_be_prefix(const unsigned char *min, const unsigned char *max, 805*de0e0e4dSAntonio Huete Jimenez const int length) 806*de0e0e4dSAntonio Huete Jimenez { 807*de0e0e4dSAntonio Huete Jimenez unsigned char mask; 808*de0e0e4dSAntonio Huete Jimenez int i, j; 809*de0e0e4dSAntonio Huete Jimenez 810*de0e0e4dSAntonio Huete Jimenez for (i = 0; i < length && min[i] == max[i]; i++) 811*de0e0e4dSAntonio Huete Jimenez continue; 812*de0e0e4dSAntonio Huete Jimenez for (j = length - 1; j >= 0 && min[j] == 0x00 && max[j] == 0xff; j--) 813*de0e0e4dSAntonio Huete Jimenez continue; 814*de0e0e4dSAntonio Huete Jimenez if (i < j) 815*de0e0e4dSAntonio Huete Jimenez return -1; 816*de0e0e4dSAntonio Huete Jimenez if (i > j) 817*de0e0e4dSAntonio Huete Jimenez return i * 8; 818*de0e0e4dSAntonio Huete Jimenez mask = min[i] ^ max[i]; 819*de0e0e4dSAntonio Huete Jimenez switch (mask) { 820*de0e0e4dSAntonio Huete Jimenez case 0x01: 821*de0e0e4dSAntonio Huete Jimenez j = 7; 822*de0e0e4dSAntonio Huete Jimenez break; 823*de0e0e4dSAntonio Huete Jimenez case 0x03: 824*de0e0e4dSAntonio Huete Jimenez j = 6; 825*de0e0e4dSAntonio Huete Jimenez break; 826*de0e0e4dSAntonio Huete Jimenez case 0x07: 827*de0e0e4dSAntonio Huete Jimenez j = 5; 828*de0e0e4dSAntonio Huete Jimenez break; 829*de0e0e4dSAntonio Huete Jimenez case 0x0f: 830*de0e0e4dSAntonio Huete Jimenez j = 4; 831*de0e0e4dSAntonio Huete Jimenez break; 832*de0e0e4dSAntonio Huete Jimenez case 0x1f: 833*de0e0e4dSAntonio Huete Jimenez j = 3; 834*de0e0e4dSAntonio Huete Jimenez break; 835*de0e0e4dSAntonio Huete Jimenez case 0x3f: 836*de0e0e4dSAntonio Huete Jimenez j = 2; 837*de0e0e4dSAntonio Huete Jimenez break; 838*de0e0e4dSAntonio Huete Jimenez case 0x7f: 839*de0e0e4dSAntonio Huete Jimenez j = 1; 840*de0e0e4dSAntonio Huete Jimenez break; 841*de0e0e4dSAntonio Huete Jimenez default: 842*de0e0e4dSAntonio Huete Jimenez return -1; 843*de0e0e4dSAntonio Huete Jimenez } 844*de0e0e4dSAntonio Huete Jimenez if ((min[i] & mask) != 0 || (max[i] & mask) != mask) 845*de0e0e4dSAntonio Huete Jimenez return -1; 846*de0e0e4dSAntonio Huete Jimenez else 847*de0e0e4dSAntonio Huete Jimenez return i * 8 + j; 848*de0e0e4dSAntonio Huete Jimenez } 849*de0e0e4dSAntonio Huete Jimenez 850*de0e0e4dSAntonio Huete Jimenez /* 851*de0e0e4dSAntonio Huete Jimenez * Fill IPAddressOrRange with bit string encoding of a prefix - RFC 3779, 2.1.1. 852*de0e0e4dSAntonio Huete Jimenez */ 853*de0e0e4dSAntonio Huete Jimenez static int 854*de0e0e4dSAntonio Huete Jimenez make_addressPrefix(IPAddressOrRange **out_aor, uint8_t *addr, uint32_t afi, 855*de0e0e4dSAntonio Huete Jimenez int prefix_len) 856*de0e0e4dSAntonio Huete Jimenez { 857*de0e0e4dSAntonio Huete Jimenez IPAddressOrRange *aor = NULL; 858*de0e0e4dSAntonio Huete Jimenez int afi_len, max_len, num_bits, num_octets; 859*de0e0e4dSAntonio Huete Jimenez uint8_t unused_bits; 860*de0e0e4dSAntonio Huete Jimenez 861*de0e0e4dSAntonio Huete Jimenez if (prefix_len < 0) 862*de0e0e4dSAntonio Huete Jimenez goto err; 863*de0e0e4dSAntonio Huete Jimenez 864*de0e0e4dSAntonio Huete Jimenez max_len = 16; 865*de0e0e4dSAntonio Huete Jimenez if ((afi_len = length_from_afi(afi)) > 0) 866*de0e0e4dSAntonio Huete Jimenez max_len = afi_len; 867*de0e0e4dSAntonio Huete Jimenez if (prefix_len > 8 * max_len) 868*de0e0e4dSAntonio Huete Jimenez goto err; 869*de0e0e4dSAntonio Huete Jimenez 870*de0e0e4dSAntonio Huete Jimenez num_octets = (prefix_len + 7) / 8; 871*de0e0e4dSAntonio Huete Jimenez num_bits = prefix_len % 8; 872*de0e0e4dSAntonio Huete Jimenez 873*de0e0e4dSAntonio Huete Jimenez unused_bits = 0; 874*de0e0e4dSAntonio Huete Jimenez if (num_bits > 0) 875*de0e0e4dSAntonio Huete Jimenez unused_bits = 8 - num_bits; 876*de0e0e4dSAntonio Huete Jimenez 877*de0e0e4dSAntonio Huete Jimenez if ((aor = IPAddressOrRange_new()) == NULL) 878*de0e0e4dSAntonio Huete Jimenez goto err; 879*de0e0e4dSAntonio Huete Jimenez 880*de0e0e4dSAntonio Huete Jimenez aor->type = IPAddressOrRange_addressPrefix; 881*de0e0e4dSAntonio Huete Jimenez 882*de0e0e4dSAntonio Huete Jimenez if ((aor->u.addressPrefix = ASN1_BIT_STRING_new()) == NULL) 883*de0e0e4dSAntonio Huete Jimenez goto err; 884*de0e0e4dSAntonio Huete Jimenez if (!ASN1_BIT_STRING_set(aor->u.addressPrefix, addr, num_octets)) 885*de0e0e4dSAntonio Huete Jimenez goto err; 886*de0e0e4dSAntonio Huete Jimenez if (!asn1_abs_set_unused_bits(aor->u.addressPrefix, unused_bits)) 887*de0e0e4dSAntonio Huete Jimenez goto err; 888*de0e0e4dSAntonio Huete Jimenez 889*de0e0e4dSAntonio Huete Jimenez *out_aor = aor; 890*de0e0e4dSAntonio Huete Jimenez return 1; 891*de0e0e4dSAntonio Huete Jimenez 892*de0e0e4dSAntonio Huete Jimenez err: 893*de0e0e4dSAntonio Huete Jimenez IPAddressOrRange_free(aor); 894*de0e0e4dSAntonio Huete Jimenez return 0; 895*de0e0e4dSAntonio Huete Jimenez } 896*de0e0e4dSAntonio Huete Jimenez 897*de0e0e4dSAntonio Huete Jimenez static uint8_t 898*de0e0e4dSAntonio Huete Jimenez count_trailing_zeroes(uint8_t octet) 899*de0e0e4dSAntonio Huete Jimenez { 900*de0e0e4dSAntonio Huete Jimenez uint8_t count = 0; 901*de0e0e4dSAntonio Huete Jimenez 902*de0e0e4dSAntonio Huete Jimenez if (octet == 0) 903*de0e0e4dSAntonio Huete Jimenez return 8; 904*de0e0e4dSAntonio Huete Jimenez 905*de0e0e4dSAntonio Huete Jimenez while ((octet & (1 << count)) == 0) 906*de0e0e4dSAntonio Huete Jimenez count++; 907*de0e0e4dSAntonio Huete Jimenez 908*de0e0e4dSAntonio Huete Jimenez return count; 909*de0e0e4dSAntonio Huete Jimenez } 910*de0e0e4dSAntonio Huete Jimenez 911*de0e0e4dSAntonio Huete Jimenez static int 912*de0e0e4dSAntonio Huete Jimenez trim_end_u8(CBS *cbs, uint8_t trim) 913*de0e0e4dSAntonio Huete Jimenez { 914*de0e0e4dSAntonio Huete Jimenez uint8_t octet; 915*de0e0e4dSAntonio Huete Jimenez 916*de0e0e4dSAntonio Huete Jimenez while (CBS_len(cbs) > 0) { 917*de0e0e4dSAntonio Huete Jimenez if (!CBS_peek_last_u8(cbs, &octet)) 918*de0e0e4dSAntonio Huete Jimenez return 0; 919*de0e0e4dSAntonio Huete Jimenez if (octet != trim) 920*de0e0e4dSAntonio Huete Jimenez return 1; 921*de0e0e4dSAntonio Huete Jimenez if (!CBS_get_last_u8(cbs, &octet)) 922*de0e0e4dSAntonio Huete Jimenez return 0; 923*de0e0e4dSAntonio Huete Jimenez } 924*de0e0e4dSAntonio Huete Jimenez 925*de0e0e4dSAntonio Huete Jimenez return 1; 926*de0e0e4dSAntonio Huete Jimenez } 927*de0e0e4dSAntonio Huete Jimenez 928*de0e0e4dSAntonio Huete Jimenez /* 929*de0e0e4dSAntonio Huete Jimenez * Populate IPAddressOrRange with bit string encoding of a range, see 930*de0e0e4dSAntonio Huete Jimenez * RFC 3779, 2.1.2. 931*de0e0e4dSAntonio Huete Jimenez */ 932*de0e0e4dSAntonio Huete Jimenez static int 933*de0e0e4dSAntonio Huete Jimenez make_addressRange(IPAddressOrRange **out_aor, uint8_t *min, uint8_t *max, 934*de0e0e4dSAntonio Huete Jimenez uint32_t afi, int length) 935*de0e0e4dSAntonio Huete Jimenez { 936*de0e0e4dSAntonio Huete Jimenez IPAddressOrRange *aor = NULL; 937*de0e0e4dSAntonio Huete Jimenez IPAddressRange *range; 938*de0e0e4dSAntonio Huete Jimenez int prefix_len; 939*de0e0e4dSAntonio Huete Jimenez CBS cbs; 940*de0e0e4dSAntonio Huete Jimenez size_t max_len, min_len; 941*de0e0e4dSAntonio Huete Jimenez uint8_t unused_bits_min, unused_bits_max; 942*de0e0e4dSAntonio Huete Jimenez uint8_t octet; 943*de0e0e4dSAntonio Huete Jimenez 944*de0e0e4dSAntonio Huete Jimenez if (memcmp(min, max, length) > 0) 945*de0e0e4dSAntonio Huete Jimenez goto err; 946*de0e0e4dSAntonio Huete Jimenez 947*de0e0e4dSAntonio Huete Jimenez /* 948*de0e0e4dSAntonio Huete Jimenez * RFC 3779, 2.2.3.6 - a range that can be expressed as a prefix 949*de0e0e4dSAntonio Huete Jimenez * must be encoded as a prefix. 950*de0e0e4dSAntonio Huete Jimenez */ 951*de0e0e4dSAntonio Huete Jimenez 952*de0e0e4dSAntonio Huete Jimenez if ((prefix_len = range_should_be_prefix(min, max, length)) >= 0) 953*de0e0e4dSAntonio Huete Jimenez return make_addressPrefix(out_aor, min, afi, prefix_len); 954*de0e0e4dSAntonio Huete Jimenez 955*de0e0e4dSAntonio Huete Jimenez /* 956*de0e0e4dSAntonio Huete Jimenez * The bit string representing min is formed by removing all its 957*de0e0e4dSAntonio Huete Jimenez * trailing zero bits, so remove all trailing zero octets and count 958*de0e0e4dSAntonio Huete Jimenez * the trailing zero bits of the last octet. 959*de0e0e4dSAntonio Huete Jimenez */ 960*de0e0e4dSAntonio Huete Jimenez 961*de0e0e4dSAntonio Huete Jimenez CBS_init(&cbs, min, length); 962*de0e0e4dSAntonio Huete Jimenez 963*de0e0e4dSAntonio Huete Jimenez if (!trim_end_u8(&cbs, 0x00)) 964*de0e0e4dSAntonio Huete Jimenez goto err; 965*de0e0e4dSAntonio Huete Jimenez 966*de0e0e4dSAntonio Huete Jimenez unused_bits_min = 0; 967*de0e0e4dSAntonio Huete Jimenez if ((min_len = CBS_len(&cbs)) > 0) { 968*de0e0e4dSAntonio Huete Jimenez if (!CBS_peek_last_u8(&cbs, &octet)) 969*de0e0e4dSAntonio Huete Jimenez goto err; 970*de0e0e4dSAntonio Huete Jimenez 971*de0e0e4dSAntonio Huete Jimenez unused_bits_min = count_trailing_zeroes(octet); 972*de0e0e4dSAntonio Huete Jimenez } 973*de0e0e4dSAntonio Huete Jimenez 974*de0e0e4dSAntonio Huete Jimenez /* 975*de0e0e4dSAntonio Huete Jimenez * The bit string representing max is formed by removing all its 976*de0e0e4dSAntonio Huete Jimenez * trailing one bits, so remove all trailing 0xff octets and count 977*de0e0e4dSAntonio Huete Jimenez * the trailing ones of the last octet. 978*de0e0e4dSAntonio Huete Jimenez */ 979*de0e0e4dSAntonio Huete Jimenez 980*de0e0e4dSAntonio Huete Jimenez CBS_init(&cbs, max, length); 981*de0e0e4dSAntonio Huete Jimenez 982*de0e0e4dSAntonio Huete Jimenez if (!trim_end_u8(&cbs, 0xff)) 983*de0e0e4dSAntonio Huete Jimenez goto err; 984*de0e0e4dSAntonio Huete Jimenez 985*de0e0e4dSAntonio Huete Jimenez unused_bits_max = 0; 986*de0e0e4dSAntonio Huete Jimenez if ((max_len = CBS_len(&cbs)) > 0) { 987*de0e0e4dSAntonio Huete Jimenez if (!CBS_peek_last_u8(&cbs, &octet)) 988*de0e0e4dSAntonio Huete Jimenez goto err; 989*de0e0e4dSAntonio Huete Jimenez 990*de0e0e4dSAntonio Huete Jimenez unused_bits_max = count_trailing_zeroes(octet + 1); 991*de0e0e4dSAntonio Huete Jimenez } 992*de0e0e4dSAntonio Huete Jimenez 993*de0e0e4dSAntonio Huete Jimenez /* 994*de0e0e4dSAntonio Huete Jimenez * Populate IPAddressOrRange. 995*de0e0e4dSAntonio Huete Jimenez */ 996*de0e0e4dSAntonio Huete Jimenez 997*de0e0e4dSAntonio Huete Jimenez if ((aor = IPAddressOrRange_new()) == NULL) 998*de0e0e4dSAntonio Huete Jimenez goto err; 999*de0e0e4dSAntonio Huete Jimenez 1000*de0e0e4dSAntonio Huete Jimenez aor->type = IPAddressOrRange_addressRange; 1001*de0e0e4dSAntonio Huete Jimenez 1002*de0e0e4dSAntonio Huete Jimenez if ((range = aor->u.addressRange = IPAddressRange_new()) == NULL) 1003*de0e0e4dSAntonio Huete Jimenez goto err; 1004*de0e0e4dSAntonio Huete Jimenez 1005*de0e0e4dSAntonio Huete Jimenez if (!ASN1_BIT_STRING_set(range->min, min, min_len)) 1006*de0e0e4dSAntonio Huete Jimenez goto err; 1007*de0e0e4dSAntonio Huete Jimenez if (!asn1_abs_set_unused_bits(range->min, unused_bits_min)) 1008*de0e0e4dSAntonio Huete Jimenez goto err; 1009*de0e0e4dSAntonio Huete Jimenez 1010*de0e0e4dSAntonio Huete Jimenez if (!ASN1_BIT_STRING_set(range->max, max, max_len)) 1011*de0e0e4dSAntonio Huete Jimenez goto err; 1012*de0e0e4dSAntonio Huete Jimenez if (!asn1_abs_set_unused_bits(range->max, unused_bits_max)) 1013*de0e0e4dSAntonio Huete Jimenez goto err; 1014*de0e0e4dSAntonio Huete Jimenez 1015*de0e0e4dSAntonio Huete Jimenez *out_aor = aor; 1016*de0e0e4dSAntonio Huete Jimenez 1017*de0e0e4dSAntonio Huete Jimenez return 1; 1018*de0e0e4dSAntonio Huete Jimenez 1019*de0e0e4dSAntonio Huete Jimenez err: 1020*de0e0e4dSAntonio Huete Jimenez IPAddressOrRange_free(aor); 1021*de0e0e4dSAntonio Huete Jimenez return 0; 1022*de0e0e4dSAntonio Huete Jimenez } 1023*de0e0e4dSAntonio Huete Jimenez 1024*de0e0e4dSAntonio Huete Jimenez /* 1025*de0e0e4dSAntonio Huete Jimenez * Construct a new address family or find an existing one. 1026*de0e0e4dSAntonio Huete Jimenez */ 1027*de0e0e4dSAntonio Huete Jimenez static IPAddressFamily * 1028*de0e0e4dSAntonio Huete Jimenez make_IPAddressFamily(IPAddrBlocks *addr, const unsigned afi, 1029*de0e0e4dSAntonio Huete Jimenez const unsigned *safi) 1030*de0e0e4dSAntonio Huete Jimenez { 1031*de0e0e4dSAntonio Huete Jimenez IPAddressFamily *af = NULL; 1032*de0e0e4dSAntonio Huete Jimenez CBB cbb; 1033*de0e0e4dSAntonio Huete Jimenez CBS cbs; 1034*de0e0e4dSAntonio Huete Jimenez uint8_t *key = NULL; 1035*de0e0e4dSAntonio Huete Jimenez size_t keylen; 1036*de0e0e4dSAntonio Huete Jimenez int i; 1037*de0e0e4dSAntonio Huete Jimenez 1038*de0e0e4dSAntonio Huete Jimenez if (!CBB_init(&cbb, 0)) 1039*de0e0e4dSAntonio Huete Jimenez goto err; 1040*de0e0e4dSAntonio Huete Jimenez 1041*de0e0e4dSAntonio Huete Jimenez /* XXX - should afi <= 65535 and *safi <= 255 be checked here? */ 1042*de0e0e4dSAntonio Huete Jimenez 1043*de0e0e4dSAntonio Huete Jimenez if (!CBB_add_u16(&cbb, afi)) 1044*de0e0e4dSAntonio Huete Jimenez goto err; 1045*de0e0e4dSAntonio Huete Jimenez if (safi != NULL) { 1046*de0e0e4dSAntonio Huete Jimenez if (!CBB_add_u8(&cbb, *safi)) 1047*de0e0e4dSAntonio Huete Jimenez goto err; 1048*de0e0e4dSAntonio Huete Jimenez } 1049*de0e0e4dSAntonio Huete Jimenez 1050*de0e0e4dSAntonio Huete Jimenez if (!CBB_finish(&cbb, &key, &keylen)) 1051*de0e0e4dSAntonio Huete Jimenez goto err; 1052*de0e0e4dSAntonio Huete Jimenez 1053*de0e0e4dSAntonio Huete Jimenez for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { 1054*de0e0e4dSAntonio Huete Jimenez af = sk_IPAddressFamily_value(addr, i); 1055*de0e0e4dSAntonio Huete Jimenez 1056*de0e0e4dSAntonio Huete Jimenez CBS_init(&cbs, af->addressFamily->data, 1057*de0e0e4dSAntonio Huete Jimenez af->addressFamily->length); 1058*de0e0e4dSAntonio Huete Jimenez if (CBS_mem_equal(&cbs, key, keylen)) 1059*de0e0e4dSAntonio Huete Jimenez goto done; 1060*de0e0e4dSAntonio Huete Jimenez } 1061*de0e0e4dSAntonio Huete Jimenez 1062*de0e0e4dSAntonio Huete Jimenez if ((af = IPAddressFamily_new()) == NULL) 1063*de0e0e4dSAntonio Huete Jimenez goto err; 1064*de0e0e4dSAntonio Huete Jimenez if (!ASN1_OCTET_STRING_set(af->addressFamily, key, keylen)) 1065*de0e0e4dSAntonio Huete Jimenez goto err; 1066*de0e0e4dSAntonio Huete Jimenez if (!sk_IPAddressFamily_push(addr, af)) 1067*de0e0e4dSAntonio Huete Jimenez goto err; 1068*de0e0e4dSAntonio Huete Jimenez 1069*de0e0e4dSAntonio Huete Jimenez done: 1070*de0e0e4dSAntonio Huete Jimenez free(key); 1071*de0e0e4dSAntonio Huete Jimenez 1072*de0e0e4dSAntonio Huete Jimenez return af; 1073*de0e0e4dSAntonio Huete Jimenez 1074*de0e0e4dSAntonio Huete Jimenez err: 1075*de0e0e4dSAntonio Huete Jimenez CBB_cleanup(&cbb); 1076*de0e0e4dSAntonio Huete Jimenez free(key); 1077*de0e0e4dSAntonio Huete Jimenez IPAddressFamily_free(af); 1078*de0e0e4dSAntonio Huete Jimenez 1079*de0e0e4dSAntonio Huete Jimenez return NULL; 1080*de0e0e4dSAntonio Huete Jimenez } 1081*de0e0e4dSAntonio Huete Jimenez 1082*de0e0e4dSAntonio Huete Jimenez /* 1083*de0e0e4dSAntonio Huete Jimenez * Add an inheritance element. 1084*de0e0e4dSAntonio Huete Jimenez */ 1085*de0e0e4dSAntonio Huete Jimenez int 1086*de0e0e4dSAntonio Huete Jimenez X509v3_addr_add_inherit(IPAddrBlocks *addr, const unsigned afi, 1087*de0e0e4dSAntonio Huete Jimenez const unsigned *safi) 1088*de0e0e4dSAntonio Huete Jimenez { 1089*de0e0e4dSAntonio Huete Jimenez IPAddressFamily *af; 1090*de0e0e4dSAntonio Huete Jimenez 1091*de0e0e4dSAntonio Huete Jimenez if ((af = make_IPAddressFamily(addr, afi, safi)) == NULL) 1092*de0e0e4dSAntonio Huete Jimenez return 0; 1093*de0e0e4dSAntonio Huete Jimenez 1094*de0e0e4dSAntonio Huete Jimenez return IPAddressFamily_set_inheritance(af); 1095*de0e0e4dSAntonio Huete Jimenez } 1096*de0e0e4dSAntonio Huete Jimenez 1097*de0e0e4dSAntonio Huete Jimenez /* 1098*de0e0e4dSAntonio Huete Jimenez * Construct an IPAddressOrRange sequence, or return an existing one. 1099*de0e0e4dSAntonio Huete Jimenez */ 1100*de0e0e4dSAntonio Huete Jimenez static IPAddressOrRanges * 1101*de0e0e4dSAntonio Huete Jimenez make_prefix_or_range(IPAddrBlocks *addr, const unsigned afi, 1102*de0e0e4dSAntonio Huete Jimenez const unsigned *safi) 1103*de0e0e4dSAntonio Huete Jimenez { 1104*de0e0e4dSAntonio Huete Jimenez IPAddressFamily *af; 1105*de0e0e4dSAntonio Huete Jimenez IPAddressOrRanges *aors = NULL; 1106*de0e0e4dSAntonio Huete Jimenez 1107*de0e0e4dSAntonio Huete Jimenez if ((af = make_IPAddressFamily(addr, afi, safi)) == NULL) 1108*de0e0e4dSAntonio Huete Jimenez return NULL; 1109*de0e0e4dSAntonio Huete Jimenez 1110*de0e0e4dSAntonio Huete Jimenez if (IPAddressFamily_inheritance(af) != NULL) 1111*de0e0e4dSAntonio Huete Jimenez return NULL; 1112*de0e0e4dSAntonio Huete Jimenez 1113*de0e0e4dSAntonio Huete Jimenez if ((aors = IPAddressFamily_addressesOrRanges(af)) != NULL) 1114*de0e0e4dSAntonio Huete Jimenez return aors; 1115*de0e0e4dSAntonio Huete Jimenez 1116*de0e0e4dSAntonio Huete Jimenez if ((aors = sk_IPAddressOrRange_new_null()) == NULL) 1117*de0e0e4dSAntonio Huete Jimenez return NULL; 1118*de0e0e4dSAntonio Huete Jimenez 1119*de0e0e4dSAntonio Huete Jimenez switch (afi) { 1120*de0e0e4dSAntonio Huete Jimenez case IANA_AFI_IPV4: 1121*de0e0e4dSAntonio Huete Jimenez (void)sk_IPAddressOrRange_set_cmp_func(aors, 1122*de0e0e4dSAntonio Huete Jimenez v4IPAddressOrRange_cmp); 1123*de0e0e4dSAntonio Huete Jimenez break; 1124*de0e0e4dSAntonio Huete Jimenez case IANA_AFI_IPV6: 1125*de0e0e4dSAntonio Huete Jimenez (void)sk_IPAddressOrRange_set_cmp_func(aors, 1126*de0e0e4dSAntonio Huete Jimenez v6IPAddressOrRange_cmp); 1127*de0e0e4dSAntonio Huete Jimenez break; 1128*de0e0e4dSAntonio Huete Jimenez } 1129*de0e0e4dSAntonio Huete Jimenez 1130*de0e0e4dSAntonio Huete Jimenez af->ipAddressChoice->type = IPAddressChoice_addressesOrRanges; 1131*de0e0e4dSAntonio Huete Jimenez af->ipAddressChoice->u.addressesOrRanges = aors; 1132*de0e0e4dSAntonio Huete Jimenez 1133*de0e0e4dSAntonio Huete Jimenez return aors; 1134*de0e0e4dSAntonio Huete Jimenez } 1135*de0e0e4dSAntonio Huete Jimenez 1136*de0e0e4dSAntonio Huete Jimenez /* 1137*de0e0e4dSAntonio Huete Jimenez * Add a prefix. 1138*de0e0e4dSAntonio Huete Jimenez */ 1139*de0e0e4dSAntonio Huete Jimenez int 1140*de0e0e4dSAntonio Huete Jimenez X509v3_addr_add_prefix(IPAddrBlocks *addr, const unsigned afi, 1141*de0e0e4dSAntonio Huete Jimenez const unsigned *safi, unsigned char *a, const int prefix_len) 1142*de0e0e4dSAntonio Huete Jimenez { 1143*de0e0e4dSAntonio Huete Jimenez IPAddressOrRanges *aors; 1144*de0e0e4dSAntonio Huete Jimenez IPAddressOrRange *aor; 1145*de0e0e4dSAntonio Huete Jimenez 1146*de0e0e4dSAntonio Huete Jimenez if ((aors = make_prefix_or_range(addr, afi, safi)) == NULL) 1147*de0e0e4dSAntonio Huete Jimenez return 0; 1148*de0e0e4dSAntonio Huete Jimenez 1149*de0e0e4dSAntonio Huete Jimenez if (!make_addressPrefix(&aor, a, afi, prefix_len)) 1150*de0e0e4dSAntonio Huete Jimenez return 0; 1151*de0e0e4dSAntonio Huete Jimenez 1152*de0e0e4dSAntonio Huete Jimenez if (sk_IPAddressOrRange_push(aors, aor) <= 0) { 1153*de0e0e4dSAntonio Huete Jimenez IPAddressOrRange_free(aor); 1154*de0e0e4dSAntonio Huete Jimenez return 0; 1155*de0e0e4dSAntonio Huete Jimenez } 1156*de0e0e4dSAntonio Huete Jimenez 1157*de0e0e4dSAntonio Huete Jimenez return 1; 1158*de0e0e4dSAntonio Huete Jimenez } 1159*de0e0e4dSAntonio Huete Jimenez 1160*de0e0e4dSAntonio Huete Jimenez /* 1161*de0e0e4dSAntonio Huete Jimenez * Add a range. 1162*de0e0e4dSAntonio Huete Jimenez */ 1163*de0e0e4dSAntonio Huete Jimenez int 1164*de0e0e4dSAntonio Huete Jimenez X509v3_addr_add_range(IPAddrBlocks *addr, const unsigned afi, 1165*de0e0e4dSAntonio Huete Jimenez const unsigned *safi, unsigned char *min, unsigned char *max) 1166*de0e0e4dSAntonio Huete Jimenez { 1167*de0e0e4dSAntonio Huete Jimenez IPAddressOrRanges *aors; 1168*de0e0e4dSAntonio Huete Jimenez IPAddressOrRange *aor; 1169*de0e0e4dSAntonio Huete Jimenez int length; 1170*de0e0e4dSAntonio Huete Jimenez 1171*de0e0e4dSAntonio Huete Jimenez if ((aors = make_prefix_or_range(addr, afi, safi)) == NULL) 1172*de0e0e4dSAntonio Huete Jimenez return 0; 1173*de0e0e4dSAntonio Huete Jimenez 1174*de0e0e4dSAntonio Huete Jimenez length = length_from_afi(afi); 1175*de0e0e4dSAntonio Huete Jimenez 1176*de0e0e4dSAntonio Huete Jimenez if (!make_addressRange(&aor, min, max, afi, length)) 1177*de0e0e4dSAntonio Huete Jimenez return 0; 1178*de0e0e4dSAntonio Huete Jimenez 1179*de0e0e4dSAntonio Huete Jimenez if (sk_IPAddressOrRange_push(aors, aor) <= 0) { 1180*de0e0e4dSAntonio Huete Jimenez IPAddressOrRange_free(aor); 1181*de0e0e4dSAntonio Huete Jimenez return 0; 1182*de0e0e4dSAntonio Huete Jimenez } 1183*de0e0e4dSAntonio Huete Jimenez 1184*de0e0e4dSAntonio Huete Jimenez return 1; 1185*de0e0e4dSAntonio Huete Jimenez } 1186*de0e0e4dSAntonio Huete Jimenez 1187*de0e0e4dSAntonio Huete Jimenez static int 1188*de0e0e4dSAntonio Huete Jimenez extract_min_max_bitstr(IPAddressOrRange *aor, ASN1_BIT_STRING **out_min, 1189*de0e0e4dSAntonio Huete Jimenez ASN1_BIT_STRING **out_max) 1190*de0e0e4dSAntonio Huete Jimenez { 1191*de0e0e4dSAntonio Huete Jimenez switch (aor->type) { 1192*de0e0e4dSAntonio Huete Jimenez case IPAddressOrRange_addressPrefix: 1193*de0e0e4dSAntonio Huete Jimenez *out_min = *out_max = aor->u.addressPrefix; 1194*de0e0e4dSAntonio Huete Jimenez return 1; 1195*de0e0e4dSAntonio Huete Jimenez case IPAddressOrRange_addressRange: 1196*de0e0e4dSAntonio Huete Jimenez *out_min = aor->u.addressRange->min; 1197*de0e0e4dSAntonio Huete Jimenez *out_max = aor->u.addressRange->max; 1198*de0e0e4dSAntonio Huete Jimenez return 1; 1199*de0e0e4dSAntonio Huete Jimenez default: 1200*de0e0e4dSAntonio Huete Jimenez return 0; 1201*de0e0e4dSAntonio Huete Jimenez } 1202*de0e0e4dSAntonio Huete Jimenez } 1203*de0e0e4dSAntonio Huete Jimenez 1204*de0e0e4dSAntonio Huete Jimenez /* 1205*de0e0e4dSAntonio Huete Jimenez * Extract min and max values from an IPAddressOrRange. 1206*de0e0e4dSAntonio Huete Jimenez */ 1207*de0e0e4dSAntonio Huete Jimenez static int 1208*de0e0e4dSAntonio Huete Jimenez extract_min_max(IPAddressOrRange *aor, unsigned char *min, unsigned char *max, 1209*de0e0e4dSAntonio Huete Jimenez int length) 1210*de0e0e4dSAntonio Huete Jimenez { 1211*de0e0e4dSAntonio Huete Jimenez ASN1_BIT_STRING *min_bitstr, *max_bitstr; 1212*de0e0e4dSAntonio Huete Jimenez 1213*de0e0e4dSAntonio Huete Jimenez if (aor == NULL || min == NULL || max == NULL) 1214*de0e0e4dSAntonio Huete Jimenez return 0; 1215*de0e0e4dSAntonio Huete Jimenez 1216*de0e0e4dSAntonio Huete Jimenez if (!extract_min_max_bitstr(aor, &min_bitstr, &max_bitstr)) 1217*de0e0e4dSAntonio Huete Jimenez return 0; 1218*de0e0e4dSAntonio Huete Jimenez 1219*de0e0e4dSAntonio Huete Jimenez if (!addr_expand(min, min_bitstr, length, 0)) 1220*de0e0e4dSAntonio Huete Jimenez return 0; 1221*de0e0e4dSAntonio Huete Jimenez 1222*de0e0e4dSAntonio Huete Jimenez return addr_expand(max, max_bitstr, length, 1); 1223*de0e0e4dSAntonio Huete Jimenez } 1224*de0e0e4dSAntonio Huete Jimenez 1225*de0e0e4dSAntonio Huete Jimenez /* 1226*de0e0e4dSAntonio Huete Jimenez * Public wrapper for extract_min_max(). 1227*de0e0e4dSAntonio Huete Jimenez */ 1228*de0e0e4dSAntonio Huete Jimenez int 1229*de0e0e4dSAntonio Huete Jimenez X509v3_addr_get_range(IPAddressOrRange *aor, const unsigned afi, 1230*de0e0e4dSAntonio Huete Jimenez unsigned char *min, unsigned char *max, const int length) 1231*de0e0e4dSAntonio Huete Jimenez { 1232*de0e0e4dSAntonio Huete Jimenez int afi_len; 1233*de0e0e4dSAntonio Huete Jimenez 1234*de0e0e4dSAntonio Huete Jimenez if ((afi_len = length_from_afi(afi)) == 0) 1235*de0e0e4dSAntonio Huete Jimenez return 0; 1236*de0e0e4dSAntonio Huete Jimenez 1237*de0e0e4dSAntonio Huete Jimenez if (length < afi_len) 1238*de0e0e4dSAntonio Huete Jimenez return 0; 1239*de0e0e4dSAntonio Huete Jimenez 1240*de0e0e4dSAntonio Huete Jimenez if (!extract_min_max(aor, min, max, afi_len)) 1241*de0e0e4dSAntonio Huete Jimenez return 0; 1242*de0e0e4dSAntonio Huete Jimenez 1243*de0e0e4dSAntonio Huete Jimenez return afi_len; 1244*de0e0e4dSAntonio Huete Jimenez } 1245*de0e0e4dSAntonio Huete Jimenez 1246*de0e0e4dSAntonio Huete Jimenez /* 1247*de0e0e4dSAntonio Huete Jimenez * Check whether an IPAddrBLocks is in canonical form. 1248*de0e0e4dSAntonio Huete Jimenez */ 1249*de0e0e4dSAntonio Huete Jimenez int 1250*de0e0e4dSAntonio Huete Jimenez X509v3_addr_is_canonical(IPAddrBlocks *addr) 1251*de0e0e4dSAntonio Huete Jimenez { 1252*de0e0e4dSAntonio Huete Jimenez unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; 1253*de0e0e4dSAntonio Huete Jimenez unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN]; 1254*de0e0e4dSAntonio Huete Jimenez IPAddressFamily *af; 1255*de0e0e4dSAntonio Huete Jimenez IPAddressOrRanges *aors; 1256*de0e0e4dSAntonio Huete Jimenez IPAddressOrRange *aor, *aor_a, *aor_b; 1257*de0e0e4dSAntonio Huete Jimenez int i, j, k, length; 1258*de0e0e4dSAntonio Huete Jimenez 1259*de0e0e4dSAntonio Huete Jimenez /* 1260*de0e0e4dSAntonio Huete Jimenez * Empty extension is canonical. 1261*de0e0e4dSAntonio Huete Jimenez */ 1262*de0e0e4dSAntonio Huete Jimenez if (addr == NULL) 1263*de0e0e4dSAntonio Huete Jimenez return 1; 1264*de0e0e4dSAntonio Huete Jimenez 1265*de0e0e4dSAntonio Huete Jimenez /* 1266*de0e0e4dSAntonio Huete Jimenez * Check whether the top-level list is in order. 1267*de0e0e4dSAntonio Huete Jimenez */ 1268*de0e0e4dSAntonio Huete Jimenez for (i = 0; i < sk_IPAddressFamily_num(addr) - 1; i++) { 1269*de0e0e4dSAntonio Huete Jimenez const IPAddressFamily *a = sk_IPAddressFamily_value(addr, i); 1270*de0e0e4dSAntonio Huete Jimenez const IPAddressFamily *b = sk_IPAddressFamily_value(addr, i + 1); 1271*de0e0e4dSAntonio Huete Jimenez 1272*de0e0e4dSAntonio Huete Jimenez /* Check that both have valid AFIs before comparing them. */ 1273*de0e0e4dSAntonio Huete Jimenez if (!IPAddressFamily_afi_is_valid(a)) 1274*de0e0e4dSAntonio Huete Jimenez return 0; 1275*de0e0e4dSAntonio Huete Jimenez if (!IPAddressFamily_afi_is_valid(b)) 1276*de0e0e4dSAntonio Huete Jimenez return 0; 1277*de0e0e4dSAntonio Huete Jimenez 1278*de0e0e4dSAntonio Huete Jimenez if (IPAddressFamily_cmp(&a, &b) >= 0) 1279*de0e0e4dSAntonio Huete Jimenez return 0; 1280*de0e0e4dSAntonio Huete Jimenez } 1281*de0e0e4dSAntonio Huete Jimenez 1282*de0e0e4dSAntonio Huete Jimenez /* 1283*de0e0e4dSAntonio Huete Jimenez * Top level's ok, now check each address family. 1284*de0e0e4dSAntonio Huete Jimenez */ 1285*de0e0e4dSAntonio Huete Jimenez for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { 1286*de0e0e4dSAntonio Huete Jimenez af = sk_IPAddressFamily_value(addr, i); 1287*de0e0e4dSAntonio Huete Jimenez 1288*de0e0e4dSAntonio Huete Jimenez if (!IPAddressFamily_afi_length(af, &length)) 1289*de0e0e4dSAntonio Huete Jimenez return 0; 1290*de0e0e4dSAntonio Huete Jimenez 1291*de0e0e4dSAntonio Huete Jimenez /* 1292*de0e0e4dSAntonio Huete Jimenez * If this family has an inheritance element, it is canonical. 1293*de0e0e4dSAntonio Huete Jimenez */ 1294*de0e0e4dSAntonio Huete Jimenez if (IPAddressFamily_inheritance(af) != NULL) 1295*de0e0e4dSAntonio Huete Jimenez continue; 1296*de0e0e4dSAntonio Huete Jimenez 1297*de0e0e4dSAntonio Huete Jimenez /* 1298*de0e0e4dSAntonio Huete Jimenez * If this family has neither an inheritance element nor an 1299*de0e0e4dSAntonio Huete Jimenez * addressesOrRanges, we don't know what this is. 1300*de0e0e4dSAntonio Huete Jimenez */ 1301*de0e0e4dSAntonio Huete Jimenez if ((aors = IPAddressFamily_addressesOrRanges(af)) == NULL) 1302*de0e0e4dSAntonio Huete Jimenez return 0; 1303*de0e0e4dSAntonio Huete Jimenez 1304*de0e0e4dSAntonio Huete Jimenez if (sk_IPAddressOrRange_num(aors) == 0) 1305*de0e0e4dSAntonio Huete Jimenez return 0; 1306*de0e0e4dSAntonio Huete Jimenez 1307*de0e0e4dSAntonio Huete Jimenez for (j = 0; j < sk_IPAddressOrRange_num(aors) - 1; j++) { 1308*de0e0e4dSAntonio Huete Jimenez aor_a = sk_IPAddressOrRange_value(aors, j); 1309*de0e0e4dSAntonio Huete Jimenez aor_b = sk_IPAddressOrRange_value(aors, j + 1); 1310*de0e0e4dSAntonio Huete Jimenez 1311*de0e0e4dSAntonio Huete Jimenez if (!extract_min_max(aor_a, a_min, a_max, length) || 1312*de0e0e4dSAntonio Huete Jimenez !extract_min_max(aor_b, b_min, b_max, length)) 1313*de0e0e4dSAntonio Huete Jimenez return 0; 1314*de0e0e4dSAntonio Huete Jimenez 1315*de0e0e4dSAntonio Huete Jimenez /* 1316*de0e0e4dSAntonio Huete Jimenez * Punt misordered list, overlapping start, or inverted 1317*de0e0e4dSAntonio Huete Jimenez * range. 1318*de0e0e4dSAntonio Huete Jimenez */ 1319*de0e0e4dSAntonio Huete Jimenez if (memcmp(a_min, b_min, length) >= 0 || 1320*de0e0e4dSAntonio Huete Jimenez memcmp(a_min, a_max, length) > 0 || 1321*de0e0e4dSAntonio Huete Jimenez memcmp(b_min, b_max, length) > 0) 1322*de0e0e4dSAntonio Huete Jimenez return 0; 1323*de0e0e4dSAntonio Huete Jimenez 1324*de0e0e4dSAntonio Huete Jimenez /* 1325*de0e0e4dSAntonio Huete Jimenez * Punt if adjacent or overlapping. Check for adjacency 1326*de0e0e4dSAntonio Huete Jimenez * by subtracting one from b_min first. 1327*de0e0e4dSAntonio Huete Jimenez */ 1328*de0e0e4dSAntonio Huete Jimenez for (k = length - 1; k >= 0 && b_min[k]-- == 0x00; k--) 1329*de0e0e4dSAntonio Huete Jimenez continue; 1330*de0e0e4dSAntonio Huete Jimenez if (memcmp(a_max, b_min, length) >= 0) 1331*de0e0e4dSAntonio Huete Jimenez return 0; 1332*de0e0e4dSAntonio Huete Jimenez 1333*de0e0e4dSAntonio Huete Jimenez /* 1334*de0e0e4dSAntonio Huete Jimenez * Check for range that should be expressed as a prefix. 1335*de0e0e4dSAntonio Huete Jimenez */ 1336*de0e0e4dSAntonio Huete Jimenez if (aor_a->type == IPAddressOrRange_addressPrefix) 1337*de0e0e4dSAntonio Huete Jimenez continue; 1338*de0e0e4dSAntonio Huete Jimenez 1339*de0e0e4dSAntonio Huete Jimenez if (range_should_be_prefix(a_min, a_max, length) >= 0) 1340*de0e0e4dSAntonio Huete Jimenez return 0; 1341*de0e0e4dSAntonio Huete Jimenez } 1342*de0e0e4dSAntonio Huete Jimenez 1343*de0e0e4dSAntonio Huete Jimenez /* 1344*de0e0e4dSAntonio Huete Jimenez * Check final range to see if it's inverted or should be a 1345*de0e0e4dSAntonio Huete Jimenez * prefix. 1346*de0e0e4dSAntonio Huete Jimenez */ 1347*de0e0e4dSAntonio Huete Jimenez aor = sk_IPAddressOrRange_value(aors, j); 1348*de0e0e4dSAntonio Huete Jimenez if (aor->type == IPAddressOrRange_addressRange) { 1349*de0e0e4dSAntonio Huete Jimenez if (!extract_min_max(aor, a_min, a_max, length)) 1350*de0e0e4dSAntonio Huete Jimenez return 0; 1351*de0e0e4dSAntonio Huete Jimenez if (memcmp(a_min, a_max, length) > 0) 1352*de0e0e4dSAntonio Huete Jimenez return 0; 1353*de0e0e4dSAntonio Huete Jimenez if (range_should_be_prefix(a_min, a_max, length) >= 0) 1354*de0e0e4dSAntonio Huete Jimenez return 0; 1355*de0e0e4dSAntonio Huete Jimenez } 1356*de0e0e4dSAntonio Huete Jimenez } 1357*de0e0e4dSAntonio Huete Jimenez 1358*de0e0e4dSAntonio Huete Jimenez /* 1359*de0e0e4dSAntonio Huete Jimenez * If we made it through all that, we're happy. 1360*de0e0e4dSAntonio Huete Jimenez */ 1361*de0e0e4dSAntonio Huete Jimenez return 1; 1362*de0e0e4dSAntonio Huete Jimenez } 1363*de0e0e4dSAntonio Huete Jimenez 1364*de0e0e4dSAntonio Huete Jimenez /* 1365*de0e0e4dSAntonio Huete Jimenez * Whack an IPAddressOrRanges into canonical form. 1366*de0e0e4dSAntonio Huete Jimenez */ 1367*de0e0e4dSAntonio Huete Jimenez static int 1368*de0e0e4dSAntonio Huete Jimenez IPAddressOrRanges_canonize(IPAddressOrRanges *aors, const unsigned afi) 1369*de0e0e4dSAntonio Huete Jimenez { 1370*de0e0e4dSAntonio Huete Jimenez IPAddressOrRange *a, *b, *merged; 1371*de0e0e4dSAntonio Huete Jimenez unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; 1372*de0e0e4dSAntonio Huete Jimenez unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN]; 1373*de0e0e4dSAntonio Huete Jimenez int i, j, length; 1374*de0e0e4dSAntonio Huete Jimenez 1375*de0e0e4dSAntonio Huete Jimenez length = length_from_afi(afi); 1376*de0e0e4dSAntonio Huete Jimenez 1377*de0e0e4dSAntonio Huete Jimenez /* 1378*de0e0e4dSAntonio Huete Jimenez * Sort the IPAddressOrRanges sequence. 1379*de0e0e4dSAntonio Huete Jimenez */ 1380*de0e0e4dSAntonio Huete Jimenez sk_IPAddressOrRange_sort(aors); 1381*de0e0e4dSAntonio Huete Jimenez 1382*de0e0e4dSAntonio Huete Jimenez /* 1383*de0e0e4dSAntonio Huete Jimenez * Clean up representation issues, punt on duplicates or overlaps. 1384*de0e0e4dSAntonio Huete Jimenez */ 1385*de0e0e4dSAntonio Huete Jimenez for (i = 0; i < sk_IPAddressOrRange_num(aors) - 1; i++) { 1386*de0e0e4dSAntonio Huete Jimenez a = sk_IPAddressOrRange_value(aors, i); 1387*de0e0e4dSAntonio Huete Jimenez b = sk_IPAddressOrRange_value(aors, i + 1); 1388*de0e0e4dSAntonio Huete Jimenez 1389*de0e0e4dSAntonio Huete Jimenez if (!extract_min_max(a, a_min, a_max, length) || 1390*de0e0e4dSAntonio Huete Jimenez !extract_min_max(b, b_min, b_max, length)) 1391*de0e0e4dSAntonio Huete Jimenez return 0; 1392*de0e0e4dSAntonio Huete Jimenez 1393*de0e0e4dSAntonio Huete Jimenez /* 1394*de0e0e4dSAntonio Huete Jimenez * Punt inverted ranges. 1395*de0e0e4dSAntonio Huete Jimenez */ 1396*de0e0e4dSAntonio Huete Jimenez if (memcmp(a_min, a_max, length) > 0 || 1397*de0e0e4dSAntonio Huete Jimenez memcmp(b_min, b_max, length) > 0) 1398*de0e0e4dSAntonio Huete Jimenez return 0; 1399*de0e0e4dSAntonio Huete Jimenez 1400*de0e0e4dSAntonio Huete Jimenez /* 1401*de0e0e4dSAntonio Huete Jimenez * Punt overlaps. 1402*de0e0e4dSAntonio Huete Jimenez */ 1403*de0e0e4dSAntonio Huete Jimenez if (memcmp(a_max, b_min, length) >= 0) 1404*de0e0e4dSAntonio Huete Jimenez return 0; 1405*de0e0e4dSAntonio Huete Jimenez 1406*de0e0e4dSAntonio Huete Jimenez /* 1407*de0e0e4dSAntonio Huete Jimenez * Merge if a and b are adjacent. We check for 1408*de0e0e4dSAntonio Huete Jimenez * adjacency by subtracting one from b_min first. 1409*de0e0e4dSAntonio Huete Jimenez */ 1410*de0e0e4dSAntonio Huete Jimenez for (j = length - 1; j >= 0 && b_min[j]-- == 0x00; j--) 1411*de0e0e4dSAntonio Huete Jimenez continue; 1412*de0e0e4dSAntonio Huete Jimenez 1413*de0e0e4dSAntonio Huete Jimenez if (memcmp(a_max, b_min, length) != 0) 1414*de0e0e4dSAntonio Huete Jimenez continue; 1415*de0e0e4dSAntonio Huete Jimenez 1416*de0e0e4dSAntonio Huete Jimenez if (!make_addressRange(&merged, a_min, b_max, afi, length)) 1417*de0e0e4dSAntonio Huete Jimenez return 0; 1418*de0e0e4dSAntonio Huete Jimenez sk_IPAddressOrRange_set(aors, i, merged); 1419*de0e0e4dSAntonio Huete Jimenez (void)sk_IPAddressOrRange_delete(aors, i + 1); 1420*de0e0e4dSAntonio Huete Jimenez IPAddressOrRange_free(a); 1421*de0e0e4dSAntonio Huete Jimenez IPAddressOrRange_free(b); 1422*de0e0e4dSAntonio Huete Jimenez i--; 1423*de0e0e4dSAntonio Huete Jimenez } 1424*de0e0e4dSAntonio Huete Jimenez 1425*de0e0e4dSAntonio Huete Jimenez /* 1426*de0e0e4dSAntonio Huete Jimenez * Check for inverted final range. 1427*de0e0e4dSAntonio Huete Jimenez */ 1428*de0e0e4dSAntonio Huete Jimenez a = sk_IPAddressOrRange_value(aors, i); 1429*de0e0e4dSAntonio Huete Jimenez if (a != NULL && a->type == IPAddressOrRange_addressRange) { 1430*de0e0e4dSAntonio Huete Jimenez if (!extract_min_max(a, a_min, a_max, length)) 1431*de0e0e4dSAntonio Huete Jimenez return 0; 1432*de0e0e4dSAntonio Huete Jimenez if (memcmp(a_min, a_max, length) > 0) 1433*de0e0e4dSAntonio Huete Jimenez return 0; 1434*de0e0e4dSAntonio Huete Jimenez } 1435*de0e0e4dSAntonio Huete Jimenez 1436*de0e0e4dSAntonio Huete Jimenez return 1; 1437*de0e0e4dSAntonio Huete Jimenez } 1438*de0e0e4dSAntonio Huete Jimenez 1439*de0e0e4dSAntonio Huete Jimenez /* 1440*de0e0e4dSAntonio Huete Jimenez * Whack an IPAddrBlocks extension into canonical form. 1441*de0e0e4dSAntonio Huete Jimenez */ 1442*de0e0e4dSAntonio Huete Jimenez int 1443*de0e0e4dSAntonio Huete Jimenez X509v3_addr_canonize(IPAddrBlocks *addr) 1444*de0e0e4dSAntonio Huete Jimenez { 1445*de0e0e4dSAntonio Huete Jimenez IPAddressFamily *af; 1446*de0e0e4dSAntonio Huete Jimenez IPAddressOrRanges *aors; 1447*de0e0e4dSAntonio Huete Jimenez uint16_t afi; 1448*de0e0e4dSAntonio Huete Jimenez int i; 1449*de0e0e4dSAntonio Huete Jimenez 1450*de0e0e4dSAntonio Huete Jimenez for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { 1451*de0e0e4dSAntonio Huete Jimenez af = sk_IPAddressFamily_value(addr, i); 1452*de0e0e4dSAntonio Huete Jimenez 1453*de0e0e4dSAntonio Huete Jimenez /* Check AFI/SAFI here - IPAddressFamily_cmp() can't error. */ 1454*de0e0e4dSAntonio Huete Jimenez if (!IPAddressFamily_afi(af, &afi)) 1455*de0e0e4dSAntonio Huete Jimenez return 0; 1456*de0e0e4dSAntonio Huete Jimenez 1457*de0e0e4dSAntonio Huete Jimenez if ((aors = IPAddressFamily_addressesOrRanges(af)) == NULL) 1458*de0e0e4dSAntonio Huete Jimenez continue; 1459*de0e0e4dSAntonio Huete Jimenez 1460*de0e0e4dSAntonio Huete Jimenez if (!IPAddressOrRanges_canonize(aors, afi)) 1461*de0e0e4dSAntonio Huete Jimenez return 0; 1462*de0e0e4dSAntonio Huete Jimenez } 1463*de0e0e4dSAntonio Huete Jimenez 1464*de0e0e4dSAntonio Huete Jimenez (void)sk_IPAddressFamily_set_cmp_func(addr, IPAddressFamily_cmp); 1465*de0e0e4dSAntonio Huete Jimenez sk_IPAddressFamily_sort(addr); 1466*de0e0e4dSAntonio Huete Jimenez 1467*de0e0e4dSAntonio Huete Jimenez return X509v3_addr_is_canonical(addr); 1468*de0e0e4dSAntonio Huete Jimenez } 1469*de0e0e4dSAntonio Huete Jimenez 1470*de0e0e4dSAntonio Huete Jimenez /* 1471*de0e0e4dSAntonio Huete Jimenez * v2i handler for the IPAddrBlocks extension. 1472*de0e0e4dSAntonio Huete Jimenez */ 1473*de0e0e4dSAntonio Huete Jimenez static void * 1474*de0e0e4dSAntonio Huete Jimenez v2i_IPAddrBlocks(const struct v3_ext_method *method, struct v3_ext_ctx *ctx, 1475*de0e0e4dSAntonio Huete Jimenez STACK_OF(CONF_VALUE)*values) 1476*de0e0e4dSAntonio Huete Jimenez { 1477*de0e0e4dSAntonio Huete Jimenez static const char v4addr_chars[] = "0123456789."; 1478*de0e0e4dSAntonio Huete Jimenez static const char v6addr_chars[] = "0123456789.:abcdefABCDEF"; 1479*de0e0e4dSAntonio Huete Jimenez IPAddrBlocks *addr = NULL; 1480*de0e0e4dSAntonio Huete Jimenez char *s = NULL, *t; 1481*de0e0e4dSAntonio Huete Jimenez int i; 1482*de0e0e4dSAntonio Huete Jimenez 1483*de0e0e4dSAntonio Huete Jimenez if ((addr = sk_IPAddressFamily_new(IPAddressFamily_cmp)) == NULL) { 1484*de0e0e4dSAntonio Huete Jimenez X509V3error(ERR_R_MALLOC_FAILURE); 1485*de0e0e4dSAntonio Huete Jimenez return NULL; 1486*de0e0e4dSAntonio Huete Jimenez } 1487*de0e0e4dSAntonio Huete Jimenez 1488*de0e0e4dSAntonio Huete Jimenez for (i = 0; i < sk_CONF_VALUE_num(values); i++) { 1489*de0e0e4dSAntonio Huete Jimenez CONF_VALUE *val = sk_CONF_VALUE_value(values, i); 1490*de0e0e4dSAntonio Huete Jimenez unsigned char min[ADDR_RAW_BUF_LEN], max[ADDR_RAW_BUF_LEN]; 1491*de0e0e4dSAntonio Huete Jimenez unsigned afi, *safi = NULL, safi_; 1492*de0e0e4dSAntonio Huete Jimenez const char *addr_chars = NULL; 1493*de0e0e4dSAntonio Huete Jimenez const char *errstr; 1494*de0e0e4dSAntonio Huete Jimenez int prefix_len, i1, i2, delim, length; 1495*de0e0e4dSAntonio Huete Jimenez 1496*de0e0e4dSAntonio Huete Jimenez if (!name_cmp(val->name, "IPv4")) { 1497*de0e0e4dSAntonio Huete Jimenez afi = IANA_AFI_IPV4; 1498*de0e0e4dSAntonio Huete Jimenez } else if (!name_cmp(val->name, "IPv6")) { 1499*de0e0e4dSAntonio Huete Jimenez afi = IANA_AFI_IPV6; 1500*de0e0e4dSAntonio Huete Jimenez } else if (!name_cmp(val->name, "IPv4-SAFI")) { 1501*de0e0e4dSAntonio Huete Jimenez afi = IANA_AFI_IPV4; 1502*de0e0e4dSAntonio Huete Jimenez safi = &safi_; 1503*de0e0e4dSAntonio Huete Jimenez } else if (!name_cmp(val->name, "IPv6-SAFI")) { 1504*de0e0e4dSAntonio Huete Jimenez afi = IANA_AFI_IPV6; 1505*de0e0e4dSAntonio Huete Jimenez safi = &safi_; 1506*de0e0e4dSAntonio Huete Jimenez } else { 1507*de0e0e4dSAntonio Huete Jimenez X509V3error(X509V3_R_EXTENSION_NAME_ERROR); 1508*de0e0e4dSAntonio Huete Jimenez X509V3_conf_err(val); 1509*de0e0e4dSAntonio Huete Jimenez goto err; 1510*de0e0e4dSAntonio Huete Jimenez } 1511*de0e0e4dSAntonio Huete Jimenez 1512*de0e0e4dSAntonio Huete Jimenez switch (afi) { 1513*de0e0e4dSAntonio Huete Jimenez case IANA_AFI_IPV4: 1514*de0e0e4dSAntonio Huete Jimenez addr_chars = v4addr_chars; 1515*de0e0e4dSAntonio Huete Jimenez break; 1516*de0e0e4dSAntonio Huete Jimenez case IANA_AFI_IPV6: 1517*de0e0e4dSAntonio Huete Jimenez addr_chars = v6addr_chars; 1518*de0e0e4dSAntonio Huete Jimenez break; 1519*de0e0e4dSAntonio Huete Jimenez } 1520*de0e0e4dSAntonio Huete Jimenez 1521*de0e0e4dSAntonio Huete Jimenez length = length_from_afi(afi); 1522*de0e0e4dSAntonio Huete Jimenez 1523*de0e0e4dSAntonio Huete Jimenez /* 1524*de0e0e4dSAntonio Huete Jimenez * Handle SAFI, if any, and strdup() so we can null-terminate 1525*de0e0e4dSAntonio Huete Jimenez * the other input values. 1526*de0e0e4dSAntonio Huete Jimenez */ 1527*de0e0e4dSAntonio Huete Jimenez if (safi != NULL) { 1528*de0e0e4dSAntonio Huete Jimenez unsigned long parsed_safi; 1529*de0e0e4dSAntonio Huete Jimenez int saved_errno = errno; 1530*de0e0e4dSAntonio Huete Jimenez 1531*de0e0e4dSAntonio Huete Jimenez errno = 0; 1532*de0e0e4dSAntonio Huete Jimenez parsed_safi = strtoul(val->value, &t, 0); 1533*de0e0e4dSAntonio Huete Jimenez 1534*de0e0e4dSAntonio Huete Jimenez /* Value must be present, then a tab, space or colon. */ 1535*de0e0e4dSAntonio Huete Jimenez if (val->value[0] == '\0' || 1536*de0e0e4dSAntonio Huete Jimenez (*t != '\t' && *t != ' ' && *t != ':')) { 1537*de0e0e4dSAntonio Huete Jimenez X509V3error(X509V3_R_INVALID_SAFI); 1538*de0e0e4dSAntonio Huete Jimenez X509V3_conf_err(val); 1539*de0e0e4dSAntonio Huete Jimenez goto err; 1540*de0e0e4dSAntonio Huete Jimenez } 1541*de0e0e4dSAntonio Huete Jimenez /* Range and overflow check. */ 1542*de0e0e4dSAntonio Huete Jimenez if ((errno == ERANGE && parsed_safi == ULONG_MAX) || 1543*de0e0e4dSAntonio Huete Jimenez parsed_safi > 0xff) { 1544*de0e0e4dSAntonio Huete Jimenez X509V3error(X509V3_R_INVALID_SAFI); 1545*de0e0e4dSAntonio Huete Jimenez X509V3_conf_err(val); 1546*de0e0e4dSAntonio Huete Jimenez goto err; 1547*de0e0e4dSAntonio Huete Jimenez } 1548*de0e0e4dSAntonio Huete Jimenez errno = saved_errno; 1549*de0e0e4dSAntonio Huete Jimenez 1550*de0e0e4dSAntonio Huete Jimenez *safi = parsed_safi; 1551*de0e0e4dSAntonio Huete Jimenez 1552*de0e0e4dSAntonio Huete Jimenez /* Check possible whitespace is followed by a colon. */ 1553*de0e0e4dSAntonio Huete Jimenez t += strspn(t, " \t"); 1554*de0e0e4dSAntonio Huete Jimenez if (*t != ':') { 1555*de0e0e4dSAntonio Huete Jimenez X509V3error(X509V3_R_INVALID_SAFI); 1556*de0e0e4dSAntonio Huete Jimenez X509V3_conf_err(val); 1557*de0e0e4dSAntonio Huete Jimenez goto err; 1558*de0e0e4dSAntonio Huete Jimenez } 1559*de0e0e4dSAntonio Huete Jimenez 1560*de0e0e4dSAntonio Huete Jimenez /* Skip over colon. */ 1561*de0e0e4dSAntonio Huete Jimenez t++; 1562*de0e0e4dSAntonio Huete Jimenez 1563*de0e0e4dSAntonio Huete Jimenez /* Then over any trailing whitespace. */ 1564*de0e0e4dSAntonio Huete Jimenez t += strspn(t, " \t"); 1565*de0e0e4dSAntonio Huete Jimenez 1566*de0e0e4dSAntonio Huete Jimenez s = strdup(t); 1567*de0e0e4dSAntonio Huete Jimenez } else { 1568*de0e0e4dSAntonio Huete Jimenez s = strdup(val->value); 1569*de0e0e4dSAntonio Huete Jimenez } 1570*de0e0e4dSAntonio Huete Jimenez if (s == NULL) { 1571*de0e0e4dSAntonio Huete Jimenez X509V3error(ERR_R_MALLOC_FAILURE); 1572*de0e0e4dSAntonio Huete Jimenez goto err; 1573*de0e0e4dSAntonio Huete Jimenez } 1574*de0e0e4dSAntonio Huete Jimenez 1575*de0e0e4dSAntonio Huete Jimenez /* 1576*de0e0e4dSAntonio Huete Jimenez * Check for inheritance. Not worth additional complexity to 1577*de0e0e4dSAntonio Huete Jimenez * optimize this (seldom-used) case. 1578*de0e0e4dSAntonio Huete Jimenez */ 1579*de0e0e4dSAntonio Huete Jimenez if (strcmp(s, "inherit") == 0) { 1580*de0e0e4dSAntonio Huete Jimenez if (!X509v3_addr_add_inherit(addr, afi, safi)) { 1581*de0e0e4dSAntonio Huete Jimenez X509V3error(X509V3_R_INVALID_INHERITANCE); 1582*de0e0e4dSAntonio Huete Jimenez X509V3_conf_err(val); 1583*de0e0e4dSAntonio Huete Jimenez goto err; 1584*de0e0e4dSAntonio Huete Jimenez } 1585*de0e0e4dSAntonio Huete Jimenez free(s); 1586*de0e0e4dSAntonio Huete Jimenez s = NULL; 1587*de0e0e4dSAntonio Huete Jimenez continue; 1588*de0e0e4dSAntonio Huete Jimenez } 1589*de0e0e4dSAntonio Huete Jimenez 1590*de0e0e4dSAntonio Huete Jimenez i1 = strspn(s, addr_chars); 1591*de0e0e4dSAntonio Huete Jimenez i2 = i1 + strspn(s + i1, " \t"); 1592*de0e0e4dSAntonio Huete Jimenez delim = s[i2++]; 1593*de0e0e4dSAntonio Huete Jimenez s[i1] = '\0'; 1594*de0e0e4dSAntonio Huete Jimenez 1595*de0e0e4dSAntonio Huete Jimenez if (a2i_ipadd(min, s) != length) { 1596*de0e0e4dSAntonio Huete Jimenez X509V3error(X509V3_R_INVALID_IPADDRESS); 1597*de0e0e4dSAntonio Huete Jimenez X509V3_conf_err(val); 1598*de0e0e4dSAntonio Huete Jimenez goto err; 1599*de0e0e4dSAntonio Huete Jimenez } 1600*de0e0e4dSAntonio Huete Jimenez 1601*de0e0e4dSAntonio Huete Jimenez switch (delim) { 1602*de0e0e4dSAntonio Huete Jimenez case '/': 1603*de0e0e4dSAntonio Huete Jimenez /* length contains the size of the address in bytes. */ 1604*de0e0e4dSAntonio Huete Jimenez if (length != 4 && length != 16) 1605*de0e0e4dSAntonio Huete Jimenez goto err; 1606*de0e0e4dSAntonio Huete Jimenez prefix_len = strtonum(s + i2, 0, 8 * length, &errstr); 1607*de0e0e4dSAntonio Huete Jimenez if (errstr != NULL) { 1608*de0e0e4dSAntonio Huete Jimenez X509V3error(X509V3_R_EXTENSION_VALUE_ERROR); 1609*de0e0e4dSAntonio Huete Jimenez X509V3_conf_err(val); 1610*de0e0e4dSAntonio Huete Jimenez goto err; 1611*de0e0e4dSAntonio Huete Jimenez } 1612*de0e0e4dSAntonio Huete Jimenez if (!X509v3_addr_add_prefix(addr, afi, safi, min, 1613*de0e0e4dSAntonio Huete Jimenez prefix_len)) { 1614*de0e0e4dSAntonio Huete Jimenez X509V3error(ERR_R_MALLOC_FAILURE); 1615*de0e0e4dSAntonio Huete Jimenez goto err; 1616*de0e0e4dSAntonio Huete Jimenez } 1617*de0e0e4dSAntonio Huete Jimenez break; 1618*de0e0e4dSAntonio Huete Jimenez case '-': 1619*de0e0e4dSAntonio Huete Jimenez i1 = i2 + strspn(s + i2, " \t"); 1620*de0e0e4dSAntonio Huete Jimenez i2 = i1 + strspn(s + i1, addr_chars); 1621*de0e0e4dSAntonio Huete Jimenez if (i1 == i2 || s[i2] != '\0') { 1622*de0e0e4dSAntonio Huete Jimenez X509V3error(X509V3_R_EXTENSION_VALUE_ERROR); 1623*de0e0e4dSAntonio Huete Jimenez X509V3_conf_err(val); 1624*de0e0e4dSAntonio Huete Jimenez goto err; 1625*de0e0e4dSAntonio Huete Jimenez } 1626*de0e0e4dSAntonio Huete Jimenez if (a2i_ipadd(max, s + i1) != length) { 1627*de0e0e4dSAntonio Huete Jimenez X509V3error(X509V3_R_INVALID_IPADDRESS); 1628*de0e0e4dSAntonio Huete Jimenez X509V3_conf_err(val); 1629*de0e0e4dSAntonio Huete Jimenez goto err; 1630*de0e0e4dSAntonio Huete Jimenez } 1631*de0e0e4dSAntonio Huete Jimenez if (memcmp(min, max, length_from_afi(afi)) > 0) { 1632*de0e0e4dSAntonio Huete Jimenez X509V3error(X509V3_R_EXTENSION_VALUE_ERROR); 1633*de0e0e4dSAntonio Huete Jimenez X509V3_conf_err(val); 1634*de0e0e4dSAntonio Huete Jimenez goto err; 1635*de0e0e4dSAntonio Huete Jimenez } 1636*de0e0e4dSAntonio Huete Jimenez if (!X509v3_addr_add_range(addr, afi, safi, min, max)) { 1637*de0e0e4dSAntonio Huete Jimenez X509V3error(ERR_R_MALLOC_FAILURE); 1638*de0e0e4dSAntonio Huete Jimenez goto err; 1639*de0e0e4dSAntonio Huete Jimenez } 1640*de0e0e4dSAntonio Huete Jimenez break; 1641*de0e0e4dSAntonio Huete Jimenez case '\0': 1642*de0e0e4dSAntonio Huete Jimenez if (!X509v3_addr_add_prefix(addr, afi, safi, min, 1643*de0e0e4dSAntonio Huete Jimenez length * 8)) { 1644*de0e0e4dSAntonio Huete Jimenez X509V3error(ERR_R_MALLOC_FAILURE); 1645*de0e0e4dSAntonio Huete Jimenez goto err; 1646*de0e0e4dSAntonio Huete Jimenez } 1647*de0e0e4dSAntonio Huete Jimenez break; 1648*de0e0e4dSAntonio Huete Jimenez default: 1649*de0e0e4dSAntonio Huete Jimenez X509V3error(X509V3_R_EXTENSION_VALUE_ERROR); 1650*de0e0e4dSAntonio Huete Jimenez X509V3_conf_err(val); 1651*de0e0e4dSAntonio Huete Jimenez goto err; 1652*de0e0e4dSAntonio Huete Jimenez } 1653*de0e0e4dSAntonio Huete Jimenez 1654*de0e0e4dSAntonio Huete Jimenez free(s); 1655*de0e0e4dSAntonio Huete Jimenez s = NULL; 1656*de0e0e4dSAntonio Huete Jimenez } 1657*de0e0e4dSAntonio Huete Jimenez 1658*de0e0e4dSAntonio Huete Jimenez /* 1659*de0e0e4dSAntonio Huete Jimenez * Canonize the result, then we're done. 1660*de0e0e4dSAntonio Huete Jimenez */ 1661*de0e0e4dSAntonio Huete Jimenez if (!X509v3_addr_canonize(addr)) 1662*de0e0e4dSAntonio Huete Jimenez goto err; 1663*de0e0e4dSAntonio Huete Jimenez return addr; 1664*de0e0e4dSAntonio Huete Jimenez 1665*de0e0e4dSAntonio Huete Jimenez err: 1666*de0e0e4dSAntonio Huete Jimenez free(s); 1667*de0e0e4dSAntonio Huete Jimenez sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free); 1668*de0e0e4dSAntonio Huete Jimenez return NULL; 1669*de0e0e4dSAntonio Huete Jimenez } 1670*de0e0e4dSAntonio Huete Jimenez 1671*de0e0e4dSAntonio Huete Jimenez /* 1672*de0e0e4dSAntonio Huete Jimenez * OpenSSL dispatch 1673*de0e0e4dSAntonio Huete Jimenez */ 1674*de0e0e4dSAntonio Huete Jimenez const X509V3_EXT_METHOD v3_addr = { 1675*de0e0e4dSAntonio Huete Jimenez .ext_nid = NID_sbgp_ipAddrBlock, 1676*de0e0e4dSAntonio Huete Jimenez .ext_flags = 0, 1677*de0e0e4dSAntonio Huete Jimenez .it = &IPAddrBlocks_it, 1678*de0e0e4dSAntonio Huete Jimenez .ext_new = NULL, 1679*de0e0e4dSAntonio Huete Jimenez .ext_free = NULL, 1680*de0e0e4dSAntonio Huete Jimenez .d2i = NULL, 1681*de0e0e4dSAntonio Huete Jimenez .i2d = NULL, 1682*de0e0e4dSAntonio Huete Jimenez .i2s = NULL, 1683*de0e0e4dSAntonio Huete Jimenez .s2i = NULL, 1684*de0e0e4dSAntonio Huete Jimenez .i2v = NULL, 1685*de0e0e4dSAntonio Huete Jimenez .v2i = v2i_IPAddrBlocks, 1686*de0e0e4dSAntonio Huete Jimenez .i2r = i2r_IPAddrBlocks, 1687*de0e0e4dSAntonio Huete Jimenez .r2i = NULL, 1688*de0e0e4dSAntonio Huete Jimenez .usr_data = NULL, 1689*de0e0e4dSAntonio Huete Jimenez }; 1690*de0e0e4dSAntonio Huete Jimenez 1691*de0e0e4dSAntonio Huete Jimenez /* 1692*de0e0e4dSAntonio Huete Jimenez * Figure out whether extension uses inheritance. 1693*de0e0e4dSAntonio Huete Jimenez */ 1694*de0e0e4dSAntonio Huete Jimenez int 1695*de0e0e4dSAntonio Huete Jimenez X509v3_addr_inherits(IPAddrBlocks *addr) 1696*de0e0e4dSAntonio Huete Jimenez { 1697*de0e0e4dSAntonio Huete Jimenez IPAddressFamily *af; 1698*de0e0e4dSAntonio Huete Jimenez int i; 1699*de0e0e4dSAntonio Huete Jimenez 1700*de0e0e4dSAntonio Huete Jimenez if (addr == NULL) 1701*de0e0e4dSAntonio Huete Jimenez return 0; 1702*de0e0e4dSAntonio Huete Jimenez 1703*de0e0e4dSAntonio Huete Jimenez for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { 1704*de0e0e4dSAntonio Huete Jimenez af = sk_IPAddressFamily_value(addr, i); 1705*de0e0e4dSAntonio Huete Jimenez 1706*de0e0e4dSAntonio Huete Jimenez if (IPAddressFamily_inheritance(af) != NULL) 1707*de0e0e4dSAntonio Huete Jimenez return 1; 1708*de0e0e4dSAntonio Huete Jimenez } 1709*de0e0e4dSAntonio Huete Jimenez 1710*de0e0e4dSAntonio Huete Jimenez return 0; 1711*de0e0e4dSAntonio Huete Jimenez } 1712*de0e0e4dSAntonio Huete Jimenez 1713*de0e0e4dSAntonio Huete Jimenez /* 1714*de0e0e4dSAntonio Huete Jimenez * Figure out whether parent contains child. 1715*de0e0e4dSAntonio Huete Jimenez * 1716*de0e0e4dSAntonio Huete Jimenez * This only works correctly if both parent and child are in canonical form. 1717*de0e0e4dSAntonio Huete Jimenez */ 1718*de0e0e4dSAntonio Huete Jimenez static int 1719*de0e0e4dSAntonio Huete Jimenez addr_contains(IPAddressOrRanges *parent, IPAddressOrRanges *child, int length) 1720*de0e0e4dSAntonio Huete Jimenez { 1721*de0e0e4dSAntonio Huete Jimenez IPAddressOrRange *child_aor, *parent_aor; 1722*de0e0e4dSAntonio Huete Jimenez uint8_t parent_min[ADDR_RAW_BUF_LEN], parent_max[ADDR_RAW_BUF_LEN]; 1723*de0e0e4dSAntonio Huete Jimenez uint8_t child_min[ADDR_RAW_BUF_LEN], child_max[ADDR_RAW_BUF_LEN]; 1724*de0e0e4dSAntonio Huete Jimenez int p, c; 1725*de0e0e4dSAntonio Huete Jimenez 1726*de0e0e4dSAntonio Huete Jimenez if (child == NULL || parent == child) 1727*de0e0e4dSAntonio Huete Jimenez return 1; 1728*de0e0e4dSAntonio Huete Jimenez if (parent == NULL) 1729*de0e0e4dSAntonio Huete Jimenez return 0; 1730*de0e0e4dSAntonio Huete Jimenez 1731*de0e0e4dSAntonio Huete Jimenez p = 0; 1732*de0e0e4dSAntonio Huete Jimenez for (c = 0; c < sk_IPAddressOrRange_num(child); c++) { 1733*de0e0e4dSAntonio Huete Jimenez child_aor = sk_IPAddressOrRange_value(child, c); 1734*de0e0e4dSAntonio Huete Jimenez 1735*de0e0e4dSAntonio Huete Jimenez if (!extract_min_max(child_aor, child_min, child_max, length)) 1736*de0e0e4dSAntonio Huete Jimenez return 0; 1737*de0e0e4dSAntonio Huete Jimenez 1738*de0e0e4dSAntonio Huete Jimenez for (;; p++) { 1739*de0e0e4dSAntonio Huete Jimenez if (p >= sk_IPAddressOrRange_num(parent)) 1740*de0e0e4dSAntonio Huete Jimenez return 0; 1741*de0e0e4dSAntonio Huete Jimenez 1742*de0e0e4dSAntonio Huete Jimenez parent_aor = sk_IPAddressOrRange_value(parent, p); 1743*de0e0e4dSAntonio Huete Jimenez 1744*de0e0e4dSAntonio Huete Jimenez if (!extract_min_max(parent_aor, parent_min, parent_max, 1745*de0e0e4dSAntonio Huete Jimenez length)) 1746*de0e0e4dSAntonio Huete Jimenez return 0; 1747*de0e0e4dSAntonio Huete Jimenez 1748*de0e0e4dSAntonio Huete Jimenez if (memcmp(parent_max, child_max, length) < 0) 1749*de0e0e4dSAntonio Huete Jimenez continue; 1750*de0e0e4dSAntonio Huete Jimenez if (memcmp(parent_min, child_min, length) > 0) 1751*de0e0e4dSAntonio Huete Jimenez return 0; 1752*de0e0e4dSAntonio Huete Jimenez break; 1753*de0e0e4dSAntonio Huete Jimenez } 1754*de0e0e4dSAntonio Huete Jimenez } 1755*de0e0e4dSAntonio Huete Jimenez 1756*de0e0e4dSAntonio Huete Jimenez return 1; 1757*de0e0e4dSAntonio Huete Jimenez } 1758*de0e0e4dSAntonio Huete Jimenez 1759*de0e0e4dSAntonio Huete Jimenez /* 1760*de0e0e4dSAntonio Huete Jimenez * Test whether |child| is a subset of |parent|. 1761*de0e0e4dSAntonio Huete Jimenez */ 1762*de0e0e4dSAntonio Huete Jimenez int 1763*de0e0e4dSAntonio Huete Jimenez X509v3_addr_subset(IPAddrBlocks *child, IPAddrBlocks *parent) 1764*de0e0e4dSAntonio Huete Jimenez { 1765*de0e0e4dSAntonio Huete Jimenez IPAddressFamily *child_af, *parent_af; 1766*de0e0e4dSAntonio Huete Jimenez IPAddressOrRanges *child_aor, *parent_aor; 1767*de0e0e4dSAntonio Huete Jimenez int i, length; 1768*de0e0e4dSAntonio Huete Jimenez 1769*de0e0e4dSAntonio Huete Jimenez if (child == NULL || child == parent) 1770*de0e0e4dSAntonio Huete Jimenez return 1; 1771*de0e0e4dSAntonio Huete Jimenez if (parent == NULL) 1772*de0e0e4dSAntonio Huete Jimenez return 0; 1773*de0e0e4dSAntonio Huete Jimenez 1774*de0e0e4dSAntonio Huete Jimenez if (X509v3_addr_inherits(child) || X509v3_addr_inherits(parent)) 1775*de0e0e4dSAntonio Huete Jimenez return 0; 1776*de0e0e4dSAntonio Huete Jimenez 1777*de0e0e4dSAntonio Huete Jimenez for (i = 0; i < sk_IPAddressFamily_num(child); i++) { 1778*de0e0e4dSAntonio Huete Jimenez child_af = sk_IPAddressFamily_value(child, i); 1779*de0e0e4dSAntonio Huete Jimenez 1780*de0e0e4dSAntonio Huete Jimenez parent_af = IPAddressFamily_find_in_parent(parent, child_af); 1781*de0e0e4dSAntonio Huete Jimenez if (parent_af == NULL) 1782*de0e0e4dSAntonio Huete Jimenez return 0; 1783*de0e0e4dSAntonio Huete Jimenez 1784*de0e0e4dSAntonio Huete Jimenez if (!IPAddressFamily_afi_length(parent_af, &length)) 1785*de0e0e4dSAntonio Huete Jimenez return 0; 1786*de0e0e4dSAntonio Huete Jimenez 1787*de0e0e4dSAntonio Huete Jimenez child_aor = IPAddressFamily_addressesOrRanges(child_af); 1788*de0e0e4dSAntonio Huete Jimenez parent_aor = IPAddressFamily_addressesOrRanges(parent_af); 1789*de0e0e4dSAntonio Huete Jimenez 1790*de0e0e4dSAntonio Huete Jimenez if (!addr_contains(parent_aor, child_aor, length)) 1791*de0e0e4dSAntonio Huete Jimenez return 0; 1792*de0e0e4dSAntonio Huete Jimenez } 1793*de0e0e4dSAntonio Huete Jimenez return 1; 1794*de0e0e4dSAntonio Huete Jimenez } 1795*de0e0e4dSAntonio Huete Jimenez 1796*de0e0e4dSAntonio Huete Jimenez static int 1797*de0e0e4dSAntonio Huete Jimenez verify_error(X509_STORE_CTX *ctx, X509 *cert, int error, int depth) 1798*de0e0e4dSAntonio Huete Jimenez { 1799*de0e0e4dSAntonio Huete Jimenez if (ctx == NULL) 1800*de0e0e4dSAntonio Huete Jimenez return 0; 1801*de0e0e4dSAntonio Huete Jimenez 1802*de0e0e4dSAntonio Huete Jimenez ctx->current_cert = cert; 1803*de0e0e4dSAntonio Huete Jimenez ctx->error = error; 1804*de0e0e4dSAntonio Huete Jimenez ctx->error_depth = depth; 1805*de0e0e4dSAntonio Huete Jimenez 1806*de0e0e4dSAntonio Huete Jimenez return ctx->verify_cb(0, ctx); 1807*de0e0e4dSAntonio Huete Jimenez } 1808*de0e0e4dSAntonio Huete Jimenez 1809*de0e0e4dSAntonio Huete Jimenez /* 1810*de0e0e4dSAntonio Huete Jimenez * Core code for RFC 3779 2.3 path validation. 1811*de0e0e4dSAntonio Huete Jimenez * 1812*de0e0e4dSAntonio Huete Jimenez * Returns 1 for success, 0 on error. 1813*de0e0e4dSAntonio Huete Jimenez * 1814*de0e0e4dSAntonio Huete Jimenez * When returning 0, ctx->error MUST be set to an appropriate value other than 1815*de0e0e4dSAntonio Huete Jimenez * X509_V_OK. 1816*de0e0e4dSAntonio Huete Jimenez */ 1817*de0e0e4dSAntonio Huete Jimenez static int 1818*de0e0e4dSAntonio Huete Jimenez addr_validate_path_internal(X509_STORE_CTX *ctx, STACK_OF(X509) *chain, 1819*de0e0e4dSAntonio Huete Jimenez IPAddrBlocks *ext) 1820*de0e0e4dSAntonio Huete Jimenez { 1821*de0e0e4dSAntonio Huete Jimenez IPAddrBlocks *child = NULL, *parent = NULL; 1822*de0e0e4dSAntonio Huete Jimenez IPAddressFamily *child_af, *parent_af; 1823*de0e0e4dSAntonio Huete Jimenez IPAddressOrRanges *child_aor, *parent_aor; 1824*de0e0e4dSAntonio Huete Jimenez X509 *cert = NULL; 1825*de0e0e4dSAntonio Huete Jimenez int depth = -1; 1826*de0e0e4dSAntonio Huete Jimenez int i; 1827*de0e0e4dSAntonio Huete Jimenez unsigned int length; 1828*de0e0e4dSAntonio Huete Jimenez int ret = 1; 1829*de0e0e4dSAntonio Huete Jimenez 1830*de0e0e4dSAntonio Huete Jimenez /* We need a non-empty chain to test against. */ 1831*de0e0e4dSAntonio Huete Jimenez if (sk_X509_num(chain) <= 0) 1832*de0e0e4dSAntonio Huete Jimenez goto err; 1833*de0e0e4dSAntonio Huete Jimenez /* We need either a store ctx or an extension to work with. */ 1834*de0e0e4dSAntonio Huete Jimenez if (ctx == NULL && ext == NULL) 1835*de0e0e4dSAntonio Huete Jimenez goto err; 1836*de0e0e4dSAntonio Huete Jimenez /* If there is a store ctx, it needs a verify_cb. */ 1837*de0e0e4dSAntonio Huete Jimenez if (ctx != NULL && ctx->verify_cb == NULL) 1838*de0e0e4dSAntonio Huete Jimenez goto err; 1839*de0e0e4dSAntonio Huete Jimenez 1840*de0e0e4dSAntonio Huete Jimenez /* 1841*de0e0e4dSAntonio Huete Jimenez * Figure out where to start. If we don't have an extension to check, 1842*de0e0e4dSAntonio Huete Jimenez * (either extracted from the leaf or passed by the caller), we're done. 1843*de0e0e4dSAntonio Huete Jimenez * Otherwise, check canonical form and set up for walking up the chain. 1844*de0e0e4dSAntonio Huete Jimenez */ 1845*de0e0e4dSAntonio Huete Jimenez if (ext == NULL) { 1846*de0e0e4dSAntonio Huete Jimenez depth = 0; 1847*de0e0e4dSAntonio Huete Jimenez cert = sk_X509_value(chain, depth); 1848*de0e0e4dSAntonio Huete Jimenez if ((X509_get_extension_flags(cert) & EXFLAG_INVALID) != 0) 1849*de0e0e4dSAntonio Huete Jimenez goto done; 1850*de0e0e4dSAntonio Huete Jimenez if ((ext = cert->rfc3779_addr) == NULL) 1851*de0e0e4dSAntonio Huete Jimenez goto done; 1852*de0e0e4dSAntonio Huete Jimenez } else if (!X509v3_addr_is_canonical(ext)) { 1853*de0e0e4dSAntonio Huete Jimenez if ((ret = verify_error(ctx, cert, 1854*de0e0e4dSAntonio Huete Jimenez X509_V_ERR_INVALID_EXTENSION, depth)) == 0) 1855*de0e0e4dSAntonio Huete Jimenez goto done; 1856*de0e0e4dSAntonio Huete Jimenez } 1857*de0e0e4dSAntonio Huete Jimenez 1858*de0e0e4dSAntonio Huete Jimenez (void)sk_IPAddressFamily_set_cmp_func(ext, IPAddressFamily_cmp); 1859*de0e0e4dSAntonio Huete Jimenez if ((child = sk_IPAddressFamily_dup(ext)) == NULL) { 1860*de0e0e4dSAntonio Huete Jimenez X509V3error(ERR_R_MALLOC_FAILURE); 1861*de0e0e4dSAntonio Huete Jimenez if (ctx != NULL) 1862*de0e0e4dSAntonio Huete Jimenez ctx->error = X509_V_ERR_OUT_OF_MEM; 1863*de0e0e4dSAntonio Huete Jimenez ret = 0; 1864*de0e0e4dSAntonio Huete Jimenez goto done; 1865*de0e0e4dSAntonio Huete Jimenez } 1866*de0e0e4dSAntonio Huete Jimenez 1867*de0e0e4dSAntonio Huete Jimenez /* 1868*de0e0e4dSAntonio Huete Jimenez * Now walk up the chain. No cert may list resources that its parent 1869*de0e0e4dSAntonio Huete Jimenez * doesn't list. 1870*de0e0e4dSAntonio Huete Jimenez */ 1871*de0e0e4dSAntonio Huete Jimenez for (depth++; depth < sk_X509_num(chain); depth++) { 1872*de0e0e4dSAntonio Huete Jimenez cert = sk_X509_value(chain, depth); 1873*de0e0e4dSAntonio Huete Jimenez 1874*de0e0e4dSAntonio Huete Jimenez if ((X509_get_extension_flags(cert) & EXFLAG_INVALID) != 0) { 1875*de0e0e4dSAntonio Huete Jimenez if ((ret = verify_error(ctx, cert, 1876*de0e0e4dSAntonio Huete Jimenez X509_V_ERR_INVALID_EXTENSION, depth)) == 0) 1877*de0e0e4dSAntonio Huete Jimenez goto done; 1878*de0e0e4dSAntonio Huete Jimenez } 1879*de0e0e4dSAntonio Huete Jimenez 1880*de0e0e4dSAntonio Huete Jimenez if ((parent = cert->rfc3779_addr) == NULL) { 1881*de0e0e4dSAntonio Huete Jimenez for (i = 0; i < sk_IPAddressFamily_num(child); i++) { 1882*de0e0e4dSAntonio Huete Jimenez child_af = sk_IPAddressFamily_value(child, i); 1883*de0e0e4dSAntonio Huete Jimenez 1884*de0e0e4dSAntonio Huete Jimenez if (IPAddressFamily_inheritance(child_af) != 1885*de0e0e4dSAntonio Huete Jimenez NULL) 1886*de0e0e4dSAntonio Huete Jimenez continue; 1887*de0e0e4dSAntonio Huete Jimenez 1888*de0e0e4dSAntonio Huete Jimenez if ((ret = verify_error(ctx, cert, 1889*de0e0e4dSAntonio Huete Jimenez X509_V_ERR_UNNESTED_RESOURCE, depth)) == 0) 1890*de0e0e4dSAntonio Huete Jimenez goto done; 1891*de0e0e4dSAntonio Huete Jimenez break; 1892*de0e0e4dSAntonio Huete Jimenez } 1893*de0e0e4dSAntonio Huete Jimenez continue; 1894*de0e0e4dSAntonio Huete Jimenez } 1895*de0e0e4dSAntonio Huete Jimenez 1896*de0e0e4dSAntonio Huete Jimenez /* 1897*de0e0e4dSAntonio Huete Jimenez * Check that the child's resources are covered by the parent. 1898*de0e0e4dSAntonio Huete Jimenez * Each covered resource is replaced with the parent's resource 1899*de0e0e4dSAntonio Huete Jimenez * covering it, so the next iteration will check that the 1900*de0e0e4dSAntonio Huete Jimenez * parent's resources are covered by the grandparent. 1901*de0e0e4dSAntonio Huete Jimenez */ 1902*de0e0e4dSAntonio Huete Jimenez for (i = 0; i < sk_IPAddressFamily_num(child); i++) { 1903*de0e0e4dSAntonio Huete Jimenez child_af = sk_IPAddressFamily_value(child, i); 1904*de0e0e4dSAntonio Huete Jimenez 1905*de0e0e4dSAntonio Huete Jimenez if ((parent_af = IPAddressFamily_find_in_parent(parent, 1906*de0e0e4dSAntonio Huete Jimenez child_af)) == NULL) { 1907*de0e0e4dSAntonio Huete Jimenez /* 1908*de0e0e4dSAntonio Huete Jimenez * If we have no match in the parent and the 1909*de0e0e4dSAntonio Huete Jimenez * child inherits, that's fine. 1910*de0e0e4dSAntonio Huete Jimenez */ 1911*de0e0e4dSAntonio Huete Jimenez if (IPAddressFamily_inheritance(child_af) != 1912*de0e0e4dSAntonio Huete Jimenez NULL) 1913*de0e0e4dSAntonio Huete Jimenez continue; 1914*de0e0e4dSAntonio Huete Jimenez 1915*de0e0e4dSAntonio Huete Jimenez /* Otherwise the child isn't covered. */ 1916*de0e0e4dSAntonio Huete Jimenez if ((ret = verify_error(ctx, cert, 1917*de0e0e4dSAntonio Huete Jimenez X509_V_ERR_UNNESTED_RESOURCE, depth)) == 0) 1918*de0e0e4dSAntonio Huete Jimenez goto done; 1919*de0e0e4dSAntonio Huete Jimenez break; 1920*de0e0e4dSAntonio Huete Jimenez } 1921*de0e0e4dSAntonio Huete Jimenez 1922*de0e0e4dSAntonio Huete Jimenez /* Parent inherits, nothing to do. */ 1923*de0e0e4dSAntonio Huete Jimenez if (IPAddressFamily_inheritance(parent_af) != NULL) 1924*de0e0e4dSAntonio Huete Jimenez continue; 1925*de0e0e4dSAntonio Huete Jimenez 1926*de0e0e4dSAntonio Huete Jimenez /* Child inherits. Use parent's address family. */ 1927*de0e0e4dSAntonio Huete Jimenez if (IPAddressFamily_inheritance(child_af) != NULL) { 1928*de0e0e4dSAntonio Huete Jimenez sk_IPAddressFamily_set(child, i, parent_af); 1929*de0e0e4dSAntonio Huete Jimenez continue; 1930*de0e0e4dSAntonio Huete Jimenez } 1931*de0e0e4dSAntonio Huete Jimenez 1932*de0e0e4dSAntonio Huete Jimenez child_aor = IPAddressFamily_addressesOrRanges(child_af); 1933*de0e0e4dSAntonio Huete Jimenez parent_aor = 1934*de0e0e4dSAntonio Huete Jimenez IPAddressFamily_addressesOrRanges(parent_af); 1935*de0e0e4dSAntonio Huete Jimenez 1936*de0e0e4dSAntonio Huete Jimenez /* 1937*de0e0e4dSAntonio Huete Jimenez * Child and parent are canonical and neither inherits. 1938*de0e0e4dSAntonio Huete Jimenez * If either addressesOrRanges is NULL, something's 1939*de0e0e4dSAntonio Huete Jimenez * very wrong. 1940*de0e0e4dSAntonio Huete Jimenez */ 1941*de0e0e4dSAntonio Huete Jimenez if (child_aor == NULL || parent_aor == NULL) 1942*de0e0e4dSAntonio Huete Jimenez goto err; 1943*de0e0e4dSAntonio Huete Jimenez 1944*de0e0e4dSAntonio Huete Jimenez if (!IPAddressFamily_afi_length(child_af, &length)) 1945*de0e0e4dSAntonio Huete Jimenez goto err; 1946*de0e0e4dSAntonio Huete Jimenez 1947*de0e0e4dSAntonio Huete Jimenez /* Now check containment and replace or error. */ 1948*de0e0e4dSAntonio Huete Jimenez if (addr_contains(parent_aor, child_aor, length)) { 1949*de0e0e4dSAntonio Huete Jimenez sk_IPAddressFamily_set(child, i, parent_af); 1950*de0e0e4dSAntonio Huete Jimenez continue; 1951*de0e0e4dSAntonio Huete Jimenez } 1952*de0e0e4dSAntonio Huete Jimenez 1953*de0e0e4dSAntonio Huete Jimenez if ((ret = verify_error(ctx, cert, 1954*de0e0e4dSAntonio Huete Jimenez X509_V_ERR_UNNESTED_RESOURCE, depth)) == 0) 1955*de0e0e4dSAntonio Huete Jimenez goto done; 1956*de0e0e4dSAntonio Huete Jimenez } 1957*de0e0e4dSAntonio Huete Jimenez } 1958*de0e0e4dSAntonio Huete Jimenez 1959*de0e0e4dSAntonio Huete Jimenez /* 1960*de0e0e4dSAntonio Huete Jimenez * Trust anchor can't inherit. 1961*de0e0e4dSAntonio Huete Jimenez */ 1962*de0e0e4dSAntonio Huete Jimenez if ((parent = cert->rfc3779_addr) != NULL) { 1963*de0e0e4dSAntonio Huete Jimenez for (i = 0; i < sk_IPAddressFamily_num(parent); i++) { 1964*de0e0e4dSAntonio Huete Jimenez parent_af = sk_IPAddressFamily_value(parent, i); 1965*de0e0e4dSAntonio Huete Jimenez 1966*de0e0e4dSAntonio Huete Jimenez if (IPAddressFamily_inheritance(parent_af) == NULL) 1967*de0e0e4dSAntonio Huete Jimenez continue; 1968*de0e0e4dSAntonio Huete Jimenez 1969*de0e0e4dSAntonio Huete Jimenez if ((ret = verify_error(ctx, cert, 1970*de0e0e4dSAntonio Huete Jimenez X509_V_ERR_UNNESTED_RESOURCE, depth)) == 0) 1971*de0e0e4dSAntonio Huete Jimenez goto done; 1972*de0e0e4dSAntonio Huete Jimenez } 1973*de0e0e4dSAntonio Huete Jimenez } 1974*de0e0e4dSAntonio Huete Jimenez 1975*de0e0e4dSAntonio Huete Jimenez done: 1976*de0e0e4dSAntonio Huete Jimenez sk_IPAddressFamily_free(child); 1977*de0e0e4dSAntonio Huete Jimenez return ret; 1978*de0e0e4dSAntonio Huete Jimenez 1979*de0e0e4dSAntonio Huete Jimenez err: 1980*de0e0e4dSAntonio Huete Jimenez sk_IPAddressFamily_free(child); 1981*de0e0e4dSAntonio Huete Jimenez 1982*de0e0e4dSAntonio Huete Jimenez if (ctx != NULL) 1983*de0e0e4dSAntonio Huete Jimenez ctx->error = X509_V_ERR_UNSPECIFIED; 1984*de0e0e4dSAntonio Huete Jimenez 1985*de0e0e4dSAntonio Huete Jimenez return 0; 1986*de0e0e4dSAntonio Huete Jimenez } 1987*de0e0e4dSAntonio Huete Jimenez 1988*de0e0e4dSAntonio Huete Jimenez /* 1989*de0e0e4dSAntonio Huete Jimenez * RFC 3779 2.3 path validation -- called from X509_verify_cert(). 1990*de0e0e4dSAntonio Huete Jimenez */ 1991*de0e0e4dSAntonio Huete Jimenez int 1992*de0e0e4dSAntonio Huete Jimenez X509v3_addr_validate_path(X509_STORE_CTX *ctx) 1993*de0e0e4dSAntonio Huete Jimenez { 1994*de0e0e4dSAntonio Huete Jimenez if (sk_X509_num(ctx->chain) <= 0 || ctx->verify_cb == NULL) { 1995*de0e0e4dSAntonio Huete Jimenez ctx->error = X509_V_ERR_UNSPECIFIED; 1996*de0e0e4dSAntonio Huete Jimenez return 0; 1997*de0e0e4dSAntonio Huete Jimenez } 1998*de0e0e4dSAntonio Huete Jimenez return addr_validate_path_internal(ctx, ctx->chain, NULL); 1999*de0e0e4dSAntonio Huete Jimenez } 2000*de0e0e4dSAntonio Huete Jimenez 2001*de0e0e4dSAntonio Huete Jimenez /* 2002*de0e0e4dSAntonio Huete Jimenez * RFC 3779 2.3 path validation of an extension. 2003*de0e0e4dSAntonio Huete Jimenez * Test whether chain covers extension. 2004*de0e0e4dSAntonio Huete Jimenez */ 2005*de0e0e4dSAntonio Huete Jimenez int 2006*de0e0e4dSAntonio Huete Jimenez X509v3_addr_validate_resource_set(STACK_OF(X509) *chain, IPAddrBlocks *ext, 2007*de0e0e4dSAntonio Huete Jimenez int allow_inheritance) 2008*de0e0e4dSAntonio Huete Jimenez { 2009*de0e0e4dSAntonio Huete Jimenez if (ext == NULL) 2010*de0e0e4dSAntonio Huete Jimenez return 1; 2011*de0e0e4dSAntonio Huete Jimenez if (sk_X509_num(chain) <= 0) 2012*de0e0e4dSAntonio Huete Jimenez return 0; 2013*de0e0e4dSAntonio Huete Jimenez if (!allow_inheritance && X509v3_addr_inherits(ext)) 2014*de0e0e4dSAntonio Huete Jimenez return 0; 2015*de0e0e4dSAntonio Huete Jimenez return addr_validate_path_internal(NULL, chain, ext); 2016*de0e0e4dSAntonio Huete Jimenez } 2017*de0e0e4dSAntonio Huete Jimenez 2018*de0e0e4dSAntonio Huete Jimenez #endif /* OPENSSL_NO_RFC3779 */ 2019