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