diff options
author | tb <> | 2022-01-04 19:49:14 +0000 |
---|---|---|
committer | tb <> | 2022-01-04 19:49:14 +0000 |
commit | 2609e55a77d1488ed932d4761f5b4025e6fadf9e (patch) | |
tree | f41760428438f1975b56a220f807c6dd43e7bc59 /src/lib | |
parent | 1a7cc6fb282b8ea2dda029734dc811a2b8be05aa (diff) | |
download | openbsd-2609e55a77d1488ed932d4761f5b4025e6fadf9e.tar.gz openbsd-2609e55a77d1488ed932d4761f5b4025e6fadf9e.tar.bz2 openbsd-2609e55a77d1488ed932d4761f5b4025e6fadf9e.zip |
Refactor IPAddressFamily accessors
Introduce a helper function that allows fetching the AFI and the
optional SAFI out of an IPAddressFamily. Also add two wrappers that
only fetch and validate the AFI, where validation currently only
means that the length is between 2 and 3.
Use these accessors throughout to simplify and streamline the code.
ok inoguchi jsing
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libcrypto/x509/x509_addr.c | 127 |
1 files changed, 90 insertions, 37 deletions
diff --git a/src/lib/libcrypto/x509/x509_addr.c b/src/lib/libcrypto/x509/x509_addr.c index f4e534a6ad..de4e42acde 100644 --- a/src/lib/libcrypto/x509/x509_addr.c +++ b/src/lib/libcrypto/x509/x509_addr.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: x509_addr.c,v 1.47 2021/12/28 21:23:40 tb Exp $ */ | 1 | /* $OpenBSD: x509_addr.c,v 1.48 2022/01/04 19:49:14 tb Exp $ */ |
2 | /* | 2 | /* |
3 | * Contributed to the OpenSSL Project by the American Registry for | 3 | * Contributed to the OpenSSL Project by the American Registry for |
4 | * Internet Numbers ("ARIN"). | 4 | * Internet Numbers ("ARIN"). |
@@ -78,8 +78,6 @@ | |||
78 | 78 | ||
79 | #ifndef OPENSSL_NO_RFC3779 | 79 | #ifndef OPENSSL_NO_RFC3779 |
80 | 80 | ||
81 | static int length_from_afi(const unsigned afi); | ||
82 | |||
83 | /* | 81 | /* |
84 | * OpenSSL ASN.1 template translation of RFC 3779 2.2.3. | 82 | * OpenSSL ASN.1 template translation of RFC 3779 2.2.3. |
85 | */ | 83 | */ |
@@ -364,21 +362,6 @@ IPAddressFamily_set_inheritance(IPAddressFamily *f) | |||
364 | return 1; | 362 | return 1; |
365 | } | 363 | } |
366 | 364 | ||
367 | static int | ||
368 | IPAddressFamily_afi_length(const IPAddressFamily *f, int *out_length) | ||
369 | { | ||
370 | unsigned int afi; | ||
371 | |||
372 | *out_length = 0; | ||
373 | |||
374 | if ((afi = X509v3_addr_get_afi(f)) == 0) | ||
375 | return 0; | ||
376 | |||
377 | *out_length = length_from_afi(afi); | ||
378 | |||
379 | return 1; | ||
380 | } | ||
381 | |||
382 | /* | 365 | /* |
383 | * How much buffer space do we need for a raw address? | 366 | * How much buffer space do we need for a raw address? |
384 | */ | 367 | */ |
@@ -401,6 +384,75 @@ length_from_afi(const unsigned afi) | |||
401 | } | 384 | } |
402 | 385 | ||
403 | /* | 386 | /* |
387 | * Get AFI and optional SAFI from an IPAddressFamily. All three out arguments | ||
388 | * are optional; if |out_safi| is non-NULL, |safi_is_set| must be non-NULL. | ||
389 | */ | ||
390 | static int | ||
391 | IPAddressFamily_afi_safi(const IPAddressFamily *f, uint16_t *out_afi, | ||
392 | uint8_t *out_safi, int *safi_is_set) | ||
393 | { | ||
394 | CBS cbs; | ||
395 | uint16_t afi; | ||
396 | uint8_t safi = 0; | ||
397 | int got_safi = 0; | ||
398 | |||
399 | CBS_init(&cbs, f->addressFamily->data, f->addressFamily->length); | ||
400 | |||
401 | if (!CBS_get_u16(&cbs, &afi)) | ||
402 | return 0; | ||
403 | |||
404 | /* Fetch the optional SAFI. */ | ||
405 | if (CBS_len(&cbs) != 0) { | ||
406 | if (!CBS_get_u8(&cbs, &safi)) | ||
407 | return 0; | ||
408 | got_safi = 1; | ||
409 | } | ||
410 | |||
411 | /* If there's anything left, it's garbage. */ | ||
412 | if (CBS_len(&cbs) != 0) | ||
413 | return 0; | ||
414 | |||
415 | /* XXX - error on reserved AFI/SAFI? */ | ||
416 | |||
417 | if (out_afi != NULL) | ||
418 | *out_afi = afi; | ||
419 | |||
420 | if (out_safi != NULL) { | ||
421 | *out_safi = safi; | ||
422 | *safi_is_set = got_safi; | ||
423 | } | ||
424 | |||
425 | return 1; | ||
426 | } | ||
427 | |||
428 | static int | ||
429 | IPAddressFamily_afi(const IPAddressFamily *f, uint16_t *out_afi) | ||
430 | { | ||
431 | return IPAddressFamily_afi_safi(f, out_afi, NULL, NULL); | ||
432 | } | ||
433 | |||
434 | static int | ||
435 | IPAddressFamily_afi_is_valid(const IPAddressFamily *f) | ||
436 | { | ||
437 | return IPAddressFamily_afi_safi(f, NULL, NULL, NULL); | ||
438 | } | ||
439 | |||
440 | static int | ||
441 | IPAddressFamily_afi_length(const IPAddressFamily *f, int *out_length) | ||
442 | { | ||
443 | uint16_t afi; | ||
444 | |||
445 | *out_length = 0; | ||
446 | |||
447 | if (!IPAddressFamily_afi(f, &afi)) | ||
448 | return 0; | ||
449 | |||
450 | *out_length = length_from_afi(afi); | ||
451 | |||
452 | return 1; | ||
453 | } | ||
454 | |||
455 | /* | ||
404 | * Extract the AFI from an IPAddressFamily. | 456 | * Extract the AFI from an IPAddressFamily. |
405 | * | 457 | * |
406 | * This is public API. It uses the reserved AFI 0 as an in-band error | 458 | * This is public API. It uses the reserved AFI 0 as an in-band error |
@@ -409,7 +461,6 @@ length_from_afi(const unsigned afi) | |||
409 | unsigned int | 461 | unsigned int |
410 | X509v3_addr_get_afi(const IPAddressFamily *f) | 462 | X509v3_addr_get_afi(const IPAddressFamily *f) |
411 | { | 463 | { |
412 | CBS cbs; | ||
413 | uint16_t afi; | 464 | uint16_t afi; |
414 | 465 | ||
415 | /* | 466 | /* |
@@ -420,13 +471,7 @@ X509v3_addr_get_afi(const IPAddressFamily *f) | |||
420 | f->addressFamily->data == NULL) | 471 | f->addressFamily->data == NULL) |
421 | return 0; | 472 | return 0; |
422 | 473 | ||
423 | CBS_init(&cbs, f->addressFamily->data, f->addressFamily->length); | 474 | if (!IPAddressFamily_afi(f, &afi)) |
424 | |||
425 | if (!CBS_get_u16(&cbs, &afi)) | ||
426 | return 0; | ||
427 | |||
428 | /* One byte for the optional SAFI, everything else is garbage. */ | ||
429 | if (CBS_len(&cbs) > 1) | ||
430 | return 0; | 475 | return 0; |
431 | 476 | ||
432 | return afi; | 477 | return afi; |
@@ -556,10 +601,17 @@ i2r_IPAddrBlocks(const X509V3_EXT_METHOD *method, void *ext, BIO *out, | |||
556 | int indent) | 601 | int indent) |
557 | { | 602 | { |
558 | const IPAddrBlocks *addr = ext; | 603 | const IPAddrBlocks *addr = ext; |
559 | int i; | 604 | IPAddressFamily *f; |
605 | uint16_t afi; | ||
606 | uint8_t safi; | ||
607 | int i, safi_is_set; | ||
608 | |||
560 | for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { | 609 | for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { |
561 | IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); | 610 | f = sk_IPAddressFamily_value(addr, i); |
562 | const unsigned int afi = X509v3_addr_get_afi(f); | 611 | |
612 | if (!IPAddressFamily_afi_safi(f, &afi, &safi, &safi_is_set)) | ||
613 | goto print_addresses; | ||
614 | |||
563 | switch (afi) { | 615 | switch (afi) { |
564 | case IANA_AFI_IPV4: | 616 | case IANA_AFI_IPV4: |
565 | BIO_printf(out, "%*sIPv4", indent, ""); | 617 | BIO_printf(out, "%*sIPv4", indent, ""); |
@@ -571,8 +623,8 @@ i2r_IPAddrBlocks(const X509V3_EXT_METHOD *method, void *ext, BIO *out, | |||
571 | BIO_printf(out, "%*sUnknown AFI %u", indent, "", afi); | 623 | BIO_printf(out, "%*sUnknown AFI %u", indent, "", afi); |
572 | break; | 624 | break; |
573 | } | 625 | } |
574 | if (f->addressFamily->length > 2) { | 626 | if (safi_is_set) { |
575 | switch (f->addressFamily->data[2]) { | 627 | switch (safi) { |
576 | case 1: | 628 | case 1: |
577 | BIO_puts(out, " (Unicast)"); | 629 | BIO_puts(out, " (Unicast)"); |
578 | break; | 630 | break; |
@@ -598,11 +650,12 @@ i2r_IPAddrBlocks(const X509V3_EXT_METHOD *method, void *ext, BIO *out, | |||
598 | BIO_puts(out, " (MPLS-labeled VPN)"); | 650 | BIO_puts(out, " (MPLS-labeled VPN)"); |
599 | break; | 651 | break; |
600 | default: | 652 | default: |
601 | BIO_printf(out, " (Unknown SAFI %u)", | 653 | BIO_printf(out, " (Unknown SAFI %u)", safi); |
602 | (unsigned)f->addressFamily->data[2]); | ||
603 | break; | 654 | break; |
604 | } | 655 | } |
605 | } | 656 | } |
657 | |||
658 | print_addresses: | ||
606 | switch (IPAddressFamily_type(f)) { | 659 | switch (IPAddressFamily_type(f)) { |
607 | case IPAddressChoice_inherit: | 660 | case IPAddressChoice_inherit: |
608 | BIO_puts(out, ": inherit\n"); | 661 | BIO_puts(out, ": inherit\n"); |
@@ -1096,9 +1149,9 @@ X509v3_addr_is_canonical(IPAddrBlocks *addr) | |||
1096 | const IPAddressFamily *b = sk_IPAddressFamily_value(addr, i + 1); | 1149 | const IPAddressFamily *b = sk_IPAddressFamily_value(addr, i + 1); |
1097 | 1150 | ||
1098 | /* Check that both have valid AFIs before comparing them. */ | 1151 | /* Check that both have valid AFIs before comparing them. */ |
1099 | if (X509v3_addr_get_afi(a) == 0) | 1152 | if (!IPAddressFamily_afi_is_valid(a)) |
1100 | return 0; | 1153 | return 0; |
1101 | if (X509v3_addr_get_afi(b) == 0) | 1154 | if (!IPAddressFamily_afi_is_valid(b)) |
1102 | return 0; | 1155 | return 0; |
1103 | 1156 | ||
1104 | if (IPAddressFamily_cmp(&a, &b) >= 0) | 1157 | if (IPAddressFamily_cmp(&a, &b) >= 0) |
@@ -1276,14 +1329,14 @@ X509v3_addr_canonize(IPAddrBlocks *addr) | |||
1276 | { | 1329 | { |
1277 | IPAddressFamily *f; | 1330 | IPAddressFamily *f; |
1278 | IPAddressOrRanges *aors; | 1331 | IPAddressOrRanges *aors; |
1279 | unsigned int afi; | 1332 | uint16_t afi; |
1280 | int i; | 1333 | int i; |
1281 | 1334 | ||
1282 | for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { | 1335 | for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { |
1283 | f = sk_IPAddressFamily_value(addr, i); | 1336 | f = sk_IPAddressFamily_value(addr, i); |
1284 | 1337 | ||
1285 | /* Check AFI/SAFI here - IPAddressFamily_cmp() can't error. */ | 1338 | /* Check AFI/SAFI here - IPAddressFamily_cmp() can't error. */ |
1286 | if ((afi = X509v3_addr_get_afi(f)) == 0) | 1339 | if (!IPAddressFamily_afi(f, &afi)) |
1287 | return 0; | 1340 | return 0; |
1288 | 1341 | ||
1289 | if ((aors = IPAddressFamily_addressesOrRanges(f)) == NULL) | 1342 | if ((aors = IPAddressFamily_addressesOrRanges(f)) == NULL) |