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