diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libcrypto/x509/x509_addr.c | 141 |
1 files changed, 104 insertions, 37 deletions
diff --git a/src/lib/libcrypto/x509/x509_addr.c b/src/lib/libcrypto/x509/x509_addr.c index ba5aaff7e6..e805a14af1 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.81 2022/05/17 07:50:59 tb Exp $ */ | 1 | /* $OpenBSD: x509_addr.c,v 1.82 2022/05/17 08:00:51 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"). |
| @@ -894,59 +894,126 @@ make_addressPrefix(IPAddressOrRange **out_aor, uint8_t *addr, uint32_t afi, | |||
| 894 | return 0; | 894 | return 0; |
| 895 | } | 895 | } |
| 896 | 896 | ||
| 897 | static uint8_t | ||
| 898 | count_trailing_zeroes(uint8_t octet) | ||
| 899 | { | ||
| 900 | uint8_t count = 0; | ||
| 901 | |||
| 902 | if (octet == 0) | ||
| 903 | return 8; | ||
| 904 | |||
| 905 | while ((octet & (1 << count)) == 0) | ||
| 906 | count++; | ||
| 907 | |||
| 908 | return count; | ||
| 909 | } | ||
| 910 | |||
| 911 | static int | ||
| 912 | trim_end_u8(CBS *cbs, uint8_t trim) | ||
| 913 | { | ||
| 914 | uint8_t octet; | ||
| 915 | |||
| 916 | while (CBS_len(cbs) > 0) { | ||
| 917 | if (!CBS_peek_last_u8(cbs, &octet)) | ||
| 918 | return 0; | ||
| 919 | if (octet != trim) | ||
| 920 | return 1; | ||
| 921 | if (!CBS_get_last_u8(cbs, &octet)) | ||
| 922 | return 0; | ||
| 923 | } | ||
| 924 | |||
| 925 | return 1; | ||
| 926 | } | ||
| 927 | |||
| 897 | /* | 928 | /* |
| 898 | * Construct a range. If it can be expressed as a prefix, | 929 | * Populate IPAddressOrRange with bit string encoding of a range, see |
| 899 | * return a prefix instead. Doing this here simplifies | 930 | * RFC 3779, 2.1.2. |
| 900 | * the rest of the code considerably. | ||
| 901 | */ | 931 | */ |
| 902 | static int | 932 | static int |
| 903 | make_addressRange(IPAddressOrRange **result, unsigned char *min, | 933 | make_addressRange(IPAddressOrRange **out_aor, uint8_t *min, uint8_t *max, |
| 904 | unsigned char *max, unsigned int afi, int length) | 934 | uint32_t afi, int length) |
| 905 | { | 935 | { |
| 906 | IPAddressOrRange *aor; | 936 | IPAddressOrRange *aor = NULL; |
| 907 | int i, prefix_len; | 937 | IPAddressRange *range; |
| 938 | int prefix_len; | ||
| 939 | CBS cbs; | ||
| 940 | size_t max_len, min_len; | ||
| 941 | uint8_t unused_bits_min, unused_bits_max; | ||
| 942 | uint8_t octet; | ||
| 908 | 943 | ||
| 909 | if (memcmp(min, max, length) > 0) | 944 | if (memcmp(min, max, length) > 0) |
| 910 | return 0; | 945 | goto err; |
| 946 | |||
| 947 | /* | ||
| 948 | * RFC 3779, 2.2.3.6 - a range that can be expressed as a prefix | ||
| 949 | * must be encoded as a prefix. | ||
| 950 | */ | ||
| 911 | 951 | ||
| 912 | if ((prefix_len = range_should_be_prefix(min, max, length)) >= 0) | 952 | if ((prefix_len = range_should_be_prefix(min, max, length)) >= 0) |
| 913 | return make_addressPrefix(result, min, afi, prefix_len); | 953 | return make_addressPrefix(out_aor, min, afi, prefix_len); |
| 954 | |||
| 955 | /* | ||
| 956 | * The bit string representing min is formed by removing all its | ||
| 957 | * trailing zero bits, so remove all trailing zero octets and count | ||
| 958 | * the trailing zero bits of the last octet. | ||
| 959 | */ | ||
| 960 | |||
| 961 | CBS_init(&cbs, min, length); | ||
| 962 | |||
| 963 | if (!trim_end_u8(&cbs, 0x00)) | ||
| 964 | goto err; | ||
| 965 | |||
| 966 | unused_bits_min = 0; | ||
| 967 | if ((min_len = CBS_len(&cbs)) > 0) { | ||
| 968 | if (!CBS_peek_last_u8(&cbs, &octet)) | ||
| 969 | goto err; | ||
| 970 | |||
| 971 | unused_bits_min = count_trailing_zeroes(octet); | ||
| 972 | } | ||
| 973 | |||
| 974 | /* | ||
| 975 | * The bit string representing max is formed by removing all its | ||
| 976 | * trailing one bits, so remove all trailing 0xff octets and count | ||
| 977 | * the trailing ones of the last octet. | ||
| 978 | */ | ||
| 979 | |||
| 980 | CBS_init(&cbs, max, length); | ||
| 981 | |||
| 982 | if (!trim_end_u8(&cbs, 0xff)) | ||
| 983 | goto err; | ||
| 984 | |||
| 985 | unused_bits_max = 0; | ||
| 986 | if ((max_len = CBS_len(&cbs)) > 0) { | ||
| 987 | if (!CBS_peek_last_u8(&cbs, &octet)) | ||
| 988 | goto err; | ||
| 989 | |||
| 990 | unused_bits_max = count_trailing_zeroes(octet + 1); | ||
| 991 | } | ||
| 992 | |||
| 993 | /* | ||
| 994 | * Populate IPAddressOrRange. | ||
| 995 | */ | ||
| 914 | 996 | ||
| 915 | if ((aor = IPAddressOrRange_new()) == NULL) | 997 | if ((aor = IPAddressOrRange_new()) == NULL) |
| 916 | return 0; | 998 | goto err; |
| 999 | |||
| 917 | aor->type = IPAddressOrRange_addressRange; | 1000 | aor->type = IPAddressOrRange_addressRange; |
| 918 | if ((aor->u.addressRange = IPAddressRange_new()) == NULL) | 1001 | |
| 1002 | if ((range = aor->u.addressRange = IPAddressRange_new()) == NULL) | ||
| 919 | goto err; | 1003 | goto err; |
| 920 | 1004 | ||
| 921 | for (i = length; i > 0 && min[i - 1] == 0x00; --i) | 1005 | if (!ASN1_BIT_STRING_set(range->min, min, min_len)) |
| 922 | continue; | 1006 | goto err; |
| 923 | if (!ASN1_BIT_STRING_set(aor->u.addressRange->min, min, i)) | 1007 | if (!asn1_abs_set_unused_bits(range->min, unused_bits_min)) |
| 924 | goto err; | 1008 | goto err; |
| 925 | aor->u.addressRange->min->flags &= ~7; | ||
| 926 | aor->u.addressRange->min->flags |= ASN1_STRING_FLAG_BITS_LEFT; | ||
| 927 | if (i > 0) { | ||
| 928 | unsigned char b = min[i - 1]; | ||
| 929 | int j = 1; | ||
| 930 | while ((b & (0xffU >> j)) != 0) | ||
| 931 | ++j; | ||
| 932 | aor->u.addressRange->min->flags |= 8 - j; | ||
| 933 | } | ||
| 934 | 1009 | ||
| 935 | for (i = length; i > 0 && max[i - 1] == 0xff; --i) | 1010 | if (!ASN1_BIT_STRING_set(range->max, max, max_len)) |
| 936 | continue; | ||
| 937 | if (!ASN1_BIT_STRING_set(aor->u.addressRange->max, max, i)) | ||
| 938 | goto err; | 1011 | goto err; |
| 939 | aor->u.addressRange->max->flags &= ~7; | 1012 | if (!asn1_abs_set_unused_bits(range->max, unused_bits_max)) |
| 940 | aor->u.addressRange->max->flags |= ASN1_STRING_FLAG_BITS_LEFT; | 1013 | goto err; |
| 941 | if (i > 0) { | 1014 | |
| 942 | unsigned char b = max[i - 1]; | 1015 | *out_aor = aor; |
| 943 | int j = 1; | ||
| 944 | while ((b & (0xffU >> j)) != (0xffU >> j)) | ||
| 945 | ++j; | ||
| 946 | aor->u.addressRange->max->flags |= 8 - j; | ||
| 947 | } | ||
| 948 | 1016 | ||
| 949 | *result = aor; | ||
| 950 | return 1; | 1017 | return 1; |
| 951 | 1018 | ||
| 952 | err: | 1019 | err: |
