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/asn1t.h>
     62 #include <openssl/err.h>
     63 #include <openssl/mem.h>
     64 #include <openssl/obj.h>
     65 
     66 #include "asn1_locl.h"
     67 #include "../internal.h"
     68 
     69 
     70 static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
     71                                     int combine);
     72 static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
     73 static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
     74 static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
     75 
     76 ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it)
     77 {
     78     ASN1_VALUE *ret = NULL;
     79     if (ASN1_item_ex_new(&ret, it) > 0)
     80         return ret;
     81     return NULL;
     82 }
     83 
     84 /* Allocate an ASN1 structure */
     85 
     86 int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
     87 {
     88     return asn1_item_ex_combine_new(pval, it, 0);
     89 }
     90 
     91 static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
     92                                     int combine)
     93 {
     94     const ASN1_TEMPLATE *tt = NULL;
     95     const ASN1_COMPAT_FUNCS *cf;
     96     const ASN1_EXTERN_FUNCS *ef;
     97     const ASN1_AUX *aux = it->funcs;
     98     ASN1_aux_cb *asn1_cb;
     99     ASN1_VALUE **pseqval;
    100     int i;
    101     if (aux && aux->asn1_cb)
    102         asn1_cb = aux->asn1_cb;
    103     else
    104         asn1_cb = 0;
    105 
    106 #ifdef CRYPTO_MDEBUG
    107     if (it->sname)
    108         CRYPTO_push_info(it->sname);
    109 #endif
    110 
    111     switch (it->itype) {
    112 
    113     case ASN1_ITYPE_EXTERN:
    114         ef = it->funcs;
    115         if (ef && ef->asn1_ex_new) {
    116             if (!ef->asn1_ex_new(pval, it))
    117                 goto memerr;
    118         }
    119         break;
    120 
    121     case ASN1_ITYPE_COMPAT:
    122         cf = it->funcs;
    123         if (cf && cf->asn1_new) {
    124             *pval = cf->asn1_new();
    125             if (!*pval)
    126                 goto memerr;
    127         }
    128         break;
    129 
    130     case ASN1_ITYPE_PRIMITIVE:
    131         if (it->templates) {
    132             if (!ASN1_template_new(pval, it->templates))
    133                 goto memerr;
    134         } else if (!ASN1_primitive_new(pval, it))
    135             goto memerr;
    136         break;
    137 
    138     case ASN1_ITYPE_MSTRING:
    139         if (!ASN1_primitive_new(pval, it))
    140             goto memerr;
    141         break;
    142 
    143     case ASN1_ITYPE_CHOICE:
    144         if (asn1_cb) {
    145             i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
    146             if (!i)
    147                 goto auxerr;
    148             if (i == 2) {
    149 #ifdef CRYPTO_MDEBUG
    150                 if (it->sname)
    151                     CRYPTO_pop_info();
    152 #endif
    153                 return 1;
    154             }
    155         }
    156         if (!combine) {
    157             *pval = OPENSSL_malloc(it->size);
    158             if (!*pval)
    159                 goto memerr;
    160             OPENSSL_memset(*pval, 0, it->size);
    161         }
    162         asn1_set_choice_selector(pval, -1, it);
    163         if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
    164             goto auxerr2;
    165         break;
    166 
    167     case ASN1_ITYPE_NDEF_SEQUENCE:
    168     case ASN1_ITYPE_SEQUENCE:
    169         if (asn1_cb) {
    170             i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
    171             if (!i)
    172                 goto auxerr;
    173             if (i == 2) {
    174 #ifdef CRYPTO_MDEBUG
    175                 if (it->sname)
    176                     CRYPTO_pop_info();
    177 #endif
    178                 return 1;
    179             }
    180         }
    181         if (!combine) {
    182             *pval = OPENSSL_malloc(it->size);
    183             if (!*pval)
    184                 goto memerr;
    185             OPENSSL_memset(*pval, 0, it->size);
    186             asn1_refcount_set_one(pval, it);
    187             asn1_enc_init(pval, it);
    188         }
    189         for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
    190             pseqval = asn1_get_field_ptr(pval, tt);
    191             if (!ASN1_template_new(pseqval, tt))
    192                 goto memerr2;
    193         }
    194         if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
    195             goto auxerr2;
    196         break;
    197     }
    198 #ifdef CRYPTO_MDEBUG
    199     if (it->sname)
    200         CRYPTO_pop_info();
    201 #endif
    202     return 1;
    203 
    204  memerr2:
    205     asn1_item_combine_free(pval, it, combine);
    206  memerr:
    207     OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
    208 #ifdef CRYPTO_MDEBUG
    209     if (it->sname)
    210         CRYPTO_pop_info();
    211 #endif
    212     return 0;
    213 
    214  auxerr2:
    215     asn1_item_combine_free(pval, it, combine);
    216  auxerr:
    217     OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR);
    218 #ifdef CRYPTO_MDEBUG
    219     if (it->sname)
    220         CRYPTO_pop_info();
    221 #endif
    222     return 0;
    223 
    224 }
    225 
    226 static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
    227 {
    228     const ASN1_EXTERN_FUNCS *ef;
    229 
    230     switch (it->itype) {
    231 
    232     case ASN1_ITYPE_EXTERN:
    233         ef = it->funcs;
    234         if (ef && ef->asn1_ex_clear)
    235             ef->asn1_ex_clear(pval, it);
    236         else
    237             *pval = NULL;
    238         break;
    239 
    240     case ASN1_ITYPE_PRIMITIVE:
    241         if (it->templates)
    242             asn1_template_clear(pval, it->templates);
    243         else
    244             asn1_primitive_clear(pval, it);
    245         break;
    246 
    247     case ASN1_ITYPE_MSTRING:
    248         asn1_primitive_clear(pval, it);
    249         break;
    250 
    251     case ASN1_ITYPE_COMPAT:
    252     case ASN1_ITYPE_CHOICE:
    253     case ASN1_ITYPE_SEQUENCE:
    254     case ASN1_ITYPE_NDEF_SEQUENCE:
    255         *pval = NULL;
    256         break;
    257     }
    258 }
    259 
    260 int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
    261 {
    262     const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item);
    263     int ret;
    264     if (tt->flags & ASN1_TFLG_OPTIONAL) {
    265         asn1_template_clear(pval, tt);
    266         return 1;
    267     }
    268     /* If ANY DEFINED BY nothing to do */
    269 
    270     if (tt->flags & ASN1_TFLG_ADB_MASK) {
    271         *pval = NULL;
    272         return 1;
    273     }
    274 #ifdef CRYPTO_MDEBUG
    275     if (tt->field_name)
    276         CRYPTO_push_info(tt->field_name);
    277 #endif
    278     /* If SET OF or SEQUENCE OF, its a STACK */
    279     if (tt->flags & ASN1_TFLG_SK_MASK) {
    280         STACK_OF(ASN1_VALUE) *skval;
    281         skval = sk_ASN1_VALUE_new_null();
    282         if (!skval) {
    283             OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
    284             ret = 0;
    285             goto done;
    286         }
    287         *pval = (ASN1_VALUE *)skval;
    288         ret = 1;
    289         goto done;
    290     }
    291     /* Otherwise pass it back to the item routine */
    292     ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE);
    293  done:
    294 #ifdef CRYPTO_MDEBUG
    295     if (it->sname)
    296         CRYPTO_pop_info();
    297 #endif
    298     return ret;
    299 }
    300 
    301 static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
    302 {
    303     /* If ADB or STACK just NULL the field */
    304     if (tt->flags & (ASN1_TFLG_ADB_MASK | ASN1_TFLG_SK_MASK))
    305         *pval = NULL;
    306     else
    307         asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item));
    308 }
    309 
    310 /*
    311  * NB: could probably combine most of the real XXX_new() behaviour and junk
    312  * all the old functions.
    313  */
    314 
    315 int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
    316 {
    317     ASN1_TYPE *typ;
    318     ASN1_STRING *str;
    319     int utype;
    320 
    321     if (!it)
    322         return 0;
    323 
    324     if (it->funcs) {
    325         const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
    326         if (pf->prim_new)
    327             return pf->prim_new(pval, it);
    328     }
    329 
    330     if (it->itype == ASN1_ITYPE_MSTRING)
    331         utype = -1;
    332     else
    333         utype = it->utype;
    334     switch (utype) {
    335     case V_ASN1_OBJECT:
    336         *pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef);
    337         return 1;
    338 
    339     case V_ASN1_BOOLEAN:
    340         *(ASN1_BOOLEAN *)pval = it->size;
    341         return 1;
    342 
    343     case V_ASN1_NULL:
    344         *pval = (ASN1_VALUE *)1;
    345         return 1;
    346 
    347     case V_ASN1_ANY:
    348         typ = OPENSSL_malloc(sizeof(ASN1_TYPE));
    349         if (!typ)
    350             return 0;
    351         typ->value.ptr = NULL;
    352         typ->type = -1;
    353         *pval = (ASN1_VALUE *)typ;
    354         break;
    355 
    356     default:
    357         str = ASN1_STRING_type_new(utype);
    358         if (it->itype == ASN1_ITYPE_MSTRING && str)
    359             str->flags |= ASN1_STRING_FLAG_MSTRING;
    360         *pval = (ASN1_VALUE *)str;
    361         break;
    362     }
    363     if (*pval)
    364         return 1;
    365     return 0;
    366 }
    367 
    368 static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
    369 {
    370     int utype;
    371     if (it && it->funcs) {
    372         const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
    373         if (pf->prim_clear)
    374             pf->prim_clear(pval, it);
    375         else
    376             *pval = NULL;
    377         return;
    378     }
    379     if (!it || (it->itype == ASN1_ITYPE_MSTRING))
    380         utype = -1;
    381     else
    382         utype = it->utype;
    383     if (utype == V_ASN1_BOOLEAN)
    384         *(ASN1_BOOLEAN *)pval = it->size;
    385     else
    386         *pval = NULL;
    387 }
    388