• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2  * All rights reserved.
3  *
4  * This package is an SSL implementation written
5  * by Eric Young (eay@cryptsoft.com).
6  * The implementation was written so as to conform with Netscapes SSL.
7  *
8  * This library is free for commercial and non-commercial use as long as
9  * the following conditions are aheared to.  The following conditions
10  * apply to all code found in this distribution, be it the RC4, RSA,
11  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
12  * included with this distribution is covered by the same copyright terms
13  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14  *
15  * Copyright remains Eric Young's, and as such any Copyright notices in
16  * the code are not to be removed.
17  * If this package is used in a product, Eric Young should be given attribution
18  * as the author of the parts of the library used.
19  * This can be in the form of a textual message at program startup or
20  * in documentation (online or textual) provided with the package.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  * 1. Redistributions of source code must retain the copyright
26  *    notice, this list of conditions and the following disclaimer.
27  * 2. Redistributions in binary form must reproduce the above copyright
28  *    notice, this list of conditions and the following disclaimer in the
29  *    documentation and/or other materials provided with the distribution.
30  * 3. All advertising materials mentioning features or use of this software
31  *    must display the following acknowledgement:
32  *    "This product includes cryptographic software written by
33  *     Eric Young (eay@cryptsoft.com)"
34  *    The word 'cryptographic' can be left out if the rouines from the library
35  *    being used are not cryptographic related :-).
36  * 4. If you include any Windows specific code (or a derivative thereof) from
37  *    the apps directory (application code) you must include an acknowledgement:
38  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39  *
40  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE.
51  *
52  * The licence and distribution terms for any publically available version or
53  * derivative of this code cannot be changed.  i.e. this code cannot simply be
54  * copied and put under another distribution licence
55  * [including the GNU Public Licence.] */
56 
57 #include <openssl/asn1.h>
58 
59 #include <string.h>
60 #include <limits.h>
61 
62 #include <openssl/err.h>
63 #include <openssl/mem.h>
64 
65 #include "../internal.h"
66 
67 
ASN1_INTEGER_dup(const ASN1_INTEGER * x)68 ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x)
69 {
70     return M_ASN1_INTEGER_dup(x);
71 }
72 
ASN1_INTEGER_cmp(const ASN1_INTEGER * x,const ASN1_INTEGER * y)73 int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
74 {
75     int neg, ret;
76     /* Compare signs */
77     neg = x->type & V_ASN1_NEG;
78     if (neg != (y->type & V_ASN1_NEG)) {
79         if (neg)
80             return -1;
81         else
82             return 1;
83     }
84 
85     ret = ASN1_STRING_cmp(x, y);
86 
87     if (neg)
88         return -ret;
89     else
90         return ret;
91 }
92 
93 /*
94  * This converts an ASN1 INTEGER into its content encoding.
95  * The internal representation is an ASN1_STRING whose data is a big endian
96  * representation of the value, ignoring the sign. The sign is determined by
97  * the type: V_ASN1_INTEGER for positive and V_ASN1_NEG_INTEGER for negative.
98  *
99  * Positive integers are no problem: they are almost the same as the DER
100  * encoding, except if the first byte is >= 0x80 we need to add a zero pad.
101  *
102  * Negative integers are a bit trickier...
103  * The DER representation of negative integers is in 2s complement form.
104  * The internal form is converted by complementing each octet and finally
105  * adding one to the result. This can be done less messily with a little trick.
106  * If the internal form has trailing zeroes then they will become FF by the
107  * complement and 0 by the add one (due to carry) so just copy as many trailing
108  * zeros to the destination as there are in the source. The carry will add one
109  * to the last none zero octet: so complement this octet and add one and finally
110  * complement any left over until you get to the start of the string.
111  *
112  * Padding is a little trickier too. If the first bytes is > 0x80 then we pad
113  * with 0xff. However if the first byte is 0x80 and one of the following bytes
114  * is non-zero we pad with 0xff. The reason for this distinction is that 0x80
115  * followed by optional zeros isn't padded.
116  */
117 
i2c_ASN1_INTEGER(ASN1_INTEGER * a,unsigned char ** pp)118 int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
119 {
120     int pad = 0, ret, i, neg;
121     unsigned char *p, *n, pb = 0;
122 
123     if (a == NULL)
124         return (0);
125     neg = a->type & V_ASN1_NEG;
126     if (a->length == 0)
127         ret = 1;
128     else {
129         ret = a->length;
130         i = a->data[0];
131         if (ret == 1 && i == 0)
132             neg = 0;
133         if (!neg && (i > 127)) {
134             pad = 1;
135             pb = 0;
136         } else if (neg) {
137             if (i > 128) {
138                 pad = 1;
139                 pb = 0xFF;
140             } else if (i == 128) {
141                 /*
142                  * Special case: if any other bytes non zero we pad:
143                  * otherwise we don't.
144                  */
145                 for (i = 1; i < a->length; i++)
146                     if (a->data[i]) {
147                         pad = 1;
148                         pb = 0xFF;
149                         break;
150                     }
151             }
152         }
153         ret += pad;
154     }
155     if (pp == NULL)
156         return (ret);
157     p = *pp;
158 
159     if (pad)
160         *(p++) = pb;
161     if (a->length == 0)
162         *(p++) = 0;
163     else if (!neg)
164         OPENSSL_memcpy(p, a->data, (unsigned int)a->length);
165     else {
166         /* Begin at the end of the encoding */
167         n = a->data + a->length - 1;
168         p += a->length - 1;
169         i = a->length;
170         /* Copy zeros to destination as long as source is zero */
171         while (!*n && i > 1) {
172             *(p--) = 0;
173             n--;
174             i--;
175         }
176         /* Complement and increment next octet */
177         *(p--) = ((*(n--)) ^ 0xff) + 1;
178         i--;
179         /* Complement any octets left */
180         for (; i > 0; i--)
181             *(p--) = *(n--) ^ 0xff;
182     }
183 
184     *pp += ret;
185     return (ret);
186 }
187 
188 /* Convert just ASN1 INTEGER content octets to ASN1_INTEGER structure */
189 
c2i_ASN1_INTEGER(ASN1_INTEGER ** a,const unsigned char ** pp,long len)190 ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp,
191                                long len)
192 {
193     ASN1_INTEGER *ret = NULL;
194     const unsigned char *p, *pend;
195     unsigned char *to, *s;
196     int i;
197 
198     if ((a == NULL) || ((*a) == NULL)) {
199         if ((ret = M_ASN1_INTEGER_new()) == NULL)
200             return (NULL);
201         ret->type = V_ASN1_INTEGER;
202     } else
203         ret = (*a);
204 
205     p = *pp;
206     pend = p + len;
207 
208     /*
209      * We must OPENSSL_malloc stuff, even for 0 bytes otherwise it signifies
210      * a missing NULL parameter.
211      */
212     s = (unsigned char *)OPENSSL_malloc((int)len + 1);
213     if (s == NULL) {
214         i = ERR_R_MALLOC_FAILURE;
215         goto err;
216     }
217     to = s;
218     if (!len) {
219         /*
220          * Strictly speaking this is an illegal INTEGER but we tolerate it.
221          */
222         ret->type = V_ASN1_INTEGER;
223     } else if (*p & 0x80) {     /* a negative number */
224         ret->type = V_ASN1_NEG_INTEGER;
225         if ((*p == 0xff) && (len != 1)) {
226             p++;
227             len--;
228         }
229         i = len;
230         p += i - 1;
231         to += i - 1;
232         while ((!*p) && i) {
233             *(to--) = 0;
234             i--;
235             p--;
236         }
237         /*
238          * Special case: if all zeros then the number will be of the form FF
239          * followed by n zero bytes: this corresponds to 1 followed by n zero
240          * bytes. We've already written n zeros so we just append an extra
241          * one and set the first byte to a 1. This is treated separately
242          * because it is the only case where the number of bytes is larger
243          * than len.
244          */
245         if (!i) {
246             *s = 1;
247             s[len] = 0;
248             len++;
249         } else {
250             *(to--) = (*(p--) ^ 0xff) + 1;
251             i--;
252             for (; i > 0; i--)
253                 *(to--) = *(p--) ^ 0xff;
254         }
255     } else {
256         ret->type = V_ASN1_INTEGER;
257         if ((*p == 0) && (len != 1)) {
258             p++;
259             len--;
260         }
261         OPENSSL_memcpy(s, p, (int)len);
262     }
263 
264     if (ret->data != NULL)
265         OPENSSL_free(ret->data);
266     ret->data = s;
267     ret->length = (int)len;
268     if (a != NULL)
269         (*a) = ret;
270     *pp = pend;
271     return (ret);
272  err:
273     OPENSSL_PUT_ERROR(ASN1, i);
274     if ((ret != NULL) && ((a == NULL) || (*a != ret)))
275         M_ASN1_INTEGER_free(ret);
276     return (NULL);
277 }
278 
279 /*
280  * This is a version of d2i_ASN1_INTEGER that ignores the sign bit of ASN1
281  * integers: some broken software can encode a positive INTEGER with its MSB
282  * set as negative (it doesn't add a padding zero).
283  */
284 
d2i_ASN1_UINTEGER(ASN1_INTEGER ** a,const unsigned char ** pp,long length)285 ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp,
286                                 long length)
287 {
288     ASN1_INTEGER *ret = NULL;
289     const unsigned char *p;
290     unsigned char *s;
291     long len;
292     int inf, tag, xclass;
293     int i;
294 
295     if ((a == NULL) || ((*a) == NULL)) {
296         if ((ret = M_ASN1_INTEGER_new()) == NULL)
297             return (NULL);
298         ret->type = V_ASN1_INTEGER;
299     } else
300         ret = (*a);
301 
302     p = *pp;
303     inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
304     if (inf & 0x80) {
305         i = ASN1_R_BAD_OBJECT_HEADER;
306         goto err;
307     }
308 
309     if (tag != V_ASN1_INTEGER) {
310         i = ASN1_R_EXPECTING_AN_INTEGER;
311         goto err;
312     }
313 
314     /*
315      * We must OPENSSL_malloc stuff, even for 0 bytes otherwise it signifies
316      * a missing NULL parameter.
317      */
318     s = (unsigned char *)OPENSSL_malloc((int)len + 1);
319     if (s == NULL) {
320         i = ERR_R_MALLOC_FAILURE;
321         goto err;
322     }
323     ret->type = V_ASN1_INTEGER;
324     if (len) {
325         if ((*p == 0) && (len != 1)) {
326             p++;
327             len--;
328         }
329         OPENSSL_memcpy(s, p, (int)len);
330         p += len;
331     }
332 
333     if (ret->data != NULL)
334         OPENSSL_free(ret->data);
335     ret->data = s;
336     ret->length = (int)len;
337     if (a != NULL)
338         (*a) = ret;
339     *pp = p;
340     return (ret);
341  err:
342     OPENSSL_PUT_ERROR(ASN1, i);
343     if ((ret != NULL) && ((a == NULL) || (*a != ret)))
344         M_ASN1_INTEGER_free(ret);
345     return (NULL);
346 }
347 
ASN1_INTEGER_set(ASN1_INTEGER * a,long v)348 int ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
349 {
350     if (v >= 0) {
351         return ASN1_INTEGER_set_uint64(a, (uint64_t) v);
352     }
353 
354     if (!ASN1_INTEGER_set_uint64(a, 0 - (uint64_t) v)) {
355         return 0;
356     }
357 
358     a->type = V_ASN1_NEG_INTEGER;
359     return 1;
360 }
361 
ASN1_INTEGER_set_uint64(ASN1_INTEGER * out,uint64_t v)362 int ASN1_INTEGER_set_uint64(ASN1_INTEGER *out, uint64_t v)
363 {
364     uint8_t *const newdata = OPENSSL_malloc(sizeof(uint64_t));
365     if (newdata == NULL) {
366         OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
367         return 0;
368     }
369 
370     OPENSSL_free(out->data);
371     out->data = newdata;
372     v = CRYPTO_bswap8(v);
373     memcpy(out->data, &v, sizeof(v));
374 
375     out->type = V_ASN1_INTEGER;
376 
377     size_t leading_zeros;
378     for (leading_zeros = 0; leading_zeros < sizeof(uint64_t) - 1;
379          leading_zeros++) {
380         if (out->data[leading_zeros] != 0) {
381             break;
382         }
383     }
384 
385     out->length = sizeof(uint64_t) - leading_zeros;
386     OPENSSL_memmove(out->data, out->data + leading_zeros, out->length);
387 
388     return 1;
389 }
390 
ASN1_INTEGER_get(const ASN1_INTEGER * a)391 long ASN1_INTEGER_get(const ASN1_INTEGER *a)
392 {
393     int neg = 0, i;
394 
395     if (a == NULL)
396         return (0L);
397     i = a->type;
398     if (i == V_ASN1_NEG_INTEGER)
399         neg = 1;
400     else if (i != V_ASN1_INTEGER)
401         return -1;
402 
403     OPENSSL_COMPILE_ASSERT(sizeof(uint64_t) >= sizeof(long),
404                            long_larger_than_uint64_t);
405 
406     if (a->length > (int)sizeof(uint64_t)) {
407         /* hmm... a bit ugly, return all ones */
408         return -1;
409     }
410 
411     uint64_t r64 = 0;
412     if (a->data != NULL) {
413       for (i = 0; i < a->length; i++) {
414           r64 <<= 8;
415           r64 |= (unsigned char)a->data[i];
416       }
417 
418       if (r64 > LONG_MAX) {
419           return -1;
420       }
421     }
422 
423     long r = (long) r64;
424     if (neg)
425         r = -r;
426 
427     return r;
428 }
429 
BN_to_ASN1_INTEGER(const BIGNUM * bn,ASN1_INTEGER * ai)430 ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
431 {
432     ASN1_INTEGER *ret;
433     int len, j;
434 
435     if (ai == NULL)
436         ret = M_ASN1_INTEGER_new();
437     else
438         ret = ai;
439     if (ret == NULL) {
440         OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
441         goto err;
442     }
443     if (BN_is_negative(bn) && !BN_is_zero(bn))
444         ret->type = V_ASN1_NEG_INTEGER;
445     else
446         ret->type = V_ASN1_INTEGER;
447     j = BN_num_bits(bn);
448     len = ((j == 0) ? 0 : ((j / 8) + 1));
449     if (ret->length < len + 4) {
450         unsigned char *new_data = OPENSSL_realloc(ret->data, len + 4);
451         if (!new_data) {
452             OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
453             goto err;
454         }
455         ret->data = new_data;
456     }
457     ret->length = BN_bn2bin(bn, ret->data);
458     /* Correct zero case */
459     if (!ret->length) {
460         ret->data[0] = 0;
461         ret->length = 1;
462     }
463     return (ret);
464  err:
465     if (ret != ai)
466         M_ASN1_INTEGER_free(ret);
467     return (NULL);
468 }
469 
ASN1_INTEGER_to_BN(const ASN1_INTEGER * ai,BIGNUM * bn)470 BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn)
471 {
472     BIGNUM *ret;
473 
474     if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL)
475         OPENSSL_PUT_ERROR(ASN1, ASN1_R_BN_LIB);
476     else if (ai->type == V_ASN1_NEG_INTEGER)
477         BN_set_negative(ret, 1);
478     return (ret);
479 }
480