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