LCOV - code coverage report
Current view: top level - third_party/openssl/crypto/asn1 - tasn_dec.c (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 233 488 47.7 %
Date: 2015-10-10 Functions: 8 12 66.7 %

          Line data    Source code
       1             : /* tasn_dec.c */
       2             : /*
       3             :  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
       4             :  * 2000.
       5             :  */
       6             : /* ====================================================================
       7             :  * Copyright (c) 2000-2005 The OpenSSL Project.  All rights reserved.
       8             :  *
       9             :  * Redistribution and use in source and binary forms, with or without
      10             :  * modification, are permitted provided that the following conditions
      11             :  * are met:
      12             :  *
      13             :  * 1. Redistributions of source code must retain the above copyright
      14             :  *    notice, this list of conditions and the following disclaimer.
      15             :  *
      16             :  * 2. Redistributions in binary form must reproduce the above copyright
      17             :  *    notice, this list of conditions and the following disclaimer in
      18             :  *    the documentation and/or other materials provided with the
      19             :  *    distribution.
      20             :  *
      21             :  * 3. All advertising materials mentioning features or use of this
      22             :  *    software must display the following acknowledgment:
      23             :  *    "This product includes software developed by the OpenSSL Project
      24             :  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
      25             :  *
      26             :  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
      27             :  *    endorse or promote products derived from this software without
      28             :  *    prior written permission. For written permission, please contact
      29             :  *    licensing@OpenSSL.org.
      30             :  *
      31             :  * 5. Products derived from this software may not be called "OpenSSL"
      32             :  *    nor may "OpenSSL" appear in their names without prior written
      33             :  *    permission of the OpenSSL Project.
      34             :  *
      35             :  * 6. Redistributions of any form whatsoever must retain the following
      36             :  *    acknowledgment:
      37             :  *    "This product includes software developed by the OpenSSL Project
      38             :  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
      39             :  *
      40             :  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
      41             :  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      42             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      43             :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
      44             :  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      45             :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      46             :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
      47             :  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      48             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
      49             :  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      50             :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
      51             :  * OF THE POSSIBILITY OF SUCH DAMAGE.
      52             :  * ====================================================================
      53             :  *
      54             :  * This product includes cryptographic software written by Eric Young
      55             :  * (eay@cryptsoft.com).  This product includes software written by Tim
      56             :  * Hudson (tjh@cryptsoft.com).
      57             :  *
      58             :  */
      59             : 
      60             : #include <stddef.h>
      61             : #include <string.h>
      62             : #include <openssl/asn1.h>
      63             : #include <openssl/asn1t.h>
      64             : #include <openssl/objects.h>
      65             : #include <openssl/buffer.h>
      66             : #include <openssl/err.h>
      67             : 
      68             : static int asn1_check_eoc(const unsigned char **in, long len);
      69             : static int asn1_find_end(const unsigned char **in, long len, char inf);
      70             : 
      71             : static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
      72             :                         char inf, int tag, int aclass, int depth);
      73             : 
      74             : static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen);
      75             : 
      76             : static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
      77             :                            char *inf, char *cst,
      78             :                            const unsigned char **in, long len,
      79             :                            int exptag, int expclass, char opt, ASN1_TLC *ctx);
      80             : 
      81             : static int asn1_template_ex_d2i(ASN1_VALUE **pval,
      82             :                                 const unsigned char **in, long len,
      83             :                                 const ASN1_TEMPLATE *tt, char opt,
      84             :                                 ASN1_TLC *ctx);
      85             : static int asn1_template_noexp_d2i(ASN1_VALUE **val,
      86             :                                    const unsigned char **in, long len,
      87             :                                    const ASN1_TEMPLATE *tt, char opt,
      88             :                                    ASN1_TLC *ctx);
      89             : static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
      90             :                                  const unsigned char **in, long len,
      91             :                                  const ASN1_ITEM *it,
      92             :                                  int tag, int aclass, char opt,
      93             :                                  ASN1_TLC *ctx);
      94             : 
      95             : /* Table to convert tags to bit values, used for MSTRING type */
      96             : static const unsigned long tag2bit[32] = {
      97             :     /* tags  0 -  3 */
      98             :     0, 0, 0, B_ASN1_BIT_STRING,
      99             :     /* tags  4- 7 */
     100             :     B_ASN1_OCTET_STRING, 0, 0, B_ASN1_UNKNOWN,
     101             :     /* tags  8-11 */
     102             :     B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN,
     103             :     /* tags 12-15 */
     104             :     B_ASN1_UTF8STRING, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN,
     105             :     /* tags 16-19 */
     106             :     B_ASN1_SEQUENCE, 0, B_ASN1_NUMERICSTRING, B_ASN1_PRINTABLESTRING,
     107             :     /* tags 20-22 */
     108             :     B_ASN1_T61STRING, B_ASN1_VIDEOTEXSTRING, B_ASN1_IA5STRING,
     109             :     /* tags 23-24 */
     110             :     B_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME,
     111             :     /* tags 25-27 */
     112             :     B_ASN1_GRAPHICSTRING, B_ASN1_ISO64STRING, B_ASN1_GENERALSTRING,
     113             :     /* tags 28-31 */
     114             :     B_ASN1_UNIVERSALSTRING, B_ASN1_UNKNOWN, B_ASN1_BMPSTRING, B_ASN1_UNKNOWN,
     115             : };
     116             : 
     117       14692 : unsigned long ASN1_tag2bit(int tag)
     118             : {
     119       32746 :     if ((tag < 0) || (tag > 30))
     120             :         return 0;
     121       32746 :     return tag2bit[tag];
     122             : }
     123             : 
     124             : /* Macro to initialize and invalidate the cache */
     125             : 
     126             : #define asn1_tlc_clear(c)       if (c) (c)->valid = 0
     127             : /* Version to avoid compiler warning about 'c' always non-NULL */
     128             : #define asn1_tlc_clear_nc(c)    (c)->valid = 0
     129             : 
     130             : /*
     131             :  * Decode an ASN1 item, this currently behaves just like a standard 'd2i'
     132             :  * function. 'in' points to a buffer to read the data from, in future we
     133             :  * will have more advanced versions that can input data a piece at a time and
     134             :  * this will simply be a special case.
     135             :  */
     136             : 
     137       10254 : ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval,
     138             :                           const unsigned char **in, long len,
     139             :                           const ASN1_ITEM *it)
     140             : {
     141             :     ASN1_TLC c;
     142       10254 :     ASN1_VALUE *ptmpval = NULL;
     143       10254 :     if (!pval)
     144             :         pval = &ptmpval;
     145       10254 :     asn1_tlc_clear_nc(&c);
     146       10254 :     if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0)
     147       10254 :         return *pval;
     148             :     return NULL;
     149             : }
     150             : 
     151           0 : int ASN1_template_d2i(ASN1_VALUE **pval,
     152             :                       const unsigned char **in, long len,
     153             :                       const ASN1_TEMPLATE *tt)
     154             : {
     155             :     ASN1_TLC c;
     156           0 :     asn1_tlc_clear_nc(&c);
     157           0 :     return asn1_template_ex_d2i(pval, in, len, tt, 0, &c);
     158             : }
     159             : 
     160             : /*
     161             :  * Decode an item, taking care of IMPLICIT tagging, if any. If 'opt' set and
     162             :  * tag mismatch return -1 to handle OPTIONAL
     163             :  */
     164             : 
     165      162581 : int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
     166             :                      const ASN1_ITEM *it,
     167             :                      int tag, int aclass, char opt, ASN1_TLC *ctx)
     168             : {
     169             :     const ASN1_TEMPLATE *tt, *errtt = NULL;
     170             :     const ASN1_COMPAT_FUNCS *cf;
     171             :     const ASN1_EXTERN_FUNCS *ef;
     172      162581 :     const ASN1_AUX *aux = it->funcs;
     173             :     ASN1_aux_cb *asn1_cb;
     174      162581 :     const unsigned char *p = NULL, *q;
     175             :     unsigned char *wp = NULL;   /* BIG FAT WARNING! BREAKS CONST WHERE USED */
     176             :     unsigned char imphack = 0, oclass;
     177             :     char seq_eoc, seq_nolen, cst, isopt;
     178             :     long tmplen;
     179             :     int i;
     180             :     int otag;
     181             :     int ret = 0;
     182             :     ASN1_VALUE **pchptr, *ptmpval;
     183      162581 :     if (!pval)
     184             :         return 0;
     185      162581 :     if (aux && aux->asn1_cb)
     186       11291 :         asn1_cb = aux->asn1_cb;
     187             :     else
     188             :         asn1_cb = 0;
     189             : 
     190      162581 :     switch (it->itype) {
     191             :     case ASN1_ITYPE_PRIMITIVE:
     192       93568 :         if (it->templates) {
     193             :             /*
     194             :              * tagging or OPTIONAL is currently illegal on an item template
     195             :              * because the flags can't get passed down. In practice this
     196             :              * isn't a problem: we include the relevant flags from the item
     197             :              * template in the template itself.
     198             :              */
     199       19564 :             if ((tag != -1) || opt) {
     200           0 :                 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
     201             :                         ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE);
     202           0 :                 goto err;
     203             :             }
     204       19564 :             return asn1_template_ex_d2i(pval, in, len,
     205             :                                         it->templates, opt, ctx);
     206             :         }
     207       74004 :         return asn1_d2i_ex_primitive(pval, in, len, it,
     208             :                                      tag, aclass, opt, ctx);
     209             :         break;
     210             : 
     211             :     case ASN1_ITYPE_MSTRING:
     212       18054 :         p = *in;
     213             :         /* Just read in tag and class */
     214       18054 :         ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL,
     215             :                               &p, len, -1, 0, 1, ctx);
     216       18054 :         if (!ret) {
     217           0 :             ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
     218           0 :             goto err;
     219             :         }
     220             : 
     221             :         /* Must be UNIVERSAL class */
     222       18054 :         if (oclass != V_ASN1_UNIVERSAL) {
     223             :             /* If OPTIONAL, assume this is OK */
     224           0 :             if (opt)
     225             :                 return -1;
     226           0 :             ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MSTRING_NOT_UNIVERSAL);
     227           0 :             goto err;
     228             :         }
     229             :         /* Check tag matches bit map */
     230       36108 :         if (!(ASN1_tag2bit(otag) & it->utype)) {
     231             :             /* If OPTIONAL, assume this is OK */
     232           0 :             if (opt)
     233             :                 return -1;
     234           0 :             ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MSTRING_WRONG_TAG);
     235           0 :             goto err;
     236             :         }
     237       18054 :         return asn1_d2i_ex_primitive(pval, in, len, it, otag, 0, 0, ctx);
     238             : 
     239             :     case ASN1_ITYPE_EXTERN:
     240             :         /* Use new style d2i */
     241             :         ef = it->funcs;
     242        3362 :         return ef->asn1_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx);
     243             : 
     244             :     case ASN1_ITYPE_COMPAT:
     245             :         /* we must resort to old style evil hackery */
     246             :         cf = it->funcs;
     247             : 
     248             :         /* If OPTIONAL see if it is there */
     249           0 :         if (opt) {
     250             :             int exptag;
     251           0 :             p = *in;
     252           0 :             if (tag == -1)
     253           0 :                 exptag = it->utype;
     254             :             else
     255             :                 exptag = tag;
     256             :             /*
     257             :              * Don't care about anything other than presence of expected tag
     258             :              */
     259             : 
     260           0 :             ret = asn1_check_tlen(NULL, NULL, NULL, NULL, NULL,
     261             :                                   &p, len, exptag, aclass, 1, ctx);
     262           0 :             if (!ret) {
     263           0 :                 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
     264           0 :                 goto err;
     265             :             }
     266           0 :             if (ret == -1)
     267             :                 return -1;
     268             :         }
     269             : 
     270             :         /*
     271             :          * This is the old style evil hack IMPLICIT handling: since the
     272             :          * underlying code is expecting a tag and class other than the one
     273             :          * present we change the buffer temporarily then change it back
     274             :          * afterwards. This doesn't and never did work for tags > 30. Yes
     275             :          * this is *horrible* but it is only needed for old style d2i which
     276             :          * will hopefully not be around for much longer. FIXME: should copy
     277             :          * the buffer then modify it so the input buffer can be const: we
     278             :          * should *always* copy because the old style d2i might modify the
     279             :          * buffer.
     280             :          */
     281             : 
     282           0 :         if (tag != -1) {
     283           0 :             wp = *(unsigned char **)in;
     284           0 :             imphack = *wp;
     285           0 :             if (p == NULL) {
     286           0 :                 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
     287           0 :                 goto err;
     288             :             }
     289           0 :             *wp = (unsigned char)((*p & V_ASN1_CONSTRUCTED)
     290           0 :                                   | it->utype);
     291             :         }
     292             : 
     293           0 :         ptmpval = cf->asn1_d2i(pval, in, len);
     294             : 
     295           0 :         if (tag != -1)
     296           0 :             *wp = imphack;
     297             : 
     298           0 :         if (ptmpval)
     299             :             return 1;
     300             : 
     301           0 :         ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
     302           0 :         goto err;
     303             : 
     304             :     case ASN1_ITYPE_CHOICE:
     305        6040 :         if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
     306             :             goto auxerr;
     307        6040 :         if (*pval) {
     308             :             /* Free up and zero CHOICE value if initialised */
     309           0 :             i = asn1_get_choice_selector(pval, it);
     310           0 :             if ((i >= 0) && (i < it->tcount)) {
     311           0 :                 tt = it->templates + i;
     312           0 :                 pchptr = asn1_get_field_ptr(pval, tt);
     313           0 :                 ASN1_template_free(pchptr, tt);
     314           0 :                 asn1_set_choice_selector(pval, -1, it);
     315             :             }
     316        6040 :         } else if (!ASN1_item_ex_new(pval, it)) {
     317           0 :             ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
     318           0 :             goto err;
     319             :         }
     320             :         /* CHOICE type, try each possibility in turn */
     321        6040 :         p = *in;
     322       51340 :         for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
     323       25670 :             pchptr = asn1_get_field_ptr(pval, tt);
     324             :             /*
     325             :              * We mark field as OPTIONAL so its absence can be recognised.
     326             :              */
     327       25670 :             ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx);
     328             :             /* If field not present, try the next one */
     329       25670 :             if (ret == -1)
     330       19630 :                 continue;
     331             :             /* If positive return, read OK, break loop */
     332        6040 :             if (ret > 0)
     333             :                 break;
     334             :             /* Otherwise must be an ASN1 parsing error */
     335             :             errtt = tt;
     336           0 :             ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
     337           0 :             goto err;
     338             :         }
     339             : 
     340             :         /* Did we fall off the end without reading anything? */
     341        6040 :         if (i == it->tcount) {
     342             :             /* If OPTIONAL, this is OK */
     343           0 :             if (opt) {
     344             :                 /* Free and zero it */
     345           0 :                 ASN1_item_ex_free(pval, it);
     346           0 :                 return -1;
     347             :             }
     348           0 :             ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_NO_MATCHING_CHOICE_TYPE);
     349           0 :             goto err;
     350             :         }
     351             : 
     352        6040 :         asn1_set_choice_selector(pval, i, it);
     353        6040 :         *in = p;
     354        6040 :         if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
     355             :             goto auxerr;
     356             :         return 1;
     357             : 
     358             :     case ASN1_ITYPE_NDEF_SEQUENCE:
     359             :     case ASN1_ITYPE_SEQUENCE:
     360       41557 :         p = *in;
     361       41557 :         tmplen = len;
     362             : 
     363             :         /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
     364       41557 :         if (tag == -1) {
     365             :             tag = V_ASN1_SEQUENCE;
     366             :             aclass = V_ASN1_UNIVERSAL;
     367             :         }
     368             :         /* Get SEQUENCE length and update len, p */
     369       41557 :         ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst,
     370             :                               &p, len, tag, aclass, opt, ctx);
     371       41557 :         if (!ret) {
     372           0 :             ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
     373           0 :             goto err;
     374       41557 :         } else if (ret == -1)
     375             :             return -1;
     376       34007 :         if (aux && (aux->flags & ASN1_AFLG_BROKEN)) {
     377           0 :             len = tmplen - (p - *in);
     378           0 :             seq_nolen = 1;
     379             :         }
     380             :         /* If indefinite we don't do a length check */
     381             :         else
     382       34007 :             seq_nolen = seq_eoc;
     383       34007 :         if (!cst) {
     384           0 :             ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_SEQUENCE_NOT_CONSTRUCTED);
     385           0 :             goto err;
     386             :         }
     387             : 
     388       34007 :         if (!*pval && !ASN1_item_ex_new(pval, it)) {
     389           0 :             ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
     390           0 :             goto err;
     391             :         }
     392             : 
     393       34007 :         if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
     394             :             goto auxerr;
     395             : 
     396             :         /* Free up and zero any ADB found */
     397      124062 :         for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
     398       90055 :             if (tt->flags & ASN1_TFLG_ADB_MASK) {
     399             :                 const ASN1_TEMPLATE *seqtt;
     400             :                 ASN1_VALUE **pseqval;
     401           0 :                 seqtt = asn1_do_adb(pval, tt, 1);
     402           0 :                 pseqval = asn1_get_field_ptr(pval, seqtt);
     403           0 :                 ASN1_template_free(pseqval, seqtt);
     404             :             }
     405             :         }
     406             : 
     407             :         /* Get each field entry */
     408      121331 :         for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
     409             :             const ASN1_TEMPLATE *seqtt;
     410             :             ASN1_VALUE **pseqval;
     411       88478 :             seqtt = asn1_do_adb(pval, tt, 1);
     412       88478 :             if (!seqtt)
     413             :                 goto err;
     414       88478 :             pseqval = asn1_get_field_ptr(pval, seqtt);
     415             :             /* Have we ran out of data? */
     416       88478 :             if (!len)
     417             :                 break;
     418       87324 :             q = p;
     419       87324 :             if (asn1_check_eoc(&p, len)) {
     420           0 :                 if (!seq_eoc) {
     421           0 :                     ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_UNEXPECTED_EOC);
     422           0 :                     goto err;
     423             :                 }
     424           0 :                 len -= p - q;
     425           0 :                 seq_eoc = 0;
     426             :                 q = p;
     427           0 :                 break;
     428             :             }
     429             :             /*
     430             :              * This determines the OPTIONAL flag value. The field cannot be
     431             :              * omitted if it is the last of a SEQUENCE and there is still
     432             :              * data to be read. This isn't strictly necessary but it
     433             :              * increases efficiency in some cases.
     434             :              */
     435       87324 :             if (i == (it->tcount - 1))
     436             :                 isopt = 0;
     437             :             else
     438       54471 :                 isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL);
     439             :             /*
     440             :              * attempt to read in field, allowing each to be OPTIONAL
     441             :              */
     442             : 
     443       87324 :             ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx);
     444       87324 :             if (!ret) {
     445             :                 errtt = seqtt;
     446             :                 goto err;
     447       87324 :             } else if (ret == -1) {
     448             :                 /*
     449             :                  * OPTIONAL component absent. Free and zero the field.
     450             :                  */
     451        6665 :                 ASN1_template_free(pseqval, seqtt);
     452        6665 :                 continue;
     453             :             }
     454             :             /* Update length */
     455       80659 :             len -= p - q;
     456             :         }
     457             : 
     458             :         /* Check for EOC if expecting one */
     459       34007 :         if (seq_eoc && !asn1_check_eoc(&p, len)) {
     460           0 :             ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MISSING_EOC);
     461           0 :             goto err;
     462             :         }
     463             :         /* Check all data read */
     464       34007 :         if (!seq_nolen && len) {
     465           0 :             ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_SEQUENCE_LENGTH_MISMATCH);
     466           0 :             goto err;
     467             :         }
     468             : 
     469             :         /*
     470             :          * If we get here we've got no more data in the SEQUENCE, however we
     471             :          * may not have read all fields so check all remaining are OPTIONAL
     472             :          * and clear any that are.
     473             :          */
     474       39469 :         for (; i < it->tcount; tt++, i++) {
     475             :             const ASN1_TEMPLATE *seqtt;
     476        2731 :             seqtt = asn1_do_adb(pval, tt, 1);
     477        2731 :             if (!seqtt)
     478             :                 goto err;
     479        2731 :             if (seqtt->flags & ASN1_TFLG_OPTIONAL) {
     480             :                 ASN1_VALUE **pseqval;
     481        2731 :                 pseqval = asn1_get_field_ptr(pval, seqtt);
     482        2731 :                 ASN1_template_free(pseqval, seqtt);
     483             :             } else {
     484             :                 errtt = seqtt;
     485           0 :                 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_FIELD_MISSING);
     486           0 :                 goto err;
     487             :             }
     488             :         }
     489             :         /* Save encoding */
     490       34007 :         if (!asn1_enc_save(pval, *in, p - *in, it))
     491             :             goto auxerr;
     492       34007 :         *in = p;
     493       34007 :         if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
     494             :             goto auxerr;
     495             :         return 1;
     496             : 
     497             :     default:
     498             :         return 0;
     499             :     }
     500             :  auxerr:
     501           0 :     ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_AUX_ERROR);
     502             :  err:
     503           0 :     ASN1_item_ex_free(pval, it);
     504           0 :     if (errtt)
     505           0 :         ERR_add_error_data(4, "Field=", errtt->field_name,
     506             :                            ", Type=", it->sname);
     507             :     else
     508           0 :         ERR_add_error_data(2, "Type=", it->sname);
     509             :     return 0;
     510             : }
     511             : 
     512             : /*
     513             :  * Templates are handled with two separate functions. One handles any
     514             :  * EXPLICIT tag and the other handles the rest.
     515             :  */
     516             : 
     517      132558 : static int asn1_template_ex_d2i(ASN1_VALUE **val,
     518             :                                 const unsigned char **in, long inlen,
     519             :                                 const ASN1_TEMPLATE *tt, char opt,
     520             :                                 ASN1_TLC *ctx)
     521             : {
     522             :     int flags, aclass;
     523             :     int ret;
     524             :     long len;
     525             :     const unsigned char *p, *q;
     526             :     char exp_eoc;
     527      132558 :     if (!val)
     528             :         return 0;
     529      132558 :     flags = tt->flags;
     530      132558 :     aclass = flags & ASN1_TFLG_TAG_CLASS;
     531             : 
     532      132558 :     p = *in;
     533             : 
     534             :     /* Check if EXPLICIT tag expected */
     535      132558 :     if (flags & ASN1_TFLG_EXPTAG) {
     536             :         char cst;
     537             :         /*
     538             :          * Need to work out amount of data available to the inner content and
     539             :          * where it starts: so read in EXPLICIT header to get the info.
     540             :          */
     541        8874 :         ret = asn1_check_tlen(&len, NULL, NULL, &exp_eoc, &cst,
     542        4437 :                               &p, inlen, tt->tag, aclass, opt, ctx);
     543        4437 :         q = p;
     544        4437 :         if (!ret) {
     545           0 :             ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
     546           0 :             return 0;
     547        4437 :         } else if (ret == -1)
     548             :             return -1;
     549        2492 :         if (!cst) {
     550           0 :             ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
     551             :                     ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED);
     552           0 :             return 0;
     553             :         }
     554             :         /* We've found the field so it can't be OPTIONAL now */
     555        2492 :         ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx);
     556        2492 :         if (!ret) {
     557           0 :             ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
     558           0 :             return 0;
     559             :         }
     560             :         /* We read the field in OK so update length */
     561        2492 :         len -= p - q;
     562        2492 :         if (exp_eoc) {
     563             :             /* If NDEF we must have an EOC here */
     564           0 :             if (!asn1_check_eoc(&p, len)) {
     565           0 :                 ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ASN1_R_MISSING_EOC);
     566           0 :                 goto err;
     567             :             }
     568             :         } else {
     569             :             /*
     570             :              * Otherwise we must hit the EXPLICIT tag end or its an error
     571             :              */
     572        2492 :             if (len) {
     573           0 :                 ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
     574             :                         ASN1_R_EXPLICIT_LENGTH_MISMATCH);
     575           0 :                 goto err;
     576             :             }
     577             :         }
     578             :     } else
     579      128121 :         return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx);
     580             : 
     581        2492 :     *in = p;
     582        2492 :     return 1;
     583             : 
     584             :  err:
     585           0 :     ASN1_template_free(val, tt);
     586           0 :     return 0;
     587             : }
     588             : 
     589      130613 : static int asn1_template_noexp_d2i(ASN1_VALUE **val,
     590             :                                    const unsigned char **in, long len,
     591             :                                    const ASN1_TEMPLATE *tt, char opt,
     592             :                                    ASN1_TLC *ctx)
     593             : {
     594             :     int flags, aclass;
     595             :     int ret;
     596             :     const unsigned char *p, *q;
     597      130613 :     if (!val)
     598             :         return 0;
     599      130613 :     flags = tt->flags;
     600      130613 :     aclass = flags & ASN1_TFLG_TAG_CLASS;
     601             : 
     602      130613 :     p = *in;
     603             :     q = p;
     604             : 
     605      130613 :     if (flags & ASN1_TFLG_SK_MASK) {
     606             :         /* SET OF, SEQUENCE OF */
     607             :         int sktag, skaclass;
     608             :         char sk_eoc;
     609             :         /* First work out expected inner tag value */
     610       20810 :         if (flags & ASN1_TFLG_IMPTAG) {
     611           0 :             sktag = tt->tag;
     612             :             skaclass = aclass;
     613             :         } else {
     614             :             skaclass = V_ASN1_UNIVERSAL;
     615       20810 :             if (flags & ASN1_TFLG_SET_OF)
     616             :                 sktag = V_ASN1_SET;
     617             :             else
     618             :                 sktag = V_ASN1_SEQUENCE;
     619             :         }
     620             :         /* Get the tag */
     621       20810 :         ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL,
     622             :                               &p, len, sktag, skaclass, opt, ctx);
     623       20810 :         if (!ret) {
     624           0 :             ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR);
     625           0 :             return 0;
     626       20810 :         } else if (ret == -1)
     627             :             return -1;
     628       20810 :         if (!*val)
     629       20810 :             *val = (ASN1_VALUE *)sk_new_null();
     630             :         else {
     631             :             /*
     632             :              * We've got a valid STACK: free up any items present
     633             :              */
     634             :             STACK_OF(ASN1_VALUE) *sktmp = (STACK_OF(ASN1_VALUE) *)*val;
     635             :             ASN1_VALUE *vtmp;
     636           0 :             while (sk_ASN1_VALUE_num(sktmp) > 0) {
     637           0 :                 vtmp = sk_ASN1_VALUE_pop(sktmp);
     638           0 :                 ASN1_item_ex_free(&vtmp, ASN1_ITEM_ptr(tt->item));
     639             :             }
     640             :         }
     641             : 
     642       20810 :         if (!*val) {
     643           0 :             ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_MALLOC_FAILURE);
     644           0 :             goto err;
     645             :         }
     646             : 
     647             :         /* Read as many items as we can */
     648       59972 :         while (len > 0) {
     649             :             ASN1_VALUE *skfield;
     650       39162 :             q = p;
     651             :             /* See if EOC found */
     652       39162 :             if (asn1_check_eoc(&p, len)) {
     653           0 :                 if (!sk_eoc) {
     654           0 :                     ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
     655             :                             ASN1_R_UNEXPECTED_EOC);
     656           0 :                     goto err;
     657             :                 }
     658           0 :                 len -= p - q;
     659           0 :                 sk_eoc = 0;
     660           0 :                 break;
     661             :             }
     662       39162 :             skfield = NULL;
     663       39162 :             if (!ASN1_item_ex_d2i(&skfield, &p, len,
     664       39162 :                                   ASN1_ITEM_ptr(tt->item), -1, 0, 0, ctx)) {
     665           0 :                 ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
     666             :                         ERR_R_NESTED_ASN1_ERROR);
     667           0 :                 goto err;
     668             :             }
     669       39162 :             len -= p - q;
     670       39162 :             if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val, skfield)) {
     671           0 :                 ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_MALLOC_FAILURE);
     672           0 :                 goto err;
     673             :             }
     674             :         }
     675       20810 :         if (sk_eoc) {
     676           0 :             ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ASN1_R_MISSING_EOC);
     677           0 :             goto err;
     678             :         }
     679      109803 :     } else if (flags & ASN1_TFLG_IMPTAG) {
     680             :         /* IMPLICIT tagging */
     681       79956 :         ret = ASN1_item_ex_d2i(val, &p, len,
     682       53304 :                                ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt,
     683             :                                ctx);
     684       26652 :         if (!ret) {
     685           0 :             ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR);
     686           0 :             goto err;
     687       26652 :         } else if (ret == -1)
     688             :             return -1;
     689             :     } else {
     690             :         /* Nothing special */
     691       83151 :         ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item),
     692             :                                -1, 0, opt, ctx);
     693       83151 :         if (!ret) {
     694           0 :             ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR);
     695           0 :             goto err;
     696       83151 :         } else if (ret == -1)
     697             :             return -1;
     698             :     }
     699             : 
     700      106263 :     *in = p;
     701      106263 :     return 1;
     702             : 
     703             :  err:
     704           0 :     ASN1_template_free(val, tt);
     705           0 :     return 0;
     706             : }
     707             : 
     708       92058 : static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
     709             :                                  const unsigned char **in, long inlen,
     710             :                                  const ASN1_ITEM *it,
     711             :                                  int tag, int aclass, char opt, ASN1_TLC *ctx)
     712             : {
     713             :     int ret = 0, utype;
     714             :     long plen;
     715       92058 :     char cst, inf, free_cont = 0;
     716             :     const unsigned char *p;
     717             :     BUF_MEM buf;
     718             :     const unsigned char *cont = NULL;
     719             :     long len;
     720       92058 :     if (!pval) {
     721           0 :         ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_NULL);
     722           0 :         return 0;               /* Should never happen */
     723             :     }
     724             : 
     725       92058 :     if (it->itype == ASN1_ITYPE_MSTRING) {
     726       18054 :         utype = tag;
     727             :         tag = -1;
     728             :     } else
     729       74004 :         utype = it->utype;
     730             : 
     731       92058 :     if (utype == V_ASN1_ANY) {
     732             :         /* If type is ANY need to figure out type from tag */
     733             :         unsigned char oclass;
     734        5812 :         if (tag >= 0) {
     735           0 :             ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_TAGGED_ANY);
     736           0 :             return 0;
     737             :         }
     738        5812 :         if (opt) {
     739           0 :             ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
     740             :                     ASN1_R_ILLEGAL_OPTIONAL_ANY);
     741           0 :             return 0;
     742             :         }
     743        5812 :         p = *in;
     744        5812 :         ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, NULL,
     745             :                               &p, inlen, -1, 0, 0, ctx);
     746        5812 :         if (!ret) {
     747           0 :             ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR);
     748           0 :             return 0;
     749             :         }
     750        5812 :         if (oclass != V_ASN1_UNIVERSAL)
     751           0 :             utype = V_ASN1_OTHER;
     752             :     }
     753       92058 :     if (tag == -1) {
     754       72956 :         tag = utype;
     755             :         aclass = V_ASN1_UNIVERSAL;
     756             :     }
     757       92058 :     p = *in;
     758             :     /* Check header */
     759       92058 :     ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst,
     760             :                           &p, inlen, tag, aclass, opt, ctx);
     761       92058 :     if (!ret) {
     762           0 :         ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR);
     763           0 :         return 0;
     764       92058 :     } else if (ret == -1)
     765             :         return -1;
     766             :     ret = 0;
     767             :     /* SEQUENCE, SET and "OTHER" are left in encoded form */
     768       75258 :     if ((utype == V_ASN1_SEQUENCE)
     769       75258 :         || (utype == V_ASN1_SET) || (utype == V_ASN1_OTHER)) {
     770             :         /*
     771             :          * Clear context cache for type OTHER because the auto clear when we
     772             :          * have a exact match wont work
     773             :          */
     774           0 :         if (utype == V_ASN1_OTHER) {
     775           0 :             asn1_tlc_clear(ctx);
     776             :         }
     777             :         /* SEQUENCE and SET must be constructed */
     778           0 :         else if (!cst) {
     779           0 :             ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
     780             :                     ASN1_R_TYPE_NOT_CONSTRUCTED);
     781           0 :             return 0;
     782             :         }
     783             : 
     784           0 :         cont = *in;
     785             :         /* If indefinite length constructed find the real end */
     786           0 :         if (inf) {
     787           0 :             if (!asn1_find_end(&p, plen, inf))
     788             :                 goto err;
     789           0 :             len = p - cont;
     790             :         } else {
     791           0 :             len = p - cont + plen;
     792           0 :             p += plen;
     793           0 :             buf.data = NULL;
     794             :         }
     795       75258 :     } else if (cst) {
     796           0 :         if (utype == V_ASN1_NULL || utype == V_ASN1_BOOLEAN
     797           0 :             || utype == V_ASN1_OBJECT || utype == V_ASN1_INTEGER
     798           0 :             || utype == V_ASN1_ENUMERATED) {
     799           0 :             ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_TYPE_NOT_PRIMITIVE);
     800           0 :             return 0;
     801             :         }
     802           0 :         buf.length = 0;
     803           0 :         buf.max = 0;
     804           0 :         buf.data = NULL;
     805             :         /*
     806             :          * Should really check the internal tags are correct but some things
     807             :          * may get this wrong. The relevant specs say that constructed string
     808             :          * types should be OCTET STRINGs internally irrespective of the type.
     809             :          * So instead just check for UNIVERSAL class and ignore the tag.
     810             :          */
     811           0 :         if (!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL, 0)) {
     812           0 :             free_cont = 1;
     813           0 :             goto err;
     814             :         }
     815           0 :         len = buf.length;
     816             :         /* Append a final null to string */
     817           0 :         if (!BUF_MEM_grow_clean(&buf, len + 1)) {
     818           0 :             ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE);
     819           0 :             return 0;
     820             :         }
     821           0 :         buf.data[len] = 0;
     822           0 :         cont = (const unsigned char *)buf.data;
     823           0 :         free_cont = 1;
     824             :     } else {
     825       75258 :         cont = p;
     826       75258 :         len = plen;
     827       75258 :         p += plen;
     828             :     }
     829             : 
     830             :     /* We now have content length and type: translate into a structure */
     831       75258 :     if (!asn1_ex_c2i(pval, cont, len, utype, &free_cont, it))
     832             :         goto err;
     833             : 
     834       75258 :     *in = p;
     835             :     ret = 1;
     836             :  err:
     837       75258 :     if (free_cont && buf.data)
     838           0 :         OPENSSL_free(buf.data);
     839       75258 :     return ret;
     840             : }
     841             : 
     842             : /* Translate ASN1 content octets into a structure */
     843             : 
     844       75258 : int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
     845             :                 int utype, char *free_cont, const ASN1_ITEM *it)
     846             : {
     847             :     ASN1_VALUE **opval = NULL;
     848             :     ASN1_STRING *stmp;
     849             :     ASN1_TYPE *typ = NULL;
     850             :     int ret = 0;
     851             :     const ASN1_PRIMITIVE_FUNCS *pf;
     852             :     ASN1_INTEGER **tint;
     853       75258 :     pf = it->funcs;
     854             : 
     855       75258 :     if (pf && pf->prim_c2i)
     856        6328 :         return pf->prim_c2i(pval, cont, len, utype, free_cont, it);
     857             :     /* If ANY type clear type and set pointer to internal value */
     858       68930 :     if (it->utype == V_ASN1_ANY) {
     859        5812 :         if (!*pval) {
     860        5800 :             typ = ASN1_TYPE_new();
     861        5800 :             if (typ == NULL)
     862             :                 goto err;
     863        5800 :             *pval = (ASN1_VALUE *)typ;
     864             :         } else
     865             :             typ = (ASN1_TYPE *)*pval;
     866             : 
     867        5812 :         if (utype != typ->type)
     868        5812 :             ASN1_TYPE_set(typ, utype, NULL);
     869             :         opval = pval;
     870        5812 :         pval = &typ->value.asn1_value;
     871             :     }
     872       68930 :     switch (utype) {
     873             :     case V_ASN1_OBJECT:
     874       24230 :         if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len))
     875             :             goto err;
     876             :         break;
     877             : 
     878             :     case V_ASN1_NULL:
     879        5800 :         if (len) {
     880           0 :             ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_NULL_IS_WRONG_LENGTH);
     881           0 :             goto err;
     882             :         }
     883        5800 :         *pval = (ASN1_VALUE *)1;
     884        5800 :         break;
     885             : 
     886             :     case V_ASN1_BOOLEAN:
     887           0 :         if (len != 1) {
     888           0 :             ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_BOOLEAN_IS_WRONG_LENGTH);
     889           0 :             goto err;
     890             :         } else {
     891             :             ASN1_BOOLEAN *tbool;
     892             :             tbool = (ASN1_BOOLEAN *)pval;
     893           0 :             *tbool = *cont;
     894             :         }
     895           0 :         break;
     896             : 
     897             :     case V_ASN1_BIT_STRING:
     898        4069 :         if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len))
     899             :             goto err;
     900             :         break;
     901             : 
     902             :     case V_ASN1_INTEGER:
     903             :     case V_ASN1_NEG_INTEGER:
     904             :     case V_ASN1_ENUMERATED:
     905             :     case V_ASN1_NEG_ENUMERATED:
     906             :         tint = (ASN1_INTEGER **)pval;
     907        4407 :         if (!c2i_ASN1_INTEGER(tint, &cont, len))
     908             :             goto err;
     909             :         /* Fixup type to match the expected form */
     910        4407 :         (*tint)->type = utype | ((*tint)->type & V_ASN1_NEG);
     911        4407 :         break;
     912             : 
     913             :     case V_ASN1_OCTET_STRING:
     914             :     case V_ASN1_NUMERICSTRING:
     915             :     case V_ASN1_PRINTABLESTRING:
     916             :     case V_ASN1_T61STRING:
     917             :     case V_ASN1_VIDEOTEXSTRING:
     918             :     case V_ASN1_IA5STRING:
     919             :     case V_ASN1_UTCTIME:
     920             :     case V_ASN1_GENERALIZEDTIME:
     921             :     case V_ASN1_GRAPHICSTRING:
     922             :     case V_ASN1_VISIBLESTRING:
     923             :     case V_ASN1_GENERALSTRING:
     924             :     case V_ASN1_UNIVERSALSTRING:
     925             :     case V_ASN1_BMPSTRING:
     926             :     case V_ASN1_UTF8STRING:
     927             :     case V_ASN1_OTHER:
     928             :     case V_ASN1_SET:
     929             :     case V_ASN1_SEQUENCE:
     930             :     default:
     931       30424 :         if (utype == V_ASN1_BMPSTRING && (len & 1)) {
     932           0 :             ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_BMPSTRING_IS_WRONG_LENGTH);
     933           0 :             goto err;
     934             :         }
     935       30424 :         if (utype == V_ASN1_UNIVERSALSTRING && (len & 3)) {
     936           0 :             ASN1err(ASN1_F_ASN1_EX_C2I,
     937             :                     ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH);
     938           0 :             goto err;
     939             :         }
     940             :         /* All based on ASN1_STRING and handled the same */
     941       30424 :         if (!*pval) {
     942        6052 :             stmp = ASN1_STRING_type_new(utype);
     943        6052 :             if (!stmp) {
     944           0 :                 ASN1err(ASN1_F_ASN1_EX_C2I, ERR_R_MALLOC_FAILURE);
     945           0 :                 goto err;
     946             :             }
     947        6052 :             *pval = (ASN1_VALUE *)stmp;
     948             :         } else {
     949             :             stmp = (ASN1_STRING *)*pval;
     950       24372 :             stmp->type = utype;
     951             :         }
     952             :         /* If we've already allocated a buffer use it */
     953       30424 :         if (*free_cont) {
     954           0 :             if (stmp->data)
     955           0 :                 OPENSSL_free(stmp->data);
     956           0 :             stmp->data = (unsigned char *)cont; /* UGLY CAST! RL */
     957           0 :             stmp->length = len;
     958           0 :             *free_cont = 0;
     959             :         } else {
     960       30424 :             if (!ASN1_STRING_set(stmp, cont, len)) {
     961           0 :                 ASN1err(ASN1_F_ASN1_EX_C2I, ERR_R_MALLOC_FAILURE);
     962           0 :                 ASN1_STRING_free(stmp);
     963           0 :                 *pval = NULL;
     964           0 :                 goto err;
     965             :             }
     966             :         }
     967             :         break;
     968             :     }
     969             :     /* If ASN1_ANY and NULL type fix up value */
     970       68930 :     if (typ && (utype == V_ASN1_NULL))
     971        5800 :         typ->value.ptr = NULL;
     972             : 
     973             :     ret = 1;
     974             :  err:
     975       68930 :     if (!ret) {
     976           0 :         ASN1_TYPE_free(typ);
     977           0 :         if (opval)
     978           0 :             *opval = NULL;
     979             :     }
     980       68930 :     return ret;
     981             : }
     982             : 
     983             : /*
     984             :  * This function finds the end of an ASN1 structure when passed its maximum
     985             :  * length, whether it is indefinite length and a pointer to the content. This
     986             :  * is more efficient than calling asn1_collect because it does not recurse on
     987             :  * each indefinite length header.
     988             :  */
     989             : 
     990           0 : static int asn1_find_end(const unsigned char **in, long len, char inf)
     991             : {
     992             :     int expected_eoc;
     993             :     long plen;
     994           0 :     const unsigned char *p = *in, *q;
     995             :     /* If not indefinite length constructed just add length */
     996           0 :     if (inf == 0) {
     997           0 :         *in += len;
     998           0 :         return 1;
     999             :     }
    1000             :     expected_eoc = 1;
    1001             :     /*
    1002             :      * Indefinite length constructed form. Find the end when enough EOCs are
    1003             :      * found. If more indefinite length constructed headers are encountered
    1004             :      * increment the expected eoc count otherwise just skip to the end of the
    1005             :      * data.
    1006             :      */
    1007           0 :     while (len > 0) {
    1008           0 :         if (asn1_check_eoc(&p, len)) {
    1009           0 :             expected_eoc--;
    1010           0 :             if (expected_eoc == 0)
    1011             :                 break;
    1012           0 :             len -= 2;
    1013           0 :             continue;
    1014             :         }
    1015           0 :         q = p;
    1016             :         /* Just read in a header: only care about the length */
    1017           0 :         if (!asn1_check_tlen(&plen, NULL, NULL, &inf, NULL, &p, len,
    1018             :                              -1, 0, 0, NULL)) {
    1019           0 :             ASN1err(ASN1_F_ASN1_FIND_END, ERR_R_NESTED_ASN1_ERROR);
    1020           0 :             return 0;
    1021             :         }
    1022           0 :         if (inf)
    1023           0 :             expected_eoc++;
    1024             :         else
    1025           0 :             p += plen;
    1026           0 :         len -= p - q;
    1027             :     }
    1028           0 :     if (expected_eoc) {
    1029           0 :         ASN1err(ASN1_F_ASN1_FIND_END, ASN1_R_MISSING_EOC);
    1030           0 :         return 0;
    1031             :     }
    1032           0 :     *in = p;
    1033           0 :     return 1;
    1034             : }
    1035             : 
    1036             : /*
    1037             :  * This function collects the asn1 data from a constructred string type into
    1038             :  * a buffer. The values of 'in' and 'len' should refer to the contents of the
    1039             :  * constructed type and 'inf' should be set if it is indefinite length.
    1040             :  */
    1041             : 
    1042             : #ifndef ASN1_MAX_STRING_NEST
    1043             : /*
    1044             :  * This determines how many levels of recursion are permitted in ASN1 string
    1045             :  * types. If it is not limited stack overflows can occur. If set to zero no
    1046             :  * recursion is allowed at all. Although zero should be adequate examples
    1047             :  * exist that require a value of 1. So 5 should be more than enough.
    1048             :  */
    1049             : # define ASN1_MAX_STRING_NEST 5
    1050             : #endif
    1051             : 
    1052           0 : static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
    1053             :                         char inf, int tag, int aclass, int depth)
    1054             : {
    1055             :     const unsigned char *p, *q;
    1056             :     long plen;
    1057             :     char cst, ininf;
    1058           0 :     p = *in;
    1059           0 :     inf &= 1;
    1060             :     /*
    1061             :      * If no buffer and not indefinite length constructed just pass over the
    1062             :      * encoded data
    1063             :      */
    1064           0 :     if (!buf && !inf) {
    1065           0 :         *in += len;
    1066           0 :         return 1;
    1067             :     }
    1068           0 :     while (len > 0) {
    1069           0 :         q = p;
    1070             :         /* Check for EOC */
    1071           0 :         if (asn1_check_eoc(&p, len)) {
    1072             :             /*
    1073             :              * EOC is illegal outside indefinite length constructed form
    1074             :              */
    1075           0 :             if (!inf) {
    1076           0 :                 ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_UNEXPECTED_EOC);
    1077           0 :                 return 0;
    1078             :             }
    1079             :             inf = 0;
    1080             :             break;
    1081             :         }
    1082             : 
    1083           0 :         if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p,
    1084             :                              len, tag, aclass, 0, NULL)) {
    1085           0 :             ASN1err(ASN1_F_ASN1_COLLECT, ERR_R_NESTED_ASN1_ERROR);
    1086           0 :             return 0;
    1087             :         }
    1088             : 
    1089             :         /* If indefinite length constructed update max length */
    1090           0 :         if (cst) {
    1091           0 :             if (depth >= ASN1_MAX_STRING_NEST) {
    1092           0 :                 ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_NESTED_ASN1_STRING);
    1093           0 :                 return 0;
    1094             :             }
    1095           0 :             if (!asn1_collect(buf, &p, plen, ininf, tag, aclass, depth + 1))
    1096             :                 return 0;
    1097           0 :         } else if (plen && !collect_data(buf, &p, plen))
    1098             :             return 0;
    1099           0 :         len -= p - q;
    1100             :     }
    1101           0 :     if (inf) {
    1102           0 :         ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_MISSING_EOC);
    1103           0 :         return 0;
    1104             :     }
    1105           0 :     *in = p;
    1106           0 :     return 1;
    1107             : }
    1108             : 
    1109           0 : static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen)
    1110             : {
    1111             :     int len;
    1112           0 :     if (buf) {
    1113           0 :         len = buf->length;
    1114           0 :         if (!BUF_MEM_grow_clean(buf, len + plen)) {
    1115           0 :             ASN1err(ASN1_F_COLLECT_DATA, ERR_R_MALLOC_FAILURE);
    1116           0 :             return 0;
    1117             :         }
    1118           0 :         memcpy(buf->data + len, *p, plen);
    1119             :     }
    1120           0 :     *p += plen;
    1121           0 :     return 1;
    1122             : }
    1123             : 
    1124             : /* Check for ASN1 EOC and swallow it if found */
    1125             : 
    1126             : static int asn1_check_eoc(const unsigned char **in, long len)
    1127             : {
    1128             :     const unsigned char *p;
    1129      126486 :     if (len < 2)
    1130             :         return 0;
    1131           0 :     p = *in;
    1132      126486 :     if (!p[0] && !p[1]) {
    1133           0 :         *in += 2;
    1134             :         return 1;
    1135             :     }
    1136             :     return 0;
    1137             : }
    1138             : 
    1139             : /*
    1140             :  * Check an ASN1 tag and length: a bit like ASN1_get_object but it sets the
    1141             :  * length for indefinite length constructed form, we don't know the exact
    1142             :  * length but we can set an upper bound to the amount of data available minus
    1143             :  * the header length just read.
    1144             :  */
    1145             : 
    1146      182728 : static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
    1147             :                            char *inf, char *cst,
    1148             :                            const unsigned char **in, long len,
    1149             :                            int exptag, int expclass, char opt, ASN1_TLC *ctx)
    1150             : {
    1151             :     int i;
    1152             :     int ptag, pclass;
    1153             :     long plen;
    1154             :     const unsigned char *p, *q;
    1155      182728 :     p = *in;
    1156             :     q = p;
    1157             : 
    1158      182728 :     if (ctx && ctx->valid) {
    1159       50161 :         i = ctx->ret;
    1160       50161 :         plen = ctx->plen;
    1161       50161 :         pclass = ctx->pclass;
    1162       50161 :         ptag = ctx->ptag;
    1163       50161 :         p += ctx->hdrlen;
    1164             :     } else {
    1165      132567 :         i = ASN1_get_object(&p, &plen, &ptag, &pclass, len);
    1166      132567 :         if (ctx) {
    1167      132567 :             ctx->ret = i;
    1168      132567 :             ctx->plen = plen;
    1169      132567 :             ctx->pclass = pclass;
    1170      132567 :             ctx->ptag = ptag;
    1171      132567 :             ctx->hdrlen = p - q;
    1172      132567 :             ctx->valid = 1;
    1173             :             /*
    1174             :              * If definite length, and no error, length + header can't exceed
    1175             :              * total amount of data available.
    1176             :              */
    1177      132567 :             if (!(i & 0x81) && ((plen + ctx->hdrlen) > len)) {
    1178           0 :                 ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_TOO_LONG);
    1179           0 :                 asn1_tlc_clear(ctx);
    1180             :                 return 0;
    1181             :             }
    1182             :         }
    1183             :     }
    1184             : 
    1185      182728 :     if (i & 0x80) {
    1186           0 :         ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_BAD_OBJECT_HEADER);
    1187           0 :         asn1_tlc_clear(ctx);
    1188             :         return 0;
    1189             :     }
    1190      182728 :     if (exptag >= 0) {
    1191      158862 :         if ((exptag != ptag) || (expclass != pclass)) {
    1192             :             /*
    1193             :              * If type is OPTIONAL, not an error: indicate missing type.
    1194             :              */
    1195       26295 :             if (opt)
    1196             :                 return -1;
    1197           0 :             asn1_tlc_clear(ctx);
    1198           0 :             ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_WRONG_TAG);
    1199           0 :             return 0;
    1200             :         }
    1201             :         /*
    1202             :          * We have a tag and class match: assume we are going to do something
    1203             :          * with it
    1204             :          */
    1205      132567 :         asn1_tlc_clear(ctx);
    1206             :     }
    1207             : 
    1208      156433 :     if (i & 1)
    1209           0 :         plen = len - (p - q);
    1210             : 
    1211      156433 :     if (inf)
    1212      132567 :         *inf = i & 1;
    1213             : 
    1214      156433 :     if (cst)
    1215      111757 :         *cst = i & V_ASN1_CONSTRUCTED;
    1216             : 
    1217      156433 :     if (olen)
    1218      132567 :         *olen = plen;
    1219             : 
    1220      156433 :     if (oclass)
    1221       23866 :         *oclass = pclass;
    1222             : 
    1223      156433 :     if (otag)
    1224       23866 :         *otag = ptag;
    1225             : 
    1226      156433 :     *in = p;
    1227      156433 :     return 1;
    1228             : }

Generated by: LCOV version 1.10