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 #include <limits.h>
     61 
     62 #include <openssl/err.h>
     63 #include <openssl/mem.h>
     64 
     65 #include "../internal.h"
     66 
     67 
     68 ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x)
     69 {
     70     return M_ASN1_INTEGER_dup(x);
     71 }
     72 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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