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 <limits.h>
     60 #include <string.h>
     61 
     62 #include <openssl/asn1_mac.h>
     63 #include <openssl/err.h>
     64 #include <openssl/mem.h>
     65 
     66 #include "../internal.h"
     67 
     68 
     69 /* Cross-module errors from crypto/x509/i2d_pr.c. */
     70 OPENSSL_DECLARE_ERROR_REASON(ASN1, UNSUPPORTED_PUBLIC_KEY_TYPE)
     71 
     72 /* Cross-module errors from crypto/x509/algorithm.c. */
     73 OPENSSL_DECLARE_ERROR_REASON(ASN1, CONTEXT_NOT_INITIALISED)
     74 OPENSSL_DECLARE_ERROR_REASON(ASN1, DIGEST_AND_KEY_TYPE_NOT_SUPPORTED)
     75 OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_MESSAGE_DIGEST_ALGORITHM)
     76 OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_SIGNATURE_ALGORITHM)
     77 OPENSSL_DECLARE_ERROR_REASON(ASN1, WRONG_PUBLIC_KEY_TYPE)
     78 /*
     79  * Cross-module errors from crypto/x509/asn1_gen.c. TODO(davidben): Remove
     80  * these once asn1_gen.c is gone.
     81  */
     82 OPENSSL_DECLARE_ERROR_REASON(ASN1, DEPTH_EXCEEDED)
     83 OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_BITSTRING_FORMAT)
     84 OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_BOOLEAN)
     85 OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_FORMAT)
     86 OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_HEX)
     87 OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_IMPLICIT_TAG)
     88 OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_INTEGER)
     89 OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_NESTED_TAGGING)
     90 OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_NULL_VALUE)
     91 OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_OBJECT)
     92 OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_TIME_VALUE)
     93 OPENSSL_DECLARE_ERROR_REASON(ASN1, INTEGER_NOT_ASCII_FORMAT)
     94 OPENSSL_DECLARE_ERROR_REASON(ASN1, INVALID_MODIFIER)
     95 OPENSSL_DECLARE_ERROR_REASON(ASN1, INVALID_NUMBER)
     96 OPENSSL_DECLARE_ERROR_REASON(ASN1, LIST_ERROR)
     97 OPENSSL_DECLARE_ERROR_REASON(ASN1, MISSING_VALUE)
     98 OPENSSL_DECLARE_ERROR_REASON(ASN1, NOT_ASCII_FORMAT)
     99 OPENSSL_DECLARE_ERROR_REASON(ASN1, OBJECT_NOT_ASCII_FORMAT)
    100 OPENSSL_DECLARE_ERROR_REASON(ASN1, SEQUENCE_OR_SET_NEEDS_CONFIG)
    101 OPENSSL_DECLARE_ERROR_REASON(ASN1, TIME_NOT_ASCII_FORMAT)
    102 OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_FORMAT)
    103 OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_TAG)
    104 OPENSSL_DECLARE_ERROR_REASON(ASN1, UNSUPPORTED_TYPE)
    105 
    106 static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
    107                            long max);
    108 static void asn1_put_length(unsigned char **pp, int length);
    109 
    110 static int _asn1_check_infinite_end(const unsigned char **p, long len)
    111 {
    112     /*
    113      * If there is 0 or 1 byte left, the length check should pick things up
    114      */
    115     if (len <= 0)
    116         return (1);
    117     else if ((len >= 2) && ((*p)[0] == 0) && ((*p)[1] == 0)) {
    118         (*p) += 2;
    119         return (1);
    120     }
    121     return (0);
    122 }
    123 
    124 int ASN1_check_infinite_end(unsigned char **p, long len)
    125 {
    126     return _asn1_check_infinite_end((const unsigned char **)p, len);
    127 }
    128 
    129 int ASN1_const_check_infinite_end(const unsigned char **p, long len)
    130 {
    131     return _asn1_check_infinite_end(p, len);
    132 }
    133 
    134 int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
    135                     int *pclass, long omax)
    136 {
    137     int i, ret;
    138     long l;
    139     const unsigned char *p = *pp;
    140     int tag, xclass, inf;
    141     long max = omax;
    142 
    143     if (!max)
    144         goto err;
    145     ret = (*p & V_ASN1_CONSTRUCTED);
    146     xclass = (*p & V_ASN1_PRIVATE);
    147     i = *p & V_ASN1_PRIMITIVE_TAG;
    148     if (i == V_ASN1_PRIMITIVE_TAG) { /* high-tag */
    149         p++;
    150         if (--max == 0)
    151             goto err;
    152         l = 0;
    153         while (*p & 0x80) {
    154             l <<= 7L;
    155             l |= *(p++) & 0x7f;
    156             if (--max == 0)
    157                 goto err;
    158             if (l > (INT_MAX >> 7L))
    159                 goto err;
    160         }
    161         l <<= 7L;
    162         l |= *(p++) & 0x7f;
    163         tag = (int)l;
    164         if (--max == 0)
    165             goto err;
    166     } else {
    167         tag = i;
    168         p++;
    169         if (--max == 0)
    170             goto err;
    171     }
    172 
    173     /* To avoid ambiguity with V_ASN1_NEG, impose a limit on universal tags. */
    174     if (xclass == V_ASN1_UNIVERSAL && tag > V_ASN1_MAX_UNIVERSAL)
    175         goto err;
    176 
    177     *ptag = tag;
    178     *pclass = xclass;
    179     if (!asn1_get_length(&p, &inf, plength, max))
    180         goto err;
    181 
    182     if (inf && !(ret & V_ASN1_CONSTRUCTED))
    183         goto err;
    184 
    185 #if 0
    186     fprintf(stderr, "p=%d + *plength=%ld > omax=%ld + *pp=%d  (%d > %d)\n",
    187             (int)p, *plength, omax, (int)*pp, (int)(p + *plength),
    188             (int)(omax + *pp));
    189 
    190 #endif
    191     if (*plength > (omax - (p - *pp))) {
    192         OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
    193         /*
    194          * Set this so that even if things are not long enough the values are
    195          * set correctly
    196          */
    197         ret |= 0x80;
    198     }
    199     *pp = p;
    200     return (ret | inf);
    201  err:
    202     OPENSSL_PUT_ERROR(ASN1, ASN1_R_HEADER_TOO_LONG);
    203     return (0x80);
    204 }
    205 
    206 static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
    207                            long max)
    208 {
    209     const unsigned char *p = *pp;
    210     unsigned long ret = 0;
    211     unsigned long i;
    212 
    213     if (max-- < 1)
    214         return 0;
    215     if (*p == 0x80) {
    216         *inf = 1;
    217         ret = 0;
    218         p++;
    219     } else {
    220         *inf = 0;
    221         i = *p & 0x7f;
    222         if (*(p++) & 0x80) {
    223             if (i > sizeof(ret) || max < (long)i)
    224                 return 0;
    225             while (i-- > 0) {
    226                 ret <<= 8L;
    227                 ret |= *(p++);
    228             }
    229         } else
    230             ret = i;
    231     }
    232     if (ret > LONG_MAX)
    233         return 0;
    234     *pp = p;
    235     *rl = (long)ret;
    236     return 1;
    237 }
    238 
    239 /*
    240  * class 0 is constructed constructed == 2 for indefinite length constructed
    241  */
    242 void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag,
    243                      int xclass)
    244 {
    245     unsigned char *p = *pp;
    246     int i, ttag;
    247 
    248     i = (constructed) ? V_ASN1_CONSTRUCTED : 0;
    249     i |= (xclass & V_ASN1_PRIVATE);
    250     if (tag < 31)
    251         *(p++) = i | (tag & V_ASN1_PRIMITIVE_TAG);
    252     else {
    253         *(p++) = i | V_ASN1_PRIMITIVE_TAG;
    254         for (i = 0, ttag = tag; ttag > 0; i++)
    255             ttag >>= 7;
    256         ttag = i;
    257         while (i-- > 0) {
    258             p[i] = tag & 0x7f;
    259             if (i != (ttag - 1))
    260                 p[i] |= 0x80;
    261             tag >>= 7;
    262         }
    263         p += ttag;
    264     }
    265     if (constructed == 2)
    266         *(p++) = 0x80;
    267     else
    268         asn1_put_length(&p, length);
    269     *pp = p;
    270 }
    271 
    272 int ASN1_put_eoc(unsigned char **pp)
    273 {
    274     unsigned char *p = *pp;
    275     *p++ = 0;
    276     *p++ = 0;
    277     *pp = p;
    278     return 2;
    279 }
    280 
    281 static void asn1_put_length(unsigned char **pp, int length)
    282 {
    283     unsigned char *p = *pp;
    284     int i, l;
    285     if (length <= 127)
    286         *(p++) = (unsigned char)length;
    287     else {
    288         l = length;
    289         for (i = 0; l > 0; i++)
    290             l >>= 8;
    291         *(p++) = i | 0x80;
    292         l = i;
    293         while (i-- > 0) {
    294             p[i] = length & 0xff;
    295             length >>= 8;
    296         }
    297         p += l;
    298     }
    299     *pp = p;
    300 }
    301 
    302 int ASN1_object_size(int constructed, int length, int tag)
    303 {
    304     int ret = 1;
    305     if (length < 0)
    306         return -1;
    307     if (tag >= 31) {
    308         while (tag > 0) {
    309             tag >>= 7;
    310             ret++;
    311         }
    312     }
    313     if (constructed == 2) {
    314         ret += 3;
    315     } else {
    316         ret++;
    317         if (length > 127) {
    318             int tmplen = length;
    319             while (tmplen > 0) {
    320                 tmplen >>= 8;
    321                 ret++;
    322             }
    323         }
    324     }
    325     if (ret >= INT_MAX - length)
    326         return -1;
    327     return ret + length;
    328 }
    329 
    330 static int _asn1_Finish(ASN1_const_CTX *c)
    331 {
    332     if ((c->inf == (1 | V_ASN1_CONSTRUCTED)) && (!c->eos)) {
    333         if (!ASN1_const_check_infinite_end(&c->p, c->slen)) {
    334             c->error = ASN1_R_MISSING_ASN1_EOS;
    335             return (0);
    336         }
    337     }
    338     if (((c->slen != 0) && !(c->inf & 1)) || ((c->slen < 0) && (c->inf & 1))) {
    339         c->error = ASN1_R_ASN1_LENGTH_MISMATCH;
    340         return (0);
    341     }
    342     return (1);
    343 }
    344 
    345 int asn1_Finish(ASN1_CTX *c)
    346 {
    347     return _asn1_Finish((ASN1_const_CTX *)c);
    348 }
    349 
    350 int asn1_const_Finish(ASN1_const_CTX *c)
    351 {
    352     return _asn1_Finish(c);
    353 }
    354 
    355 int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str)
    356 {
    357     if (str == NULL)
    358         return 0;
    359     dst->type = str->type;
    360     if (!ASN1_STRING_set(dst, str->data, str->length))
    361         return 0;
    362     dst->flags = str->flags;
    363     return 1;
    364 }
    365 
    366 ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str)
    367 {
    368     ASN1_STRING *ret;
    369     if (!str)
    370         return NULL;
    371     ret = ASN1_STRING_new();
    372     if (!ret)
    373         return NULL;
    374     if (!ASN1_STRING_copy(ret, str)) {
    375         ASN1_STRING_free(ret);
    376         return NULL;
    377     }
    378     return ret;
    379 }
    380 
    381 int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len)
    382 {
    383     unsigned char *c;
    384     const char *data = _data;
    385 
    386     if (len < 0) {
    387         if (data == NULL)
    388             return (0);
    389         else
    390             len = strlen(data);
    391     }
    392     if ((str->length <= len) || (str->data == NULL)) {
    393         c = str->data;
    394         if (c == NULL)
    395             str->data = OPENSSL_malloc(len + 1);
    396         else
    397             str->data = OPENSSL_realloc(c, len + 1);
    398 
    399         if (str->data == NULL) {
    400             OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
    401             str->data = c;
    402             return (0);
    403         }
    404     }
    405     str->length = len;
    406     if (data != NULL) {
    407         OPENSSL_memcpy(str->data, data, len);
    408         /* an allowance for strings :-) */
    409         str->data[len] = '\0';
    410     }
    411     return (1);
    412 }
    413 
    414 void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len)
    415 {
    416     if (str->data)
    417         OPENSSL_free(str->data);
    418     str->data = data;
    419     str->length = len;
    420 }
    421 
    422 ASN1_STRING *ASN1_STRING_new(void)
    423 {
    424     return (ASN1_STRING_type_new(V_ASN1_OCTET_STRING));
    425 }
    426 
    427 ASN1_STRING *ASN1_STRING_type_new(int type)
    428 {
    429     ASN1_STRING *ret;
    430 
    431     ret = (ASN1_STRING *)OPENSSL_malloc(sizeof(ASN1_STRING));
    432     if (ret == NULL) {
    433         OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
    434         return (NULL);
    435     }
    436     ret->length = 0;
    437     ret->type = type;
    438     ret->data = NULL;
    439     ret->flags = 0;
    440     return (ret);
    441 }
    442 
    443 void ASN1_STRING_free(ASN1_STRING *a)
    444 {
    445     if (a == NULL)
    446         return;
    447     if (a->data && !(a->flags & ASN1_STRING_FLAG_NDEF))
    448         OPENSSL_free(a->data);
    449     OPENSSL_free(a);
    450 }
    451 
    452 int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
    453 {
    454     int i;
    455 
    456     i = (a->length - b->length);
    457     if (i == 0) {
    458         i = OPENSSL_memcmp(a->data, b->data, a->length);
    459         if (i == 0)
    460             return (a->type - b->type);
    461         else
    462             return (i);
    463     } else
    464         return (i);
    465 }
    466 
    467 int ASN1_STRING_length(const ASN1_STRING *x)
    468 {
    469     return M_ASN1_STRING_length(x);
    470 }
    471 
    472 void ASN1_STRING_length_set(ASN1_STRING *x, int len)
    473 {
    474     M_ASN1_STRING_length_set(x, len);
    475     return;
    476 }
    477 
    478 int ASN1_STRING_type(ASN1_STRING *x)
    479 {
    480     return M_ASN1_STRING_type(x);
    481 }
    482 
    483 unsigned char *ASN1_STRING_data(ASN1_STRING *x)
    484 {
    485     return M_ASN1_STRING_data(x);
    486 }
    487