xref: /openbsd-src/lib/libcrypto/asn1/a_int.c (revision c1a45aed656e7d5627c30c92421893a76f370ccb)
1 /* $OpenBSD: a_int.c,v 1.38 2021/12/25 13:17:48 jsing 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 const ASN1_ITEM ASN1_INTEGER_it = {
70 	.itype = ASN1_ITYPE_PRIMITIVE,
71 	.utype = V_ASN1_INTEGER,
72 	.sname = "ASN1_INTEGER",
73 };
74 
75 ASN1_INTEGER *
76 ASN1_INTEGER_new(void)
77 {
78 	return (ASN1_INTEGER *)ASN1_item_new(&ASN1_INTEGER_it);
79 }
80 
81 void
82 ASN1_INTEGER_free(ASN1_INTEGER *a)
83 {
84 	ASN1_item_free((ASN1_VALUE *)a, &ASN1_INTEGER_it);
85 }
86 
87 static int
88 ASN1_INTEGER_valid(const ASN1_INTEGER *a)
89 {
90 	return (a != NULL && a->length >= 0);
91 }
92 
93 ASN1_INTEGER *
94 ASN1_INTEGER_dup(const ASN1_INTEGER *x)
95 {
96 	if (!ASN1_INTEGER_valid(x))
97 		return NULL;
98 
99 	return ASN1_STRING_dup(x);
100 }
101 
102 int
103 ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
104 {
105 	int neg, ret;
106 
107 	/* Compare signs */
108 	neg = x->type & V_ASN1_NEG;
109 	if (neg != (y->type & V_ASN1_NEG)) {
110 		if (neg)
111 			return -1;
112 		else
113 			return 1;
114 	}
115 
116 	ret = ASN1_STRING_cmp(x, y);
117 
118 	if (neg)
119 		return -ret;
120 	else
121 		return ret;
122 }
123 
124 int
125 ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
126 {
127 	int j, k;
128 	unsigned int i;
129 	unsigned char buf[sizeof(long) + 1];
130 	long d;
131 
132 	a->type = V_ASN1_INTEGER;
133 	/* XXX ssl/ssl_asn1.c:i2d_SSL_SESSION() depends upon this bound vae */
134 	if (a->length < (int)(sizeof(long) + 1)) {
135 		free(a->data);
136 		a->data = calloc(1, sizeof(long) + 1);
137 	}
138 	if (a->data == NULL) {
139 		ASN1error(ERR_R_MALLOC_FAILURE);
140 		return (0);
141 	}
142 	d = v;
143 	if (d < 0) {
144 		d = -d;
145 		a->type = V_ASN1_NEG_INTEGER;
146 	}
147 
148 	for (i = 0; i < sizeof(long); i++) {
149 		if (d == 0)
150 			break;
151 		buf[i] = (int)d & 0xff;
152 		d >>= 8;
153 	}
154 	j = 0;
155 	for (k = i - 1; k >= 0; k--)
156 		a->data[j++] = buf[k];
157 	a->length = j;
158 	return (1);
159 }
160 
161 /*
162  * XXX this particular API is a gibbering eidrich horror that makes it
163  * impossible to determine valid return cases from errors.. "a bit
164  * ugly" is preserved for posterity, unfortunately this is probably
165  * unfixable without changing public API
166  */
167 long
168 ASN1_INTEGER_get(const ASN1_INTEGER *a)
169 {
170 	int neg = 0, i;
171 	unsigned long r = 0;
172 
173 	if (a == NULL)
174 		return (0L);
175 	i = a->type;
176 	if (i == V_ASN1_NEG_INTEGER)
177 		neg = 1;
178 	else if (i != V_ASN1_INTEGER)
179 		return -1;
180 
181 	if (!ASN1_INTEGER_valid(a))
182 		return -1; /* XXX best effort */
183 
184 	if (a->length > (int)sizeof(long)) {
185 		/* hmm... a bit ugly, return all ones */
186 		return -1;
187 	}
188 	if (a->data == NULL)
189 		return 0;
190 
191 	for (i = 0; i < a->length; i++) {
192 		r <<= 8;
193 		r |= (unsigned char)a->data[i];
194 	}
195 
196 	if (r > LONG_MAX)
197 		return -1;
198 
199 	if (neg)
200 		return -(long)r;
201 	return (long)r;
202 }
203 
204 ASN1_INTEGER *
205 BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
206 {
207 	ASN1_INTEGER *ret;
208 	int len, j;
209 
210 	if (ai == NULL)
211 		ret = ASN1_INTEGER_new();
212 	else
213 		ret = ai;
214 	if (ret == NULL) {
215 		ASN1error(ERR_R_NESTED_ASN1_ERROR);
216 		goto err;
217 	}
218 
219 	if (!ASN1_INTEGER_valid(ret))
220 		goto err;
221 
222 	if (BN_is_negative(bn))
223 		ret->type = V_ASN1_NEG_INTEGER;
224 	else
225 		ret->type = V_ASN1_INTEGER;
226 	j = BN_num_bits(bn);
227 	len = ((j == 0) ? 0 : ((j / 8) + 1));
228 	if (ret->length < len + 4) {
229 		unsigned char *new_data = realloc(ret->data, len + 4);
230 		if (!new_data) {
231 			ASN1error(ERR_R_MALLOC_FAILURE);
232 			goto err;
233 		}
234 		ret->data = new_data;
235 	}
236 	ret->length = BN_bn2bin(bn, ret->data);
237 
238 	/* Correct zero case */
239 	if (!ret->length) {
240 		ret->data[0] = 0;
241 		ret->length = 1;
242 	}
243 	return (ret);
244 
245  err:
246 	if (ret != ai)
247 		ASN1_INTEGER_free(ret);
248 	return (NULL);
249 }
250 
251 BIGNUM *
252 ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn)
253 {
254 	BIGNUM *ret;
255 
256 	if (!ASN1_INTEGER_valid(ai))
257 		return (NULL);
258 
259 	if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL)
260 		ASN1error(ASN1_R_BN_LIB);
261 	else if (ai->type == V_ASN1_NEG_INTEGER)
262 		BN_set_negative(ret, 1);
263 	return (ret);
264 }
265 
266 int
267 i2a_ASN1_INTEGER(BIO *bp, const ASN1_INTEGER *a)
268 {
269 	int i, n = 0;
270 	static const char h[] = "0123456789ABCDEF";
271 	char buf[2];
272 
273 	if (a == NULL)
274 		return (0);
275 
276 	if (a->type & V_ASN1_NEG) {
277 		if (BIO_write(bp, "-", 1) != 1)
278 			goto err;
279 		n = 1;
280 	}
281 
282 	if (a->length == 0) {
283 		if (BIO_write(bp, "00", 2) != 2)
284 			goto err;
285 		n += 2;
286 	} else {
287 		for (i = 0; i < a->length; i++) {
288 			if ((i != 0) && (i % 35 == 0)) {
289 				if (BIO_write(bp, "\\\n", 2) != 2)
290 					goto err;
291 				n += 2;
292 			}
293 			buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
294 			buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
295 			if (BIO_write(bp, buf, 2) != 2)
296 				goto err;
297 			n += 2;
298 		}
299 	}
300 	return (n);
301 
302  err:
303 	return (-1);
304 }
305 
306 int
307 a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
308 {
309 	int ret = 0;
310 	int i, j,k, m,n, again, bufsize;
311 	unsigned char *s = NULL, *sp;
312 	unsigned char *bufp;
313 	int num = 0, slen = 0, first = 1;
314 
315 	bs->type = V_ASN1_INTEGER;
316 
317 	bufsize = BIO_gets(bp, buf, size);
318 	for (;;) {
319 		if (bufsize < 1)
320 			goto err_sl;
321 		i = bufsize;
322 		if (buf[i - 1] == '\n')
323 			buf[--i] = '\0';
324 		if (i == 0)
325 			goto err_sl;
326 		if (buf[i - 1] == '\r')
327 			buf[--i] = '\0';
328 		if (i == 0)
329 			goto err_sl;
330 		if (buf[i - 1] == '\\') {
331 			i--;
332 			again = 1;
333 		} else
334 			again = 0;
335 		buf[i] = '\0';
336 		if (i < 2)
337 			goto err_sl;
338 
339 		bufp = (unsigned char *)buf;
340 		if (first) {
341 			first = 0;
342 			if ((bufp[0] == '0') && (buf[1] == '0')) {
343 				bufp += 2;
344 				i -= 2;
345 			}
346 		}
347 		k = 0;
348 		if (i % 2 != 0) {
349 			ASN1error(ASN1_R_ODD_NUMBER_OF_CHARS);
350 			goto err;
351 		}
352 		i /= 2;
353 		if (num + i > slen) {
354 			if ((sp = recallocarray(s, slen, num + i, 1)) == NULL) {
355 				ASN1error(ERR_R_MALLOC_FAILURE);
356 				goto err;
357 			}
358 			s = sp;
359 			slen = num + i;
360 		}
361 		for (j = 0; j < i; j++, k += 2) {
362 			for (n = 0; n < 2; n++) {
363 				m = bufp[k + n];
364 				if ((m >= '0') && (m <= '9'))
365 					m -= '0';
366 				else if ((m >= 'a') && (m <= 'f'))
367 					m = m - 'a' + 10;
368 				else if ((m >= 'A') && (m <= 'F'))
369 					m = m - 'A' + 10;
370 				else {
371 					ASN1error(ASN1_R_NON_HEX_CHARACTERS);
372 					goto err;
373 				}
374 				s[num + j] <<= 4;
375 				s[num + j] |= m;
376 			}
377 		}
378 		num += i;
379 		if (again)
380 			bufsize = BIO_gets(bp, buf, size);
381 		else
382 			break;
383 	}
384 	bs->length = num;
385 	bs->data = s;
386 	return (1);
387 
388  err_sl:
389 	ASN1error(ASN1_R_SHORT_LINE);
390  err:
391 	free(s);
392 	return (ret);
393 }
394 
395 /*
396  * This converts an ASN1 INTEGER into its content encoding.
397  * The internal representation is an ASN1_STRING whose data is a big endian
398  * representation of the value, ignoring the sign. The sign is determined by
399  * the type: V_ASN1_INTEGER for positive and V_ASN1_NEG_INTEGER for negative.
400  *
401  * Positive integers are no problem: they are almost the same as the DER
402  * encoding, except if the first byte is >= 0x80 we need to add a zero pad.
403  *
404  * Negative integers are a bit trickier...
405  * The DER representation of negative integers is in 2s complement form.
406  * The internal form is converted by complementing each octet and finally
407  * adding one to the result. This can be done less messily with a little trick.
408  * If the internal form has trailing zeroes then they will become FF by the
409  * complement and 0 by the add one (due to carry) so just copy as many trailing
410  * zeros to the destination as there are in the source. The carry will add one
411  * to the last none zero octet: so complement this octet and add one and finally
412  * complement any left over until you get to the start of the string.
413  *
414  * Padding is a little trickier too. If the first bytes is > 0x80 then we pad
415  * with 0xff. However if the first byte is 0x80 and one of the following bytes
416  * is non-zero we pad with 0xff. The reason for this distinction is that 0x80
417  * followed by optional zeros isn't padded.
418  */
419 
420 int
421 i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
422 {
423 	int pad = 0, ret, i, neg;
424 	unsigned char *p, *n, pb = 0;
425 
426 	if (!ASN1_INTEGER_valid(a))
427 		return 0;
428 
429 	neg = a->type & V_ASN1_NEG;
430 	if (a->length == 0)
431 		ret = 1;
432 	else {
433 		ret = a->length;
434 		i = a->data[0];
435 		if (!neg && (i > 127)) {
436 			pad = 1;
437 			pb = 0;
438 		} else if (neg) {
439 			if (i > 128) {
440 				pad = 1;
441 				pb = 0xFF;
442 			} else if (i == 128) {
443 				/*
444 				 * Special case: if any other bytes non zero we pad:
445 				 * otherwise we don't.
446 				 */
447 				for (i = 1; i < a->length; i++) if (a->data[i]) {
448 					pad = 1;
449 					pb = 0xFF;
450 					break;
451 				}
452 			}
453 		}
454 		ret += pad;
455 	}
456 	if (pp == NULL)
457 		return (ret);
458 	p= *pp;
459 
460 	if (pad)
461 		*(p++) = pb;
462 	if (a->length == 0)
463 		*(p++) = 0;
464 	else if (!neg)
465 		memcpy(p, a->data, a->length);
466 	else {
467 		/* Begin at the end of the encoding */
468 		n = a->data + a->length - 1;
469 		p += a->length - 1;
470 		i = a->length;
471 		/* Copy zeros to destination as long as source is zero */
472 		while (!*n) {
473 			*(p--) = 0;
474 			n--;
475 			i--;
476 		}
477 		/* Complement and increment next octet */
478 		*(p--) = ((*(n--)) ^ 0xff) + 1;
479 		i--;
480 		/* Complement any octets left */
481 		for (; i > 0; i--)
482 			*(p--) = *(n--) ^ 0xff;
483 	}
484 
485 	*pp += ret;
486 	return (ret);
487 }
488 
489 /* Convert just ASN1 INTEGER content octets to ASN1_INTEGER structure */
490 
491 ASN1_INTEGER *
492 c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, long len)
493 {
494 	ASN1_INTEGER *ret = NULL;
495 	const unsigned char *p, *pend;
496 	unsigned char *to, *s;
497 	int i;
498 
499 	if ((a == NULL) || ((*a) == NULL)) {
500 		if ((ret = ASN1_INTEGER_new()) == NULL)
501 			return (NULL);
502 	} else
503 		ret = (*a);
504 
505 	if (!ASN1_INTEGER_valid(ret)) {
506 		/*
507 		 * XXX using i for an alert is confusing,
508 		 * we should call this al
509 		 */
510 		i = ERR_R_ASN1_LENGTH_MISMATCH;
511 		goto err;
512 	}
513 
514 	p = *pp;
515 	pend = p + len;
516 
517 	/* We must malloc stuff, even for 0 bytes otherwise it
518 	 * signifies a missing NULL parameter. */
519 	if (len < 0 || len > INT_MAX) {
520 		i = ERR_R_ASN1_LENGTH_MISMATCH;
521 		goto err;
522 	}
523 	s = malloc(len + 1);
524 	if (s == NULL) {
525 		i = ERR_R_MALLOC_FAILURE;
526 		goto err;
527 	}
528 	to = s;
529 	if (!len) {
530 		/* Strictly speaking this is an illegal INTEGER but we
531 		 * tolerate it.
532 		 */
533 		ret->type = V_ASN1_INTEGER;
534 	} else if (*p & 0x80) /* a negative number */ {
535 		ret->type = V_ASN1_NEG_INTEGER;
536 		if ((*p == 0xff) && (len != 1)) {
537 			p++;
538 			len--;
539 		}
540 		i = len;
541 		p += i - 1;
542 		to += i - 1;
543 		while((!*p) && i) {
544 			*(to--) = 0;
545 			i--;
546 			p--;
547 		}
548 		/* Special case: if all zeros then the number will be of
549 		 * the form FF followed by n zero bytes: this corresponds to
550 		 * 1 followed by n zero bytes. We've already written n zeros
551 		 * so we just append an extra one and set the first byte to
552 		 * a 1. This is treated separately because it is the only case
553 		 * where the number of bytes is larger than len.
554 		 */
555 		if (!i) {
556 			*s = 1;
557 			s[len] = 0;
558 			len++;
559 		} else {
560 			*(to--) = (*(p--) ^ 0xff) + 1;
561 			i--;
562 			for (; i > 0; i--)
563 				*(to--) = *(p--) ^ 0xff;
564 		}
565 	} else {
566 		ret->type = V_ASN1_INTEGER;
567 		if ((*p == 0) && (len != 1)) {
568 			p++;
569 			len--;
570 		}
571 		memcpy(s, p, len);
572 	}
573 
574 	free(ret->data);
575 	ret->data = s;
576 	ret->length = (int)len;
577 	if (a != NULL)
578 		(*a) = ret;
579 	*pp = pend;
580 	return (ret);
581 
582  err:
583 	ASN1error(i);
584 	if (a == NULL || *a != ret)
585 		ASN1_INTEGER_free(ret);
586 	return (NULL);
587 }
588 
589 int
590 i2d_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **out)
591 {
592 	return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_INTEGER_it);
593 }
594 
595 ASN1_INTEGER *
596 d2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **in, long len)
597 {
598 	return (ASN1_INTEGER *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
599 	    &ASN1_INTEGER_it);
600 }
601 
602 /* This is a version of d2i_ASN1_INTEGER that ignores the sign bit of
603  * ASN1 integers: some broken software can encode a positive INTEGER
604  * with its MSB set as negative (it doesn't add a padding zero).
605  */
606 
607 ASN1_INTEGER *
608 d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, long length)
609 {
610 	ASN1_INTEGER *ret = NULL;
611 	const unsigned char *p;
612 	unsigned char *s;
613 	long len;
614 	int inf, tag, xclass;
615 	int i;
616 
617 	if ((a == NULL) || ((*a) == NULL)) {
618 		if ((ret = ASN1_INTEGER_new()) == NULL)
619 			return (NULL);
620 	} else
621 		ret = (*a);
622 
623 	if (!ASN1_INTEGER_valid(ret)) {
624 		i = ERR_R_ASN1_LENGTH_MISMATCH;
625 		goto err;
626 	}
627 
628 	p = *pp;
629 	inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
630 	if (inf & 0x80) {
631 		i = ASN1_R_BAD_OBJECT_HEADER;
632 		goto err;
633 	}
634 
635 	if (tag != V_ASN1_INTEGER) {
636 		i = ASN1_R_EXPECTING_AN_INTEGER;
637 		goto err;
638 	}
639 
640 	/* We must malloc stuff, even for 0 bytes otherwise it
641 	 * signifies a missing NULL parameter. */
642 	if (len < 0 || len > INT_MAX) {
643 		i = ERR_R_ASN1_LENGTH_MISMATCH;
644 		goto err;
645 	}
646 	s = malloc(len + 1);
647 	if (s == NULL) {
648 		i = ERR_R_MALLOC_FAILURE;
649 		goto err;
650 	}
651 	ret->type = V_ASN1_INTEGER;
652 	if (len) {
653 		if ((*p == 0) && (len != 1)) {
654 			p++;
655 			len--;
656 		}
657 		memcpy(s, p, len);
658 		p += len;
659 	}
660 
661 	free(ret->data);
662 	ret->data = s;
663 	ret->length = (int)len;
664 	if (a != NULL)
665 		(*a) = ret;
666 	*pp = p;
667 	return (ret);
668 
669  err:
670 	ASN1error(i);
671 	if (a == NULL || *a != ret)
672 		ASN1_INTEGER_free(ret);
673 	return (NULL);
674 }
675