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