Home | History | Annotate | Download | only in asn1
      1 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com)
      2  * All rights reserved.
      3  *
      4  * This package is an SSL implementation written
      5  * by Eric Young (eay (at) 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 (at) 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 (at) 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 (at) 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 
     67 ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x)
     68 {
     69     return M_ASN1_INTEGER_dup(x);
     70 }
     71 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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