xref: /dragonfly/crypto/libressl/crypto/asn1/a_int.c (revision cca6fc52)
1 /* $OpenBSD: a_int.c,v 1.34 2019/04/28 05:03:56 tb 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/bn.h>
65 #include <openssl/err.h>
66 
67 static int
68 ASN1_INTEGER_valid(const ASN1_INTEGER *a)
69 {
70 	return (a != NULL && a->length >= 0);
71 }
72 
73 ASN1_INTEGER *
74 ASN1_INTEGER_dup(const ASN1_INTEGER *x)
75 {
76 	if (!ASN1_INTEGER_valid(x))
77 		return NULL;
78 
79 	return ASN1_STRING_dup(x);
80 }
81 
82 int
83 ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
84 {
85 	int neg, ret;
86 
87 	/* Compare signs */
88 	neg = x->type & V_ASN1_NEG;
89 	if (neg != (y->type & V_ASN1_NEG)) {
90 		if (neg)
91 			return -1;
92 		else
93 			return 1;
94 	}
95 
96 	ret = ASN1_STRING_cmp(x, y);
97 
98 	if (neg)
99 		return -ret;
100 	else
101 		return ret;
102 }
103 
104 
105 /*
106  * This converts an ASN1 INTEGER into its content encoding.
107  * The internal representation is an ASN1_STRING whose data is a big endian
108  * representation of the value, ignoring the sign. The sign is determined by
109  * the type: V_ASN1_INTEGER for positive and V_ASN1_NEG_INTEGER for negative.
110  *
111  * Positive integers are no problem: they are almost the same as the DER
112  * encoding, except if the first byte is >= 0x80 we need to add a zero pad.
113  *
114  * Negative integers are a bit trickier...
115  * The DER representation of negative integers is in 2s complement form.
116  * The internal form is converted by complementing each octet and finally
117  * adding one to the result. This can be done less messily with a little trick.
118  * If the internal form has trailing zeroes then they will become FF by the
119  * complement and 0 by the add one (due to carry) so just copy as many trailing
120  * zeros to the destination as there are in the source. The carry will add one
121  * to the last none zero octet: so complement this octet and add one and finally
122  * complement any left over until you get to the start of the string.
123  *
124  * Padding is a little trickier too. If the first bytes is > 0x80 then we pad
125  * with 0xff. However if the first byte is 0x80 and one of the following bytes
126  * is non-zero we pad with 0xff. The reason for this distinction is that 0x80
127  * followed by optional zeros isn't padded.
128  */
129 
130 int
131 i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
132 {
133 	int pad = 0, ret, i, neg;
134 	unsigned char *p, *n, pb = 0;
135 
136 	if (!ASN1_INTEGER_valid(a))
137 		return 0;
138 
139 	neg = a->type & V_ASN1_NEG;
140 	if (a->length == 0)
141 		ret = 1;
142 	else {
143 		ret = a->length;
144 		i = a->data[0];
145 		if (!neg && (i > 127)) {
146 			pad = 1;
147 			pb = 0;
148 		} else if (neg) {
149 			if (i > 128) {
150 				pad = 1;
151 				pb = 0xFF;
152 			} else if (i == 128) {
153 				/*
154 				 * Special case: if any other bytes non zero we pad:
155 				 * otherwise we don't.
156 				 */
157 				for (i = 1; i < a->length; i++) if (a->data[i]) {
158 					pad = 1;
159 					pb = 0xFF;
160 					break;
161 				}
162 			}
163 		}
164 		ret += pad;
165 	}
166 	if (pp == NULL)
167 		return (ret);
168 	p= *pp;
169 
170 	if (pad)
171 		*(p++) = pb;
172 	if (a->length == 0)
173 		*(p++) = 0;
174 	else if (!neg)
175 		memcpy(p, a->data, a->length);
176 	else {
177 		/* Begin at the end of the encoding */
178 		n = a->data + a->length - 1;
179 		p += a->length - 1;
180 		i = a->length;
181 		/* Copy zeros to destination as long as source is zero */
182 		while (!*n) {
183 			*(p--) = 0;
184 			n--;
185 			i--;
186 		}
187 		/* Complement and increment next octet */
188 		*(p--) = ((*(n--)) ^ 0xff) + 1;
189 		i--;
190 		/* Complement any octets left */
191 		for (; i > 0; i--)
192 			*(p--) = *(n--) ^ 0xff;
193 	}
194 
195 	*pp += ret;
196 	return (ret);
197 }
198 
199 /* Convert just ASN1 INTEGER content octets to ASN1_INTEGER structure */
200 
201 ASN1_INTEGER *
202 c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, long len)
203 {
204 	ASN1_INTEGER *ret = NULL;
205 	const unsigned char *p, *pend;
206 	unsigned char *to, *s;
207 	int i;
208 
209 	if ((a == NULL) || ((*a) == NULL)) {
210 		if ((ret = ASN1_INTEGER_new()) == NULL)
211 			return (NULL);
212 	} else
213 		ret = (*a);
214 
215 	if (!ASN1_INTEGER_valid(ret)) {
216 		/*
217 		 * XXX using i for an alert is confusing,
218 		 * we should call this al
219 		 */
220 		i = ERR_R_ASN1_LENGTH_MISMATCH;
221 		goto err;
222 	}
223 
224 	p = *pp;
225 	pend = p + len;
226 
227 	/* We must malloc stuff, even for 0 bytes otherwise it
228 	 * signifies a missing NULL parameter. */
229 	if (len < 0 || len > INT_MAX) {
230 		i = ERR_R_ASN1_LENGTH_MISMATCH;
231 		goto err;
232 	}
233 	s = malloc(len + 1);
234 	if (s == NULL) {
235 		i = ERR_R_MALLOC_FAILURE;
236 		goto err;
237 	}
238 	to = s;
239 	if (!len) {
240 		/* Strictly speaking this is an illegal INTEGER but we
241 		 * tolerate it.
242 		 */
243 		ret->type = V_ASN1_INTEGER;
244 	} else if (*p & 0x80) /* a negative number */ {
245 		ret->type = V_ASN1_NEG_INTEGER;
246 		if ((*p == 0xff) && (len != 1)) {
247 			p++;
248 			len--;
249 		}
250 		i = len;
251 		p += i - 1;
252 		to += i - 1;
253 		while((!*p) && i) {
254 			*(to--) = 0;
255 			i--;
256 			p--;
257 		}
258 		/* Special case: if all zeros then the number will be of
259 		 * the form FF followed by n zero bytes: this corresponds to
260 		 * 1 followed by n zero bytes. We've already written n zeros
261 		 * so we just append an extra one and set the first byte to
262 		 * a 1. This is treated separately because it is the only case
263 		 * where the number of bytes is larger than len.
264 		 */
265 		if (!i) {
266 			*s = 1;
267 			s[len] = 0;
268 			len++;
269 		} else {
270 			*(to--) = (*(p--) ^ 0xff) + 1;
271 			i--;
272 			for (; i > 0; i--)
273 				*(to--) = *(p--) ^ 0xff;
274 		}
275 	} else {
276 		ret->type = V_ASN1_INTEGER;
277 		if ((*p == 0) && (len != 1)) {
278 			p++;
279 			len--;
280 		}
281 		memcpy(s, p, len);
282 	}
283 
284 	free(ret->data);
285 	ret->data = s;
286 	ret->length = (int)len;
287 	if (a != NULL)
288 		(*a) = ret;
289 	*pp = pend;
290 	return (ret);
291 
292 err:
293 	ASN1error(i);
294 	if (a == NULL || *a != ret)
295 		ASN1_INTEGER_free(ret);
296 	return (NULL);
297 }
298 
299 
300 /* This is a version of d2i_ASN1_INTEGER that ignores the sign bit of
301  * ASN1 integers: some broken software can encode a positive INTEGER
302  * with its MSB set as negative (it doesn't add a padding zero).
303  */
304 
305 ASN1_INTEGER *
306 d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, long length)
307 {
308 	ASN1_INTEGER *ret = NULL;
309 	const unsigned char *p;
310 	unsigned char *s;
311 	long len;
312 	int inf, tag, xclass;
313 	int i;
314 
315 	if ((a == NULL) || ((*a) == NULL)) {
316 		if ((ret = ASN1_INTEGER_new()) == NULL)
317 			return (NULL);
318 	} else
319 		ret = (*a);
320 
321 	if (!ASN1_INTEGER_valid(ret)) {
322 		i = ERR_R_ASN1_LENGTH_MISMATCH;
323 		goto err;
324 	}
325 
326 	p = *pp;
327 	inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
328 	if (inf & 0x80) {
329 		i = ASN1_R_BAD_OBJECT_HEADER;
330 		goto err;
331 	}
332 
333 	if (tag != V_ASN1_INTEGER) {
334 		i = ASN1_R_EXPECTING_AN_INTEGER;
335 		goto err;
336 	}
337 
338 	/* We must malloc stuff, even for 0 bytes otherwise it
339 	 * signifies a missing NULL parameter. */
340 	if (len < 0 || len > INT_MAX) {
341 		i = ERR_R_ASN1_LENGTH_MISMATCH;
342 		goto err;
343 	}
344 	s = malloc(len + 1);
345 	if (s == NULL) {
346 		i = ERR_R_MALLOC_FAILURE;
347 		goto err;
348 	}
349 	ret->type = V_ASN1_INTEGER;
350 	if (len) {
351 		if ((*p == 0) && (len != 1)) {
352 			p++;
353 			len--;
354 		}
355 		memcpy(s, p, len);
356 		p += len;
357 	}
358 
359 	free(ret->data);
360 	ret->data = s;
361 	ret->length = (int)len;
362 	if (a != NULL)
363 		(*a) = ret;
364 	*pp = p;
365 	return (ret);
366 
367 err:
368 	ASN1error(i);
369 	if (a == NULL || *a != ret)
370 		ASN1_INTEGER_free(ret);
371 	return (NULL);
372 }
373 
374 int
375 ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
376 {
377 	int j, k;
378 	unsigned int i;
379 	unsigned char buf[sizeof(long) + 1];
380 	long d;
381 
382 	a->type = V_ASN1_INTEGER;
383 	/* XXX ssl/ssl_asn1.c:i2d_SSL_SESSION() depends upon this bound vae */
384 	if (a->length < (int)(sizeof(long) + 1)) {
385 		free(a->data);
386 		a->data = calloc(1, sizeof(long) + 1);
387 	}
388 	if (a->data == NULL) {
389 		ASN1error(ERR_R_MALLOC_FAILURE);
390 		return (0);
391 	}
392 	d = v;
393 	if (d < 0) {
394 		d = -d;
395 		a->type = V_ASN1_NEG_INTEGER;
396 	}
397 
398 	for (i = 0; i < sizeof(long); i++) {
399 		if (d == 0)
400 			break;
401 		buf[i] = (int)d & 0xff;
402 		d >>= 8;
403 	}
404 	j = 0;
405 	for (k = i - 1; k >= 0; k--)
406 		a->data[j++] = buf[k];
407 	a->length = j;
408 	return (1);
409 }
410 
411 /*
412  * XXX this particular API is a gibbering eidrich horror that makes it
413  * impossible to determine valid return cases from errors.. "a bit
414  * ugly" is preserved for posterity, unfortunately this is probably
415  * unfixable without changing public API
416  */
417 long
418 ASN1_INTEGER_get(const ASN1_INTEGER *a)
419 {
420 	int neg = 0, i;
421 	unsigned long r = 0;
422 
423 	if (a == NULL)
424 		return (0L);
425 	i = a->type;
426 	if (i == V_ASN1_NEG_INTEGER)
427 		neg = 1;
428 	else if (i != V_ASN1_INTEGER)
429 		return -1;
430 
431 	if (!ASN1_INTEGER_valid(a))
432 		return -1; /* XXX best effort */
433 
434 	if (a->length > (int)sizeof(long)) {
435 		/* hmm... a bit ugly, return all ones */
436 		return -1;
437 	}
438 	if (a->data == NULL)
439 		return 0;
440 
441 	for (i = 0; i < a->length; i++) {
442 		r <<= 8;
443 		r |= (unsigned char)a->data[i];
444 	}
445 
446 	if (r > LONG_MAX)
447 		return -1;
448 
449 	if (neg)
450 		return -(long)r;
451 	return (long)r;
452 }
453 
454 ASN1_INTEGER *
455 BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
456 {
457 	ASN1_INTEGER *ret;
458 	int len, j;
459 
460 	if (ai == NULL)
461 		ret = ASN1_INTEGER_new();
462 	else
463 		ret = ai;
464 	if (ret == NULL) {
465 		ASN1error(ERR_R_NESTED_ASN1_ERROR);
466 		goto err;
467 	}
468 
469 	if (!ASN1_INTEGER_valid(ret))
470 		goto err;
471 
472 	if (BN_is_negative(bn))
473 		ret->type = V_ASN1_NEG_INTEGER;
474 	else
475 		ret->type = V_ASN1_INTEGER;
476 	j = BN_num_bits(bn);
477 	len = ((j == 0) ? 0 : ((j / 8) + 1));
478 	if (ret->length < len + 4) {
479 		unsigned char *new_data = realloc(ret->data, len + 4);
480 		if (!new_data) {
481 			ASN1error(ERR_R_MALLOC_FAILURE);
482 			goto err;
483 		}
484 		ret->data = new_data;
485 	}
486 	ret->length = BN_bn2bin(bn, ret->data);
487 
488 	/* Correct zero case */
489 	if (!ret->length) {
490 		ret->data[0] = 0;
491 		ret->length = 1;
492 	}
493 	return (ret);
494 
495 err:
496 	if (ret != ai)
497 		ASN1_INTEGER_free(ret);
498 	return (NULL);
499 }
500 
501 BIGNUM *
502 ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn)
503 {
504 	BIGNUM *ret;
505 
506 	if (!ASN1_INTEGER_valid(ai))
507 		return (NULL);
508 
509 	if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL)
510 		ASN1error(ASN1_R_BN_LIB);
511 	else if (ai->type == V_ASN1_NEG_INTEGER)
512 		BN_set_negative(ret, 1);
513 	return (ret);
514 }
515