xref: /openbsd/lib/libcrypto/asn1/a_int.c (revision acf64401)
1 /* $OpenBSD: a_int.c,v 1.47 2023/07/05 21:23:36 beck Exp $ */
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3  * All rights reserved.
4  *
5  * This package is an SSL implementation written
6  * by Eric Young (eay@cryptsoft.com).
7  * The implementation was written so as to conform with Netscapes SSL.
8  *
9  * This library is free for commercial and non-commercial use as long as
10  * the following conditions are aheared to.  The following conditions
11  * apply to all code found in this distribution, be it the RC4, RSA,
12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13  * included with this distribution is covered by the same copyright terms
14  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15  *
16  * Copyright remains Eric Young's, and as such any Copyright notices in
17  * the code are not to be removed.
18  * If this package is used in a product, Eric Young should be given attribution
19  * as the author of the parts of the library used.
20  * This can be in the form of a textual message at program startup or
21  * in documentation (online or textual) provided with the package.
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  *    notice, this list of conditions and the following disclaimer in the
30  *    documentation and/or other materials provided with the distribution.
31  * 3. All advertising materials mentioning features or use of this software
32  *    must display the following acknowledgement:
33  *    "This product includes cryptographic software written by
34  *     Eric Young (eay@cryptsoft.com)"
35  *    The word 'cryptographic' can be left out if the rouines from the library
36  *    being used are not cryptographic related :-).
37  * 4. If you include any Windows specific code (or a derivative thereof) from
38  *    the apps directory (application code) you must include an acknowledgement:
39  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40  *
41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  *
53  * The licence and distribution terms for any publically available version or
54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55  * copied and put under another distribution licence
56  * [including the GNU Public Licence.]
57  */
58 
59 #include <limits.h>
60 #include <stdio.h>
61 #include <string.h>
62 
63 #include <openssl/asn1.h>
64 #include <openssl/asn1t.h>
65 #include <openssl/bn.h>
66 #include <openssl/buffer.h>
67 #include <openssl/err.h>
68 
69 #include "bytestring.h"
70 
71 const ASN1_ITEM ASN1_INTEGER_it = {
72 	.itype = ASN1_ITYPE_PRIMITIVE,
73 	.utype = V_ASN1_INTEGER,
74 	.sname = "ASN1_INTEGER",
75 };
76 
77 ASN1_INTEGER *
ASN1_INTEGER_new(void)78 ASN1_INTEGER_new(void)
79 {
80 	return (ASN1_INTEGER *)ASN1_item_new(&ASN1_INTEGER_it);
81 }
82 LCRYPTO_ALIAS(ASN1_INTEGER_new);
83 
84 static void
asn1_aint_clear(ASN1_INTEGER * aint)85 asn1_aint_clear(ASN1_INTEGER *aint)
86 {
87 	freezero(aint->data, aint->length);
88 
89 	memset(aint, 0, sizeof(*aint));
90 
91 	aint->type = V_ASN1_INTEGER;
92 }
93 
94 void
ASN1_INTEGER_free(ASN1_INTEGER * a)95 ASN1_INTEGER_free(ASN1_INTEGER *a)
96 {
97 	ASN1_item_free((ASN1_VALUE *)a, &ASN1_INTEGER_it);
98 }
99 LCRYPTO_ALIAS(ASN1_INTEGER_free);
100 
101 static int
ASN1_INTEGER_valid(const ASN1_INTEGER * a)102 ASN1_INTEGER_valid(const ASN1_INTEGER *a)
103 {
104 	return (a != NULL && a->length >= 0);
105 }
106 
107 ASN1_INTEGER *
ASN1_INTEGER_dup(const ASN1_INTEGER * x)108 ASN1_INTEGER_dup(const ASN1_INTEGER *x)
109 {
110 	if (!ASN1_INTEGER_valid(x))
111 		return NULL;
112 
113 	return ASN1_STRING_dup(x);
114 }
115 LCRYPTO_ALIAS(ASN1_INTEGER_dup);
116 
117 int
ASN1_INTEGER_cmp(const ASN1_INTEGER * a,const ASN1_INTEGER * b)118 ASN1_INTEGER_cmp(const ASN1_INTEGER *a, const ASN1_INTEGER *b)
119 {
120 	int ret = 1;
121 
122 	/* Compare sign, then content. */
123 	if ((a->type & V_ASN1_NEG) == (b->type & V_ASN1_NEG))
124 		ret = ASN1_STRING_cmp(a, b);
125 
126 	if ((a->type & V_ASN1_NEG) != 0)
127 		return -ret;
128 
129 	return ret;
130 }
131 LCRYPTO_ALIAS(ASN1_INTEGER_cmp);
132 
133 int
asn1_aint_get_uint64(CBS * cbs,uint64_t * out_val)134 asn1_aint_get_uint64(CBS *cbs, uint64_t *out_val)
135 {
136 	uint64_t val = 0;
137 	uint8_t u8;
138 
139 	*out_val = 0;
140 
141 	while (CBS_len(cbs) > 0) {
142 		if (!CBS_get_u8(cbs, &u8))
143 			return 0;
144 		if (val > (UINT64_MAX >> 8)) {
145 			ASN1error(ASN1_R_TOO_LARGE);
146 			return 0;
147 		}
148 		val = val << 8 | u8;
149 	}
150 
151 	*out_val = val;
152 
153 	return 1;
154 }
155 
156 int
asn1_aint_set_uint64(uint64_t val,uint8_t ** out_data,int * out_len)157 asn1_aint_set_uint64(uint64_t val, uint8_t **out_data, int *out_len)
158 {
159 	uint8_t *data = NULL;
160 	size_t data_len = 0;
161 	int started = 0;
162 	uint8_t u8;
163 	CBB cbb;
164 	int i;
165 	int ret = 0;
166 
167 	if (!CBB_init(&cbb, sizeof(long)))
168 		goto err;
169 
170 	if (out_data == NULL || out_len == NULL)
171 		goto err;
172 	if (*out_data != NULL || *out_len != 0)
173 		goto err;
174 
175 	for (i = sizeof(uint64_t) - 1; i >= 0; i--) {
176 		u8 = (val >> (i * 8)) & 0xff;
177 		if (!started && i != 0 && u8 == 0)
178 			continue;
179 		if (!CBB_add_u8(&cbb, u8))
180 			goto err;
181 		started = 1;
182 	}
183 
184 	if (!CBB_finish(&cbb, &data, &data_len))
185 		goto err;
186 	if (data_len > INT_MAX)
187 		goto err;
188 
189 	*out_data = data;
190 	*out_len = (int)data_len;
191 	data = NULL;
192 
193 	ret = 1;
194  err:
195 	CBB_cleanup(&cbb);
196 	freezero(data, data_len);
197 
198 	return ret;
199 }
200 
201 int
asn1_aint_get_int64(CBS * cbs,int negative,int64_t * out_val)202 asn1_aint_get_int64(CBS *cbs, int negative, int64_t *out_val)
203 {
204 	uint64_t val;
205 
206 	if (!asn1_aint_get_uint64(cbs, &val))
207 		return 0;
208 
209 	if (negative) {
210 		if (val > (uint64_t)INT64_MIN) {
211 			ASN1error(ASN1_R_TOO_SMALL);
212 			return 0;
213 		}
214 		*out_val = (int64_t)-val;
215 	} else {
216 		if (val > (uint64_t)INT64_MAX) {
217 			ASN1error(ASN1_R_TOO_LARGE);
218 			return 0;
219 		}
220 		*out_val = (int64_t)val;
221 	}
222 
223 	return 1;
224 }
225 
226 int
ASN1_INTEGER_get_uint64(uint64_t * out_val,const ASN1_INTEGER * aint)227 ASN1_INTEGER_get_uint64(uint64_t *out_val, const ASN1_INTEGER *aint)
228 {
229 	uint64_t val;
230 	CBS cbs;
231 
232 	*out_val = 0;
233 
234 	if (aint == NULL || aint->length < 0)
235 		return 0;
236 
237 	if (aint->type == V_ASN1_NEG_INTEGER) {
238 		ASN1error(ASN1_R_ILLEGAL_NEGATIVE_VALUE);
239 		return 0;
240 	}
241 	if (aint->type != V_ASN1_INTEGER) {
242 		ASN1error(ASN1_R_WRONG_INTEGER_TYPE);
243 		return 0;
244 	}
245 
246 	CBS_init(&cbs, aint->data, aint->length);
247 
248 	if (!asn1_aint_get_uint64(&cbs, &val))
249 		return 0;
250 
251 	*out_val = val;
252 
253 	return 1;
254 }
255 LCRYPTO_ALIAS(ASN1_INTEGER_get_uint64);
256 
257 int
ASN1_INTEGER_set_uint64(ASN1_INTEGER * aint,uint64_t val)258 ASN1_INTEGER_set_uint64(ASN1_INTEGER *aint, uint64_t val)
259 {
260 	asn1_aint_clear(aint);
261 
262 	return asn1_aint_set_uint64(val, &aint->data, &aint->length);
263 }
264 LCRYPTO_ALIAS(ASN1_INTEGER_set_uint64);
265 
266 int
ASN1_INTEGER_get_int64(int64_t * out_val,const ASN1_INTEGER * aint)267 ASN1_INTEGER_get_int64(int64_t *out_val, const ASN1_INTEGER *aint)
268 {
269 	CBS cbs;
270 
271 	*out_val = 0;
272 
273 	if (aint == NULL || aint->length < 0)
274 		return 0;
275 
276 	if (aint->type != V_ASN1_INTEGER &&
277 	    aint->type != V_ASN1_NEG_INTEGER) {
278 		ASN1error(ASN1_R_WRONG_INTEGER_TYPE);
279 		return 0;
280 	}
281 
282 	CBS_init(&cbs, aint->data, aint->length);
283 
284 	return asn1_aint_get_int64(&cbs, (aint->type == V_ASN1_NEG_INTEGER),
285 	    out_val);
286 }
287 LCRYPTO_ALIAS(ASN1_INTEGER_get_int64);
288 
289 int
ASN1_INTEGER_set_int64(ASN1_INTEGER * aint,int64_t val)290 ASN1_INTEGER_set_int64(ASN1_INTEGER *aint, int64_t val)
291 {
292 	uint64_t uval;
293 
294 	asn1_aint_clear(aint);
295 
296 	uval = (uint64_t)val;
297 
298 	if (val < 0) {
299 		aint->type = V_ASN1_NEG_INTEGER;
300 		uval = -uval;
301 	}
302 
303 	return asn1_aint_set_uint64(uval, &aint->data, &aint->length);
304 }
305 LCRYPTO_ALIAS(ASN1_INTEGER_set_int64);
306 
307 long
ASN1_INTEGER_get(const ASN1_INTEGER * aint)308 ASN1_INTEGER_get(const ASN1_INTEGER *aint)
309 {
310 	int64_t val;
311 
312 	if (aint == NULL)
313 		return 0;
314 	if (!ASN1_INTEGER_get_int64(&val, aint))
315 		return -1;
316 	if (val < LONG_MIN || val > LONG_MAX) {
317 		/* hmm... a bit ugly, return all ones */
318 		return -1;
319 	}
320 
321 	return (long)val;
322 }
323 LCRYPTO_ALIAS(ASN1_INTEGER_get);
324 
325 int
ASN1_INTEGER_set(ASN1_INTEGER * aint,long val)326 ASN1_INTEGER_set(ASN1_INTEGER *aint, long val)
327 {
328 	return ASN1_INTEGER_set_int64(aint, val);
329 }
330 LCRYPTO_ALIAS(ASN1_INTEGER_set);
331 
332 ASN1_INTEGER *
BN_to_ASN1_INTEGER(const BIGNUM * bn,ASN1_INTEGER * ai)333 BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
334 {
335 	ASN1_INTEGER *ret;
336 	int len, j;
337 
338 	if (ai == NULL)
339 		ret = ASN1_INTEGER_new();
340 	else
341 		ret = ai;
342 	if (ret == NULL) {
343 		ASN1error(ERR_R_NESTED_ASN1_ERROR);
344 		goto err;
345 	}
346 
347 	if (!ASN1_INTEGER_valid(ret))
348 		goto err;
349 
350 	if (BN_is_negative(bn))
351 		ret->type = V_ASN1_NEG_INTEGER;
352 	else
353 		ret->type = V_ASN1_INTEGER;
354 	j = BN_num_bits(bn);
355 	len = ((j == 0) ? 0 : ((j / 8) + 1));
356 	if (ret->length < len + 4) {
357 		unsigned char *new_data = realloc(ret->data, len + 4);
358 		if (!new_data) {
359 			ASN1error(ERR_R_MALLOC_FAILURE);
360 			goto err;
361 		}
362 		ret->data = new_data;
363 	}
364 	ret->length = BN_bn2bin(bn, ret->data);
365 
366 	/* Correct zero case */
367 	if (!ret->length) {
368 		ret->data[0] = 0;
369 		ret->length = 1;
370 	}
371 	return (ret);
372 
373  err:
374 	if (ret != ai)
375 		ASN1_INTEGER_free(ret);
376 	return (NULL);
377 }
378 LCRYPTO_ALIAS(BN_to_ASN1_INTEGER);
379 
380 BIGNUM *
ASN1_INTEGER_to_BN(const ASN1_INTEGER * ai,BIGNUM * bn)381 ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn)
382 {
383 	BIGNUM *ret;
384 
385 	if (!ASN1_INTEGER_valid(ai))
386 		return (NULL);
387 
388 	if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL)
389 		ASN1error(ASN1_R_BN_LIB);
390 	else if (ai->type == V_ASN1_NEG_INTEGER)
391 		BN_set_negative(ret, 1);
392 	return (ret);
393 }
394 LCRYPTO_ALIAS(ASN1_INTEGER_to_BN);
395 
396 int
i2a_ASN1_INTEGER(BIO * bp,const ASN1_INTEGER * a)397 i2a_ASN1_INTEGER(BIO *bp, const ASN1_INTEGER *a)
398 {
399 	int i, n = 0;
400 	static const char h[] = "0123456789ABCDEF";
401 	char buf[2];
402 
403 	if (a == NULL)
404 		return (0);
405 
406 	if (a->type & V_ASN1_NEG) {
407 		if (BIO_write(bp, "-", 1) != 1)
408 			goto err;
409 		n = 1;
410 	}
411 
412 	if (a->length == 0) {
413 		if (BIO_write(bp, "00", 2) != 2)
414 			goto err;
415 		n += 2;
416 	} else {
417 		for (i = 0; i < a->length; i++) {
418 			if ((i != 0) && (i % 35 == 0)) {
419 				if (BIO_write(bp, "\\\n", 2) != 2)
420 					goto err;
421 				n += 2;
422 			}
423 			buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
424 			buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
425 			if (BIO_write(bp, buf, 2) != 2)
426 				goto err;
427 			n += 2;
428 		}
429 	}
430 	return (n);
431 
432  err:
433 	return (-1);
434 }
435 LCRYPTO_ALIAS(i2a_ASN1_INTEGER);
436 
437 int
a2i_ASN1_INTEGER(BIO * bp,ASN1_INTEGER * bs,char * buf,int size)438 a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
439 {
440 	int ret = 0;
441 	int i, j,k, m,n, again, bufsize;
442 	unsigned char *s = NULL, *sp;
443 	unsigned char *bufp;
444 	int num = 0, slen = 0, first = 1;
445 
446 	bs->type = V_ASN1_INTEGER;
447 
448 	bufsize = BIO_gets(bp, buf, size);
449 	for (;;) {
450 		if (bufsize < 1)
451 			goto err_sl;
452 		i = bufsize;
453 		if (buf[i - 1] == '\n')
454 			buf[--i] = '\0';
455 		if (i == 0)
456 			goto err_sl;
457 		if (buf[i - 1] == '\r')
458 			buf[--i] = '\0';
459 		if (i == 0)
460 			goto err_sl;
461 		if (buf[i - 1] == '\\') {
462 			i--;
463 			again = 1;
464 		} else
465 			again = 0;
466 		buf[i] = '\0';
467 		if (i < 2)
468 			goto err_sl;
469 
470 		bufp = (unsigned char *)buf;
471 		if (first) {
472 			first = 0;
473 			if ((bufp[0] == '0') && (buf[1] == '0')) {
474 				bufp += 2;
475 				i -= 2;
476 			}
477 		}
478 		k = 0;
479 		if (i % 2 != 0) {
480 			ASN1error(ASN1_R_ODD_NUMBER_OF_CHARS);
481 			goto err;
482 		}
483 		i /= 2;
484 		if (num + i > slen) {
485 			if ((sp = recallocarray(s, slen, num + i, 1)) == NULL) {
486 				ASN1error(ERR_R_MALLOC_FAILURE);
487 				goto err;
488 			}
489 			s = sp;
490 			slen = num + i;
491 		}
492 		for (j = 0; j < i; j++, k += 2) {
493 			for (n = 0; n < 2; n++) {
494 				m = bufp[k + n];
495 				if ((m >= '0') && (m <= '9'))
496 					m -= '0';
497 				else if ((m >= 'a') && (m <= 'f'))
498 					m = m - 'a' + 10;
499 				else if ((m >= 'A') && (m <= 'F'))
500 					m = m - 'A' + 10;
501 				else {
502 					ASN1error(ASN1_R_NON_HEX_CHARACTERS);
503 					goto err;
504 				}
505 				s[num + j] <<= 4;
506 				s[num + j] |= m;
507 			}
508 		}
509 		num += i;
510 		if (again)
511 			bufsize = BIO_gets(bp, buf, size);
512 		else
513 			break;
514 	}
515 	bs->length = num;
516 	bs->data = s;
517 	return (1);
518 
519  err_sl:
520 	ASN1error(ASN1_R_SHORT_LINE);
521  err:
522 	free(s);
523 	return (ret);
524 }
525 LCRYPTO_ALIAS(a2i_ASN1_INTEGER);
526 
527 static void
asn1_aint_twos_complement(uint8_t * data,size_t data_len)528 asn1_aint_twos_complement(uint8_t *data, size_t data_len)
529 {
530 	uint8_t carry = 1;
531 	ssize_t i;
532 
533 	for (i = data_len - 1; i >= 0; i--) {
534 		data[i] = (data[i] ^ 0xff) + carry;
535 		if (data[i] != 0)
536 			carry = 0;
537 	}
538 }
539 
540 static int
asn1_aint_keep_twos_padding(const uint8_t * data,size_t data_len)541 asn1_aint_keep_twos_padding(const uint8_t *data, size_t data_len)
542 {
543 	size_t i;
544 
545 	/*
546 	 * If a two's complement value has a padding byte (0xff) and the rest
547 	 * of the value is all zeros, the padding byte cannot be removed as when
548 	 * converted from two's complement this becomes 0x01 (in the place of
549 	 * the padding byte) followed by the same number of zero bytes.
550 	 */
551 	if (data_len <= 1 || data[0] != 0xff)
552 		return 0;
553 	for (i = 1; i < data_len; i++) {
554 		if (data[i] != 0)
555 			return 0;
556 	}
557 	return 1;
558 }
559 
560 static int
i2c_ASN1_INTEGER_cbb(ASN1_INTEGER * aint,CBB * cbb)561 i2c_ASN1_INTEGER_cbb(ASN1_INTEGER *aint, CBB *cbb)
562 {
563 	uint8_t *data = NULL;
564 	size_t data_len = 0;
565 	uint8_t padding, val;
566 	uint8_t msb;
567 	CBS cbs;
568 	int ret = 0;
569 
570 	if (aint->length < 0)
571 		goto err;
572 	if (aint->data == NULL && aint->length != 0)
573 		goto err;
574 
575 	if ((aint->type & ~V_ASN1_NEG) != V_ASN1_ENUMERATED &&
576 	    (aint->type & ~V_ASN1_NEG) != V_ASN1_INTEGER)
577 		goto err;
578 
579 	CBS_init(&cbs, aint->data, aint->length);
580 
581 	/* Find the first non-zero byte. */
582 	while (CBS_len(&cbs) > 0) {
583 		if (!CBS_peek_u8(&cbs, &val))
584 			goto err;
585 		if (val != 0)
586 			break;
587 		if (!CBS_skip(&cbs, 1))
588 			goto err;
589 	}
590 
591 	/* A zero value is encoded as a single octet. */
592 	if (CBS_len(&cbs) == 0) {
593 		if (!CBB_add_u8(cbb, 0))
594 			goto err;
595 		goto done;
596 	}
597 
598 	if (!CBS_stow(&cbs, &data, &data_len))
599 		goto err;
600 
601 	if ((aint->type & V_ASN1_NEG) != 0)
602 		asn1_aint_twos_complement(data, data_len);
603 
604 	/* Topmost bit indicates sign, padding is all zeros or all ones. */
605 	msb = (data[0] >> 7);
606 	padding = (msb - 1) & 0xff;
607 
608 	/* See if we need a padding octet to avoid incorrect sign. */
609 	if (((aint->type & V_ASN1_NEG) == 0 && msb == 1) ||
610 	    ((aint->type & V_ASN1_NEG) != 0 && msb == 0)) {
611 		if (!CBB_add_u8(cbb, padding))
612 			goto err;
613 	}
614 	if (!CBB_add_bytes(cbb, data, data_len))
615 		goto err;
616 
617  done:
618 	ret = 1;
619 
620  err:
621 	freezero(data, data_len);
622 
623 	return ret;
624 }
625 
626 int
i2c_ASN1_INTEGER(ASN1_INTEGER * aint,unsigned char ** pp)627 i2c_ASN1_INTEGER(ASN1_INTEGER *aint, unsigned char **pp)
628 {
629 	uint8_t *data = NULL;
630 	size_t data_len = 0;
631 	CBB cbb;
632 	int ret = -3;
633 
634 	if (!CBB_init(&cbb, 0))
635 		goto err;
636 	if (!i2c_ASN1_INTEGER_cbb(aint, &cbb))
637 		goto err;
638 	if (!CBB_finish(&cbb, &data, &data_len))
639 		goto err;
640 	if (data_len > INT_MAX)
641 		goto err;
642 
643 	if (pp != NULL) {
644 		if ((uintptr_t)*pp > UINTPTR_MAX - data_len)
645 			goto err;
646 		memcpy(*pp, data, data_len);
647 		*pp += data_len;
648 	}
649 
650 	ret = data_len;
651 
652  err:
653 	freezero(data, data_len);
654 	CBB_cleanup(&cbb);
655 
656 	return ret;
657 }
658 
659 int
c2i_ASN1_INTEGER_cbs(ASN1_INTEGER ** out_aint,CBS * cbs)660 c2i_ASN1_INTEGER_cbs(ASN1_INTEGER **out_aint, CBS *cbs)
661 {
662 	ASN1_INTEGER *aint = NULL;
663 	uint8_t *data = NULL;
664 	size_t data_len = 0;
665 	uint8_t padding, val;
666 	uint8_t negative;
667 	int ret = 0;
668 
669 	if (out_aint == NULL)
670 		goto err;
671 
672 	if (*out_aint != NULL) {
673 		ASN1_INTEGER_free(*out_aint);
674 		*out_aint = NULL;
675 	}
676 
677 	if (CBS_len(cbs) == 0) {
678 		/* XXX INVALID ENCODING? */
679 		ASN1error(ERR_R_ASN1_LENGTH_MISMATCH);
680 		goto err;
681 	}
682 	if (!CBS_peek_u8(cbs, &val))
683 		goto err;
684 
685 	/* Topmost bit indicates sign, padding is all zeros or all ones. */
686 	negative = (val >> 7);
687 	padding = ~(negative - 1) & 0xff;
688 
689 	/*
690 	 * Ensure that the first 9 bits are not all zero or all one, as per
691 	 * X.690 section 8.3.2. Remove the padding octet if possible.
692 	 */
693 	if (CBS_len(cbs) > 1 && val == padding) {
694 		if (!asn1_aint_keep_twos_padding(CBS_data(cbs), CBS_len(cbs))) {
695 			if (!CBS_get_u8(cbs, &padding))
696 				goto err;
697 			if (!CBS_peek_u8(cbs, &val))
698 				goto err;
699 			if ((val >> 7) == (padding >> 7)) {
700 				/* XXX INVALID ENCODING? */
701 				ASN1error(ERR_R_ASN1_LENGTH_MISMATCH);
702 				goto err;
703 			}
704 		}
705 	}
706 
707 	if (!CBS_stow(cbs, &data, &data_len))
708 		goto err;
709 	if (data_len > INT_MAX)
710 		goto err;
711 
712 	if ((aint = ASN1_INTEGER_new()) == NULL)
713 		goto err;
714 
715 	/*
716 	 * Negative integers are handled as a separate type - convert from
717 	 * two's complement for internal representation.
718 	 */
719 	if (negative) {
720 		aint->type = V_ASN1_NEG_INTEGER;
721 		asn1_aint_twos_complement(data, data_len);
722 	}
723 
724 	aint->data = data;
725 	aint->length = (int)data_len;
726 	data = NULL;
727 
728 	*out_aint = aint;
729 	aint = NULL;
730 
731 	ret = 1;
732 
733  err:
734 	ASN1_INTEGER_free(aint);
735 	freezero(data, data_len);
736 
737 	return ret;
738 }
739 
740 ASN1_INTEGER *
c2i_ASN1_INTEGER(ASN1_INTEGER ** out_aint,const unsigned char ** pp,long len)741 c2i_ASN1_INTEGER(ASN1_INTEGER **out_aint, const unsigned char **pp, long len)
742 {
743 	ASN1_INTEGER *aint = NULL;
744 	CBS content;
745 
746 	if (out_aint != NULL) {
747 		ASN1_INTEGER_free(*out_aint);
748 		*out_aint = NULL;
749 	}
750 
751 	if (len < 0) {
752 		ASN1error(ASN1_R_LENGTH_ERROR);
753 		return NULL;
754 	}
755 
756 	CBS_init(&content, *pp, len);
757 
758 	if (!c2i_ASN1_INTEGER_cbs(&aint, &content))
759 		return NULL;
760 
761 	*pp = CBS_data(&content);
762 
763 	if (out_aint != NULL)
764 		*out_aint = aint;
765 
766 	return aint;
767 }
768 
769 int
i2d_ASN1_INTEGER(ASN1_INTEGER * a,unsigned char ** out)770 i2d_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **out)
771 {
772 	return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_INTEGER_it);
773 }
774 LCRYPTO_ALIAS(i2d_ASN1_INTEGER);
775 
776 ASN1_INTEGER *
d2i_ASN1_INTEGER(ASN1_INTEGER ** a,const unsigned char ** in,long len)777 d2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **in, long len)
778 {
779 	return (ASN1_INTEGER *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
780 	    &ASN1_INTEGER_it);
781 }
782 LCRYPTO_ALIAS(d2i_ASN1_INTEGER);
783 
784 /* This is a version of d2i_ASN1_INTEGER that ignores the sign bit of
785  * ASN1 integers: some broken software can encode a positive INTEGER
786  * with its MSB set as negative (it doesn't add a padding zero).
787  */
788 
789 ASN1_INTEGER *
d2i_ASN1_UINTEGER(ASN1_INTEGER ** a,const unsigned char ** pp,long length)790 d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, long length)
791 {
792 	ASN1_INTEGER *ret = NULL;
793 	const unsigned char *p;
794 	unsigned char *s;
795 	long len;
796 	int inf, tag, xclass;
797 	int i;
798 
799 	if ((a == NULL) || ((*a) == NULL)) {
800 		if ((ret = ASN1_INTEGER_new()) == NULL)
801 			return (NULL);
802 	} else
803 		ret = (*a);
804 
805 	if (!ASN1_INTEGER_valid(ret)) {
806 		i = ERR_R_ASN1_LENGTH_MISMATCH;
807 		goto err;
808 	}
809 
810 	p = *pp;
811 	inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
812 	if (inf & 0x80) {
813 		i = ASN1_R_BAD_OBJECT_HEADER;
814 		goto err;
815 	}
816 
817 	if (tag != V_ASN1_INTEGER) {
818 		i = ASN1_R_EXPECTING_AN_INTEGER;
819 		goto err;
820 	}
821 
822 	/* We must malloc stuff, even for 0 bytes otherwise it
823 	 * signifies a missing NULL parameter. */
824 	if (len < 0 || len > INT_MAX) {
825 		i = ERR_R_ASN1_LENGTH_MISMATCH;
826 		goto err;
827 	}
828 	s = malloc(len + 1);
829 	if (s == NULL) {
830 		i = ERR_R_MALLOC_FAILURE;
831 		goto err;
832 	}
833 	ret->type = V_ASN1_INTEGER;
834 	if (len) {
835 		if ((*p == 0) && (len != 1)) {
836 			p++;
837 			len--;
838 		}
839 		memcpy(s, p, len);
840 		p += len;
841 	}
842 
843 	free(ret->data);
844 	ret->data = s;
845 	ret->length = (int)len;
846 	if (a != NULL)
847 		(*a) = ret;
848 	*pp = p;
849 	return (ret);
850 
851  err:
852 	ASN1error(i);
853 	if (a == NULL || *a != ret)
854 		ASN1_INTEGER_free(ret);
855 	return (NULL);
856 }
857 LCRYPTO_ALIAS(d2i_ASN1_UINTEGER);
858