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