xref: /dragonfly/crypto/libressl/crypto/asn1/a_int.c (revision de0e0e4d)
1*de0e0e4dSAntonio Huete Jimenez /* $OpenBSD: a_int.c,v 1.46 2022/08/28 17:49:25 jsing 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 
5972c33676SMaxim Ag #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>
65f5b1c8a1SJohn Marino #include <openssl/bn.h>
66*de0e0e4dSAntonio Huete Jimenez #include <openssl/buffer.h>
67f5b1c8a1SJohn Marino #include <openssl/err.h>
68f5b1c8a1SJohn Marino 
69*de0e0e4dSAntonio Huete Jimenez #include "bytestring.h"
70*de0e0e4dSAntonio Huete Jimenez 
71*de0e0e4dSAntonio Huete Jimenez const ASN1_ITEM ASN1_INTEGER_it = {
72*de0e0e4dSAntonio Huete Jimenez 	.itype = ASN1_ITYPE_PRIMITIVE,
73*de0e0e4dSAntonio Huete Jimenez 	.utype = V_ASN1_INTEGER,
74*de0e0e4dSAntonio Huete Jimenez 	.sname = "ASN1_INTEGER",
75*de0e0e4dSAntonio Huete Jimenez };
76*de0e0e4dSAntonio Huete Jimenez 
77*de0e0e4dSAntonio Huete Jimenez ASN1_INTEGER *
ASN1_INTEGER_new(void)78*de0e0e4dSAntonio Huete Jimenez ASN1_INTEGER_new(void)
79*de0e0e4dSAntonio Huete Jimenez {
80*de0e0e4dSAntonio Huete Jimenez 	return (ASN1_INTEGER *)ASN1_item_new(&ASN1_INTEGER_it);
81*de0e0e4dSAntonio Huete Jimenez }
82*de0e0e4dSAntonio Huete Jimenez 
83*de0e0e4dSAntonio Huete Jimenez static void
asn1_aint_clear(ASN1_INTEGER * aint)84*de0e0e4dSAntonio Huete Jimenez asn1_aint_clear(ASN1_INTEGER *aint)
85*de0e0e4dSAntonio Huete Jimenez {
86*de0e0e4dSAntonio Huete Jimenez 	freezero(aint->data, aint->length);
87*de0e0e4dSAntonio Huete Jimenez 
88*de0e0e4dSAntonio Huete Jimenez 	memset(aint, 0, sizeof(*aint));
89*de0e0e4dSAntonio Huete Jimenez 
90*de0e0e4dSAntonio Huete Jimenez 	aint->type = V_ASN1_INTEGER;
91*de0e0e4dSAntonio Huete Jimenez }
92*de0e0e4dSAntonio Huete Jimenez 
93*de0e0e4dSAntonio Huete Jimenez void
ASN1_INTEGER_free(ASN1_INTEGER * a)94*de0e0e4dSAntonio Huete Jimenez ASN1_INTEGER_free(ASN1_INTEGER *a)
95*de0e0e4dSAntonio Huete Jimenez {
96*de0e0e4dSAntonio Huete Jimenez 	ASN1_item_free((ASN1_VALUE *)a, &ASN1_INTEGER_it);
97*de0e0e4dSAntonio Huete Jimenez }
98*de0e0e4dSAntonio Huete Jimenez 
9972c33676SMaxim Ag static int
ASN1_INTEGER_valid(const ASN1_INTEGER * a)10072c33676SMaxim Ag ASN1_INTEGER_valid(const ASN1_INTEGER *a)
10172c33676SMaxim Ag {
10272c33676SMaxim Ag 	return (a != NULL && a->length >= 0);
10372c33676SMaxim Ag }
10472c33676SMaxim Ag 
105f5b1c8a1SJohn Marino ASN1_INTEGER *
ASN1_INTEGER_dup(const ASN1_INTEGER * x)106f5b1c8a1SJohn Marino ASN1_INTEGER_dup(const ASN1_INTEGER *x)
107f5b1c8a1SJohn Marino {
10872c33676SMaxim Ag 	if (!ASN1_INTEGER_valid(x))
10972c33676SMaxim Ag 		return NULL;
11072c33676SMaxim Ag 
111f5b1c8a1SJohn Marino 	return ASN1_STRING_dup(x);
112f5b1c8a1SJohn Marino }
113f5b1c8a1SJohn Marino 
114f5b1c8a1SJohn Marino int
ASN1_INTEGER_cmp(const ASN1_INTEGER * a,const ASN1_INTEGER * b)115*de0e0e4dSAntonio Huete Jimenez ASN1_INTEGER_cmp(const ASN1_INTEGER *a, const ASN1_INTEGER *b)
116f5b1c8a1SJohn Marino {
117*de0e0e4dSAntonio Huete Jimenez 	int ret = 1;
118f5b1c8a1SJohn Marino 
119*de0e0e4dSAntonio Huete Jimenez 	/* Compare sign, then content. */
120*de0e0e4dSAntonio Huete Jimenez 	if ((a->type & V_ASN1_NEG) == (b->type & V_ASN1_NEG))
121*de0e0e4dSAntonio Huete Jimenez 		ret = ASN1_STRING_cmp(a, b);
122f5b1c8a1SJohn Marino 
123*de0e0e4dSAntonio Huete Jimenez 	if ((a->type & V_ASN1_NEG) != 0)
124f5b1c8a1SJohn Marino 		return -ret;
125*de0e0e4dSAntonio Huete Jimenez 
126f5b1c8a1SJohn Marino 	return ret;
127f5b1c8a1SJohn Marino }
128f5b1c8a1SJohn Marino 
129*de0e0e4dSAntonio Huete Jimenez int
asn1_aint_get_uint64(CBS * cbs,uint64_t * out_val)130*de0e0e4dSAntonio Huete Jimenez asn1_aint_get_uint64(CBS *cbs, uint64_t *out_val)
131*de0e0e4dSAntonio Huete Jimenez {
132*de0e0e4dSAntonio Huete Jimenez 	uint64_t val = 0;
133*de0e0e4dSAntonio Huete Jimenez 	uint8_t u8;
134f5b1c8a1SJohn Marino 
135*de0e0e4dSAntonio Huete Jimenez 	*out_val = 0;
136*de0e0e4dSAntonio Huete Jimenez 
137*de0e0e4dSAntonio Huete Jimenez 	while (CBS_len(cbs) > 0) {
138*de0e0e4dSAntonio Huete Jimenez 		if (!CBS_get_u8(cbs, &u8))
139*de0e0e4dSAntonio Huete Jimenez 			return 0;
140*de0e0e4dSAntonio Huete Jimenez 		if (val > (UINT64_MAX >> 8)) {
141*de0e0e4dSAntonio Huete Jimenez 			ASN1error(ASN1_R_TOO_LARGE);
142*de0e0e4dSAntonio Huete Jimenez 			return 0;
143*de0e0e4dSAntonio Huete Jimenez 		}
144*de0e0e4dSAntonio Huete Jimenez 		val = val << 8 | u8;
145*de0e0e4dSAntonio Huete Jimenez 	}
146*de0e0e4dSAntonio Huete Jimenez 
147*de0e0e4dSAntonio Huete Jimenez 	*out_val = val;
148*de0e0e4dSAntonio Huete Jimenez 
149*de0e0e4dSAntonio Huete Jimenez 	return 1;
150*de0e0e4dSAntonio Huete Jimenez }
151f5b1c8a1SJohn Marino 
152f5b1c8a1SJohn Marino int
asn1_aint_set_uint64(uint64_t val,uint8_t ** out_data,int * out_len)153*de0e0e4dSAntonio Huete Jimenez asn1_aint_set_uint64(uint64_t val, uint8_t **out_data, int *out_len)
154f5b1c8a1SJohn Marino {
155*de0e0e4dSAntonio Huete Jimenez 	uint8_t *data = NULL;
156*de0e0e4dSAntonio Huete Jimenez 	size_t data_len = 0;
157*de0e0e4dSAntonio Huete Jimenez 	int started = 0;
158*de0e0e4dSAntonio Huete Jimenez 	uint8_t u8;
159*de0e0e4dSAntonio Huete Jimenez 	CBB cbb;
160*de0e0e4dSAntonio Huete Jimenez 	int i;
161*de0e0e4dSAntonio Huete Jimenez 	int ret = 0;
162f5b1c8a1SJohn Marino 
163*de0e0e4dSAntonio Huete Jimenez 	if (!CBB_init(&cbb, sizeof(long)))
164*de0e0e4dSAntonio Huete Jimenez 		goto err;
165*de0e0e4dSAntonio Huete Jimenez 
166*de0e0e4dSAntonio Huete Jimenez 	if (out_data == NULL || out_len == NULL)
167*de0e0e4dSAntonio Huete Jimenez 		goto err;
168*de0e0e4dSAntonio Huete Jimenez 	if (*out_data != NULL || *out_len != 0)
169*de0e0e4dSAntonio Huete Jimenez 		goto err;
170*de0e0e4dSAntonio Huete Jimenez 
171*de0e0e4dSAntonio Huete Jimenez 	for (i = sizeof(uint64_t) - 1; i >= 0; i--) {
172*de0e0e4dSAntonio Huete Jimenez 		u8 = (val >> (i * 8)) & 0xff;
173*de0e0e4dSAntonio Huete Jimenez 		if (!started && i != 0 && u8 == 0)
174*de0e0e4dSAntonio Huete Jimenez 			continue;
175*de0e0e4dSAntonio Huete Jimenez 		if (!CBB_add_u8(&cbb, u8))
176*de0e0e4dSAntonio Huete Jimenez 			goto err;
177*de0e0e4dSAntonio Huete Jimenez 		started = 1;
178*de0e0e4dSAntonio Huete Jimenez 	}
179*de0e0e4dSAntonio Huete Jimenez 
180*de0e0e4dSAntonio Huete Jimenez 	if (!CBB_finish(&cbb, &data, &data_len))
181*de0e0e4dSAntonio Huete Jimenez 		goto err;
182*de0e0e4dSAntonio Huete Jimenez 	if (data_len > INT_MAX)
183*de0e0e4dSAntonio Huete Jimenez 		goto err;
184*de0e0e4dSAntonio Huete Jimenez 
185*de0e0e4dSAntonio Huete Jimenez 	*out_data = data;
186*de0e0e4dSAntonio Huete Jimenez 	*out_len = (int)data_len;
187*de0e0e4dSAntonio Huete Jimenez 	data = NULL;
188*de0e0e4dSAntonio Huete Jimenez 
189*de0e0e4dSAntonio Huete Jimenez 	ret = 1;
190*de0e0e4dSAntonio Huete Jimenez  err:
191*de0e0e4dSAntonio Huete Jimenez 	CBB_cleanup(&cbb);
192*de0e0e4dSAntonio Huete Jimenez 	freezero(data, data_len);
193*de0e0e4dSAntonio Huete Jimenez 
194*de0e0e4dSAntonio Huete Jimenez 	return ret;
195*de0e0e4dSAntonio Huete Jimenez }
196*de0e0e4dSAntonio Huete Jimenez 
197*de0e0e4dSAntonio Huete Jimenez int
asn1_aint_get_int64(CBS * cbs,int negative,int64_t * out_val)198*de0e0e4dSAntonio Huete Jimenez asn1_aint_get_int64(CBS *cbs, int negative, int64_t *out_val)
199*de0e0e4dSAntonio Huete Jimenez {
200*de0e0e4dSAntonio Huete Jimenez 	uint64_t val;
201*de0e0e4dSAntonio Huete Jimenez 
202*de0e0e4dSAntonio Huete Jimenez 	if (!asn1_aint_get_uint64(cbs, &val))
20372c33676SMaxim Ag 		return 0;
20472c33676SMaxim Ag 
205*de0e0e4dSAntonio Huete Jimenez 	if (negative) {
206*de0e0e4dSAntonio Huete Jimenez 		if (val > (uint64_t)INT64_MIN) {
207*de0e0e4dSAntonio Huete Jimenez 			ASN1error(ASN1_R_TOO_SMALL);
208*de0e0e4dSAntonio Huete Jimenez 			return 0;
209f5b1c8a1SJohn Marino 		}
210*de0e0e4dSAntonio Huete Jimenez 		*out_val = (int64_t)-val;
211*de0e0e4dSAntonio Huete Jimenez 	} else {
212*de0e0e4dSAntonio Huete Jimenez 		if (val > (uint64_t)INT64_MAX) {
213*de0e0e4dSAntonio Huete Jimenez 			ASN1error(ASN1_R_TOO_LARGE);
214*de0e0e4dSAntonio Huete Jimenez 			return 0;
215f5b1c8a1SJohn Marino 		}
216*de0e0e4dSAntonio Huete Jimenez 		*out_val = (int64_t)val;
217f5b1c8a1SJohn Marino 	}
218f5b1c8a1SJohn Marino 
219*de0e0e4dSAntonio Huete Jimenez 	return 1;
220f5b1c8a1SJohn Marino }
221f5b1c8a1SJohn Marino 
222*de0e0e4dSAntonio Huete Jimenez int
ASN1_INTEGER_get_uint64(uint64_t * out_val,const ASN1_INTEGER * aint)223*de0e0e4dSAntonio Huete Jimenez ASN1_INTEGER_get_uint64(uint64_t *out_val, const ASN1_INTEGER *aint)
224*de0e0e4dSAntonio Huete Jimenez {
225*de0e0e4dSAntonio Huete Jimenez 	uint64_t val;
226*de0e0e4dSAntonio Huete Jimenez 	CBS cbs;
227*de0e0e4dSAntonio Huete Jimenez 
228*de0e0e4dSAntonio Huete Jimenez 	*out_val = 0;
229*de0e0e4dSAntonio Huete Jimenez 
230*de0e0e4dSAntonio Huete Jimenez 	if (aint == NULL || aint->length < 0)
231*de0e0e4dSAntonio Huete Jimenez 		return 0;
232*de0e0e4dSAntonio Huete Jimenez 
233*de0e0e4dSAntonio Huete Jimenez 	if (aint->type == V_ASN1_NEG_INTEGER) {
234*de0e0e4dSAntonio Huete Jimenez 		ASN1error(ASN1_R_ILLEGAL_NEGATIVE_VALUE);
235*de0e0e4dSAntonio Huete Jimenez 		return 0;
236*de0e0e4dSAntonio Huete Jimenez 	}
237*de0e0e4dSAntonio Huete Jimenez 	if (aint->type != V_ASN1_INTEGER) {
238*de0e0e4dSAntonio Huete Jimenez 		ASN1error(ASN1_R_WRONG_INTEGER_TYPE);
239*de0e0e4dSAntonio Huete Jimenez 		return 0;
240*de0e0e4dSAntonio Huete Jimenez 	}
241*de0e0e4dSAntonio Huete Jimenez 
242*de0e0e4dSAntonio Huete Jimenez 	CBS_init(&cbs, aint->data, aint->length);
243*de0e0e4dSAntonio Huete Jimenez 
244*de0e0e4dSAntonio Huete Jimenez 	if (!asn1_aint_get_uint64(&cbs, &val))
245*de0e0e4dSAntonio Huete Jimenez 		return 0;
246*de0e0e4dSAntonio Huete Jimenez 
247*de0e0e4dSAntonio Huete Jimenez 	*out_val = val;
248*de0e0e4dSAntonio Huete Jimenez 
249*de0e0e4dSAntonio Huete Jimenez 	return 1;
250*de0e0e4dSAntonio Huete Jimenez }
251*de0e0e4dSAntonio Huete Jimenez 
252*de0e0e4dSAntonio Huete Jimenez int
ASN1_INTEGER_set_uint64(ASN1_INTEGER * aint,uint64_t val)253*de0e0e4dSAntonio Huete Jimenez ASN1_INTEGER_set_uint64(ASN1_INTEGER *aint, uint64_t val)
254*de0e0e4dSAntonio Huete Jimenez {
255*de0e0e4dSAntonio Huete Jimenez 	asn1_aint_clear(aint);
256*de0e0e4dSAntonio Huete Jimenez 
257*de0e0e4dSAntonio Huete Jimenez 	return asn1_aint_set_uint64(val, &aint->data, &aint->length);
258*de0e0e4dSAntonio Huete Jimenez }
259*de0e0e4dSAntonio Huete Jimenez 
260*de0e0e4dSAntonio Huete Jimenez int
ASN1_INTEGER_get_int64(int64_t * out_val,const ASN1_INTEGER * aint)261*de0e0e4dSAntonio Huete Jimenez ASN1_INTEGER_get_int64(int64_t *out_val, const ASN1_INTEGER *aint)
262*de0e0e4dSAntonio Huete Jimenez {
263*de0e0e4dSAntonio Huete Jimenez 	CBS cbs;
264*de0e0e4dSAntonio Huete Jimenez 
265*de0e0e4dSAntonio Huete Jimenez 	*out_val = 0;
266*de0e0e4dSAntonio Huete Jimenez 
267*de0e0e4dSAntonio Huete Jimenez 	if (aint == NULL || aint->length < 0)
268*de0e0e4dSAntonio Huete Jimenez 		return 0;
269*de0e0e4dSAntonio Huete Jimenez 
270*de0e0e4dSAntonio Huete Jimenez 	if (aint->type != V_ASN1_INTEGER &&
271*de0e0e4dSAntonio Huete Jimenez 	    aint->type != V_ASN1_NEG_INTEGER) {
272*de0e0e4dSAntonio Huete Jimenez 		ASN1error(ASN1_R_WRONG_INTEGER_TYPE);
273*de0e0e4dSAntonio Huete Jimenez 		return 0;
274*de0e0e4dSAntonio Huete Jimenez 	}
275*de0e0e4dSAntonio Huete Jimenez 
276*de0e0e4dSAntonio Huete Jimenez 	CBS_init(&cbs, aint->data, aint->length);
277*de0e0e4dSAntonio Huete Jimenez 
278*de0e0e4dSAntonio Huete Jimenez 	return asn1_aint_get_int64(&cbs, (aint->type == V_ASN1_NEG_INTEGER),
279*de0e0e4dSAntonio Huete Jimenez 	    out_val);
280*de0e0e4dSAntonio Huete Jimenez }
281*de0e0e4dSAntonio Huete Jimenez 
282*de0e0e4dSAntonio Huete Jimenez int
ASN1_INTEGER_set_int64(ASN1_INTEGER * aint,int64_t val)283*de0e0e4dSAntonio Huete Jimenez ASN1_INTEGER_set_int64(ASN1_INTEGER *aint, int64_t val)
284*de0e0e4dSAntonio Huete Jimenez {
285*de0e0e4dSAntonio Huete Jimenez 	uint64_t uval;
286*de0e0e4dSAntonio Huete Jimenez 
287*de0e0e4dSAntonio Huete Jimenez 	asn1_aint_clear(aint);
288*de0e0e4dSAntonio Huete Jimenez 
289*de0e0e4dSAntonio Huete Jimenez 	uval = (uint64_t)val;
290*de0e0e4dSAntonio Huete Jimenez 
291*de0e0e4dSAntonio Huete Jimenez 	if (val < 0) {
292*de0e0e4dSAntonio Huete Jimenez 		aint->type = V_ASN1_NEG_INTEGER;
293*de0e0e4dSAntonio Huete Jimenez 		uval = -uval;
294*de0e0e4dSAntonio Huete Jimenez 	}
295*de0e0e4dSAntonio Huete Jimenez 
296*de0e0e4dSAntonio Huete Jimenez 	return asn1_aint_set_uint64(uval, &aint->data, &aint->length);
297*de0e0e4dSAntonio Huete Jimenez }
298*de0e0e4dSAntonio Huete Jimenez 
299*de0e0e4dSAntonio Huete Jimenez long
ASN1_INTEGER_get(const ASN1_INTEGER * aint)300*de0e0e4dSAntonio Huete Jimenez ASN1_INTEGER_get(const ASN1_INTEGER *aint)
301*de0e0e4dSAntonio Huete Jimenez {
302*de0e0e4dSAntonio Huete Jimenez 	int64_t val;
303*de0e0e4dSAntonio Huete Jimenez 
304*de0e0e4dSAntonio Huete Jimenez 	if (aint == NULL)
305*de0e0e4dSAntonio Huete Jimenez 		return 0;
306*de0e0e4dSAntonio Huete Jimenez 	if (!ASN1_INTEGER_get_int64(&val, aint))
307*de0e0e4dSAntonio Huete Jimenez 		return -1;
308*de0e0e4dSAntonio Huete Jimenez 	if (val < LONG_MIN || val > LONG_MAX) {
309*de0e0e4dSAntonio Huete Jimenez 		/* hmm... a bit ugly, return all ones */
310*de0e0e4dSAntonio Huete Jimenez 		return -1;
311*de0e0e4dSAntonio Huete Jimenez 	}
312*de0e0e4dSAntonio Huete Jimenez 
313*de0e0e4dSAntonio Huete Jimenez 	return (long)val;
314*de0e0e4dSAntonio Huete Jimenez }
315*de0e0e4dSAntonio Huete Jimenez 
316*de0e0e4dSAntonio Huete Jimenez int
ASN1_INTEGER_set(ASN1_INTEGER * aint,long val)317*de0e0e4dSAntonio Huete Jimenez ASN1_INTEGER_set(ASN1_INTEGER *aint, long val)
318*de0e0e4dSAntonio Huete Jimenez {
319*de0e0e4dSAntonio Huete Jimenez 	return ASN1_INTEGER_set_int64(aint, val);
320*de0e0e4dSAntonio Huete Jimenez }
321f5b1c8a1SJohn Marino 
322f5b1c8a1SJohn Marino ASN1_INTEGER *
BN_to_ASN1_INTEGER(const BIGNUM * bn,ASN1_INTEGER * ai)323*de0e0e4dSAntonio Huete Jimenez BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
324f5b1c8a1SJohn Marino {
325*de0e0e4dSAntonio Huete Jimenez 	ASN1_INTEGER *ret;
326*de0e0e4dSAntonio Huete Jimenez 	int len, j;
327f5b1c8a1SJohn Marino 
328*de0e0e4dSAntonio Huete Jimenez 	if (ai == NULL)
329*de0e0e4dSAntonio Huete Jimenez 		ret = ASN1_INTEGER_new();
330*de0e0e4dSAntonio Huete Jimenez 	else
331*de0e0e4dSAntonio Huete Jimenez 		ret = ai;
332*de0e0e4dSAntonio Huete Jimenez 	if (ret == NULL) {
333*de0e0e4dSAntonio Huete Jimenez 		ASN1error(ERR_R_NESTED_ASN1_ERROR);
33472c33676SMaxim Ag 		goto err;
33572c33676SMaxim Ag 	}
33672c33676SMaxim Ag 
337*de0e0e4dSAntonio Huete Jimenez 	if (!ASN1_INTEGER_valid(ret))
338*de0e0e4dSAntonio Huete Jimenez 		goto err;
339f5b1c8a1SJohn Marino 
340*de0e0e4dSAntonio Huete Jimenez 	if (BN_is_negative(bn))
341f5b1c8a1SJohn Marino 		ret->type = V_ASN1_NEG_INTEGER;
342*de0e0e4dSAntonio Huete Jimenez 	else
343f5b1c8a1SJohn Marino 		ret->type = V_ASN1_INTEGER;
344*de0e0e4dSAntonio Huete Jimenez 	j = BN_num_bits(bn);
345*de0e0e4dSAntonio Huete Jimenez 	len = ((j == 0) ? 0 : ((j / 8) + 1));
346*de0e0e4dSAntonio Huete Jimenez 	if (ret->length < len + 4) {
347*de0e0e4dSAntonio Huete Jimenez 		unsigned char *new_data = realloc(ret->data, len + 4);
348*de0e0e4dSAntonio Huete Jimenez 		if (!new_data) {
349*de0e0e4dSAntonio Huete Jimenez 			ASN1error(ERR_R_MALLOC_FAILURE);
350*de0e0e4dSAntonio Huete Jimenez 			goto err;
351f5b1c8a1SJohn Marino 		}
352*de0e0e4dSAntonio Huete Jimenez 		ret->data = new_data;
353f5b1c8a1SJohn Marino 	}
354*de0e0e4dSAntonio Huete Jimenez 	ret->length = BN_bn2bin(bn, ret->data);
355f5b1c8a1SJohn Marino 
356*de0e0e4dSAntonio Huete Jimenez 	/* Correct zero case */
357*de0e0e4dSAntonio Huete Jimenez 	if (!ret->length) {
358*de0e0e4dSAntonio Huete Jimenez 		ret->data[0] = 0;
359*de0e0e4dSAntonio Huete Jimenez 		ret->length = 1;
360*de0e0e4dSAntonio Huete Jimenez 	}
361f5b1c8a1SJohn Marino 	return (ret);
362f5b1c8a1SJohn Marino 
363f5b1c8a1SJohn Marino  err:
364*de0e0e4dSAntonio Huete Jimenez 	if (ret != ai)
365f5b1c8a1SJohn Marino 		ASN1_INTEGER_free(ret);
366f5b1c8a1SJohn Marino 	return (NULL);
367f5b1c8a1SJohn Marino }
368f5b1c8a1SJohn Marino 
369*de0e0e4dSAntonio Huete Jimenez BIGNUM *
ASN1_INTEGER_to_BN(const ASN1_INTEGER * ai,BIGNUM * bn)370*de0e0e4dSAntonio Huete Jimenez ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn)
371*de0e0e4dSAntonio Huete Jimenez {
372*de0e0e4dSAntonio Huete Jimenez 	BIGNUM *ret;
373*de0e0e4dSAntonio Huete Jimenez 
374*de0e0e4dSAntonio Huete Jimenez 	if (!ASN1_INTEGER_valid(ai))
375*de0e0e4dSAntonio Huete Jimenez 		return (NULL);
376*de0e0e4dSAntonio Huete Jimenez 
377*de0e0e4dSAntonio Huete Jimenez 	if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL)
378*de0e0e4dSAntonio Huete Jimenez 		ASN1error(ASN1_R_BN_LIB);
379*de0e0e4dSAntonio Huete Jimenez 	else if (ai->type == V_ASN1_NEG_INTEGER)
380*de0e0e4dSAntonio Huete Jimenez 		BN_set_negative(ret, 1);
381*de0e0e4dSAntonio Huete Jimenez 	return (ret);
382*de0e0e4dSAntonio Huete Jimenez }
383*de0e0e4dSAntonio Huete Jimenez 
384*de0e0e4dSAntonio Huete Jimenez int
i2a_ASN1_INTEGER(BIO * bp,const ASN1_INTEGER * a)385*de0e0e4dSAntonio Huete Jimenez i2a_ASN1_INTEGER(BIO *bp, const ASN1_INTEGER *a)
386*de0e0e4dSAntonio Huete Jimenez {
387*de0e0e4dSAntonio Huete Jimenez 	int i, n = 0;
388*de0e0e4dSAntonio Huete Jimenez 	static const char h[] = "0123456789ABCDEF";
389*de0e0e4dSAntonio Huete Jimenez 	char buf[2];
390*de0e0e4dSAntonio Huete Jimenez 
391*de0e0e4dSAntonio Huete Jimenez 	if (a == NULL)
392*de0e0e4dSAntonio Huete Jimenez 		return (0);
393*de0e0e4dSAntonio Huete Jimenez 
394*de0e0e4dSAntonio Huete Jimenez 	if (a->type & V_ASN1_NEG) {
395*de0e0e4dSAntonio Huete Jimenez 		if (BIO_write(bp, "-", 1) != 1)
396*de0e0e4dSAntonio Huete Jimenez 			goto err;
397*de0e0e4dSAntonio Huete Jimenez 		n = 1;
398*de0e0e4dSAntonio Huete Jimenez 	}
399*de0e0e4dSAntonio Huete Jimenez 
400*de0e0e4dSAntonio Huete Jimenez 	if (a->length == 0) {
401*de0e0e4dSAntonio Huete Jimenez 		if (BIO_write(bp, "00", 2) != 2)
402*de0e0e4dSAntonio Huete Jimenez 			goto err;
403*de0e0e4dSAntonio Huete Jimenez 		n += 2;
404*de0e0e4dSAntonio Huete Jimenez 	} else {
405*de0e0e4dSAntonio Huete Jimenez 		for (i = 0; i < a->length; i++) {
406*de0e0e4dSAntonio Huete Jimenez 			if ((i != 0) && (i % 35 == 0)) {
407*de0e0e4dSAntonio Huete Jimenez 				if (BIO_write(bp, "\\\n", 2) != 2)
408*de0e0e4dSAntonio Huete Jimenez 					goto err;
409*de0e0e4dSAntonio Huete Jimenez 				n += 2;
410*de0e0e4dSAntonio Huete Jimenez 			}
411*de0e0e4dSAntonio Huete Jimenez 			buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
412*de0e0e4dSAntonio Huete Jimenez 			buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
413*de0e0e4dSAntonio Huete Jimenez 			if (BIO_write(bp, buf, 2) != 2)
414*de0e0e4dSAntonio Huete Jimenez 				goto err;
415*de0e0e4dSAntonio Huete Jimenez 			n += 2;
416*de0e0e4dSAntonio Huete Jimenez 		}
417*de0e0e4dSAntonio Huete Jimenez 	}
418*de0e0e4dSAntonio Huete Jimenez 	return (n);
419*de0e0e4dSAntonio Huete Jimenez 
420*de0e0e4dSAntonio Huete Jimenez  err:
421*de0e0e4dSAntonio Huete Jimenez 	return (-1);
422*de0e0e4dSAntonio Huete Jimenez }
423*de0e0e4dSAntonio Huete Jimenez 
424*de0e0e4dSAntonio Huete Jimenez int
a2i_ASN1_INTEGER(BIO * bp,ASN1_INTEGER * bs,char * buf,int size)425*de0e0e4dSAntonio Huete Jimenez a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
426*de0e0e4dSAntonio Huete Jimenez {
427*de0e0e4dSAntonio Huete Jimenez 	int ret = 0;
428*de0e0e4dSAntonio Huete Jimenez 	int i, j,k, m,n, again, bufsize;
429*de0e0e4dSAntonio Huete Jimenez 	unsigned char *s = NULL, *sp;
430*de0e0e4dSAntonio Huete Jimenez 	unsigned char *bufp;
431*de0e0e4dSAntonio Huete Jimenez 	int num = 0, slen = 0, first = 1;
432*de0e0e4dSAntonio Huete Jimenez 
433*de0e0e4dSAntonio Huete Jimenez 	bs->type = V_ASN1_INTEGER;
434*de0e0e4dSAntonio Huete Jimenez 
435*de0e0e4dSAntonio Huete Jimenez 	bufsize = BIO_gets(bp, buf, size);
436*de0e0e4dSAntonio Huete Jimenez 	for (;;) {
437*de0e0e4dSAntonio Huete Jimenez 		if (bufsize < 1)
438*de0e0e4dSAntonio Huete Jimenez 			goto err_sl;
439*de0e0e4dSAntonio Huete Jimenez 		i = bufsize;
440*de0e0e4dSAntonio Huete Jimenez 		if (buf[i - 1] == '\n')
441*de0e0e4dSAntonio Huete Jimenez 			buf[--i] = '\0';
442*de0e0e4dSAntonio Huete Jimenez 		if (i == 0)
443*de0e0e4dSAntonio Huete Jimenez 			goto err_sl;
444*de0e0e4dSAntonio Huete Jimenez 		if (buf[i - 1] == '\r')
445*de0e0e4dSAntonio Huete Jimenez 			buf[--i] = '\0';
446*de0e0e4dSAntonio Huete Jimenez 		if (i == 0)
447*de0e0e4dSAntonio Huete Jimenez 			goto err_sl;
448*de0e0e4dSAntonio Huete Jimenez 		if (buf[i - 1] == '\\') {
449*de0e0e4dSAntonio Huete Jimenez 			i--;
450*de0e0e4dSAntonio Huete Jimenez 			again = 1;
451*de0e0e4dSAntonio Huete Jimenez 		} else
452*de0e0e4dSAntonio Huete Jimenez 			again = 0;
453*de0e0e4dSAntonio Huete Jimenez 		buf[i] = '\0';
454*de0e0e4dSAntonio Huete Jimenez 		if (i < 2)
455*de0e0e4dSAntonio Huete Jimenez 			goto err_sl;
456*de0e0e4dSAntonio Huete Jimenez 
457*de0e0e4dSAntonio Huete Jimenez 		bufp = (unsigned char *)buf;
458*de0e0e4dSAntonio Huete Jimenez 		if (first) {
459*de0e0e4dSAntonio Huete Jimenez 			first = 0;
460*de0e0e4dSAntonio Huete Jimenez 			if ((bufp[0] == '0') && (buf[1] == '0')) {
461*de0e0e4dSAntonio Huete Jimenez 				bufp += 2;
462*de0e0e4dSAntonio Huete Jimenez 				i -= 2;
463*de0e0e4dSAntonio Huete Jimenez 			}
464*de0e0e4dSAntonio Huete Jimenez 		}
465*de0e0e4dSAntonio Huete Jimenez 		k = 0;
466*de0e0e4dSAntonio Huete Jimenez 		if (i % 2 != 0) {
467*de0e0e4dSAntonio Huete Jimenez 			ASN1error(ASN1_R_ODD_NUMBER_OF_CHARS);
468*de0e0e4dSAntonio Huete Jimenez 			goto err;
469*de0e0e4dSAntonio Huete Jimenez 		}
470*de0e0e4dSAntonio Huete Jimenez 		i /= 2;
471*de0e0e4dSAntonio Huete Jimenez 		if (num + i > slen) {
472*de0e0e4dSAntonio Huete Jimenez 			if ((sp = recallocarray(s, slen, num + i, 1)) == NULL) {
473*de0e0e4dSAntonio Huete Jimenez 				ASN1error(ERR_R_MALLOC_FAILURE);
474*de0e0e4dSAntonio Huete Jimenez 				goto err;
475*de0e0e4dSAntonio Huete Jimenez 			}
476*de0e0e4dSAntonio Huete Jimenez 			s = sp;
477*de0e0e4dSAntonio Huete Jimenez 			slen = num + i;
478*de0e0e4dSAntonio Huete Jimenez 		}
479*de0e0e4dSAntonio Huete Jimenez 		for (j = 0; j < i; j++, k += 2) {
480*de0e0e4dSAntonio Huete Jimenez 			for (n = 0; n < 2; n++) {
481*de0e0e4dSAntonio Huete Jimenez 				m = bufp[k + n];
482*de0e0e4dSAntonio Huete Jimenez 				if ((m >= '0') && (m <= '9'))
483*de0e0e4dSAntonio Huete Jimenez 					m -= '0';
484*de0e0e4dSAntonio Huete Jimenez 				else if ((m >= 'a') && (m <= 'f'))
485*de0e0e4dSAntonio Huete Jimenez 					m = m - 'a' + 10;
486*de0e0e4dSAntonio Huete Jimenez 				else if ((m >= 'A') && (m <= 'F'))
487*de0e0e4dSAntonio Huete Jimenez 					m = m - 'A' + 10;
488*de0e0e4dSAntonio Huete Jimenez 				else {
489*de0e0e4dSAntonio Huete Jimenez 					ASN1error(ASN1_R_NON_HEX_CHARACTERS);
490*de0e0e4dSAntonio Huete Jimenez 					goto err;
491*de0e0e4dSAntonio Huete Jimenez 				}
492*de0e0e4dSAntonio Huete Jimenez 				s[num + j] <<= 4;
493*de0e0e4dSAntonio Huete Jimenez 				s[num + j] |= m;
494*de0e0e4dSAntonio Huete Jimenez 			}
495*de0e0e4dSAntonio Huete Jimenez 		}
496*de0e0e4dSAntonio Huete Jimenez 		num += i;
497*de0e0e4dSAntonio Huete Jimenez 		if (again)
498*de0e0e4dSAntonio Huete Jimenez 			bufsize = BIO_gets(bp, buf, size);
499*de0e0e4dSAntonio Huete Jimenez 		else
500*de0e0e4dSAntonio Huete Jimenez 			break;
501*de0e0e4dSAntonio Huete Jimenez 	}
502*de0e0e4dSAntonio Huete Jimenez 	bs->length = num;
503*de0e0e4dSAntonio Huete Jimenez 	bs->data = s;
504*de0e0e4dSAntonio Huete Jimenez 	return (1);
505*de0e0e4dSAntonio Huete Jimenez 
506*de0e0e4dSAntonio Huete Jimenez  err_sl:
507*de0e0e4dSAntonio Huete Jimenez 	ASN1error(ASN1_R_SHORT_LINE);
508*de0e0e4dSAntonio Huete Jimenez  err:
509*de0e0e4dSAntonio Huete Jimenez 	free(s);
510*de0e0e4dSAntonio Huete Jimenez 	return (ret);
511*de0e0e4dSAntonio Huete Jimenez }
512*de0e0e4dSAntonio Huete Jimenez 
513*de0e0e4dSAntonio Huete Jimenez static void
asn1_aint_twos_complement(uint8_t * data,size_t data_len)514*de0e0e4dSAntonio Huete Jimenez asn1_aint_twos_complement(uint8_t *data, size_t data_len)
515*de0e0e4dSAntonio Huete Jimenez {
516*de0e0e4dSAntonio Huete Jimenez 	uint8_t carry = 1;
517*de0e0e4dSAntonio Huete Jimenez 	ssize_t i;
518*de0e0e4dSAntonio Huete Jimenez 
519*de0e0e4dSAntonio Huete Jimenez 	for (i = data_len - 1; i >= 0; i--) {
520*de0e0e4dSAntonio Huete Jimenez 		data[i] = (data[i] ^ 0xff) + carry;
521*de0e0e4dSAntonio Huete Jimenez 		if (data[i] != 0)
522*de0e0e4dSAntonio Huete Jimenez 			carry = 0;
523*de0e0e4dSAntonio Huete Jimenez 	}
524*de0e0e4dSAntonio Huete Jimenez }
525*de0e0e4dSAntonio Huete Jimenez 
526*de0e0e4dSAntonio Huete Jimenez static int
asn1_aint_keep_twos_padding(const uint8_t * data,size_t data_len)527*de0e0e4dSAntonio Huete Jimenez asn1_aint_keep_twos_padding(const uint8_t *data, size_t data_len)
528*de0e0e4dSAntonio Huete Jimenez {
529*de0e0e4dSAntonio Huete Jimenez 	size_t i;
530*de0e0e4dSAntonio Huete Jimenez 
531*de0e0e4dSAntonio Huete Jimenez 	/*
532*de0e0e4dSAntonio Huete Jimenez 	 * If a two's complement value has a padding byte (0xff) and the rest
533*de0e0e4dSAntonio Huete Jimenez 	 * of the value is all zeros, the padding byte cannot be removed as when
534*de0e0e4dSAntonio Huete Jimenez 	 * converted from two's complement this becomes 0x01 (in the place of
535*de0e0e4dSAntonio Huete Jimenez 	 * the padding byte) followed by the same number of zero bytes.
536*de0e0e4dSAntonio Huete Jimenez 	 */
537*de0e0e4dSAntonio Huete Jimenez 	if (data_len <= 1 || data[0] != 0xff)
538*de0e0e4dSAntonio Huete Jimenez 		return 0;
539*de0e0e4dSAntonio Huete Jimenez 	for (i = 1; i < data_len; i++) {
540*de0e0e4dSAntonio Huete Jimenez 		if (data[i] != 0)
541*de0e0e4dSAntonio Huete Jimenez 			return 0;
542*de0e0e4dSAntonio Huete Jimenez 	}
543*de0e0e4dSAntonio Huete Jimenez 	return 1;
544*de0e0e4dSAntonio Huete Jimenez }
545*de0e0e4dSAntonio Huete Jimenez 
546*de0e0e4dSAntonio Huete Jimenez static int
i2c_ASN1_INTEGER_cbb(ASN1_INTEGER * aint,CBB * cbb)547*de0e0e4dSAntonio Huete Jimenez i2c_ASN1_INTEGER_cbb(ASN1_INTEGER *aint, CBB *cbb)
548*de0e0e4dSAntonio Huete Jimenez {
549*de0e0e4dSAntonio Huete Jimenez 	uint8_t *data = NULL;
550*de0e0e4dSAntonio Huete Jimenez 	size_t data_len = 0;
551*de0e0e4dSAntonio Huete Jimenez 	uint8_t padding, val;
552*de0e0e4dSAntonio Huete Jimenez 	uint8_t msb;
553*de0e0e4dSAntonio Huete Jimenez 	CBS cbs;
554*de0e0e4dSAntonio Huete Jimenez 	int ret = 0;
555*de0e0e4dSAntonio Huete Jimenez 
556*de0e0e4dSAntonio Huete Jimenez 	if (aint->length < 0)
557*de0e0e4dSAntonio Huete Jimenez 		goto err;
558*de0e0e4dSAntonio Huete Jimenez 	if (aint->data == NULL && aint->length != 0)
559*de0e0e4dSAntonio Huete Jimenez 		goto err;
560*de0e0e4dSAntonio Huete Jimenez 
561*de0e0e4dSAntonio Huete Jimenez 	if ((aint->type & ~V_ASN1_NEG) != V_ASN1_ENUMERATED &&
562*de0e0e4dSAntonio Huete Jimenez 	    (aint->type & ~V_ASN1_NEG) != V_ASN1_INTEGER)
563*de0e0e4dSAntonio Huete Jimenez 		goto err;
564*de0e0e4dSAntonio Huete Jimenez 
565*de0e0e4dSAntonio Huete Jimenez 	CBS_init(&cbs, aint->data, aint->length);
566*de0e0e4dSAntonio Huete Jimenez 
567*de0e0e4dSAntonio Huete Jimenez 	/* Find the first non-zero byte. */
568*de0e0e4dSAntonio Huete Jimenez 	while (CBS_len(&cbs) > 0) {
569*de0e0e4dSAntonio Huete Jimenez 		if (!CBS_peek_u8(&cbs, &val))
570*de0e0e4dSAntonio Huete Jimenez 			goto err;
571*de0e0e4dSAntonio Huete Jimenez 		if (val != 0)
572*de0e0e4dSAntonio Huete Jimenez 			break;
573*de0e0e4dSAntonio Huete Jimenez 		if (!CBS_skip(&cbs, 1))
574*de0e0e4dSAntonio Huete Jimenez 			goto err;
575*de0e0e4dSAntonio Huete Jimenez 	}
576*de0e0e4dSAntonio Huete Jimenez 
577*de0e0e4dSAntonio Huete Jimenez 	/* A zero value is encoded as a single octet. */
578*de0e0e4dSAntonio Huete Jimenez 	if (CBS_len(&cbs) == 0) {
579*de0e0e4dSAntonio Huete Jimenez 		if (!CBB_add_u8(cbb, 0))
580*de0e0e4dSAntonio Huete Jimenez 			goto err;
581*de0e0e4dSAntonio Huete Jimenez 		goto done;
582*de0e0e4dSAntonio Huete Jimenez 	}
583*de0e0e4dSAntonio Huete Jimenez 
584*de0e0e4dSAntonio Huete Jimenez 	if (!CBS_stow(&cbs, &data, &data_len))
585*de0e0e4dSAntonio Huete Jimenez 		goto err;
586*de0e0e4dSAntonio Huete Jimenez 
587*de0e0e4dSAntonio Huete Jimenez 	if ((aint->type & V_ASN1_NEG) != 0)
588*de0e0e4dSAntonio Huete Jimenez 		asn1_aint_twos_complement(data, data_len);
589*de0e0e4dSAntonio Huete Jimenez 
590*de0e0e4dSAntonio Huete Jimenez 	/* Topmost bit indicates sign, padding is all zeros or all ones. */
591*de0e0e4dSAntonio Huete Jimenez 	msb = (data[0] >> 7);
592*de0e0e4dSAntonio Huete Jimenez 	padding = (msb - 1) & 0xff;
593*de0e0e4dSAntonio Huete Jimenez 
594*de0e0e4dSAntonio Huete Jimenez 	/* See if we need a padding octet to avoid incorrect sign. */
595*de0e0e4dSAntonio Huete Jimenez 	if (((aint->type & V_ASN1_NEG) == 0 && msb == 1) ||
596*de0e0e4dSAntonio Huete Jimenez 	    ((aint->type & V_ASN1_NEG) != 0 && msb == 0)) {
597*de0e0e4dSAntonio Huete Jimenez 		if (!CBB_add_u8(cbb, padding))
598*de0e0e4dSAntonio Huete Jimenez 			goto err;
599*de0e0e4dSAntonio Huete Jimenez 	}
600*de0e0e4dSAntonio Huete Jimenez 	if (!CBB_add_bytes(cbb, data, data_len))
601*de0e0e4dSAntonio Huete Jimenez 		goto err;
602*de0e0e4dSAntonio Huete Jimenez 
603*de0e0e4dSAntonio Huete Jimenez  done:
604*de0e0e4dSAntonio Huete Jimenez 	ret = 1;
605*de0e0e4dSAntonio Huete Jimenez 
606*de0e0e4dSAntonio Huete Jimenez  err:
607*de0e0e4dSAntonio Huete Jimenez 	freezero(data, data_len);
608*de0e0e4dSAntonio Huete Jimenez 
609*de0e0e4dSAntonio Huete Jimenez 	return ret;
610*de0e0e4dSAntonio Huete Jimenez }
611*de0e0e4dSAntonio Huete Jimenez 
612*de0e0e4dSAntonio Huete Jimenez int
i2c_ASN1_INTEGER(ASN1_INTEGER * aint,unsigned char ** pp)613*de0e0e4dSAntonio Huete Jimenez i2c_ASN1_INTEGER(ASN1_INTEGER *aint, unsigned char **pp)
614*de0e0e4dSAntonio Huete Jimenez {
615*de0e0e4dSAntonio Huete Jimenez 	uint8_t *data = NULL;
616*de0e0e4dSAntonio Huete Jimenez 	size_t data_len = 0;
617*de0e0e4dSAntonio Huete Jimenez 	CBB cbb;
618*de0e0e4dSAntonio Huete Jimenez 	int ret = -3;
619*de0e0e4dSAntonio Huete Jimenez 
620*de0e0e4dSAntonio Huete Jimenez 	if (!CBB_init(&cbb, 0))
621*de0e0e4dSAntonio Huete Jimenez 		goto err;
622*de0e0e4dSAntonio Huete Jimenez 	if (!i2c_ASN1_INTEGER_cbb(aint, &cbb))
623*de0e0e4dSAntonio Huete Jimenez 		goto err;
624*de0e0e4dSAntonio Huete Jimenez 	if (!CBB_finish(&cbb, &data, &data_len))
625*de0e0e4dSAntonio Huete Jimenez 		goto err;
626*de0e0e4dSAntonio Huete Jimenez 	if (data_len > INT_MAX)
627*de0e0e4dSAntonio Huete Jimenez 		goto err;
628*de0e0e4dSAntonio Huete Jimenez 
629*de0e0e4dSAntonio Huete Jimenez 	if (pp != NULL) {
630*de0e0e4dSAntonio Huete Jimenez 		if ((uintptr_t)*pp > UINTPTR_MAX - data_len)
631*de0e0e4dSAntonio Huete Jimenez 			goto err;
632*de0e0e4dSAntonio Huete Jimenez 		memcpy(*pp, data, data_len);
633*de0e0e4dSAntonio Huete Jimenez 		*pp += data_len;
634*de0e0e4dSAntonio Huete Jimenez 	}
635*de0e0e4dSAntonio Huete Jimenez 
636*de0e0e4dSAntonio Huete Jimenez 	ret = data_len;
637*de0e0e4dSAntonio Huete Jimenez 
638*de0e0e4dSAntonio Huete Jimenez  err:
639*de0e0e4dSAntonio Huete Jimenez 	freezero(data, data_len);
640*de0e0e4dSAntonio Huete Jimenez 	CBB_cleanup(&cbb);
641*de0e0e4dSAntonio Huete Jimenez 
642*de0e0e4dSAntonio Huete Jimenez 	return ret;
643*de0e0e4dSAntonio Huete Jimenez }
644*de0e0e4dSAntonio Huete Jimenez 
645*de0e0e4dSAntonio Huete Jimenez int
c2i_ASN1_INTEGER_cbs(ASN1_INTEGER ** out_aint,CBS * cbs)646*de0e0e4dSAntonio Huete Jimenez c2i_ASN1_INTEGER_cbs(ASN1_INTEGER **out_aint, CBS *cbs)
647*de0e0e4dSAntonio Huete Jimenez {
648*de0e0e4dSAntonio Huete Jimenez 	ASN1_INTEGER *aint = NULL;
649*de0e0e4dSAntonio Huete Jimenez 	uint8_t *data = NULL;
650*de0e0e4dSAntonio Huete Jimenez 	size_t data_len = 0;
651*de0e0e4dSAntonio Huete Jimenez 	uint8_t padding, val;
652*de0e0e4dSAntonio Huete Jimenez 	uint8_t negative;
653*de0e0e4dSAntonio Huete Jimenez 	int ret = 0;
654*de0e0e4dSAntonio Huete Jimenez 
655*de0e0e4dSAntonio Huete Jimenez 	if (out_aint == NULL)
656*de0e0e4dSAntonio Huete Jimenez 		goto err;
657*de0e0e4dSAntonio Huete Jimenez 
658*de0e0e4dSAntonio Huete Jimenez 	if (*out_aint != NULL) {
659*de0e0e4dSAntonio Huete Jimenez 		ASN1_INTEGER_free(*out_aint);
660*de0e0e4dSAntonio Huete Jimenez 		*out_aint = NULL;
661*de0e0e4dSAntonio Huete Jimenez 	}
662*de0e0e4dSAntonio Huete Jimenez 
663*de0e0e4dSAntonio Huete Jimenez 	if (CBS_len(cbs) == 0) {
664*de0e0e4dSAntonio Huete Jimenez 		/* XXX INVALID ENCODING? */
665*de0e0e4dSAntonio Huete Jimenez 		ASN1error(ERR_R_ASN1_LENGTH_MISMATCH);
666*de0e0e4dSAntonio Huete Jimenez 		goto err;
667*de0e0e4dSAntonio Huete Jimenez 	}
668*de0e0e4dSAntonio Huete Jimenez 	if (!CBS_peek_u8(cbs, &val))
669*de0e0e4dSAntonio Huete Jimenez 		goto err;
670*de0e0e4dSAntonio Huete Jimenez 
671*de0e0e4dSAntonio Huete Jimenez 	/* Topmost bit indicates sign, padding is all zeros or all ones. */
672*de0e0e4dSAntonio Huete Jimenez 	negative = (val >> 7);
673*de0e0e4dSAntonio Huete Jimenez 	padding = ~(negative - 1) & 0xff;
674*de0e0e4dSAntonio Huete Jimenez 
675*de0e0e4dSAntonio Huete Jimenez 	/*
676*de0e0e4dSAntonio Huete Jimenez 	 * Ensure that the first 9 bits are not all zero or all one, as per
677*de0e0e4dSAntonio Huete Jimenez 	 * X.690 section 8.3.2. Remove the padding octet if possible.
678*de0e0e4dSAntonio Huete Jimenez 	 */
679*de0e0e4dSAntonio Huete Jimenez 	if (CBS_len(cbs) > 1 && val == padding) {
680*de0e0e4dSAntonio Huete Jimenez 		if (!asn1_aint_keep_twos_padding(CBS_data(cbs), CBS_len(cbs))) {
681*de0e0e4dSAntonio Huete Jimenez 			if (!CBS_get_u8(cbs, &padding))
682*de0e0e4dSAntonio Huete Jimenez 				goto err;
683*de0e0e4dSAntonio Huete Jimenez 			if (!CBS_peek_u8(cbs, &val))
684*de0e0e4dSAntonio Huete Jimenez 				goto err;
685*de0e0e4dSAntonio Huete Jimenez 			if ((val >> 7) == (padding >> 7)) {
686*de0e0e4dSAntonio Huete Jimenez 				/* XXX INVALID ENCODING? */
687*de0e0e4dSAntonio Huete Jimenez 				ASN1error(ERR_R_ASN1_LENGTH_MISMATCH);
688*de0e0e4dSAntonio Huete Jimenez 				goto err;
689*de0e0e4dSAntonio Huete Jimenez 			}
690*de0e0e4dSAntonio Huete Jimenez 		}
691*de0e0e4dSAntonio Huete Jimenez 	}
692*de0e0e4dSAntonio Huete Jimenez 
693*de0e0e4dSAntonio Huete Jimenez 	if (!CBS_stow(cbs, &data, &data_len))
694*de0e0e4dSAntonio Huete Jimenez 		goto err;
695*de0e0e4dSAntonio Huete Jimenez 	if (data_len > INT_MAX)
696*de0e0e4dSAntonio Huete Jimenez 		goto err;
697*de0e0e4dSAntonio Huete Jimenez 
698*de0e0e4dSAntonio Huete Jimenez 	if ((aint = ASN1_INTEGER_new()) == NULL)
699*de0e0e4dSAntonio Huete Jimenez 		goto err;
700*de0e0e4dSAntonio Huete Jimenez 
701*de0e0e4dSAntonio Huete Jimenez 	/*
702*de0e0e4dSAntonio Huete Jimenez 	 * Negative integers are handled as a separate type - convert from
703*de0e0e4dSAntonio Huete Jimenez 	 * two's complement for internal representation.
704*de0e0e4dSAntonio Huete Jimenez 	 */
705*de0e0e4dSAntonio Huete Jimenez 	if (negative) {
706*de0e0e4dSAntonio Huete Jimenez 		aint->type = V_ASN1_NEG_INTEGER;
707*de0e0e4dSAntonio Huete Jimenez 		asn1_aint_twos_complement(data, data_len);
708*de0e0e4dSAntonio Huete Jimenez 	}
709*de0e0e4dSAntonio Huete Jimenez 
710*de0e0e4dSAntonio Huete Jimenez 	aint->data = data;
711*de0e0e4dSAntonio Huete Jimenez 	aint->length = (int)data_len;
712*de0e0e4dSAntonio Huete Jimenez 	data = NULL;
713*de0e0e4dSAntonio Huete Jimenez 
714*de0e0e4dSAntonio Huete Jimenez 	*out_aint = aint;
715*de0e0e4dSAntonio Huete Jimenez 	aint = NULL;
716*de0e0e4dSAntonio Huete Jimenez 
717*de0e0e4dSAntonio Huete Jimenez 	ret = 1;
718*de0e0e4dSAntonio Huete Jimenez 
719*de0e0e4dSAntonio Huete Jimenez  err:
720*de0e0e4dSAntonio Huete Jimenez 	ASN1_INTEGER_free(aint);
721*de0e0e4dSAntonio Huete Jimenez 	freezero(data, data_len);
722*de0e0e4dSAntonio Huete Jimenez 
723*de0e0e4dSAntonio Huete Jimenez 	return ret;
724*de0e0e4dSAntonio Huete Jimenez }
725*de0e0e4dSAntonio Huete Jimenez 
726*de0e0e4dSAntonio Huete Jimenez ASN1_INTEGER *
c2i_ASN1_INTEGER(ASN1_INTEGER ** out_aint,const unsigned char ** pp,long len)727*de0e0e4dSAntonio Huete Jimenez c2i_ASN1_INTEGER(ASN1_INTEGER **out_aint, const unsigned char **pp, long len)
728*de0e0e4dSAntonio Huete Jimenez {
729*de0e0e4dSAntonio Huete Jimenez 	ASN1_INTEGER *aint = NULL;
730*de0e0e4dSAntonio Huete Jimenez 	CBS content;
731*de0e0e4dSAntonio Huete Jimenez 
732*de0e0e4dSAntonio Huete Jimenez 	if (out_aint != NULL) {
733*de0e0e4dSAntonio Huete Jimenez 		ASN1_INTEGER_free(*out_aint);
734*de0e0e4dSAntonio Huete Jimenez 		*out_aint = NULL;
735*de0e0e4dSAntonio Huete Jimenez 	}
736*de0e0e4dSAntonio Huete Jimenez 
737*de0e0e4dSAntonio Huete Jimenez 	if (len < 0) {
738*de0e0e4dSAntonio Huete Jimenez 		ASN1error(ASN1_R_LENGTH_ERROR);
739*de0e0e4dSAntonio Huete Jimenez 		return NULL;
740*de0e0e4dSAntonio Huete Jimenez 	}
741*de0e0e4dSAntonio Huete Jimenez 
742*de0e0e4dSAntonio Huete Jimenez 	CBS_init(&content, *pp, len);
743*de0e0e4dSAntonio Huete Jimenez 
744*de0e0e4dSAntonio Huete Jimenez 	if (!c2i_ASN1_INTEGER_cbs(&aint, &content))
745*de0e0e4dSAntonio Huete Jimenez 		return NULL;
746*de0e0e4dSAntonio Huete Jimenez 
747*de0e0e4dSAntonio Huete Jimenez 	*pp = CBS_data(&content);
748*de0e0e4dSAntonio Huete Jimenez 
749*de0e0e4dSAntonio Huete Jimenez 	if (out_aint != NULL)
750*de0e0e4dSAntonio Huete Jimenez 		*out_aint = aint;
751*de0e0e4dSAntonio Huete Jimenez 
752*de0e0e4dSAntonio Huete Jimenez 	return aint;
753*de0e0e4dSAntonio Huete Jimenez }
754*de0e0e4dSAntonio Huete Jimenez 
755*de0e0e4dSAntonio Huete Jimenez int
i2d_ASN1_INTEGER(ASN1_INTEGER * a,unsigned char ** out)756*de0e0e4dSAntonio Huete Jimenez i2d_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **out)
757*de0e0e4dSAntonio Huete Jimenez {
758*de0e0e4dSAntonio Huete Jimenez 	return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_INTEGER_it);
759*de0e0e4dSAntonio Huete Jimenez }
760*de0e0e4dSAntonio Huete Jimenez 
761*de0e0e4dSAntonio Huete Jimenez ASN1_INTEGER *
d2i_ASN1_INTEGER(ASN1_INTEGER ** a,const unsigned char ** in,long len)762*de0e0e4dSAntonio Huete Jimenez d2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **in, long len)
763*de0e0e4dSAntonio Huete Jimenez {
764*de0e0e4dSAntonio Huete Jimenez 	return (ASN1_INTEGER *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
765*de0e0e4dSAntonio Huete Jimenez 	    &ASN1_INTEGER_it);
766*de0e0e4dSAntonio Huete Jimenez }
767f5b1c8a1SJohn Marino 
768f5b1c8a1SJohn Marino /* This is a version of d2i_ASN1_INTEGER that ignores the sign bit of
769f5b1c8a1SJohn Marino  * ASN1 integers: some broken software can encode a positive INTEGER
770f5b1c8a1SJohn Marino  * with its MSB set as negative (it doesn't add a padding zero).
771f5b1c8a1SJohn Marino  */
772f5b1c8a1SJohn Marino 
773f5b1c8a1SJohn Marino ASN1_INTEGER *
d2i_ASN1_UINTEGER(ASN1_INTEGER ** a,const unsigned char ** pp,long length)774f5b1c8a1SJohn Marino d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, long length)
775f5b1c8a1SJohn Marino {
776f5b1c8a1SJohn Marino 	ASN1_INTEGER *ret = NULL;
777f5b1c8a1SJohn Marino 	const unsigned char *p;
778f5b1c8a1SJohn Marino 	unsigned char *s;
779f5b1c8a1SJohn Marino 	long len;
780f5b1c8a1SJohn Marino 	int inf, tag, xclass;
781f5b1c8a1SJohn Marino 	int i;
782f5b1c8a1SJohn Marino 
783f5b1c8a1SJohn Marino 	if ((a == NULL) || ((*a) == NULL)) {
784f5b1c8a1SJohn Marino 		if ((ret = ASN1_INTEGER_new()) == NULL)
785f5b1c8a1SJohn Marino 			return (NULL);
786f5b1c8a1SJohn Marino 	} else
787f5b1c8a1SJohn Marino 		ret = (*a);
788f5b1c8a1SJohn Marino 
78972c33676SMaxim Ag 	if (!ASN1_INTEGER_valid(ret)) {
79072c33676SMaxim Ag 		i = ERR_R_ASN1_LENGTH_MISMATCH;
79172c33676SMaxim Ag 		goto err;
79272c33676SMaxim Ag 	}
79372c33676SMaxim Ag 
794f5b1c8a1SJohn Marino 	p = *pp;
795f5b1c8a1SJohn Marino 	inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
796f5b1c8a1SJohn Marino 	if (inf & 0x80) {
797f5b1c8a1SJohn Marino 		i = ASN1_R_BAD_OBJECT_HEADER;
798f5b1c8a1SJohn Marino 		goto err;
799f5b1c8a1SJohn Marino 	}
800f5b1c8a1SJohn Marino 
801f5b1c8a1SJohn Marino 	if (tag != V_ASN1_INTEGER) {
802f5b1c8a1SJohn Marino 		i = ASN1_R_EXPECTING_AN_INTEGER;
803f5b1c8a1SJohn Marino 		goto err;
804f5b1c8a1SJohn Marino 	}
805f5b1c8a1SJohn Marino 
806f5b1c8a1SJohn Marino 	/* We must malloc stuff, even for 0 bytes otherwise it
807f5b1c8a1SJohn Marino 	 * signifies a missing NULL parameter. */
80872c33676SMaxim Ag 	if (len < 0 || len > INT_MAX) {
80972c33676SMaxim Ag 		i = ERR_R_ASN1_LENGTH_MISMATCH;
81072c33676SMaxim Ag 		goto err;
81172c33676SMaxim Ag 	}
812f5b1c8a1SJohn Marino 	s = malloc(len + 1);
813f5b1c8a1SJohn Marino 	if (s == NULL) {
814f5b1c8a1SJohn Marino 		i = ERR_R_MALLOC_FAILURE;
815f5b1c8a1SJohn Marino 		goto err;
816f5b1c8a1SJohn Marino 	}
817f5b1c8a1SJohn Marino 	ret->type = V_ASN1_INTEGER;
818f5b1c8a1SJohn Marino 	if (len) {
819f5b1c8a1SJohn Marino 		if ((*p == 0) && (len != 1)) {
820f5b1c8a1SJohn Marino 			p++;
821f5b1c8a1SJohn Marino 			len--;
822f5b1c8a1SJohn Marino 		}
823f5b1c8a1SJohn Marino 		memcpy(s, p, len);
824f5b1c8a1SJohn Marino 		p += len;
825f5b1c8a1SJohn Marino 	}
826f5b1c8a1SJohn Marino 
827f5b1c8a1SJohn Marino 	free(ret->data);
828f5b1c8a1SJohn Marino 	ret->data = s;
829f5b1c8a1SJohn Marino 	ret->length = (int)len;
830f5b1c8a1SJohn Marino 	if (a != NULL)
831f5b1c8a1SJohn Marino 		(*a) = ret;
832f5b1c8a1SJohn Marino 	*pp = p;
833f5b1c8a1SJohn Marino 	return (ret);
834f5b1c8a1SJohn Marino 
835f5b1c8a1SJohn Marino  err:
83672c33676SMaxim Ag 	ASN1error(i);
837f5b1c8a1SJohn Marino 	if (a == NULL || *a != ret)
838f5b1c8a1SJohn Marino 		ASN1_INTEGER_free(ret);
839f5b1c8a1SJohn Marino 	return (NULL);
840f5b1c8a1SJohn Marino }
841