LCOV - code coverage report
Current view: top level - asn1 - tasn_dec.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 326 503 64.8 %
Date: 2014-08-02 Functions: 11 13 84.6 %
Branches: 223 369 60.4 %

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

Generated by: LCOV version 1.9