1*de0e0e4dSAntonio Huete Jimenez /* $OpenBSD: a_bitstr.c,v 1.36 2022/05/17 09:17:20 tb Exp $ */
2f5b1c8a1SJohn Marino /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3f5b1c8a1SJohn Marino  * All rights reserved.
4f5b1c8a1SJohn Marino  *
5f5b1c8a1SJohn Marino  * This package is an SSL implementation written
6f5b1c8a1SJohn Marino  * by Eric Young (eay@cryptsoft.com).
7f5b1c8a1SJohn Marino  * The implementation was written so as to conform with Netscapes SSL.
8f5b1c8a1SJohn Marino  *
9f5b1c8a1SJohn Marino  * This library is free for commercial and non-commercial use as long as
10f5b1c8a1SJohn Marino  * the following conditions are aheared to.  The following conditions
11f5b1c8a1SJohn Marino  * apply to all code found in this distribution, be it the RC4, RSA,
12f5b1c8a1SJohn Marino  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13f5b1c8a1SJohn Marino  * included with this distribution is covered by the same copyright terms
14f5b1c8a1SJohn Marino  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15f5b1c8a1SJohn Marino  *
16f5b1c8a1SJohn Marino  * Copyright remains Eric Young's, and as such any Copyright notices in
17f5b1c8a1SJohn Marino  * the code are not to be removed.
18f5b1c8a1SJohn Marino  * If this package is used in a product, Eric Young should be given attribution
19f5b1c8a1SJohn Marino  * as the author of the parts of the library used.
20f5b1c8a1SJohn Marino  * This can be in the form of a textual message at program startup or
21f5b1c8a1SJohn Marino  * in documentation (online or textual) provided with the package.
22f5b1c8a1SJohn Marino  *
23f5b1c8a1SJohn Marino  * Redistribution and use in source and binary forms, with or without
24f5b1c8a1SJohn Marino  * modification, are permitted provided that the following conditions
25f5b1c8a1SJohn Marino  * are met:
26f5b1c8a1SJohn Marino  * 1. Redistributions of source code must retain the copyright
27f5b1c8a1SJohn Marino  *    notice, this list of conditions and the following disclaimer.
28f5b1c8a1SJohn Marino  * 2. Redistributions in binary form must reproduce the above copyright
29f5b1c8a1SJohn Marino  *    notice, this list of conditions and the following disclaimer in the
30f5b1c8a1SJohn Marino  *    documentation and/or other materials provided with the distribution.
31f5b1c8a1SJohn Marino  * 3. All advertising materials mentioning features or use of this software
32f5b1c8a1SJohn Marino  *    must display the following acknowledgement:
33f5b1c8a1SJohn Marino  *    "This product includes cryptographic software written by
34f5b1c8a1SJohn Marino  *     Eric Young (eay@cryptsoft.com)"
35f5b1c8a1SJohn Marino  *    The word 'cryptographic' can be left out if the rouines from the library
36f5b1c8a1SJohn Marino  *    being used are not cryptographic related :-).
37f5b1c8a1SJohn Marino  * 4. If you include any Windows specific code (or a derivative thereof) from
38f5b1c8a1SJohn Marino  *    the apps directory (application code) you must include an acknowledgement:
39f5b1c8a1SJohn Marino  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40f5b1c8a1SJohn Marino  *
41f5b1c8a1SJohn Marino  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42f5b1c8a1SJohn Marino  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43f5b1c8a1SJohn Marino  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44f5b1c8a1SJohn Marino  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45f5b1c8a1SJohn Marino  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46f5b1c8a1SJohn Marino  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47f5b1c8a1SJohn Marino  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48f5b1c8a1SJohn Marino  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49f5b1c8a1SJohn Marino  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50f5b1c8a1SJohn Marino  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51f5b1c8a1SJohn Marino  * SUCH DAMAGE.
52f5b1c8a1SJohn Marino  *
53f5b1c8a1SJohn Marino  * The licence and distribution terms for any publically available version or
54f5b1c8a1SJohn Marino  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55f5b1c8a1SJohn Marino  * copied and put under another distribution licence
56f5b1c8a1SJohn Marino  * [including the GNU Public Licence.]
57f5b1c8a1SJohn Marino  */
58f5b1c8a1SJohn Marino 
59*de0e0e4dSAntonio Huete Jimenez #include <limits.h>
60f5b1c8a1SJohn Marino #include <stdio.h>
61f5b1c8a1SJohn Marino #include <string.h>
62f5b1c8a1SJohn Marino 
63f5b1c8a1SJohn Marino #include <openssl/asn1.h>
64*de0e0e4dSAntonio Huete Jimenez #include <openssl/asn1t.h>
65*de0e0e4dSAntonio Huete Jimenez #include <openssl/conf.h>
66f5b1c8a1SJohn Marino #include <openssl/err.h>
67*de0e0e4dSAntonio Huete Jimenez #include <openssl/x509v3.h>
68*de0e0e4dSAntonio Huete Jimenez 
69*de0e0e4dSAntonio Huete Jimenez #include "bytestring.h"
70*de0e0e4dSAntonio Huete Jimenez 
71*de0e0e4dSAntonio Huete Jimenez const ASN1_ITEM ASN1_BIT_STRING_it = {
72*de0e0e4dSAntonio Huete Jimenez 	.itype = ASN1_ITYPE_PRIMITIVE,
73*de0e0e4dSAntonio Huete Jimenez 	.utype = V_ASN1_BIT_STRING,
74*de0e0e4dSAntonio Huete Jimenez 	.sname = "ASN1_BIT_STRING",
75*de0e0e4dSAntonio Huete Jimenez };
76*de0e0e4dSAntonio Huete Jimenez 
77*de0e0e4dSAntonio Huete Jimenez ASN1_BIT_STRING *
ASN1_BIT_STRING_new(void)78*de0e0e4dSAntonio Huete Jimenez ASN1_BIT_STRING_new(void)
79*de0e0e4dSAntonio Huete Jimenez {
80*de0e0e4dSAntonio Huete Jimenez 	return (ASN1_BIT_STRING *)ASN1_item_new(&ASN1_BIT_STRING_it);
81*de0e0e4dSAntonio Huete Jimenez }
82*de0e0e4dSAntonio Huete Jimenez 
83*de0e0e4dSAntonio Huete Jimenez void
ASN1_BIT_STRING_free(ASN1_BIT_STRING * a)84*de0e0e4dSAntonio Huete Jimenez ASN1_BIT_STRING_free(ASN1_BIT_STRING *a)
85*de0e0e4dSAntonio Huete Jimenez {
86*de0e0e4dSAntonio Huete Jimenez 	ASN1_item_free((ASN1_VALUE *)a, &ASN1_BIT_STRING_it);
87*de0e0e4dSAntonio Huete Jimenez }
88*de0e0e4dSAntonio Huete Jimenez 
89*de0e0e4dSAntonio Huete Jimenez static void
asn1_abs_clear_unused_bits(ASN1_BIT_STRING * abs)90*de0e0e4dSAntonio Huete Jimenez asn1_abs_clear_unused_bits(ASN1_BIT_STRING *abs)
91*de0e0e4dSAntonio Huete Jimenez {
92*de0e0e4dSAntonio Huete Jimenez 	abs->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
93*de0e0e4dSAntonio Huete Jimenez }
94*de0e0e4dSAntonio Huete Jimenez 
95*de0e0e4dSAntonio Huete Jimenez int
asn1_abs_set_unused_bits(ASN1_BIT_STRING * abs,uint8_t unused_bits)96*de0e0e4dSAntonio Huete Jimenez asn1_abs_set_unused_bits(ASN1_BIT_STRING *abs, uint8_t unused_bits)
97*de0e0e4dSAntonio Huete Jimenez {
98*de0e0e4dSAntonio Huete Jimenez 	if (unused_bits > 7)
99*de0e0e4dSAntonio Huete Jimenez 		return 0;
100*de0e0e4dSAntonio Huete Jimenez 
101*de0e0e4dSAntonio Huete Jimenez 	asn1_abs_clear_unused_bits(abs);
102*de0e0e4dSAntonio Huete Jimenez 
103*de0e0e4dSAntonio Huete Jimenez 	abs->flags |= ASN1_STRING_FLAG_BITS_LEFT | unused_bits;
104*de0e0e4dSAntonio Huete Jimenez 
105*de0e0e4dSAntonio Huete Jimenez 	return 1;
106*de0e0e4dSAntonio Huete Jimenez }
107f5b1c8a1SJohn Marino 
108f5b1c8a1SJohn Marino int
ASN1_BIT_STRING_set(ASN1_BIT_STRING * x,unsigned char * d,int len)109f5b1c8a1SJohn Marino ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len)
110f5b1c8a1SJohn Marino {
111f5b1c8a1SJohn Marino 	return ASN1_STRING_set(x, d, len);
112f5b1c8a1SJohn Marino }
113f5b1c8a1SJohn Marino 
114f5b1c8a1SJohn Marino int
ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING * a,int n,int value)115*de0e0e4dSAntonio Huete Jimenez ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
116*de0e0e4dSAntonio Huete Jimenez {
117*de0e0e4dSAntonio Huete Jimenez 	int w, v, iv;
118*de0e0e4dSAntonio Huete Jimenez 	unsigned char *c;
119*de0e0e4dSAntonio Huete Jimenez 
120*de0e0e4dSAntonio Huete Jimenez 	w = n/8;
121*de0e0e4dSAntonio Huete Jimenez 	v = 1 << (7 - (n & 0x07));
122*de0e0e4dSAntonio Huete Jimenez 	iv = ~v;
123*de0e0e4dSAntonio Huete Jimenez 	if (!value)
124*de0e0e4dSAntonio Huete Jimenez 		v = 0;
125*de0e0e4dSAntonio Huete Jimenez 
126*de0e0e4dSAntonio Huete Jimenez 	if (a == NULL)
127*de0e0e4dSAntonio Huete Jimenez 		return 0;
128*de0e0e4dSAntonio Huete Jimenez 
129*de0e0e4dSAntonio Huete Jimenez 	asn1_abs_clear_unused_bits(a);
130*de0e0e4dSAntonio Huete Jimenez 
131*de0e0e4dSAntonio Huete Jimenez 	if ((a->length < (w + 1)) || (a->data == NULL)) {
132*de0e0e4dSAntonio Huete Jimenez 		if (!value)
133*de0e0e4dSAntonio Huete Jimenez 			return(1); /* Don't need to set */
134*de0e0e4dSAntonio Huete Jimenez 		if ((c = recallocarray(a->data, a->length, w + 1, 1)) == NULL) {
135*de0e0e4dSAntonio Huete Jimenez 			ASN1error(ERR_R_MALLOC_FAILURE);
136*de0e0e4dSAntonio Huete Jimenez 			return 0;
137*de0e0e4dSAntonio Huete Jimenez 		}
138*de0e0e4dSAntonio Huete Jimenez 		a->data = c;
139*de0e0e4dSAntonio Huete Jimenez 		a->length = w + 1;
140*de0e0e4dSAntonio Huete Jimenez 	}
141*de0e0e4dSAntonio Huete Jimenez 	a->data[w] = ((a->data[w]) & iv) | v;
142*de0e0e4dSAntonio Huete Jimenez 	while ((a->length > 0) && (a->data[a->length - 1] == 0))
143*de0e0e4dSAntonio Huete Jimenez 		a->length--;
144*de0e0e4dSAntonio Huete Jimenez 
145*de0e0e4dSAntonio Huete Jimenez 	return (1);
146*de0e0e4dSAntonio Huete Jimenez }
147*de0e0e4dSAntonio Huete Jimenez 
148*de0e0e4dSAntonio Huete Jimenez int
ASN1_BIT_STRING_get_bit(const ASN1_BIT_STRING * a,int n)149*de0e0e4dSAntonio Huete Jimenez ASN1_BIT_STRING_get_bit(const ASN1_BIT_STRING *a, int n)
150*de0e0e4dSAntonio Huete Jimenez {
151*de0e0e4dSAntonio Huete Jimenez 	int w, v;
152*de0e0e4dSAntonio Huete Jimenez 
153*de0e0e4dSAntonio Huete Jimenez 	w = n / 8;
154*de0e0e4dSAntonio Huete Jimenez 	v = 1 << (7 - (n & 0x07));
155*de0e0e4dSAntonio Huete Jimenez 	if ((a == NULL) || (a->length < (w + 1)) || (a->data == NULL))
156*de0e0e4dSAntonio Huete Jimenez 		return (0);
157*de0e0e4dSAntonio Huete Jimenez 	return ((a->data[w] & v) != 0);
158*de0e0e4dSAntonio Huete Jimenez }
159*de0e0e4dSAntonio Huete Jimenez 
160*de0e0e4dSAntonio Huete Jimenez /*
161*de0e0e4dSAntonio Huete Jimenez  * Checks if the given bit string contains only bits specified by
162*de0e0e4dSAntonio Huete Jimenez  * the flags vector. Returns 0 if there is at least one bit set in 'a'
163*de0e0e4dSAntonio Huete Jimenez  * which is not specified in 'flags', 1 otherwise.
164*de0e0e4dSAntonio Huete Jimenez  * 'len' is the length of 'flags'.
165*de0e0e4dSAntonio Huete Jimenez  */
166*de0e0e4dSAntonio Huete Jimenez int
ASN1_BIT_STRING_check(const ASN1_BIT_STRING * a,const unsigned char * flags,int flags_len)167*de0e0e4dSAntonio Huete Jimenez ASN1_BIT_STRING_check(const ASN1_BIT_STRING *a, const unsigned char *flags,
168*de0e0e4dSAntonio Huete Jimenez     int flags_len)
169*de0e0e4dSAntonio Huete Jimenez {
170*de0e0e4dSAntonio Huete Jimenez 	int i, ok;
171*de0e0e4dSAntonio Huete Jimenez 
172*de0e0e4dSAntonio Huete Jimenez 	/* Check if there is one bit set at all. */
173*de0e0e4dSAntonio Huete Jimenez 	if (!a || !a->data)
174*de0e0e4dSAntonio Huete Jimenez 		return 1;
175*de0e0e4dSAntonio Huete Jimenez 
176*de0e0e4dSAntonio Huete Jimenez 	/* Check each byte of the internal representation of the bit string. */
177*de0e0e4dSAntonio Huete Jimenez 	ok = 1;
178*de0e0e4dSAntonio Huete Jimenez 	for (i = 0; i < a->length && ok; ++i) {
179*de0e0e4dSAntonio Huete Jimenez 		unsigned char mask = i < flags_len ? ~flags[i] : 0xff;
180*de0e0e4dSAntonio Huete Jimenez 		/* We are done if there is an unneeded bit set. */
181*de0e0e4dSAntonio Huete Jimenez 		ok = (a->data[i] & mask) == 0;
182*de0e0e4dSAntonio Huete Jimenez 	}
183*de0e0e4dSAntonio Huete Jimenez 	return ok;
184*de0e0e4dSAntonio Huete Jimenez }
185*de0e0e4dSAntonio Huete Jimenez 
186*de0e0e4dSAntonio Huete Jimenez int
ASN1_BIT_STRING_name_print(BIO * out,ASN1_BIT_STRING * bs,BIT_STRING_BITNAME * tbl,int indent)187*de0e0e4dSAntonio Huete Jimenez ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs,
188*de0e0e4dSAntonio Huete Jimenez     BIT_STRING_BITNAME *tbl, int indent)
189*de0e0e4dSAntonio Huete Jimenez {
190*de0e0e4dSAntonio Huete Jimenez 	BIT_STRING_BITNAME *bnam;
191*de0e0e4dSAntonio Huete Jimenez 	char first = 1;
192*de0e0e4dSAntonio Huete Jimenez 
193*de0e0e4dSAntonio Huete Jimenez 	BIO_printf(out, "%*s", indent, "");
194*de0e0e4dSAntonio Huete Jimenez 	for (bnam = tbl; bnam->lname; bnam++) {
195*de0e0e4dSAntonio Huete Jimenez 		if (ASN1_BIT_STRING_get_bit(bs, bnam->bitnum)) {
196*de0e0e4dSAntonio Huete Jimenez 			if (!first)
197*de0e0e4dSAntonio Huete Jimenez 				BIO_puts(out, ", ");
198*de0e0e4dSAntonio Huete Jimenez 			BIO_puts(out, bnam->lname);
199*de0e0e4dSAntonio Huete Jimenez 			first = 0;
200*de0e0e4dSAntonio Huete Jimenez 		}
201*de0e0e4dSAntonio Huete Jimenez 	}
202*de0e0e4dSAntonio Huete Jimenez 	BIO_puts(out, "\n");
203*de0e0e4dSAntonio Huete Jimenez 	return 1;
204*de0e0e4dSAntonio Huete Jimenez }
205*de0e0e4dSAntonio Huete Jimenez 
206*de0e0e4dSAntonio Huete Jimenez int
ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING * bs,const char * name,int value,BIT_STRING_BITNAME * tbl)207*de0e0e4dSAntonio Huete Jimenez ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, const char *name, int value,
208*de0e0e4dSAntonio Huete Jimenez     BIT_STRING_BITNAME *tbl)
209*de0e0e4dSAntonio Huete Jimenez {
210*de0e0e4dSAntonio Huete Jimenez 	int bitnum;
211*de0e0e4dSAntonio Huete Jimenez 
212*de0e0e4dSAntonio Huete Jimenez 	bitnum = ASN1_BIT_STRING_num_asc(name, tbl);
213*de0e0e4dSAntonio Huete Jimenez 	if (bitnum < 0)
214*de0e0e4dSAntonio Huete Jimenez 		return 0;
215*de0e0e4dSAntonio Huete Jimenez 	if (bs) {
216*de0e0e4dSAntonio Huete Jimenez 		if (!ASN1_BIT_STRING_set_bit(bs, bitnum, value))
217*de0e0e4dSAntonio Huete Jimenez 			return 0;
218*de0e0e4dSAntonio Huete Jimenez 	}
219*de0e0e4dSAntonio Huete Jimenez 	return 1;
220*de0e0e4dSAntonio Huete Jimenez }
221*de0e0e4dSAntonio Huete Jimenez 
222*de0e0e4dSAntonio Huete Jimenez int
ASN1_BIT_STRING_num_asc(const char * name,BIT_STRING_BITNAME * tbl)223*de0e0e4dSAntonio Huete Jimenez ASN1_BIT_STRING_num_asc(const char *name, BIT_STRING_BITNAME *tbl)
224*de0e0e4dSAntonio Huete Jimenez {
225*de0e0e4dSAntonio Huete Jimenez 	BIT_STRING_BITNAME *bnam;
226*de0e0e4dSAntonio Huete Jimenez 
227*de0e0e4dSAntonio Huete Jimenez 	for (bnam = tbl; bnam->lname; bnam++) {
228*de0e0e4dSAntonio Huete Jimenez 		if (!strcmp(bnam->sname, name) ||
229*de0e0e4dSAntonio Huete Jimenez 		    !strcmp(bnam->lname, name))
230*de0e0e4dSAntonio Huete Jimenez 			return bnam->bitnum;
231*de0e0e4dSAntonio Huete Jimenez 	}
232*de0e0e4dSAntonio Huete Jimenez 	return -1;
233*de0e0e4dSAntonio Huete Jimenez }
234*de0e0e4dSAntonio Huete Jimenez 
235*de0e0e4dSAntonio Huete Jimenez int
i2c_ASN1_BIT_STRING(ASN1_BIT_STRING * a,unsigned char ** pp)236f5b1c8a1SJohn Marino i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp)
237f5b1c8a1SJohn Marino {
238f5b1c8a1SJohn Marino 	int ret, j, bits, len;
239f5b1c8a1SJohn Marino 	unsigned char *p, *d;
240f5b1c8a1SJohn Marino 
241f5b1c8a1SJohn Marino 	if (a == NULL)
242f5b1c8a1SJohn Marino 		return (0);
243f5b1c8a1SJohn Marino 
244f5b1c8a1SJohn Marino 	len = a->length;
245f5b1c8a1SJohn Marino 
246f5b1c8a1SJohn Marino 	if (len > 0) {
247f5b1c8a1SJohn Marino 		if (a->flags & ASN1_STRING_FLAG_BITS_LEFT) {
248f5b1c8a1SJohn Marino 			bits = (int)a->flags & 0x07;
249f5b1c8a1SJohn Marino 		} else {
250f5b1c8a1SJohn Marino 			for (; len > 0; len--) {
251f5b1c8a1SJohn Marino 				if (a->data[len - 1])
252f5b1c8a1SJohn Marino 					break;
253f5b1c8a1SJohn Marino 			}
254f5b1c8a1SJohn Marino 			j = a->data[len - 1];
255f5b1c8a1SJohn Marino 			if (j & 0x01)
256f5b1c8a1SJohn Marino 				bits = 0;
257f5b1c8a1SJohn Marino 			else if (j & 0x02)
258f5b1c8a1SJohn Marino 				bits = 1;
259f5b1c8a1SJohn Marino 			else if (j & 0x04)
260f5b1c8a1SJohn Marino 				bits = 2;
261f5b1c8a1SJohn Marino 			else if (j & 0x08)
262f5b1c8a1SJohn Marino 				bits = 3;
263f5b1c8a1SJohn Marino 			else if (j & 0x10)
264f5b1c8a1SJohn Marino 				bits = 4;
265f5b1c8a1SJohn Marino 			else if (j & 0x20)
266f5b1c8a1SJohn Marino 				bits = 5;
267f5b1c8a1SJohn Marino 			else if (j & 0x40)
268f5b1c8a1SJohn Marino 				bits = 6;
269f5b1c8a1SJohn Marino 			else if (j & 0x80)
270f5b1c8a1SJohn Marino 				bits = 7;
271f5b1c8a1SJohn Marino 			else
272f5b1c8a1SJohn Marino 				bits = 0; /* should not happen */
273f5b1c8a1SJohn Marino 		}
274f5b1c8a1SJohn Marino 	} else
275f5b1c8a1SJohn Marino 		bits = 0;
276f5b1c8a1SJohn Marino 
277f5b1c8a1SJohn Marino 	ret = 1 + len;
278f5b1c8a1SJohn Marino 	if (pp == NULL)
279f5b1c8a1SJohn Marino 		return (ret);
280f5b1c8a1SJohn Marino 
281f5b1c8a1SJohn Marino 	p= *pp;
282f5b1c8a1SJohn Marino 
283f5b1c8a1SJohn Marino 	*(p++) = (unsigned char)bits;
284f5b1c8a1SJohn Marino 	d = a->data;
28572c33676SMaxim Ag 	if (len > 0) {
286f5b1c8a1SJohn Marino 		memcpy(p, d, len);
287f5b1c8a1SJohn Marino 		p += len;
28872c33676SMaxim Ag 		p[-1] &= 0xff << bits;
28972c33676SMaxim Ag 	}
290f5b1c8a1SJohn Marino 	*pp = p;
291f5b1c8a1SJohn Marino 	return (ret);
292f5b1c8a1SJohn Marino }
293f5b1c8a1SJohn Marino 
294*de0e0e4dSAntonio Huete Jimenez int
c2i_ASN1_BIT_STRING_cbs(ASN1_BIT_STRING ** out_abs,CBS * cbs)295*de0e0e4dSAntonio Huete Jimenez c2i_ASN1_BIT_STRING_cbs(ASN1_BIT_STRING **out_abs, CBS *cbs)
296f5b1c8a1SJohn Marino {
297*de0e0e4dSAntonio Huete Jimenez 	ASN1_BIT_STRING *abs = NULL;
298*de0e0e4dSAntonio Huete Jimenez 	uint8_t *data = NULL;
299*de0e0e4dSAntonio Huete Jimenez 	size_t data_len = 0;
300*de0e0e4dSAntonio Huete Jimenez 	uint8_t unused_bits;
301*de0e0e4dSAntonio Huete Jimenez 	int ret = 0;
302f5b1c8a1SJohn Marino 
303*de0e0e4dSAntonio Huete Jimenez 	if (out_abs == NULL)
304*de0e0e4dSAntonio Huete Jimenez 		goto err;
305*de0e0e4dSAntonio Huete Jimenez 
306*de0e0e4dSAntonio Huete Jimenez 	if (*out_abs != NULL) {
307*de0e0e4dSAntonio Huete Jimenez 		ASN1_BIT_STRING_free(*out_abs);
308*de0e0e4dSAntonio Huete Jimenez 		*out_abs = NULL;
309*de0e0e4dSAntonio Huete Jimenez 	}
310*de0e0e4dSAntonio Huete Jimenez 
311*de0e0e4dSAntonio Huete Jimenez 	if (!CBS_get_u8(cbs, &unused_bits)) {
31272c33676SMaxim Ag 		ASN1error(ASN1_R_STRING_TOO_SHORT);
313f5b1c8a1SJohn Marino 		goto err;
314f5b1c8a1SJohn Marino 	}
315f5b1c8a1SJohn Marino 
316*de0e0e4dSAntonio Huete Jimenez 	if (!CBS_stow(cbs, &data, &data_len))
31772c33676SMaxim Ag 		goto err;
318*de0e0e4dSAntonio Huete Jimenez 	if (data_len > INT_MAX)
319*de0e0e4dSAntonio Huete Jimenez 		goto err;
320*de0e0e4dSAntonio Huete Jimenez 
321*de0e0e4dSAntonio Huete Jimenez 	if ((abs = ASN1_BIT_STRING_new()) == NULL)
322*de0e0e4dSAntonio Huete Jimenez 		goto err;
323*de0e0e4dSAntonio Huete Jimenez 
324*de0e0e4dSAntonio Huete Jimenez 	abs->data = data;
325*de0e0e4dSAntonio Huete Jimenez 	abs->length = (int)data_len;
326*de0e0e4dSAntonio Huete Jimenez 	data = NULL;
327f5b1c8a1SJohn Marino 
32872c33676SMaxim Ag 	/*
32972c33676SMaxim Ag 	 * We do this to preserve the settings. If we modify the settings,
33072c33676SMaxim Ag 	 * via the _set_bit function, we will recalculate on output.
33172c33676SMaxim Ag 	 */
332*de0e0e4dSAntonio Huete Jimenez 	if (!asn1_abs_set_unused_bits(abs, unused_bits)) {
333*de0e0e4dSAntonio Huete Jimenez 		ASN1error(ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
334f5b1c8a1SJohn Marino 		goto err;
335f5b1c8a1SJohn Marino 	}
336*de0e0e4dSAntonio Huete Jimenez 	if (abs->length > 0)
337*de0e0e4dSAntonio Huete Jimenez 		abs->data[abs->length - 1] &= 0xff << unused_bits;
338f5b1c8a1SJohn Marino 
339*de0e0e4dSAntonio Huete Jimenez 	*out_abs = abs;
340*de0e0e4dSAntonio Huete Jimenez 	abs = NULL;
34172c33676SMaxim Ag 
342*de0e0e4dSAntonio Huete Jimenez 	ret = 1;
343f5b1c8a1SJohn Marino 
344f5b1c8a1SJohn Marino  err:
345*de0e0e4dSAntonio Huete Jimenez 	ASN1_BIT_STRING_free(abs);
346*de0e0e4dSAntonio Huete Jimenez 	freezero(data, data_len);
34772c33676SMaxim Ag 
348*de0e0e4dSAntonio Huete Jimenez 	return ret;
349*de0e0e4dSAntonio Huete Jimenez }
350*de0e0e4dSAntonio Huete Jimenez 
351*de0e0e4dSAntonio Huete Jimenez ASN1_BIT_STRING *
c2i_ASN1_BIT_STRING(ASN1_BIT_STRING ** out_abs,const unsigned char ** pp,long len)352*de0e0e4dSAntonio Huete Jimenez c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **out_abs, const unsigned char **pp, long len)
353*de0e0e4dSAntonio Huete Jimenez {
354*de0e0e4dSAntonio Huete Jimenez 	ASN1_BIT_STRING *abs = NULL;
355*de0e0e4dSAntonio Huete Jimenez 	CBS content;
356*de0e0e4dSAntonio Huete Jimenez 
357*de0e0e4dSAntonio Huete Jimenez 	if (out_abs != NULL) {
358*de0e0e4dSAntonio Huete Jimenez 		ASN1_BIT_STRING_free(*out_abs);
359*de0e0e4dSAntonio Huete Jimenez 		*out_abs = NULL;
360*de0e0e4dSAntonio Huete Jimenez 	}
361*de0e0e4dSAntonio Huete Jimenez 
362*de0e0e4dSAntonio Huete Jimenez 	if (len < 0) {
363*de0e0e4dSAntonio Huete Jimenez 		ASN1error(ASN1_R_LENGTH_ERROR);
364*de0e0e4dSAntonio Huete Jimenez 		return NULL;
365*de0e0e4dSAntonio Huete Jimenez 	}
366*de0e0e4dSAntonio Huete Jimenez 
367*de0e0e4dSAntonio Huete Jimenez 	CBS_init(&content, *pp, len);
368*de0e0e4dSAntonio Huete Jimenez 
369*de0e0e4dSAntonio Huete Jimenez 	if (!c2i_ASN1_BIT_STRING_cbs(&abs, &content))
370*de0e0e4dSAntonio Huete Jimenez 		return NULL;
371*de0e0e4dSAntonio Huete Jimenez 
372*de0e0e4dSAntonio Huete Jimenez 	*pp = CBS_data(&content);
373*de0e0e4dSAntonio Huete Jimenez 
374*de0e0e4dSAntonio Huete Jimenez 	if (out_abs != NULL)
375*de0e0e4dSAntonio Huete Jimenez 		*out_abs = abs;
376*de0e0e4dSAntonio Huete Jimenez 
377*de0e0e4dSAntonio Huete Jimenez 	return abs;
378f5b1c8a1SJohn Marino }
379f5b1c8a1SJohn Marino 
380f5b1c8a1SJohn Marino int
i2d_ASN1_BIT_STRING(ASN1_BIT_STRING * a,unsigned char ** out)381*de0e0e4dSAntonio Huete Jimenez i2d_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **out)
382f5b1c8a1SJohn Marino {
383*de0e0e4dSAntonio Huete Jimenez 	return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_BIT_STRING_it);
384f5b1c8a1SJohn Marino }
385f5b1c8a1SJohn Marino 
386*de0e0e4dSAntonio Huete Jimenez ASN1_BIT_STRING *
d2i_ASN1_BIT_STRING(ASN1_BIT_STRING ** a,const unsigned char ** in,long len)387*de0e0e4dSAntonio Huete Jimenez d2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, const unsigned char **in, long len)
388f5b1c8a1SJohn Marino {
389*de0e0e4dSAntonio Huete Jimenez 	return (ASN1_BIT_STRING *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
390*de0e0e4dSAntonio Huete Jimenez 	    &ASN1_BIT_STRING_it);
391f5b1c8a1SJohn Marino }
392