diff options
| author | tb <> | 2026-04-26 17:58:58 +0000 |
|---|---|---|
| committer | tb <> | 2026-04-26 17:58:58 +0000 |
| commit | 6dd7ca7383df89a74220119e1a3d69460ec22921 (patch) | |
| tree | 2c9dd223b4249e8bb95a39d6ad61dee88e93280d | |
| parent | 38105b7cb94d5e0839470521c269b2c565624ff1 (diff) | |
| download | openbsd-6dd7ca7383df89a74220119e1a3d69460ec22921.tar.gz openbsd-6dd7ca7383df89a74220119e1a3d69460ec22921.tar.bz2 openbsd-6dd7ca7383df89a74220119e1a3d69460ec22921.zip | |
make_addressRange: unused bits in max must be zero
X509v3_addr_add_range() requires that min and max of an address range
have network encoding. In the RFC 3779 encoding of an actual address
range (as opposed to a prefix) as a SEQUENCE OF two ASN.1 BIT STRINGs,
the trailing one bits of the maximum become unused bits and therefore
must be DER encoded as zeroes. The DER encoder will clear them via i2d
but these trailing ones are annoying. Make a copy in which the unused
bits are cleared.
ok kenjiro
| -rw-r--r-- | src/lib/libcrypto/x509/x509_addr.c | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/src/lib/libcrypto/x509/x509_addr.c b/src/lib/libcrypto/x509/x509_addr.c index b4ee92a14b..ef2f7e0889 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.94 2025/05/10 05:54:39 tb Exp $ */ | 1 | /* $OpenBSD: x509_addr.c,v 1.95 2026/04/26 17:58:58 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"). |
| @@ -961,18 +961,22 @@ trim_end_u8(CBS *cbs, uint8_t trim) | |||
| 961 | * RFC 3779, 2.1.2. | 961 | * RFC 3779, 2.1.2. |
| 962 | */ | 962 | */ |
| 963 | static int | 963 | static int |
| 964 | make_addressRange(IPAddressOrRange **out_aor, uint8_t *min, uint8_t *max, | 964 | make_addressRange(IPAddressOrRange **out_aor, uint8_t *min, uint8_t *in_max, |
| 965 | uint32_t afi, int length) | 965 | uint32_t afi, int length) |
| 966 | { | 966 | { |
| 967 | IPAddressOrRange *aor = NULL; | 967 | IPAddressOrRange *aor = NULL; |
| 968 | IPAddressRange *range; | 968 | IPAddressRange *range; |
| 969 | int prefix_len; | 969 | int prefix_len; |
| 970 | CBS cbs; | 970 | CBS cbs; |
| 971 | CBB cbb; | ||
| 972 | uint8_t max[ADDR_RAW_BUF_LEN]; | ||
| 971 | size_t max_len, min_len; | 973 | size_t max_len, min_len; |
| 972 | uint8_t unused_bits_min, unused_bits_max; | 974 | uint8_t unused_bits_min, unused_bits_max; |
| 973 | uint8_t octet; | 975 | uint8_t octet; |
| 974 | 976 | ||
| 975 | if (memcmp(min, max, length) > 0) | 977 | memset(&cbb, 0, sizeof(cbb)); |
| 978 | |||
| 979 | if (memcmp(min, in_max, length) > 0) | ||
| 976 | goto err; | 980 | goto err; |
| 977 | 981 | ||
| 978 | /* | 982 | /* |
| @@ -980,7 +984,7 @@ make_addressRange(IPAddressOrRange **out_aor, uint8_t *min, uint8_t *max, | |||
| 980 | * must be encoded as a prefix. | 984 | * must be encoded as a prefix. |
| 981 | */ | 985 | */ |
| 982 | 986 | ||
| 983 | if ((prefix_len = range_should_be_prefix(min, max, length)) >= 0) | 987 | if ((prefix_len = range_should_be_prefix(min, in_max, length)) >= 0) |
| 984 | return make_addressPrefix(out_aor, min, afi, prefix_len); | 988 | return make_addressPrefix(out_aor, min, afi, prefix_len); |
| 985 | 989 | ||
| 986 | /* | 990 | /* |
| @@ -1008,18 +1012,30 @@ make_addressRange(IPAddressOrRange **out_aor, uint8_t *min, uint8_t *max, | |||
| 1008 | * the trailing ones of the last octet. | 1012 | * the trailing ones of the last octet. |
| 1009 | */ | 1013 | */ |
| 1010 | 1014 | ||
| 1011 | CBS_init(&cbs, max, length); | 1015 | CBS_init(&cbs, in_max, length); |
| 1016 | if (!CBB_init_fixed(&cbb, max, sizeof(max))) | ||
| 1017 | goto err; | ||
| 1012 | 1018 | ||
| 1013 | if (!trim_end_u8(&cbs, 0xff)) | 1019 | if (!trim_end_u8(&cbs, 0xff)) |
| 1014 | goto err; | 1020 | goto err; |
| 1015 | 1021 | ||
| 1016 | unused_bits_max = 0; | 1022 | unused_bits_max = 0; |
| 1017 | if ((max_len = CBS_len(&cbs)) > 0) { | 1023 | if ((max_len = CBS_len(&cbs)) > 0) { |
| 1018 | if (!CBS_peek_last_u8(&cbs, &octet)) | 1024 | if (!CBS_get_last_u8(&cbs, &octet)) |
| 1019 | goto err; | 1025 | goto err; |
| 1020 | 1026 | ||
| 1021 | unused_bits_max = count_trailing_zeroes(octet + 1); | 1027 | unused_bits_max = count_trailing_zeroes(octet + 1); |
| 1028 | octet &= 0xff << unused_bits_max; | ||
| 1029 | } | ||
| 1030 | |||
| 1031 | if (!CBB_add_bytes(&cbb, CBS_data(&cbs), CBS_len(&cbs))) | ||
| 1032 | goto err; | ||
| 1033 | if (max_len > 0) { | ||
| 1034 | if (!CBB_add_u8(&cbb, octet)) | ||
| 1035 | goto err; | ||
| 1022 | } | 1036 | } |
| 1037 | if (!CBB_finish(&cbb, NULL, NULL)) | ||
| 1038 | goto err; | ||
| 1023 | 1039 | ||
| 1024 | /* | 1040 | /* |
| 1025 | * Populate IPAddressOrRange. | 1041 | * Populate IPAddressOrRange. |
| @@ -1048,6 +1064,7 @@ make_addressRange(IPAddressOrRange **out_aor, uint8_t *min, uint8_t *max, | |||
| 1048 | return 1; | 1064 | return 1; |
| 1049 | 1065 | ||
| 1050 | err: | 1066 | err: |
| 1067 | CBB_cleanup(&cbb); | ||
| 1051 | IPAddressOrRange_free(aor); | 1068 | IPAddressOrRange_free(aor); |
| 1052 | return 0; | 1069 | return 0; |
| 1053 | } | 1070 | } |
