diff options
| -rw-r--r-- | src/lib/libcrypto/asn1/a_bitstr.c | 52 |
1 files changed, 43 insertions, 9 deletions
diff --git a/src/lib/libcrypto/asn1/a_bitstr.c b/src/lib/libcrypto/asn1/a_bitstr.c index e656c43f0c..d84ecb025e 100644 --- a/src/lib/libcrypto/asn1/a_bitstr.c +++ b/src/lib/libcrypto/asn1/a_bitstr.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: a_bitstr.c,v 1.48 2026/01/04 09:54:23 tb Exp $ */ | 1 | /* $OpenBSD: a_bitstr.c,v 1.49 2026/02/08 10:27:00 tb Exp $ */ |
| 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * | 4 | * |
| @@ -108,6 +108,39 @@ asn1_abs_set_unused_bits(ASN1_BIT_STRING *abs, uint8_t unused_bits) | |||
| 108 | return 1; | 108 | return 1; |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | /* | ||
| 112 | * X.690, 11.2.2: [When a "NamedBitList" is used] [...], the bitstring shall | ||
| 113 | * have all trailing 0 bits removed before it is encoded. | ||
| 114 | */ | ||
| 115 | static int | ||
| 116 | asn1_abs_trim_trailing_zero_bits(ASN1_BIT_STRING *abs) | ||
| 117 | { | ||
| 118 | int unused_bits = 0; | ||
| 119 | |||
| 120 | /* Remove trailing zero octets. */ | ||
| 121 | while (abs->length > 0 && abs->data[abs->length - 1] == 0) | ||
| 122 | abs->length--; | ||
| 123 | |||
| 124 | /* Remove trailing zero bits by setting the unused bits octet. */ | ||
| 125 | if (abs->length > 0) { | ||
| 126 | uint8_t u8 = abs->data[abs->length - 1]; | ||
| 127 | |||
| 128 | /* u8 != 0. Only keep least significant bit. */ | ||
| 129 | u8 &= 0x100 - u8; | ||
| 130 | |||
| 131 | /* Count trailing zero bits. */ | ||
| 132 | unused_bits = 7; | ||
| 133 | if ((u8 & 0x0f) != 0) | ||
| 134 | unused_bits -= 4; | ||
| 135 | if ((u8 & 0x33) != 0) | ||
| 136 | unused_bits -= 2; | ||
| 137 | if ((u8 & 0x55) != 0) | ||
| 138 | unused_bits -= 1; | ||
| 139 | } | ||
| 140 | |||
| 141 | return asn1_abs_set_unused_bits(abs, unused_bits); | ||
| 142 | } | ||
| 143 | |||
| 111 | int | 144 | int |
| 112 | ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len) | 145 | ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len) |
| 113 | { | 146 | { |
| @@ -133,12 +166,14 @@ ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value) | |||
| 133 | if (value == 0) | 166 | if (value == 0) |
| 134 | v = 0; | 167 | v = 0; |
| 135 | 168 | ||
| 136 | asn1_abs_clear_unused_bits(a); | ||
| 137 | |||
| 138 | if (a->length < w + 1 || a->data == NULL) { | 169 | if (a->length < w + 1 || a->data == NULL) { |
| 139 | /* Don't expand if there's no bit to set. */ | 170 | /* |
| 171 | * Don't expand if there's no bit to set. | ||
| 172 | * XXX - switch back to return 1 here when we drop | ||
| 173 | * ASN1_STRING_FLAG_BITS_LEFT? | ||
| 174 | */ | ||
| 140 | if (value == 0) | 175 | if (value == 0) |
| 141 | return 1; | 176 | return asn1_abs_trim_trailing_zero_bits(a); |
| 142 | if ((c = recallocarray(a->data, a->length, w + 1, 1)) == NULL) { | 177 | if ((c = recallocarray(a->data, a->length, w + 1, 1)) == NULL) { |
| 143 | ASN1error(ERR_R_MALLOC_FAILURE); | 178 | ASN1error(ERR_R_MALLOC_FAILURE); |
| 144 | return 0; | 179 | return 0; |
| @@ -147,11 +182,9 @@ ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value) | |||
| 147 | a->length = w + 1; | 182 | a->length = w + 1; |
| 148 | } | 183 | } |
| 149 | 184 | ||
| 150 | a->data[w] = ((a->data[w]) & iv) | v; | 185 | a->data[w] = (a->data[w] & iv) | v; |
| 151 | while (a->length > 0 && a->data[a->length - 1] == 0) | ||
| 152 | a->length--; | ||
| 153 | 186 | ||
| 154 | return 1; | 187 | return asn1_abs_trim_trailing_zero_bits(a); |
| 155 | } | 188 | } |
| 156 | LCRYPTO_ALIAS(ASN1_BIT_STRING_set_bit); | 189 | LCRYPTO_ALIAS(ASN1_BIT_STRING_set_bit); |
| 157 | 190 | ||
| @@ -189,6 +222,7 @@ i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp) | |||
| 189 | if (a->flags & ASN1_STRING_FLAG_BITS_LEFT) { | 222 | if (a->flags & ASN1_STRING_FLAG_BITS_LEFT) { |
| 190 | bits = (int)a->flags & 0x07; | 223 | bits = (int)a->flags & 0x07; |
| 191 | } else { | 224 | } else { |
| 225 | /* XXX - dedup with asn1_abs_trim_trailing_zero_bits? */ | ||
| 192 | j = 0; | 226 | j = 0; |
| 193 | for (; len > 0; len--) { | 227 | for (; len > 0; len--) { |
| 194 | if (a->data[len - 1]) | 228 | if (a->data[len - 1]) |
