summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/libcrypto/x509/x509_addr.c141
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
897static uint8_t
898count_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
911static int
912trim_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 */
902static int 932static int
903make_addressRange(IPAddressOrRange **result, unsigned char *min, 933make_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: