diff options
-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: |