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     /*
199      * This function can handle lengths up to INT_MAX - 1, but the rest of the
200      * legacy ASN.1 code mixes integer types, so avoid exposing it to
201      * ASN1_INTEGERS with larger lengths.
202      */
203     if (len < 0 || len > INT_MAX / 2) {
204         OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
205         return NULL;
206     }
207 
208     if ((a == NULL) || ((*a) == NULL)) {
209         if ((ret = M_ASN1_INTEGER_new()) == NULL)
210             return (NULL);
211         ret->type = V_ASN1_INTEGER;
212     } else
213         ret = (*a);
214 
215     p = *pp;
216     pend = p + len;
217 
218     /*
219      * We must OPENSSL_malloc stuff, even for 0 bytes otherwise it signifies
220      * a missing NULL parameter.
221      */
222     s = (unsigned char *)OPENSSL_malloc((int)len + 1);
223     if (s == NULL) {
224         i = ERR_R_MALLOC_FAILURE;
225         goto err;
226     }
227     to = s;
228     if (!len) {
229         /*
230          * Strictly speaking this is an illegal INTEGER but we tolerate it.
231          */
232         ret->type = V_ASN1_INTEGER;
233     } else if (*p & 0x80) {     /* a negative number */
234         ret->type = V_ASN1_NEG_INTEGER;
235         if ((*p == 0xff) && (len != 1)) {
236             p++;
237             len--;
238         }
239         i = len;
240         p += i - 1;
241         to += i - 1;
242         while ((!*p) && i) {
243             *(to--) = 0;
244             i--;
245             p--;
246         }
247         /*
248          * Special case: if all zeros then the number will be of the form FF
249          * followed by n zero bytes: this corresponds to 1 followed by n zero
250          * bytes. We've already written n zeros so we just append an extra
251          * one and set the first byte to a 1. This is treated separately
252          * because it is the only case where the number of bytes is larger
253          * than len.
254          */
255         if (!i) {
256             *s = 1;
257             s[len] = 0;
258             len++;
259         } else {
260             *(to--) = (*(p--) ^ 0xff) + 1;
261             i--;
262             for (; i > 0; i--)
263                 *(to--) = *(p--) ^ 0xff;
264         }
265     } else {
266         ret->type = V_ASN1_INTEGER;
267         if ((*p == 0) && (len != 1)) {
268             p++;
269             len--;
270         }
271         OPENSSL_memcpy(s, p, (int)len);
272     }
273 
274     if (ret->data != NULL)
275         OPENSSL_free(ret->data);
276     ret->data = s;
277     ret->length = (int)len;
278     if (a != NULL)
279         (*a) = ret;
280     *pp = pend;
281     return (ret);
282  err:
283     OPENSSL_PUT_ERROR(ASN1, i);
284     if ((ret != NULL) && ((a == NULL) || (*a != ret)))
285         M_ASN1_INTEGER_free(ret);
286     return (NULL);
287 }
288 
ASN1_INTEGER_set(ASN1_INTEGER * a,long v)289 int ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
290 {
291     if (v >= 0) {
292         return ASN1_INTEGER_set_uint64(a, (uint64_t) v);
293     }
294 
295     if (!ASN1_INTEGER_set_uint64(a, 0 - (uint64_t) v)) {
296         return 0;
297     }
298 
299     a->type = V_ASN1_NEG_INTEGER;
300     return 1;
301 }
302 
ASN1_INTEGER_set_uint64(ASN1_INTEGER * out,uint64_t v)303 int ASN1_INTEGER_set_uint64(ASN1_INTEGER *out, uint64_t v)
304 {
305     uint8_t *const newdata = OPENSSL_malloc(sizeof(uint64_t));
306     if (newdata == NULL) {
307         OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
308         return 0;
309     }
310 
311     OPENSSL_free(out->data);
312     out->data = newdata;
313 #ifndef OPENSSL_BIGENDIAN
314     v = CRYPTO_bswap8(v);
315 #endif
316     memcpy(out->data, &v, sizeof(v));
317 
318     out->type = V_ASN1_INTEGER;
319 
320     size_t leading_zeros;
321     for (leading_zeros = 0; leading_zeros < sizeof(uint64_t) - 1;
322          leading_zeros++) {
323         if (out->data[leading_zeros] != 0) {
324             break;
325         }
326     }
327 
328     out->length = sizeof(uint64_t) - leading_zeros;
329     OPENSSL_memmove(out->data, out->data + leading_zeros, out->length);
330 
331     return 1;
332 }
333 
ASN1_INTEGER_get(const ASN1_INTEGER * a)334 long ASN1_INTEGER_get(const ASN1_INTEGER *a)
335 {
336     int neg = 0, i;
337 
338     if (a == NULL)
339         return (0L);
340     i = a->type;
341     if (i == V_ASN1_NEG_INTEGER)
342         neg = 1;
343     else if (i != V_ASN1_INTEGER)
344         return -1;
345 
346     OPENSSL_STATIC_ASSERT(sizeof(uint64_t) >= sizeof(long),
347                           "long larger than uint64_t");
348 
349     if (a->length > (int)sizeof(uint64_t)) {
350         /* hmm... a bit ugly, return all ones */
351         return -1;
352     }
353 
354     uint64_t r64 = 0;
355     if (a->data != NULL) {
356       for (i = 0; i < a->length; i++) {
357           r64 <<= 8;
358           r64 |= (unsigned char)a->data[i];
359       }
360 
361       if (r64 > LONG_MAX) {
362           return -1;
363       }
364     }
365 
366     long r = (long) r64;
367     if (neg)
368         r = -r;
369 
370     return r;
371 }
372 
BN_to_ASN1_INTEGER(const BIGNUM * bn,ASN1_INTEGER * ai)373 ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
374 {
375     ASN1_INTEGER *ret;
376     int len, j;
377 
378     if (ai == NULL)
379         ret = M_ASN1_INTEGER_new();
380     else
381         ret = ai;
382     if (ret == NULL) {
383         OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
384         goto err;
385     }
386     if (BN_is_negative(bn) && !BN_is_zero(bn))
387         ret->type = V_ASN1_NEG_INTEGER;
388     else
389         ret->type = V_ASN1_INTEGER;
390     j = BN_num_bits(bn);
391     len = ((j == 0) ? 0 : ((j / 8) + 1));
392     if (ret->length < len + 4) {
393         unsigned char *new_data = OPENSSL_realloc(ret->data, len + 4);
394         if (!new_data) {
395             OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
396             goto err;
397         }
398         ret->data = new_data;
399     }
400     ret->length = BN_bn2bin(bn, ret->data);
401     /* Correct zero case */
402     if (!ret->length) {
403         ret->data[0] = 0;
404         ret->length = 1;
405     }
406     return (ret);
407  err:
408     if (ret != ai)
409         M_ASN1_INTEGER_free(ret);
410     return (NULL);
411 }
412 
ASN1_INTEGER_to_BN(const ASN1_INTEGER * ai,BIGNUM * bn)413 BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn)
414 {
415     BIGNUM *ret;
416 
417     if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL)
418         OPENSSL_PUT_ERROR(ASN1, ASN1_R_BN_LIB);
419     else if (ai->type == V_ASN1_NEG_INTEGER)
420         BN_set_negative(ret, 1);
421     return (ret);
422 }
423