|
1 /* |
|
2 * Contributed to the OpenSSL Project by the American Registry for |
|
3 * Internet Numbers ("ARIN"). |
|
4 */ |
|
5 /* ==================================================================== |
|
6 * Copyright (c) 2006 The OpenSSL Project. All rights reserved. |
|
7 * |
|
8 * Redistribution and use in source and binary forms, with or without |
|
9 * modification, are permitted provided that the following conditions |
|
10 * are met: |
|
11 * |
|
12 * 1. Redistributions of source code must retain the above copyright |
|
13 * notice, this list of conditions and the following disclaimer. |
|
14 * |
|
15 * 2. Redistributions in binary form must reproduce the above copyright |
|
16 * notice, this list of conditions and the following disclaimer in |
|
17 * the documentation and/or other materials provided with the |
|
18 * distribution. |
|
19 * |
|
20 * 3. All advertising materials mentioning features or use of this |
|
21 * software must display the following acknowledgment: |
|
22 * "This product includes software developed by the OpenSSL Project |
|
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" |
|
24 * |
|
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to |
|
26 * endorse or promote products derived from this software without |
|
27 * prior written permission. For written permission, please contact |
|
28 * licensing@OpenSSL.org. |
|
29 * |
|
30 * 5. Products derived from this software may not be called "OpenSSL" |
|
31 * nor may "OpenSSL" appear in their names without prior written |
|
32 * permission of the OpenSSL Project. |
|
33 * |
|
34 * 6. Redistributions of any form whatsoever must retain the following |
|
35 * acknowledgment: |
|
36 * "This product includes software developed by the OpenSSL Project |
|
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" |
|
38 * |
|
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY |
|
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR |
|
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
|
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
|
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
|
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
|
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
|
50 * OF THE POSSIBILITY OF SUCH DAMAGE. |
|
51 * ==================================================================== |
|
52 * |
|
53 * This product includes cryptographic software written by Eric Young |
|
54 * (eay@cryptsoft.com). This product includes software written by Tim |
|
55 * Hudson (tjh@cryptsoft.com). |
|
56 */ |
|
57 |
|
58 /* |
|
59 * Implementation of RFC 3779 section 2.2. |
|
60 */ |
|
61 |
|
62 #include <stdio.h> |
|
63 #include <stdlib.h> |
|
64 #include <assert.h> |
|
65 #include "cryptlib.h" |
|
66 #include <openssl/conf.h> |
|
67 #include <openssl/asn1.h> |
|
68 #include <openssl/asn1t.h> |
|
69 #include <openssl/buffer.h> |
|
70 #include <openssl/x509v3.h> |
|
71 |
|
72 #ifndef OPENSSL_NO_RFC3779 |
|
73 |
|
74 /* |
|
75 * OpenSSL ASN.1 template translation of RFC 3779 2.2.3. |
|
76 */ |
|
77 |
|
78 ASN1_SEQUENCE(IPAddressRange) = { |
|
79 ASN1_SIMPLE(IPAddressRange, min, ASN1_BIT_STRING), |
|
80 ASN1_SIMPLE(IPAddressRange, max, ASN1_BIT_STRING) |
|
81 } ASN1_SEQUENCE_END(IPAddressRange) |
|
82 |
|
83 ASN1_CHOICE(IPAddressOrRange) = { |
|
84 ASN1_SIMPLE(IPAddressOrRange, u.addressPrefix, ASN1_BIT_STRING), |
|
85 ASN1_SIMPLE(IPAddressOrRange, u.addressRange, IPAddressRange) |
|
86 } ASN1_CHOICE_END(IPAddressOrRange) |
|
87 |
|
88 ASN1_CHOICE(IPAddressChoice) = { |
|
89 ASN1_SIMPLE(IPAddressChoice, u.inherit, ASN1_NULL), |
|
90 ASN1_SEQUENCE_OF(IPAddressChoice, u.addressesOrRanges, IPAddressOrRange) |
|
91 } ASN1_CHOICE_END(IPAddressChoice) |
|
92 |
|
93 ASN1_SEQUENCE(IPAddressFamily) = { |
|
94 ASN1_SIMPLE(IPAddressFamily, addressFamily, ASN1_OCTET_STRING), |
|
95 ASN1_SIMPLE(IPAddressFamily, ipAddressChoice, IPAddressChoice) |
|
96 } ASN1_SEQUENCE_END(IPAddressFamily) |
|
97 |
|
98 ASN1_ITEM_TEMPLATE(IPAddrBlocks) = |
|
99 ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, |
|
100 IPAddrBlocks, IPAddressFamily) |
|
101 ASN1_ITEM_TEMPLATE_END(IPAddrBlocks) |
|
102 |
|
103 IMPLEMENT_ASN1_FUNCTIONS(IPAddressRange) |
|
104 IMPLEMENT_ASN1_FUNCTIONS(IPAddressOrRange) |
|
105 IMPLEMENT_ASN1_FUNCTIONS(IPAddressChoice) |
|
106 IMPLEMENT_ASN1_FUNCTIONS(IPAddressFamily) |
|
107 |
|
108 /* |
|
109 * How much buffer space do we need for a raw address? |
|
110 */ |
|
111 #define ADDR_RAW_BUF_LEN 16 |
|
112 |
|
113 /* |
|
114 * What's the address length associated with this AFI? |
|
115 */ |
|
116 static int length_from_afi(const unsigned afi) |
|
117 { |
|
118 switch (afi) { |
|
119 case IANA_AFI_IPV4: |
|
120 return 4; |
|
121 case IANA_AFI_IPV6: |
|
122 return 16; |
|
123 default: |
|
124 return 0; |
|
125 } |
|
126 } |
|
127 |
|
128 /* |
|
129 * Extract the AFI from an IPAddressFamily. |
|
130 */ |
|
131 unsigned v3_addr_get_afi(const IPAddressFamily *f) |
|
132 { |
|
133 return ((f != NULL && |
|
134 f->addressFamily != NULL && |
|
135 f->addressFamily->data != NULL) |
|
136 ? ((f->addressFamily->data[0] << 8) | |
|
137 (f->addressFamily->data[1])) |
|
138 : 0); |
|
139 } |
|
140 |
|
141 /* |
|
142 * Expand the bitstring form of an address into a raw byte array. |
|
143 * At the moment this is coded for simplicity, not speed. |
|
144 */ |
|
145 static void addr_expand(unsigned char *addr, |
|
146 const ASN1_BIT_STRING *bs, |
|
147 const int length, |
|
148 const unsigned char fill) |
|
149 { |
|
150 assert(bs->length >= 0 && bs->length <= length); |
|
151 if (bs->length > 0) { |
|
152 memcpy(addr, bs->data, bs->length); |
|
153 if ((bs->flags & 7) != 0) { |
|
154 unsigned char mask = 0xFF >> (8 - (bs->flags & 7)); |
|
155 if (fill == 0) |
|
156 addr[bs->length - 1] &= ~mask; |
|
157 else |
|
158 addr[bs->length - 1] |= mask; |
|
159 } |
|
160 } |
|
161 memset(addr + bs->length, fill, length - bs->length); |
|
162 } |
|
163 |
|
164 /* |
|
165 * Extract the prefix length from a bitstring. |
|
166 */ |
|
167 #define addr_prefixlen(bs) ((int) ((bs)->length * 8 - ((bs)->flags & 7))) |
|
168 |
|
169 /* |
|
170 * i2r handler for one address bitstring. |
|
171 */ |
|
172 static int i2r_address(BIO *out, |
|
173 const unsigned afi, |
|
174 const unsigned char fill, |
|
175 const ASN1_BIT_STRING *bs) |
|
176 { |
|
177 unsigned char addr[ADDR_RAW_BUF_LEN]; |
|
178 int i, n; |
|
179 |
|
180 switch (afi) { |
|
181 case IANA_AFI_IPV4: |
|
182 addr_expand(addr, bs, 4, fill); |
|
183 BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]); |
|
184 break; |
|
185 case IANA_AFI_IPV6: |
|
186 addr_expand(addr, bs, 16, fill); |
|
187 for (n = 16; n > 1 && addr[n-1] == 0x00 && addr[n-2] == 0x00; n -= 2) |
|
188 ; |
|
189 for (i = 0; i < n; i += 2) |
|
190 BIO_printf(out, "%x%s", (addr[i] << 8) | addr[i+1], (i < 14 ? ":" : "")); |
|
191 if (i < 16) |
|
192 BIO_puts(out, ":"); |
|
193 break; |
|
194 default: |
|
195 for (i = 0; i < bs->length; i++) |
|
196 BIO_printf(out, "%s%02x", (i > 0 ? ":" : ""), bs->data[i]); |
|
197 BIO_printf(out, "[%d]", (int) (bs->flags & 7)); |
|
198 break; |
|
199 } |
|
200 return 1; |
|
201 } |
|
202 |
|
203 /* |
|
204 * i2r handler for a sequence of addresses and ranges. |
|
205 */ |
|
206 static int i2r_IPAddressOrRanges(BIO *out, |
|
207 const int indent, |
|
208 const IPAddressOrRanges *aors, |
|
209 const unsigned afi) |
|
210 { |
|
211 int i; |
|
212 for (i = 0; i < sk_IPAddressOrRange_num(aors); i++) { |
|
213 const IPAddressOrRange *aor = sk_IPAddressOrRange_value(aors, i); |
|
214 BIO_printf(out, "%*s", indent, ""); |
|
215 switch (aor->type) { |
|
216 case IPAddressOrRange_addressPrefix: |
|
217 if (!i2r_address(out, afi, 0x00, aor->u.addressPrefix)) |
|
218 return 0; |
|
219 BIO_printf(out, "/%d\n", addr_prefixlen(aor->u.addressPrefix)); |
|
220 continue; |
|
221 case IPAddressOrRange_addressRange: |
|
222 if (!i2r_address(out, afi, 0x00, aor->u.addressRange->min)) |
|
223 return 0; |
|
224 BIO_puts(out, "-"); |
|
225 if (!i2r_address(out, afi, 0xFF, aor->u.addressRange->max)) |
|
226 return 0; |
|
227 BIO_puts(out, "\n"); |
|
228 continue; |
|
229 } |
|
230 } |
|
231 return 1; |
|
232 } |
|
233 |
|
234 /* |
|
235 * i2r handler for an IPAddrBlocks extension. |
|
236 */ |
|
237 static int i2r_IPAddrBlocks(X509V3_EXT_METHOD *method, |
|
238 void *ext, |
|
239 BIO *out, |
|
240 int indent) |
|
241 { |
|
242 const IPAddrBlocks *addr = ext; |
|
243 int i; |
|
244 for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { |
|
245 IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); |
|
246 const unsigned afi = v3_addr_get_afi(f); |
|
247 switch (afi) { |
|
248 case IANA_AFI_IPV4: |
|
249 BIO_printf(out, "%*sIPv4", indent, ""); |
|
250 break; |
|
251 case IANA_AFI_IPV6: |
|
252 BIO_printf(out, "%*sIPv6", indent, ""); |
|
253 break; |
|
254 default: |
|
255 BIO_printf(out, "%*sUnknown AFI %u", indent, "", afi); |
|
256 break; |
|
257 } |
|
258 if (f->addressFamily->length > 2) { |
|
259 switch (f->addressFamily->data[2]) { |
|
260 case 1: |
|
261 BIO_puts(out, " (Unicast)"); |
|
262 break; |
|
263 case 2: |
|
264 BIO_puts(out, " (Multicast)"); |
|
265 break; |
|
266 case 3: |
|
267 BIO_puts(out, " (Unicast/Multicast)"); |
|
268 break; |
|
269 case 4: |
|
270 BIO_puts(out, " (MPLS)"); |
|
271 break; |
|
272 case 64: |
|
273 BIO_puts(out, " (Tunnel)"); |
|
274 break; |
|
275 case 65: |
|
276 BIO_puts(out, " (VPLS)"); |
|
277 break; |
|
278 case 66: |
|
279 BIO_puts(out, " (BGP MDT)"); |
|
280 break; |
|
281 case 128: |
|
282 BIO_puts(out, " (MPLS-labeled VPN)"); |
|
283 break; |
|
284 default: |
|
285 BIO_printf(out, " (Unknown SAFI %u)", |
|
286 (unsigned) f->addressFamily->data[2]); |
|
287 break; |
|
288 } |
|
289 } |
|
290 switch (f->ipAddressChoice->type) { |
|
291 case IPAddressChoice_inherit: |
|
292 BIO_puts(out, ": inherit\n"); |
|
293 break; |
|
294 case IPAddressChoice_addressesOrRanges: |
|
295 BIO_puts(out, ":\n"); |
|
296 if (!i2r_IPAddressOrRanges(out, |
|
297 indent + 2, |
|
298 f->ipAddressChoice->u.addressesOrRanges, |
|
299 afi)) |
|
300 return 0; |
|
301 break; |
|
302 } |
|
303 } |
|
304 return 1; |
|
305 } |
|
306 |
|
307 /* |
|
308 * Sort comparison function for a sequence of IPAddressOrRange |
|
309 * elements. |
|
310 */ |
|
311 static int IPAddressOrRange_cmp(const IPAddressOrRange *a, |
|
312 const IPAddressOrRange *b, |
|
313 const int length) |
|
314 { |
|
315 unsigned char addr_a[ADDR_RAW_BUF_LEN], addr_b[ADDR_RAW_BUF_LEN]; |
|
316 int prefixlen_a = 0; |
|
317 int prefixlen_b = 0; |
|
318 int r; |
|
319 |
|
320 switch (a->type) { |
|
321 case IPAddressOrRange_addressPrefix: |
|
322 addr_expand(addr_a, a->u.addressPrefix, length, 0x00); |
|
323 prefixlen_a = addr_prefixlen(a->u.addressPrefix); |
|
324 break; |
|
325 case IPAddressOrRange_addressRange: |
|
326 addr_expand(addr_a, a->u.addressRange->min, length, 0x00); |
|
327 prefixlen_a = length * 8; |
|
328 break; |
|
329 } |
|
330 |
|
331 switch (b->type) { |
|
332 case IPAddressOrRange_addressPrefix: |
|
333 addr_expand(addr_b, b->u.addressPrefix, length, 0x00); |
|
334 prefixlen_b = addr_prefixlen(b->u.addressPrefix); |
|
335 break; |
|
336 case IPAddressOrRange_addressRange: |
|
337 addr_expand(addr_b, b->u.addressRange->min, length, 0x00); |
|
338 prefixlen_b = length * 8; |
|
339 break; |
|
340 } |
|
341 |
|
342 if ((r = memcmp(addr_a, addr_b, length)) != 0) |
|
343 return r; |
|
344 else |
|
345 return prefixlen_a - prefixlen_b; |
|
346 } |
|
347 |
|
348 /* |
|
349 * IPv4-specific closure over IPAddressOrRange_cmp, since sk_sort() |
|
350 * comparision routines are only allowed two arguments. |
|
351 */ |
|
352 static int v4IPAddressOrRange_cmp(const IPAddressOrRange * const *a, |
|
353 const IPAddressOrRange * const *b) |
|
354 { |
|
355 return IPAddressOrRange_cmp(*a, *b, 4); |
|
356 } |
|
357 |
|
358 /* |
|
359 * IPv6-specific closure over IPAddressOrRange_cmp, since sk_sort() |
|
360 * comparision routines are only allowed two arguments. |
|
361 */ |
|
362 static int v6IPAddressOrRange_cmp(const IPAddressOrRange * const *a, |
|
363 const IPAddressOrRange * const *b) |
|
364 { |
|
365 return IPAddressOrRange_cmp(*a, *b, 16); |
|
366 } |
|
367 |
|
368 /* |
|
369 * Calculate whether a range collapses to a prefix. |
|
370 * See last paragraph of RFC 3779 2.2.3.7. |
|
371 */ |
|
372 static int range_should_be_prefix(const unsigned char *min, |
|
373 const unsigned char *max, |
|
374 const int length) |
|
375 { |
|
376 unsigned char mask; |
|
377 int i, j; |
|
378 |
|
379 for (i = 0; i < length && min[i] == max[i]; i++) |
|
380 ; |
|
381 for (j = length - 1; j >= 0 && min[j] == 0x00 && max[j] == 0xFF; j--) |
|
382 ; |
|
383 if (i < j) |
|
384 return -1; |
|
385 if (i > j) |
|
386 return i * 8; |
|
387 mask = min[i] ^ max[i]; |
|
388 switch (mask) { |
|
389 case 0x01: j = 7; break; |
|
390 case 0x03: j = 6; break; |
|
391 case 0x07: j = 5; break; |
|
392 case 0x0F: j = 4; break; |
|
393 case 0x1F: j = 3; break; |
|
394 case 0x3F: j = 2; break; |
|
395 case 0x7F: j = 1; break; |
|
396 default: return -1; |
|
397 } |
|
398 if ((min[i] & mask) != 0 || (max[i] & mask) != mask) |
|
399 return -1; |
|
400 else |
|
401 return i * 8 + j; |
|
402 } |
|
403 |
|
404 /* |
|
405 * Construct a prefix. |
|
406 */ |
|
407 static int make_addressPrefix(IPAddressOrRange **result, |
|
408 unsigned char *addr, |
|
409 const int prefixlen) |
|
410 { |
|
411 int bytelen = (prefixlen + 7) / 8, bitlen = prefixlen % 8; |
|
412 IPAddressOrRange *aor = IPAddressOrRange_new(); |
|
413 |
|
414 if (aor == NULL) |
|
415 return 0; |
|
416 aor->type = IPAddressOrRange_addressPrefix; |
|
417 if (aor->u.addressPrefix == NULL && |
|
418 (aor->u.addressPrefix = ASN1_BIT_STRING_new()) == NULL) |
|
419 goto err; |
|
420 if (!ASN1_BIT_STRING_set(aor->u.addressPrefix, addr, bytelen)) |
|
421 goto err; |
|
422 aor->u.addressPrefix->flags &= ~7; |
|
423 aor->u.addressPrefix->flags |= ASN1_STRING_FLAG_BITS_LEFT; |
|
424 if (bitlen > 0) { |
|
425 aor->u.addressPrefix->data[bytelen - 1] &= ~(0xFF >> bitlen); |
|
426 aor->u.addressPrefix->flags |= 8 - bitlen; |
|
427 } |
|
428 |
|
429 *result = aor; |
|
430 return 1; |
|
431 |
|
432 err: |
|
433 IPAddressOrRange_free(aor); |
|
434 return 0; |
|
435 } |
|
436 |
|
437 /* |
|
438 * Construct a range. If it can be expressed as a prefix, |
|
439 * return a prefix instead. Doing this here simplifies |
|
440 * the rest of the code considerably. |
|
441 */ |
|
442 static int make_addressRange(IPAddressOrRange **result, |
|
443 unsigned char *min, |
|
444 unsigned char *max, |
|
445 const int length) |
|
446 { |
|
447 IPAddressOrRange *aor; |
|
448 int i, prefixlen; |
|
449 |
|
450 if ((prefixlen = range_should_be_prefix(min, max, length)) >= 0) |
|
451 return make_addressPrefix(result, min, prefixlen); |
|
452 |
|
453 if ((aor = IPAddressOrRange_new()) == NULL) |
|
454 return 0; |
|
455 aor->type = IPAddressOrRange_addressRange; |
|
456 assert(aor->u.addressRange == NULL); |
|
457 if ((aor->u.addressRange = IPAddressRange_new()) == NULL) |
|
458 goto err; |
|
459 if (aor->u.addressRange->min == NULL && |
|
460 (aor->u.addressRange->min = ASN1_BIT_STRING_new()) == NULL) |
|
461 goto err; |
|
462 if (aor->u.addressRange->max == NULL && |
|
463 (aor->u.addressRange->max = ASN1_BIT_STRING_new()) == NULL) |
|
464 goto err; |
|
465 |
|
466 for (i = length; i > 0 && min[i - 1] == 0x00; --i) |
|
467 ; |
|
468 if (!ASN1_BIT_STRING_set(aor->u.addressRange->min, min, i)) |
|
469 goto err; |
|
470 aor->u.addressRange->min->flags &= ~7; |
|
471 aor->u.addressRange->min->flags |= ASN1_STRING_FLAG_BITS_LEFT; |
|
472 if (i > 0) { |
|
473 unsigned char b = min[i - 1]; |
|
474 int j = 1; |
|
475 while ((b & (0xFFU >> j)) != 0) |
|
476 ++j; |
|
477 aor->u.addressRange->min->flags |= 8 - j; |
|
478 } |
|
479 |
|
480 for (i = length; i > 0 && max[i - 1] == 0xFF; --i) |
|
481 ; |
|
482 if (!ASN1_BIT_STRING_set(aor->u.addressRange->max, max, i)) |
|
483 goto err; |
|
484 aor->u.addressRange->max->flags &= ~7; |
|
485 aor->u.addressRange->max->flags |= ASN1_STRING_FLAG_BITS_LEFT; |
|
486 if (i > 0) { |
|
487 unsigned char b = max[i - 1]; |
|
488 int j = 1; |
|
489 while ((b & (0xFFU >> j)) != (0xFFU >> j)) |
|
490 ++j; |
|
491 aor->u.addressRange->max->flags |= 8 - j; |
|
492 } |
|
493 |
|
494 *result = aor; |
|
495 return 1; |
|
496 |
|
497 err: |
|
498 IPAddressOrRange_free(aor); |
|
499 return 0; |
|
500 } |
|
501 |
|
502 /* |
|
503 * Construct a new address family or find an existing one. |
|
504 */ |
|
505 static IPAddressFamily *make_IPAddressFamily(IPAddrBlocks *addr, |
|
506 const unsigned afi, |
|
507 const unsigned *safi) |
|
508 { |
|
509 IPAddressFamily *f; |
|
510 unsigned char key[3]; |
|
511 unsigned keylen; |
|
512 int i; |
|
513 |
|
514 key[0] = (afi >> 8) & 0xFF; |
|
515 key[1] = afi & 0xFF; |
|
516 if (safi != NULL) { |
|
517 key[2] = *safi & 0xFF; |
|
518 keylen = 3; |
|
519 } else { |
|
520 keylen = 2; |
|
521 } |
|
522 |
|
523 for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { |
|
524 f = sk_IPAddressFamily_value(addr, i); |
|
525 assert(f->addressFamily->data != NULL); |
|
526 if (f->addressFamily->length == keylen && |
|
527 !memcmp(f->addressFamily->data, key, keylen)) |
|
528 return f; |
|
529 } |
|
530 |
|
531 if ((f = IPAddressFamily_new()) == NULL) |
|
532 goto err; |
|
533 if (f->ipAddressChoice == NULL && |
|
534 (f->ipAddressChoice = IPAddressChoice_new()) == NULL) |
|
535 goto err; |
|
536 if (f->addressFamily == NULL && |
|
537 (f->addressFamily = ASN1_OCTET_STRING_new()) == NULL) |
|
538 goto err; |
|
539 if (!ASN1_OCTET_STRING_set(f->addressFamily, key, keylen)) |
|
540 goto err; |
|
541 if (!sk_IPAddressFamily_push(addr, f)) |
|
542 goto err; |
|
543 |
|
544 return f; |
|
545 |
|
546 err: |
|
547 IPAddressFamily_free(f); |
|
548 return NULL; |
|
549 } |
|
550 |
|
551 /* |
|
552 * Add an inheritance element. |
|
553 */ |
|
554 int v3_addr_add_inherit(IPAddrBlocks *addr, |
|
555 const unsigned afi, |
|
556 const unsigned *safi) |
|
557 { |
|
558 IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi); |
|
559 if (f == NULL || |
|
560 f->ipAddressChoice == NULL || |
|
561 (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges && |
|
562 f->ipAddressChoice->u.addressesOrRanges != NULL)) |
|
563 return 0; |
|
564 if (f->ipAddressChoice->type == IPAddressChoice_inherit && |
|
565 f->ipAddressChoice->u.inherit != NULL) |
|
566 return 1; |
|
567 if (f->ipAddressChoice->u.inherit == NULL && |
|
568 (f->ipAddressChoice->u.inherit = ASN1_NULL_new()) == NULL) |
|
569 return 0; |
|
570 f->ipAddressChoice->type = IPAddressChoice_inherit; |
|
571 return 1; |
|
572 } |
|
573 |
|
574 /* |
|
575 * Construct an IPAddressOrRange sequence, or return an existing one. |
|
576 */ |
|
577 static IPAddressOrRanges *make_prefix_or_range(IPAddrBlocks *addr, |
|
578 const unsigned afi, |
|
579 const unsigned *safi) |
|
580 { |
|
581 IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi); |
|
582 IPAddressOrRanges *aors = NULL; |
|
583 |
|
584 if (f == NULL || |
|
585 f->ipAddressChoice == NULL || |
|
586 (f->ipAddressChoice->type == IPAddressChoice_inherit && |
|
587 f->ipAddressChoice->u.inherit != NULL)) |
|
588 return NULL; |
|
589 if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges) |
|
590 aors = f->ipAddressChoice->u.addressesOrRanges; |
|
591 if (aors != NULL) |
|
592 return aors; |
|
593 if ((aors = sk_IPAddressOrRange_new_null()) == NULL) |
|
594 return NULL; |
|
595 switch (afi) { |
|
596 case IANA_AFI_IPV4: |
|
597 sk_IPAddressOrRange_set_cmp_func(aors, v4IPAddressOrRange_cmp); |
|
598 break; |
|
599 case IANA_AFI_IPV6: |
|
600 sk_IPAddressOrRange_set_cmp_func(aors, v6IPAddressOrRange_cmp); |
|
601 break; |
|
602 } |
|
603 f->ipAddressChoice->type = IPAddressChoice_addressesOrRanges; |
|
604 f->ipAddressChoice->u.addressesOrRanges = aors; |
|
605 return aors; |
|
606 } |
|
607 |
|
608 /* |
|
609 * Add a prefix. |
|
610 */ |
|
611 int v3_addr_add_prefix(IPAddrBlocks *addr, |
|
612 const unsigned afi, |
|
613 const unsigned *safi, |
|
614 unsigned char *a, |
|
615 const int prefixlen) |
|
616 { |
|
617 IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi); |
|
618 IPAddressOrRange *aor; |
|
619 if (aors == NULL || !make_addressPrefix(&aor, a, prefixlen)) |
|
620 return 0; |
|
621 if (sk_IPAddressOrRange_push(aors, aor)) |
|
622 return 1; |
|
623 IPAddressOrRange_free(aor); |
|
624 return 0; |
|
625 } |
|
626 |
|
627 /* |
|
628 * Add a range. |
|
629 */ |
|
630 int v3_addr_add_range(IPAddrBlocks *addr, |
|
631 const unsigned afi, |
|
632 const unsigned *safi, |
|
633 unsigned char *min, |
|
634 unsigned char *max) |
|
635 { |
|
636 IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi); |
|
637 IPAddressOrRange *aor; |
|
638 int length = length_from_afi(afi); |
|
639 if (aors == NULL) |
|
640 return 0; |
|
641 if (!make_addressRange(&aor, min, max, length)) |
|
642 return 0; |
|
643 if (sk_IPAddressOrRange_push(aors, aor)) |
|
644 return 1; |
|
645 IPAddressOrRange_free(aor); |
|
646 return 0; |
|
647 } |
|
648 |
|
649 /* |
|
650 * Extract min and max values from an IPAddressOrRange. |
|
651 */ |
|
652 static void extract_min_max(IPAddressOrRange *aor, |
|
653 unsigned char *min, |
|
654 unsigned char *max, |
|
655 int length) |
|
656 { |
|
657 assert(aor != NULL && min != NULL && max != NULL); |
|
658 switch (aor->type) { |
|
659 case IPAddressOrRange_addressPrefix: |
|
660 addr_expand(min, aor->u.addressPrefix, length, 0x00); |
|
661 addr_expand(max, aor->u.addressPrefix, length, 0xFF); |
|
662 return; |
|
663 case IPAddressOrRange_addressRange: |
|
664 addr_expand(min, aor->u.addressRange->min, length, 0x00); |
|
665 addr_expand(max, aor->u.addressRange->max, length, 0xFF); |
|
666 return; |
|
667 } |
|
668 } |
|
669 |
|
670 /* |
|
671 * Public wrapper for extract_min_max(). |
|
672 */ |
|
673 int v3_addr_get_range(IPAddressOrRange *aor, |
|
674 const unsigned afi, |
|
675 unsigned char *min, |
|
676 unsigned char *max, |
|
677 const int length) |
|
678 { |
|
679 int afi_length = length_from_afi(afi); |
|
680 if (aor == NULL || min == NULL || max == NULL || |
|
681 afi_length == 0 || length < afi_length || |
|
682 (aor->type != IPAddressOrRange_addressPrefix && |
|
683 aor->type != IPAddressOrRange_addressRange)) |
|
684 return 0; |
|
685 extract_min_max(aor, min, max, afi_length); |
|
686 return afi_length; |
|
687 } |
|
688 |
|
689 /* |
|
690 * Sort comparision function for a sequence of IPAddressFamily. |
|
691 * |
|
692 * The last paragraph of RFC 3779 2.2.3.3 is slightly ambiguous about |
|
693 * the ordering: I can read it as meaning that IPv6 without a SAFI |
|
694 * comes before IPv4 with a SAFI, which seems pretty weird. The |
|
695 * examples in appendix B suggest that the author intended the |
|
696 * null-SAFI rule to apply only within a single AFI, which is what I |
|
697 * would have expected and is what the following code implements. |
|
698 */ |
|
699 static int IPAddressFamily_cmp(const IPAddressFamily * const *a_, |
|
700 const IPAddressFamily * const *b_) |
|
701 { |
|
702 const ASN1_OCTET_STRING *a = (*a_)->addressFamily; |
|
703 const ASN1_OCTET_STRING *b = (*b_)->addressFamily; |
|
704 int len = ((a->length <= b->length) ? a->length : b->length); |
|
705 int cmp = memcmp(a->data, b->data, len); |
|
706 return cmp ? cmp : a->length - b->length; |
|
707 } |
|
708 |
|
709 /* |
|
710 * Check whether an IPAddrBLocks is in canonical form. |
|
711 */ |
|
712 int v3_addr_is_canonical(IPAddrBlocks *addr) |
|
713 { |
|
714 unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; |
|
715 unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN]; |
|
716 IPAddressOrRanges *aors; |
|
717 int i, j, k; |
|
718 |
|
719 /* |
|
720 * Empty extension is cannonical. |
|
721 */ |
|
722 if (addr == NULL) |
|
723 return 1; |
|
724 |
|
725 /* |
|
726 * Check whether the top-level list is in order. |
|
727 */ |
|
728 for (i = 0; i < sk_IPAddressFamily_num(addr) - 1; i++) { |
|
729 const IPAddressFamily *a = sk_IPAddressFamily_value(addr, i); |
|
730 const IPAddressFamily *b = sk_IPAddressFamily_value(addr, i + 1); |
|
731 if (IPAddressFamily_cmp(&a, &b) >= 0) |
|
732 return 0; |
|
733 } |
|
734 |
|
735 /* |
|
736 * Top level's ok, now check each address family. |
|
737 */ |
|
738 for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { |
|
739 IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); |
|
740 int length = length_from_afi(v3_addr_get_afi(f)); |
|
741 |
|
742 /* |
|
743 * Inheritance is canonical. Anything other than inheritance or |
|
744 * a SEQUENCE OF IPAddressOrRange is an ASN.1 error or something. |
|
745 */ |
|
746 if (f == NULL || f->ipAddressChoice == NULL) |
|
747 return 0; |
|
748 switch (f->ipAddressChoice->type) { |
|
749 case IPAddressChoice_inherit: |
|
750 continue; |
|
751 case IPAddressChoice_addressesOrRanges: |
|
752 break; |
|
753 default: |
|
754 return 0; |
|
755 } |
|
756 |
|
757 /* |
|
758 * It's an IPAddressOrRanges sequence, check it. |
|
759 */ |
|
760 aors = f->ipAddressChoice->u.addressesOrRanges; |
|
761 if (sk_IPAddressOrRange_num(aors) == 0) |
|
762 return 0; |
|
763 for (j = 0; j < sk_IPAddressOrRange_num(aors) - 1; j++) { |
|
764 IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); |
|
765 IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, j + 1); |
|
766 |
|
767 extract_min_max(a, a_min, a_max, length); |
|
768 extract_min_max(b, b_min, b_max, length); |
|
769 |
|
770 /* |
|
771 * Punt misordered list, overlapping start, or inverted range. |
|
772 */ |
|
773 if (memcmp(a_min, b_min, length) >= 0 || |
|
774 memcmp(a_min, a_max, length) > 0 || |
|
775 memcmp(b_min, b_max, length) > 0) |
|
776 return 0; |
|
777 |
|
778 /* |
|
779 * Punt if adjacent or overlapping. Check for adjacency by |
|
780 * subtracting one from b_min first. |
|
781 */ |
|
782 for (k = length - 1; k >= 0 && b_min[k]-- == 0x00; k--) |
|
783 ; |
|
784 if (memcmp(a_max, b_min, length) >= 0) |
|
785 return 0; |
|
786 |
|
787 /* |
|
788 * Check for range that should be expressed as a prefix. |
|
789 */ |
|
790 if (a->type == IPAddressOrRange_addressRange && |
|
791 range_should_be_prefix(a_min, a_max, length) >= 0) |
|
792 return 0; |
|
793 } |
|
794 |
|
795 /* |
|
796 * Check final range to see if it should be a prefix. |
|
797 */ |
|
798 j = sk_IPAddressOrRange_num(aors) - 1; |
|
799 { |
|
800 IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); |
|
801 if (a->type == IPAddressOrRange_addressRange) { |
|
802 extract_min_max(a, a_min, a_max, length); |
|
803 if (range_should_be_prefix(a_min, a_max, length) >= 0) |
|
804 return 0; |
|
805 } |
|
806 } |
|
807 } |
|
808 |
|
809 /* |
|
810 * If we made it through all that, we're happy. |
|
811 */ |
|
812 return 1; |
|
813 } |
|
814 |
|
815 /* |
|
816 * Whack an IPAddressOrRanges into canonical form. |
|
817 */ |
|
818 static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors, |
|
819 const unsigned afi) |
|
820 { |
|
821 int i, j, length = length_from_afi(afi); |
|
822 |
|
823 /* |
|
824 * Sort the IPAddressOrRanges sequence. |
|
825 */ |
|
826 sk_IPAddressOrRange_sort(aors); |
|
827 |
|
828 /* |
|
829 * Clean up representation issues, punt on duplicates or overlaps. |
|
830 */ |
|
831 for (i = 0; i < sk_IPAddressOrRange_num(aors) - 1; i++) { |
|
832 IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, i); |
|
833 IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, i + 1); |
|
834 unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; |
|
835 unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN]; |
|
836 |
|
837 extract_min_max(a, a_min, a_max, length); |
|
838 extract_min_max(b, b_min, b_max, length); |
|
839 |
|
840 /* |
|
841 * Punt overlaps. |
|
842 */ |
|
843 if (memcmp(a_max, b_min, length) >= 0) |
|
844 return 0; |
|
845 |
|
846 /* |
|
847 * Merge if a and b are adjacent. We check for |
|
848 * adjacency by subtracting one from b_min first. |
|
849 */ |
|
850 for (j = length - 1; j >= 0 && b_min[j]-- == 0x00; j--) |
|
851 ; |
|
852 if (memcmp(a_max, b_min, length) == 0) { |
|
853 IPAddressOrRange *merged; |
|
854 if (!make_addressRange(&merged, a_min, b_max, length)) |
|
855 return 0; |
|
856 sk_IPAddressOrRange_set(aors, i, merged); |
|
857 sk_IPAddressOrRange_delete(aors, i + 1); |
|
858 IPAddressOrRange_free(a); |
|
859 IPAddressOrRange_free(b); |
|
860 --i; |
|
861 continue; |
|
862 } |
|
863 } |
|
864 |
|
865 return 1; |
|
866 } |
|
867 |
|
868 /* |
|
869 * Whack an IPAddrBlocks extension into canonical form. |
|
870 */ |
|
871 int v3_addr_canonize(IPAddrBlocks *addr) |
|
872 { |
|
873 int i; |
|
874 for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { |
|
875 IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); |
|
876 if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges && |
|
877 !IPAddressOrRanges_canonize(f->ipAddressChoice->u.addressesOrRanges, |
|
878 v3_addr_get_afi(f))) |
|
879 return 0; |
|
880 } |
|
881 sk_IPAddressFamily_sort(addr); |
|
882 assert(v3_addr_is_canonical(addr)); |
|
883 return 1; |
|
884 } |
|
885 |
|
886 /* |
|
887 * v2i handler for the IPAddrBlocks extension. |
|
888 */ |
|
889 static void *v2i_IPAddrBlocks(struct v3_ext_method *method, |
|
890 struct v3_ext_ctx *ctx, |
|
891 STACK_OF(CONF_VALUE) *values) |
|
892 { |
|
893 static const char v4addr_chars[] = "0123456789."; |
|
894 static const char v6addr_chars[] = "0123456789.:abcdefABCDEF"; |
|
895 IPAddrBlocks *addr = NULL; |
|
896 char *s = NULL, *t; |
|
897 int i; |
|
898 |
|
899 if ((addr = sk_IPAddressFamily_new(IPAddressFamily_cmp)) == NULL) { |
|
900 X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); |
|
901 return NULL; |
|
902 } |
|
903 |
|
904 for (i = 0; i < sk_CONF_VALUE_num(values); i++) { |
|
905 CONF_VALUE *val = sk_CONF_VALUE_value(values, i); |
|
906 unsigned char min[ADDR_RAW_BUF_LEN], max[ADDR_RAW_BUF_LEN]; |
|
907 unsigned afi, *safi = NULL, safi_; |
|
908 const char *addr_chars; |
|
909 int prefixlen, i1, i2, delim, length; |
|
910 |
|
911 if ( !name_cmp(val->name, "IPv4")) { |
|
912 afi = IANA_AFI_IPV4; |
|
913 } else if (!name_cmp(val->name, "IPv6")) { |
|
914 afi = IANA_AFI_IPV6; |
|
915 } else if (!name_cmp(val->name, "IPv4-SAFI")) { |
|
916 afi = IANA_AFI_IPV4; |
|
917 safi = &safi_; |
|
918 } else if (!name_cmp(val->name, "IPv6-SAFI")) { |
|
919 afi = IANA_AFI_IPV6; |
|
920 safi = &safi_; |
|
921 } else { |
|
922 X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_NAME_ERROR); |
|
923 X509V3_conf_err(val); |
|
924 goto err; |
|
925 } |
|
926 |
|
927 switch (afi) { |
|
928 case IANA_AFI_IPV4: |
|
929 addr_chars = v4addr_chars; |
|
930 break; |
|
931 case IANA_AFI_IPV6: |
|
932 addr_chars = v6addr_chars; |
|
933 break; |
|
934 } |
|
935 |
|
936 length = length_from_afi(afi); |
|
937 |
|
938 /* |
|
939 * Handle SAFI, if any, and BUF_strdup() so we can null-terminate |
|
940 * the other input values. |
|
941 */ |
|
942 if (safi != NULL) { |
|
943 *safi = strtoul(val->value, &t, 0); |
|
944 t += strspn(t, " \t"); |
|
945 if (*safi > 0xFF || *t++ != ':') { |
|
946 X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_SAFI); |
|
947 X509V3_conf_err(val); |
|
948 goto err; |
|
949 } |
|
950 t += strspn(t, " \t"); |
|
951 s = BUF_strdup(t); |
|
952 } else { |
|
953 s = BUF_strdup(val->value); |
|
954 } |
|
955 if (s == NULL) { |
|
956 X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); |
|
957 goto err; |
|
958 } |
|
959 |
|
960 /* |
|
961 * Check for inheritance. Not worth additional complexity to |
|
962 * optimize this (seldom-used) case. |
|
963 */ |
|
964 if (!strcmp(s, "inherit")) { |
|
965 if (!v3_addr_add_inherit(addr, afi, safi)) { |
|
966 X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_INHERITANCE); |
|
967 X509V3_conf_err(val); |
|
968 goto err; |
|
969 } |
|
970 OPENSSL_free(s); |
|
971 s = NULL; |
|
972 continue; |
|
973 } |
|
974 |
|
975 i1 = strspn(s, addr_chars); |
|
976 i2 = i1 + strspn(s + i1, " \t"); |
|
977 delim = s[i2++]; |
|
978 s[i1] = '\0'; |
|
979 |
|
980 if (a2i_ipadd(min, s) != length) { |
|
981 X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_IPADDRESS); |
|
982 X509V3_conf_err(val); |
|
983 goto err; |
|
984 } |
|
985 |
|
986 switch (delim) { |
|
987 case '/': |
|
988 prefixlen = (int) strtoul(s + i2, &t, 10); |
|
989 if (t == s + i2 || *t != '\0') { |
|
990 X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR); |
|
991 X509V3_conf_err(val); |
|
992 goto err; |
|
993 } |
|
994 if (!v3_addr_add_prefix(addr, afi, safi, min, prefixlen)) { |
|
995 X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); |
|
996 goto err; |
|
997 } |
|
998 break; |
|
999 case '-': |
|
1000 i1 = i2 + strspn(s + i2, " \t"); |
|
1001 i2 = i1 + strspn(s + i1, addr_chars); |
|
1002 if (i1 == i2 || s[i2] != '\0') { |
|
1003 X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR); |
|
1004 X509V3_conf_err(val); |
|
1005 goto err; |
|
1006 } |
|
1007 if (a2i_ipadd(max, s + i1) != length) { |
|
1008 X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_IPADDRESS); |
|
1009 X509V3_conf_err(val); |
|
1010 goto err; |
|
1011 } |
|
1012 if (!v3_addr_add_range(addr, afi, safi, min, max)) { |
|
1013 X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); |
|
1014 goto err; |
|
1015 } |
|
1016 break; |
|
1017 case '\0': |
|
1018 if (!v3_addr_add_prefix(addr, afi, safi, min, length * 8)) { |
|
1019 X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); |
|
1020 goto err; |
|
1021 } |
|
1022 break; |
|
1023 default: |
|
1024 X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR); |
|
1025 X509V3_conf_err(val); |
|
1026 goto err; |
|
1027 } |
|
1028 |
|
1029 OPENSSL_free(s); |
|
1030 s = NULL; |
|
1031 } |
|
1032 |
|
1033 /* |
|
1034 * Canonize the result, then we're done. |
|
1035 */ |
|
1036 if (!v3_addr_canonize(addr)) |
|
1037 goto err; |
|
1038 return addr; |
|
1039 |
|
1040 err: |
|
1041 OPENSSL_free(s); |
|
1042 sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free); |
|
1043 return NULL; |
|
1044 } |
|
1045 |
|
1046 /* |
|
1047 * OpenSSL dispatch |
|
1048 */ |
|
1049 const X509V3_EXT_METHOD v3_addr = { |
|
1050 NID_sbgp_ipAddrBlock, /* nid */ |
|
1051 0, /* flags */ |
|
1052 ASN1_ITEM_ref(IPAddrBlocks), /* template */ |
|
1053 0, 0, 0, 0, /* old functions, ignored */ |
|
1054 0, /* i2s */ |
|
1055 0, /* s2i */ |
|
1056 0, /* i2v */ |
|
1057 v2i_IPAddrBlocks, /* v2i */ |
|
1058 i2r_IPAddrBlocks, /* i2r */ |
|
1059 0, /* r2i */ |
|
1060 NULL /* extension-specific data */ |
|
1061 }; |
|
1062 |
|
1063 /* |
|
1064 * Figure out whether extension sues inheritance. |
|
1065 */ |
|
1066 int v3_addr_inherits(IPAddrBlocks *addr) |
|
1067 { |
|
1068 int i; |
|
1069 if (addr == NULL) |
|
1070 return 0; |
|
1071 for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { |
|
1072 IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); |
|
1073 if (f->ipAddressChoice->type == IPAddressChoice_inherit) |
|
1074 return 1; |
|
1075 } |
|
1076 return 0; |
|
1077 } |
|
1078 |
|
1079 /* |
|
1080 * Figure out whether parent contains child. |
|
1081 */ |
|
1082 static int addr_contains(IPAddressOrRanges *parent, |
|
1083 IPAddressOrRanges *child, |
|
1084 int length) |
|
1085 { |
|
1086 unsigned char p_min[ADDR_RAW_BUF_LEN], p_max[ADDR_RAW_BUF_LEN]; |
|
1087 unsigned char c_min[ADDR_RAW_BUF_LEN], c_max[ADDR_RAW_BUF_LEN]; |
|
1088 int p, c; |
|
1089 |
|
1090 if (child == NULL || parent == child) |
|
1091 return 1; |
|
1092 if (parent == NULL) |
|
1093 return 0; |
|
1094 |
|
1095 p = 0; |
|
1096 for (c = 0; c < sk_IPAddressOrRange_num(child); c++) { |
|
1097 extract_min_max(sk_IPAddressOrRange_value(child, c), |
|
1098 c_min, c_max, length); |
|
1099 for (;; p++) { |
|
1100 if (p >= sk_IPAddressOrRange_num(parent)) |
|
1101 return 0; |
|
1102 extract_min_max(sk_IPAddressOrRange_value(parent, p), |
|
1103 p_min, p_max, length); |
|
1104 if (memcmp(p_max, c_max, length) < 0) |
|
1105 continue; |
|
1106 if (memcmp(p_min, c_min, length) > 0) |
|
1107 return 0; |
|
1108 break; |
|
1109 } |
|
1110 } |
|
1111 |
|
1112 return 1; |
|
1113 } |
|
1114 |
|
1115 /* |
|
1116 * Test whether a is a subset of b. |
|
1117 */ |
|
1118 int v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b) |
|
1119 { |
|
1120 int i; |
|
1121 if (a == NULL || a == b) |
|
1122 return 1; |
|
1123 if (b == NULL || v3_addr_inherits(a) || v3_addr_inherits(b)) |
|
1124 return 0; |
|
1125 sk_IPAddressFamily_set_cmp_func(b, IPAddressFamily_cmp); |
|
1126 for (i = 0; i < sk_IPAddressFamily_num(a); i++) { |
|
1127 IPAddressFamily *fa = sk_IPAddressFamily_value(a, i); |
|
1128 int j = sk_IPAddressFamily_find(b, fa); |
|
1129 IPAddressFamily *fb = sk_IPAddressFamily_value(b, j); |
|
1130 if (!addr_contains(fb->ipAddressChoice->u.addressesOrRanges, |
|
1131 fa->ipAddressChoice->u.addressesOrRanges, |
|
1132 length_from_afi(v3_addr_get_afi(fb)))) |
|
1133 return 0; |
|
1134 } |
|
1135 return 1; |
|
1136 } |
|
1137 |
|
1138 /* |
|
1139 * Validation error handling via callback. |
|
1140 */ |
|
1141 #define validation_err(_err_) \ |
|
1142 do { \ |
|
1143 if (ctx != NULL) { \ |
|
1144 ctx->error = _err_; \ |
|
1145 ctx->error_depth = i; \ |
|
1146 ctx->current_cert = x; \ |
|
1147 ret = ctx->verify_cb(0, ctx); \ |
|
1148 } else { \ |
|
1149 ret = 0; \ |
|
1150 } \ |
|
1151 if (!ret) \ |
|
1152 goto done; \ |
|
1153 } while (0) |
|
1154 |
|
1155 /* |
|
1156 * Core code for RFC 3779 2.3 path validation. |
|
1157 */ |
|
1158 static int v3_addr_validate_path_internal(X509_STORE_CTX *ctx, |
|
1159 STACK_OF(X509) *chain, |
|
1160 IPAddrBlocks *ext) |
|
1161 { |
|
1162 IPAddrBlocks *child = NULL; |
|
1163 int i, j, ret = 1; |
|
1164 X509 *x = NULL; |
|
1165 |
|
1166 assert(chain != NULL && sk_X509_num(chain) > 0); |
|
1167 assert(ctx != NULL || ext != NULL); |
|
1168 assert(ctx == NULL || ctx->verify_cb != NULL); |
|
1169 |
|
1170 /* |
|
1171 * Figure out where to start. If we don't have an extension to |
|
1172 * check, we're done. Otherwise, check canonical form and |
|
1173 * set up for walking up the chain. |
|
1174 */ |
|
1175 if (ext != NULL) { |
|
1176 i = -1; |
|
1177 } else { |
|
1178 i = 0; |
|
1179 x = sk_X509_value(chain, i); |
|
1180 assert(x != NULL); |
|
1181 if ((ext = x->rfc3779_addr) == NULL) |
|
1182 goto done; |
|
1183 } |
|
1184 if (!v3_addr_is_canonical(ext)) |
|
1185 validation_err(X509_V_ERR_INVALID_EXTENSION); |
|
1186 sk_IPAddressFamily_set_cmp_func(ext, IPAddressFamily_cmp); |
|
1187 if ((child = sk_IPAddressFamily_dup(ext)) == NULL) { |
|
1188 X509V3err(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL, ERR_R_MALLOC_FAILURE); |
|
1189 ret = 0; |
|
1190 goto done; |
|
1191 } |
|
1192 |
|
1193 /* |
|
1194 * Now walk up the chain. No cert may list resources that its |
|
1195 * parent doesn't list. |
|
1196 */ |
|
1197 for (i++; i < sk_X509_num(chain); i++) { |
|
1198 x = sk_X509_value(chain, i); |
|
1199 assert(x != NULL); |
|
1200 if (!v3_addr_is_canonical(x->rfc3779_addr)) |
|
1201 validation_err(X509_V_ERR_INVALID_EXTENSION); |
|
1202 if (x->rfc3779_addr == NULL) { |
|
1203 for (j = 0; j < sk_IPAddressFamily_num(child); j++) { |
|
1204 IPAddressFamily *fc = sk_IPAddressFamily_value(child, j); |
|
1205 if (fc->ipAddressChoice->type != IPAddressChoice_inherit) { |
|
1206 validation_err(X509_V_ERR_UNNESTED_RESOURCE); |
|
1207 break; |
|
1208 } |
|
1209 } |
|
1210 continue; |
|
1211 } |
|
1212 sk_IPAddressFamily_set_cmp_func(x->rfc3779_addr, IPAddressFamily_cmp); |
|
1213 for (j = 0; j < sk_IPAddressFamily_num(child); j++) { |
|
1214 IPAddressFamily *fc = sk_IPAddressFamily_value(child, j); |
|
1215 int k = sk_IPAddressFamily_find(x->rfc3779_addr, fc); |
|
1216 IPAddressFamily *fp = sk_IPAddressFamily_value(x->rfc3779_addr, k); |
|
1217 if (fp == NULL) { |
|
1218 if (fc->ipAddressChoice->type == IPAddressChoice_addressesOrRanges) { |
|
1219 validation_err(X509_V_ERR_UNNESTED_RESOURCE); |
|
1220 break; |
|
1221 } |
|
1222 continue; |
|
1223 } |
|
1224 if (fp->ipAddressChoice->type == IPAddressChoice_addressesOrRanges) { |
|
1225 if (fc->ipAddressChoice->type == IPAddressChoice_inherit || |
|
1226 addr_contains(fp->ipAddressChoice->u.addressesOrRanges, |
|
1227 fc->ipAddressChoice->u.addressesOrRanges, |
|
1228 length_from_afi(v3_addr_get_afi(fc)))) |
|
1229 sk_IPAddressFamily_set(child, j, fp); |
|
1230 else |
|
1231 validation_err(X509_V_ERR_UNNESTED_RESOURCE); |
|
1232 } |
|
1233 } |
|
1234 } |
|
1235 |
|
1236 /* |
|
1237 * Trust anchor can't inherit. |
|
1238 */ |
|
1239 if (x->rfc3779_addr != NULL) { |
|
1240 for (j = 0; j < sk_IPAddressFamily_num(x->rfc3779_addr); j++) { |
|
1241 IPAddressFamily *fp = sk_IPAddressFamily_value(x->rfc3779_addr, j); |
|
1242 if (fp->ipAddressChoice->type == IPAddressChoice_inherit && |
|
1243 sk_IPAddressFamily_find(child, fp) >= 0) |
|
1244 validation_err(X509_V_ERR_UNNESTED_RESOURCE); |
|
1245 } |
|
1246 } |
|
1247 |
|
1248 done: |
|
1249 sk_IPAddressFamily_free(child); |
|
1250 return ret; |
|
1251 } |
|
1252 |
|
1253 #undef validation_err |
|
1254 |
|
1255 /* |
|
1256 * RFC 3779 2.3 path validation -- called from X509_verify_cert(). |
|
1257 */ |
|
1258 int v3_addr_validate_path(X509_STORE_CTX *ctx) |
|
1259 { |
|
1260 return v3_addr_validate_path_internal(ctx, ctx->chain, NULL); |
|
1261 } |
|
1262 |
|
1263 /* |
|
1264 * RFC 3779 2.3 path validation of an extension. |
|
1265 * Test whether chain covers extension. |
|
1266 */ |
|
1267 int v3_addr_validate_resource_set(STACK_OF(X509) *chain, |
|
1268 IPAddrBlocks *ext, |
|
1269 int allow_inheritance) |
|
1270 { |
|
1271 if (ext == NULL) |
|
1272 return 1; |
|
1273 if (chain == NULL || sk_X509_num(chain) == 0) |
|
1274 return 0; |
|
1275 if (!allow_inheritance && v3_addr_inherits(ext)) |
|
1276 return 0; |
|
1277 return v3_addr_validate_path_internal(NULL, chain, ext); |
|
1278 } |
|
1279 |
|
1280 #endif /* OPENSSL_NO_RFC3779 */ |