summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto')
-rw-r--r--src/lib/libcrypto/asn1/a_bitstr.c52
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 */
115static int
116asn1_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
111int 144int
112ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len) 145ASN1_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}
156LCRYPTO_ALIAS(ASN1_BIT_STRING_set_bit); 189LCRYPTO_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])