xref: /dflybsd-src/crypto/libressl/crypto/x509/x509_addr.c (revision 961e30ea7dc61d1112b778ea4981eac68129fb86)
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 *
d2i_IPAddressRange(IPAddressRange ** a,const unsigned char ** in,long len)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
i2d_IPAddressRange(IPAddressRange * a,unsigned char ** out)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 *
IPAddressRange_new(void)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
IPAddressRange_free(IPAddressRange * a)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 *
d2i_IPAddressOrRange(IPAddressOrRange ** a,const unsigned char ** in,long len)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
i2d_IPAddressOrRange(IPAddressOrRange * a,unsigned char ** out)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 *
IPAddressOrRange_new(void)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
IPAddressOrRange_free(IPAddressOrRange * a)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 *
d2i_IPAddressChoice(IPAddressChoice ** a,const unsigned char ** in,long len)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
i2d_IPAddressChoice(IPAddressChoice * a,unsigned char ** out)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 *
IPAddressChoice_new(void)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
IPAddressChoice_free(IPAddressChoice * a)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 *
d2i_IPAddressFamily(IPAddressFamily ** a,const unsigned char ** in,long len)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
i2d_IPAddressFamily(IPAddressFamily * a,unsigned char ** out)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 *
IPAddressFamily_new(void)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
IPAddressFamily_free(IPAddressFamily * a)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
IPAddressFamily_type(IPAddressFamily * af)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 *
IPAddressFamily_addressesOrRanges(IPAddressFamily * af)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 *
IPAddressFamily_inheritance(IPAddressFamily * af)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
IPAddressFamily_set_inheritance(IPAddressFamily * af)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
length_from_afi(const unsigned afi)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
IPAddressFamily_afi_safi(const IPAddressFamily * af,uint16_t * out_afi,uint8_t * out_safi,int * safi_is_set)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
IPAddressFamily_afi(const IPAddressFamily * af,uint16_t * out_afi)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
IPAddressFamily_afi_is_valid(const IPAddressFamily * af)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
IPAddressFamily_afi_length(const IPAddressFamily * af,int * out_length)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
IPAddressFamily_cmp(const IPAddressFamily * const * a_,const IPAddressFamily * const * b_)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 *
IPAddressFamily_find_in_parent(IPAddrBlocks * parent,IPAddressFamily * child_af)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
X509v3_addr_get_afi(const IPAddressFamily * af)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
addr_expand(unsigned char * addr,const ASN1_BIT_STRING * bs,const int length,uint8_t fill)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
i2r_address(BIO * out,const unsigned afi,const unsigned char fill,const ASN1_BIT_STRING * bs)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
i2r_IPAddressOrRanges(BIO * out,const int indent,const IPAddressOrRanges * aors,const unsigned afi)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
i2r_IPAddrBlocks(const X509V3_EXT_METHOD * method,void * ext,BIO * out,int indent)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
IPAddressOrRange_cmp(const IPAddressOrRange * a,const IPAddressOrRange * b,const int length)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
v4IPAddressOrRange_cmp(const IPAddressOrRange * const * a,const IPAddressOrRange * const * b)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
v6IPAddressOrRange_cmp(const IPAddressOrRange * const * a,const IPAddressOrRange * const * b)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
range_should_be_prefix(const unsigned char * min,const unsigned char * max,const int length)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
make_addressPrefix(IPAddressOrRange ** out_aor,uint8_t * addr,uint32_t afi,int prefix_len)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
count_trailing_zeroes(uint8_t octet)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
trim_end_u8(CBS * cbs,uint8_t trim)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
make_addressRange(IPAddressOrRange ** out_aor,uint8_t * min,uint8_t * max,uint32_t afi,int length)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 *
make_IPAddressFamily(IPAddrBlocks * addr,const unsigned afi,const unsigned * safi)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
X509v3_addr_add_inherit(IPAddrBlocks * addr,const unsigned afi,const unsigned * safi)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 *
make_prefix_or_range(IPAddrBlocks * addr,const unsigned afi,const unsigned * safi)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
X509v3_addr_add_prefix(IPAddrBlocks * addr,const unsigned afi,const unsigned * safi,unsigned char * a,const int prefix_len)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
X509v3_addr_add_range(IPAddrBlocks * addr,const unsigned afi,const unsigned * safi,unsigned char * min,unsigned char * max)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
extract_min_max_bitstr(IPAddressOrRange * aor,ASN1_BIT_STRING ** out_min,ASN1_BIT_STRING ** out_max)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
extract_min_max(IPAddressOrRange * aor,unsigned char * min,unsigned char * max,int length)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
X509v3_addr_get_range(IPAddressOrRange * aor,const unsigned afi,unsigned char * min,unsigned char * max,const int length)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
X509v3_addr_is_canonical(IPAddrBlocks * addr)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
IPAddressOrRanges_canonize(IPAddressOrRanges * aors,const unsigned afi)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
X509v3_addr_canonize(IPAddrBlocks * addr)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 *
v2i_IPAddrBlocks(const struct v3_ext_method * method,struct v3_ext_ctx * ctx,STACK_OF (CONF_VALUE)* values)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
X509v3_addr_inherits(IPAddrBlocks * addr)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
addr_contains(IPAddressOrRanges * parent,IPAddressOrRanges * child,int length)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
X509v3_addr_subset(IPAddrBlocks * child,IPAddrBlocks * parent)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
verify_error(X509_STORE_CTX * ctx,X509 * cert,int error,int depth)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
addr_validate_path_internal(X509_STORE_CTX * ctx,STACK_OF (X509)* chain,IPAddrBlocks * ext)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
X509v3_addr_validate_path(X509_STORE_CTX * ctx)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
X509v3_addr_validate_resource_set(STACK_OF (X509)* chain,IPAddrBlocks * ext,int allow_inheritance)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