LCOV - code coverage report
Current view: top level - libtasn1-2.x/lib - decoding.c (source / functions) Hit Total Coverage
Test: GNU Libtasn1 Lines: 786 1491 52.7 %
Date: 2012-09-24 Functions: 16 18 88.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 493 1069 46.1 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (C) 2002-2012 Free Software Foundation, Inc.
       3                 :            :  *
       4                 :            :  * This file is part of LIBTASN1.
       5                 :            :  *
       6                 :            :  * The LIBTASN1 library is free software; you can redistribute it
       7                 :            :  * and/or modify it under the terms of the GNU Lesser General Public
       8                 :            :  * License as published by the Free Software Foundation; either
       9                 :            :  * version 2.1 of the License, or (at your option) any later version.
      10                 :            :  *
      11                 :            :  * This library is distributed in the hope that it will be useful, but
      12                 :            :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      13                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14                 :            :  * Lesser General Public License for more details.
      15                 :            :  *
      16                 :            :  * You should have received a copy of the GNU Lesser General Public
      17                 :            :  * License along with this library; if not, write to the Free Software
      18                 :            :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
      19                 :            :  * 02110-1301, USA
      20                 :            :  */
      21                 :            : 
      22                 :            : 
      23                 :            : /*****************************************************/
      24                 :            : /* File: decoding.c                                  */
      25                 :            : /* Description: Functions to manage DER decoding     */
      26                 :            : /*****************************************************/
      27                 :            : 
      28                 :            : #include <int.h>
      29                 :            : #include "parser_aux.h"
      30                 :            : #include <gstr.h>
      31                 :            : #include "structure.h"
      32                 :            : #include "element.h"
      33                 :            : #include <limits.h>
      34                 :            : 
      35                 :            : static asn1_retCode
      36                 :            : _asn1_get_indefinite_length_string (const unsigned char *der, int *len);
      37                 :            : 
      38                 :            : static void
      39                 :          0 : _asn1_error_description_tag_error (ASN1_TYPE node, char *ErrorDescription)
      40                 :            : {
      41                 :            : 
      42                 :          0 :   Estrcpy (ErrorDescription, ":: tag error near element '");
      43                 :          0 :   _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription),
      44                 :            :                            ASN1_MAX_ERROR_DESCRIPTION_SIZE - 40);
      45                 :          0 :   Estrcat (ErrorDescription, "'");
      46                 :            : 
      47                 :          0 : }
      48                 :            : 
      49                 :            : /**
      50                 :            :  * asn1_get_length_der:
      51                 :            :  * @der: DER data to decode.
      52                 :            :  * @der_len: Length of DER data to decode.
      53                 :            :  * @len: Output variable containing the length of the DER length field.
      54                 :            :  *
      55                 :            :  * Extract a length field from DER data.
      56                 :            :  *
      57                 :            :  * Returns: Return the decoded length value, or -1 on indefinite
      58                 :            :  *   length, or -2 when the value was too big to fit in a int, or -4
      59                 :            :  *   when the decoded length value plus @len would exceed @der_len.
      60                 :            :  **/
      61                 :            : long
      62                 :        459 : asn1_get_length_der (const unsigned char *der, int der_len, int *len)
      63                 :            : {
      64                 :            :   unsigned int ans, sum, last;
      65                 :            :   int k, punt;
      66                 :            : 
      67                 :        459 :   *len = 0;
      68         [ -  + ]:        459 :   if (der_len <= 0)
      69                 :          0 :     return 0;
      70                 :            : 
      71         [ +  + ]:        459 :   if (!(der[0] & 128))
      72                 :            :     {
      73                 :            :       /* short form */
      74                 :        425 :       *len = 1;
      75                 :        425 :       ans = der[0];
      76                 :            :     }
      77                 :            :   else
      78                 :            :     {
      79                 :            :       /* Long form */
      80                 :         34 :       k = der[0] & 0x7F;
      81                 :         34 :       punt = 1;
      82         [ +  + ]:         34 :       if (k)
      83                 :            :         {                       /* definite length method */
      84                 :         20 :           ans = 0;
      85 [ +  + ][ +  - ]:         71 :           while (punt <= k && punt < der_len)
      86                 :            :             {
      87                 :         52 :               last = ans;
      88                 :            : 
      89                 :         52 :               ans = (ans*256) + der[punt++];
      90         [ +  + ]:         52 :               if (ans < last)
      91                 :            :                 /* we wrapped around, no bignum support... */
      92                 :          1 :                 return -2;
      93                 :            :             }
      94                 :            :         }
      95                 :            :       else
      96                 :            :         {                       /* indefinite length method */
      97                 :         14 :           *len = punt;
      98                 :         14 :           return -1;
      99                 :            :         }
     100                 :            : 
     101                 :         19 :       *len = punt;
     102                 :            :     }
     103                 :            : 
     104                 :        444 :   sum = ans + *len;
     105                 :            : 
     106                 :            :   /* check for overflow as well INT_MAX as a maximum upper
     107                 :            :    * limit for length */
     108 [ +  + ][ +  + ]:        444 :   if (sum >= INT_MAX || sum < ans)
     109                 :          2 :     return -2;
     110                 :            : 
     111         [ +  + ]:        442 :   if (((int) sum) > der_len)
     112                 :          3 :     return -4;
     113                 :            : 
     114                 :        459 :   return ans;
     115                 :            : }
     116                 :            : 
     117                 :            : /**
     118                 :            :  * asn1_get_tag_der:
     119                 :            :  * @der: DER data to decode.
     120                 :            :  * @der_len: Length of DER data to decode.
     121                 :            :  * @cls: Output variable containing decoded class.
     122                 :            :  * @len: Output variable containing the length of the DER TAG data.
     123                 :            :  * @tag: Output variable containing the decoded tag.
     124                 :            :  *
     125                 :            :  * Decode the class and TAG from DER code.
     126                 :            :  *
     127                 :            :  * Returns: Returns %ASN1_SUCCESS on success, or an error.
     128                 :            :  **/
     129                 :            : int
     130                 :        269 : asn1_get_tag_der (const unsigned char *der, int der_len,
     131                 :            :                   unsigned char *cls, int *len, unsigned long *tag)
     132                 :            : {
     133                 :            :   unsigned int ris;
     134                 :            :   int punt;
     135                 :            :   unsigned int last;
     136                 :            : 
     137 [ +  - ][ +  + ]:        269 :   if (der == NULL || der_len < 2 || len == NULL)
                 [ -  + ]
     138                 :          1 :     return ASN1_DER_ERROR;
     139                 :            : 
     140                 :        268 :   *cls = der[0] & 0xE0;
     141         [ +  - ]:        268 :   if ((der[0] & 0x1F) != 0x1F)
     142                 :            :     {
     143                 :            :       /* short form */
     144                 :        268 :       *len = 1;
     145                 :        268 :       ris = der[0] & 0x1F;
     146                 :            :     }
     147                 :            :   else
     148                 :            :     {
     149                 :            :       /* Long form */
     150                 :          0 :       punt = 1;
     151                 :          0 :       ris = 0;
     152 [ #  # ][ #  # ]:          0 :       while (punt <= der_len && der[punt] & 128)
     153                 :            :         {
     154                 :          0 :           last = ris;
     155                 :            : 
     156                 :          0 :           ris = (ris * 128) + (der[punt++] & 0x7F);
     157         [ #  # ]:          0 :           if (ris < last)
     158                 :            :             /* wrapped around, and no bignums... */
     159                 :          0 :             return ASN1_DER_ERROR;
     160                 :            :         }
     161                 :            : 
     162         [ #  # ]:          0 :       if (punt >= der_len)
     163                 :          0 :         return ASN1_DER_ERROR;
     164                 :            : 
     165                 :          0 :       last = ris;
     166                 :            : 
     167                 :          0 :       ris = (ris * 128) + (der[punt++] & 0x7F);
     168         [ #  # ]:          0 :       if (ris < last)
     169                 :          0 :         return ASN1_DER_ERROR;
     170                 :            : 
     171                 :          0 :       *len = punt;
     172                 :            :     }
     173         [ +  + ]:        268 :   if (tag)
     174                 :        257 :     *tag = ris;
     175                 :        269 :   return ASN1_SUCCESS;
     176                 :            : }
     177                 :            : 
     178                 :            : /**
     179                 :            :  * asn1_get_length_ber:
     180                 :            :  * @ber: BER data to decode.
     181                 :            :  * @ber_len: Length of BER data to decode.
     182                 :            :  * @len: Output variable containing the length of the BER length field.
     183                 :            :  *
     184                 :            :  * Extract a length field from BER data.  The difference to
     185                 :            :  * asn1_get_length_der() is that this function will return a length
     186                 :            :  * even if the value has indefinite encoding.
     187                 :            :  *
     188                 :            :  * Returns: Return the decoded length value, or negative value when
     189                 :            :  *   the value was too big.
     190                 :            :  *
     191                 :            :  * Since: 2.0
     192                 :            :  **/
     193                 :            : long
     194                 :         10 : asn1_get_length_ber (const unsigned char *ber, int ber_len, int *len)
     195                 :            : {
     196                 :            :   int ret;
     197                 :            :   long err;
     198                 :            : 
     199                 :         10 :   ret = asn1_get_length_der (ber, ber_len, len);
     200         [ +  + ]:         10 :   if (ret == -1)
     201                 :            :     {                           /* indefinite length method */
     202                 :          1 :       ret = ber_len;
     203                 :          1 :       err = _asn1_get_indefinite_length_string (ber + 1, &ret);
     204         [ -  + ]:          1 :       if (err != ASN1_SUCCESS)
     205                 :          0 :         return -3;
     206                 :            :     }
     207                 :            : 
     208                 :         10 :   return ret;
     209                 :            : }
     210                 :            : 
     211                 :            : /**
     212                 :            :  * asn1_get_octet_der:
     213                 :            :  * @der: DER data to decode containing the OCTET SEQUENCE.
     214                 :            :  * @der_len: Length of DER data to decode.
     215                 :            :  * @ret_len: Output variable containing the length of the DER data.
     216                 :            :  * @str: Pre-allocated output buffer to put decoded OCTET SEQUENCE in.
     217                 :            :  * @str_size: Length of pre-allocated output buffer.
     218                 :            :  * @str_len: Output variable containing the length of the OCTET SEQUENCE.
     219                 :            :  *
     220                 :            :  * Extract an OCTET SEQUENCE from DER data.
     221                 :            :  *
     222                 :            :  * Returns: Returns %ASN1_SUCCESS on success, or an error.
     223                 :            :  **/
     224                 :            : int
     225                 :          9 : asn1_get_octet_der (const unsigned char *der, int der_len,
     226                 :            :                     int *ret_len, unsigned char *str, int str_size,
     227                 :            :                     int *str_len)
     228                 :            : {
     229                 :            :   int len_len;
     230                 :            : 
     231         [ -  + ]:          9 :   if (der_len <= 0)
     232                 :          0 :     return ASN1_GENERIC_ERROR;
     233                 :            : 
     234                 :            :   /* if(str==NULL) return ASN1_SUCCESS; */
     235                 :          9 :   *str_len = asn1_get_length_der (der, der_len, &len_len);
     236                 :            : 
     237         [ -  + ]:          9 :   if (*str_len < 0)
     238                 :          0 :     return ASN1_DER_ERROR;
     239                 :            : 
     240                 :          9 :   *ret_len = *str_len + len_len;
     241         [ +  + ]:          9 :   if (str_size >= *str_len)
     242                 :          4 :     memcpy (str, der + len_len, *str_len);
     243                 :            :   else
     244                 :            :     {
     245                 :          9 :       return ASN1_MEM_ERROR;
     246                 :            :     }
     247                 :            : 
     248                 :          4 :   return ASN1_SUCCESS;
     249                 :            : }
     250                 :            : 
     251                 :            : /* Returns ASN1_SUCCESS on success or an error code on error.
     252                 :            :  */
     253                 :            : static int
     254                 :          4 : _asn1_get_time_der (const unsigned char *der, int der_len, int *ret_len,
     255                 :            :                     char *str, int str_size)
     256                 :            : {
     257                 :            :   int len_len, str_len;
     258                 :            : 
     259 [ +  - ][ -  + ]:          4 :   if (der_len <= 0 || str == NULL)
     260                 :          0 :     return ASN1_DER_ERROR;
     261                 :          4 :   str_len = asn1_get_length_der (der, der_len, &len_len);
     262 [ +  - ][ -  + ]:          4 :   if (str_len < 0 || str_size < str_len)
     263                 :          0 :     return ASN1_DER_ERROR;
     264                 :          4 :   memcpy (str, der + len_len, str_len);
     265                 :          4 :   str[str_len] = 0;
     266                 :          4 :   *ret_len = str_len + len_len;
     267                 :            : 
     268                 :          4 :   return ASN1_SUCCESS;
     269                 :            : }
     270                 :            : 
     271                 :            : static int
     272                 :         26 : _asn1_get_objectid_der (const unsigned char *der, int der_len, int *ret_len,
     273                 :            :                         char *str, int str_size)
     274                 :            : {
     275                 :            :   int len_len, len, k;
     276                 :            :   int leading;
     277                 :            :   char temp[20];
     278                 :            :   unsigned long val, val1, prev_val;
     279                 :            : 
     280                 :         26 :   *ret_len = 0;
     281 [ +  - ][ +  - ]:         26 :   if (str && str_size > 0)
     282                 :         26 :     str[0] = 0;                 /* no oid */
     283                 :            : 
     284 [ +  - ][ -  + ]:         26 :   if (str == NULL || der_len <= 0)
     285                 :          0 :     return ASN1_GENERIC_ERROR;
     286                 :         26 :   len = asn1_get_length_der (der, der_len, &len_len);
     287                 :            : 
     288 [ +  - ][ +  - ]:         26 :   if (len < 0 || len > der_len || len_len > der_len)
                 [ -  + ]
     289                 :          0 :     return ASN1_DER_ERROR;
     290                 :            : 
     291                 :         26 :   val1 = der[len_len] / 40;
     292                 :         26 :   val = der[len_len] - val1 * 40;
     293                 :            : 
     294                 :         26 :   _asn1_str_cpy (str, str_size, _asn1_ltostr (val1, temp));
     295                 :         26 :   _asn1_str_cat (str, str_size, ".");
     296                 :         26 :   _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp));
     297                 :            : 
     298                 :         26 :   prev_val = 0;
     299                 :         26 :   val = 0;
     300                 :         26 :   leading = 1;
     301         [ +  + ]:        110 :   for (k = 1; k < len; k++)
     302                 :            :     {
     303                 :            :       /* X.690 mandates that the leading byte must never be 0x80
     304                 :            :        */
     305 [ +  + ][ -  + ]:         84 :       if (leading != 0 && der[len_len + k] == 0x80)
     306                 :          0 :         return ASN1_DER_ERROR;
     307                 :         84 :       leading = 0;
     308                 :            : 
     309                 :            :       /* check for wrap around */
     310                 :         84 :       val = val << 7;
     311                 :         84 :       val |= der[len_len + k] & 0x7F;
     312                 :            : 
     313         [ -  + ]:         84 :       if (val < prev_val)
     314                 :          0 :         return ASN1_DER_ERROR;
     315                 :            : 
     316                 :         84 :       prev_val = val;
     317                 :            : 
     318         [ +  + ]:         84 :       if (!(der[len_len + k] & 0x80))
     319                 :            :         {
     320                 :         69 :           _asn1_str_cat (str, str_size, ".");
     321                 :         69 :           _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp));
     322                 :         69 :           val = 0;
     323                 :         69 :           prev_val = 0;
     324                 :         69 :           leading = 1;
     325                 :            :         }
     326                 :            :     }
     327                 :         26 :   *ret_len = len + len_len;
     328                 :            : 
     329                 :         26 :   return ASN1_SUCCESS;
     330                 :            : }
     331                 :            : 
     332                 :            : /**
     333                 :            :  * asn1_get_bit_der:
     334                 :            :  * @der: DER data to decode containing the BIT SEQUENCE.
     335                 :            :  * @der_len: Length of DER data to decode.
     336                 :            :  * @ret_len: Output variable containing the length of the DER data.
     337                 :            :  * @str: Pre-allocated output buffer to put decoded BIT SEQUENCE in.
     338                 :            :  * @str_size: Length of pre-allocated output buffer.
     339                 :            :  * @bit_len: Output variable containing the size of the BIT SEQUENCE.
     340                 :            :  *
     341                 :            :  * Extract a BIT SEQUENCE from DER data.
     342                 :            :  *
     343                 :            :  * Returns: Return %ASN1_SUCCESS on success, or an error.
     344                 :            :  **/
     345                 :            : int
     346                 :         45 : asn1_get_bit_der (const unsigned char *der, int der_len,
     347                 :            :                   int *ret_len, unsigned char *str, int str_size,
     348                 :            :                   int *bit_len)
     349                 :            : {
     350                 :            :   int len_len, len_byte;
     351                 :            : 
     352         [ +  + ]:         45 :   if (der_len <= 0)
     353                 :          1 :     return ASN1_GENERIC_ERROR;
     354                 :         44 :   len_byte = asn1_get_length_der (der, der_len, &len_len) - 1;
     355         [ -  + ]:         44 :   if (len_byte < 0)
     356                 :          0 :     return ASN1_DER_ERROR;
     357                 :            : 
     358                 :         44 :   *ret_len = len_byte + len_len + 1;
     359                 :         44 :   *bit_len = len_byte * 8 - der[len_len];
     360                 :            : 
     361         [ +  + ]:         44 :   if (str_size >= len_byte)
     362                 :         43 :     memcpy (str, der + len_len + 1, len_byte);
     363                 :            :   else
     364                 :            :     {
     365                 :         45 :       return ASN1_MEM_ERROR;
     366                 :            :     }
     367                 :            : 
     368                 :         43 :   return ASN1_SUCCESS;
     369                 :            : }
     370                 :            : 
     371                 :            : static int
     372                 :        225 : _asn1_extract_tag_der (ASN1_TYPE node, const unsigned char *der, int der_len,
     373                 :            :                        int *ret_len)
     374                 :            : {
     375                 :            :   ASN1_TYPE p;
     376                 :            :   int counter, len2, len3, is_tag_implicit;
     377                 :        225 :   unsigned long tag, tag_implicit = 0;
     378                 :        225 :   unsigned char class, class2, class_implicit = 0;
     379                 :            : 
     380         [ -  + ]:        225 :   if (der_len <= 0)
     381                 :          0 :     return ASN1_GENERIC_ERROR;
     382                 :            : 
     383                 :        225 :   counter = is_tag_implicit = 0;
     384                 :            : 
     385         [ +  + ]:        225 :   if (node->type & CONST_TAG)
     386                 :            :     {
     387                 :         41 :       p = node->down;
     388         [ +  + ]:        131 :       while (p)
     389                 :            :         {
     390         [ +  + ]:         90 :           if (type_field (p->type) == TYPE_TAG)
     391                 :            :             {
     392         [ +  + ]:         43 :               if (p->type & CONST_APPLICATION)
     393                 :          1 :                 class2 = ASN1_CLASS_APPLICATION;
     394         [ +  + ]:         42 :               else if (p->type & CONST_UNIVERSAL)
     395                 :          2 :                 class2 = ASN1_CLASS_UNIVERSAL;
     396         [ -  + ]:         40 :               else if (p->type & CONST_PRIVATE)
     397                 :          0 :                 class2 = ASN1_CLASS_PRIVATE;
     398                 :            :               else
     399                 :         40 :                 class2 = ASN1_CLASS_CONTEXT_SPECIFIC;
     400                 :            : 
     401         [ +  + ]:         43 :               if (p->type & CONST_EXPLICIT)
     402                 :            :                 {
     403         [ -  + ]:         10 :                   if (asn1_get_tag_der
     404                 :         10 :                       (der + counter, der_len - counter, &class, &len2,
     405                 :            :                        &tag) != ASN1_SUCCESS)
     406                 :          0 :                     return ASN1_DER_ERROR;
     407                 :            : 
     408         [ -  + ]:         10 :                   if (counter + len2 > der_len)
     409                 :          0 :                     return ASN1_DER_ERROR;
     410                 :         10 :                   counter += len2;
     411                 :            : 
     412                 :         10 :                   len3 =
     413                 :         10 :                     asn1_get_length_ber (der + counter, der_len - counter,
     414                 :            :                                          &len2);
     415         [ -  + ]:         10 :                   if (len3 < 0)
     416                 :          0 :                     return ASN1_DER_ERROR;
     417                 :            : 
     418                 :         10 :                   counter += len2;
     419         [ -  + ]:         10 :                   if (counter > der_len)
     420                 :          0 :                     return ASN1_DER_ERROR;
     421                 :            : 
     422         [ +  - ]:         10 :                   if (!is_tag_implicit)
     423                 :            :                     {
     424   [ +  -  -  + ]:         20 :                       if ((class != (class2 | ASN1_CLASS_STRUCTURED)) ||
     425                 :         10 :                           (tag != strtoul ((char *) p->value, NULL, 10)))
     426                 :          0 :                         return ASN1_TAG_ERROR;
     427                 :            :                     }
     428                 :            :                   else
     429                 :            :                     {           /* ASN1_TAG_IMPLICIT */
     430 [ #  # ][ #  # ]:          0 :                       if ((class != class_implicit) || (tag != tag_implicit))
     431                 :          0 :                         return ASN1_TAG_ERROR;
     432                 :            :                     }
     433                 :         10 :                   is_tag_implicit = 0;
     434                 :            :                 }
     435                 :            :               else
     436                 :            :                 {               /* ASN1_TAG_IMPLICIT */
     437         [ +  - ]:         33 :                   if (!is_tag_implicit)
     438                 :            :                     {
     439 [ +  + ][ +  - ]:         33 :                       if ((type_field (node->type) == TYPE_SEQUENCE) ||
     440         [ +  - ]:         22 :                           (type_field (node->type) == TYPE_SEQUENCE_OF) ||
     441         [ +  + ]:         22 :                           (type_field (node->type) == TYPE_SET) ||
     442                 :         22 :                           (type_field (node->type) == TYPE_SET_OF))
     443                 :         13 :                         class2 |= ASN1_CLASS_STRUCTURED;
     444                 :         33 :                       class_implicit = class2;
     445                 :         33 :                       tag_implicit = strtoul ((char *) p->value, NULL, 10);
     446                 :         33 :                       is_tag_implicit = 1;
     447                 :            :                     }
     448                 :            :                 }
     449                 :            :             }
     450                 :         90 :           p = p->right;
     451                 :            :         }
     452                 :            :     }
     453                 :            : 
     454         [ +  + ]:        225 :   if (is_tag_implicit)
     455                 :            :     {
     456         [ -  + ]:         33 :       if (asn1_get_tag_der
     457                 :         33 :           (der + counter, der_len - counter, &class, &len2,
     458                 :            :            &tag) != ASN1_SUCCESS)
     459                 :          0 :         return ASN1_DER_ERROR;
     460         [ -  + ]:         33 :       if (counter + len2 > der_len)
     461                 :          0 :         return ASN1_DER_ERROR;
     462                 :            : 
     463 [ +  + ][ +  + ]:         33 :       if ((class != class_implicit) || (tag != tag_implicit))
     464                 :            :         {
     465         [ -  + ]:         11 :           if (type_field (node->type) == TYPE_OCTET_STRING)
     466                 :            :             {
     467                 :          0 :               class_implicit |= ASN1_CLASS_STRUCTURED;
     468 [ #  # ][ #  # ]:          0 :               if ((class != class_implicit) || (tag != tag_implicit))
     469                 :          0 :                 return ASN1_TAG_ERROR;
     470                 :            :             }
     471                 :            :           else
     472                 :         11 :             return ASN1_TAG_ERROR;
     473                 :            :         }
     474                 :            :     }
     475                 :            :   else
     476                 :            :     {
     477         [ +  + ]:        192 :       if (type_field (node->type) == TYPE_TAG)
     478                 :            :         {
     479                 :          6 :           counter = 0;
     480                 :          6 :           *ret_len = counter;
     481                 :          6 :           return ASN1_SUCCESS;
     482                 :            :         }
     483                 :            : 
     484         [ -  + ]:        186 :       if (asn1_get_tag_der
     485                 :        186 :           (der + counter, der_len - counter, &class, &len2,
     486                 :            :            &tag) != ASN1_SUCCESS)
     487                 :          0 :         return ASN1_DER_ERROR;
     488                 :            : 
     489         [ -  + ]:        186 :       if (counter + len2 > der_len)
     490                 :          0 :         return ASN1_DER_ERROR;
     491                 :            : 
     492   [ -  +  +  +  :        186 :       switch (type_field (node->type))
          +  +  +  +  +  
             +  +  +  - ]
     493                 :            :         {
     494                 :            :         case TYPE_NULL:
     495 [ #  # ][ #  # ]:          0 :           if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_NULL))
     496                 :          0 :             return ASN1_DER_ERROR;
     497                 :          0 :           break;
     498                 :            :         case TYPE_BOOLEAN:
     499 [ +  - ][ +  + ]:          4 :           if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_BOOLEAN))
     500                 :          3 :             return ASN1_DER_ERROR;
     501                 :          1 :           break;
     502                 :            :         case TYPE_INTEGER:
     503 [ +  - ][ -  + ]:         35 :           if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_INTEGER))
     504                 :          0 :             return ASN1_DER_ERROR;
     505                 :         35 :           break;
     506                 :            :         case TYPE_ENUMERATED:
     507 [ +  - ][ -  + ]:          1 :           if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_ENUMERATED))
     508                 :          0 :             return ASN1_DER_ERROR;
     509                 :          1 :           break;
     510                 :            :         case TYPE_OBJECT_ID:
     511 [ +  - ][ -  + ]:         30 :           if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_OBJECT_ID))
     512                 :          0 :             return ASN1_DER_ERROR;
     513                 :         30 :           break;
     514                 :            :         case TYPE_TIME:
     515         [ +  + ]:          6 :           if (node->type & CONST_UTC)
     516                 :            :             {
     517         [ +  - ]:          5 :               if ((class != ASN1_CLASS_UNIVERSAL)
     518         [ -  + ]:          5 :                   || (tag != ASN1_TAG_UTCTime))
     519                 :          0 :                 return ASN1_DER_ERROR;
     520                 :            :             }
     521                 :            :           else
     522                 :            :             {
     523         [ +  - ]:          1 :               if ((class != ASN1_CLASS_UNIVERSAL)
     524         [ -  + ]:          1 :                   || (tag != ASN1_TAG_GENERALIZEDTime))
     525                 :          0 :                 return ASN1_DER_ERROR;
     526                 :            :             }
     527                 :          6 :           break;
     528                 :            :         case TYPE_OCTET_STRING:
     529         [ -  + ]:          8 :           if (((class != ASN1_CLASS_UNIVERSAL)
     530         [ #  # ]:          0 :                && (class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED)))
     531         [ -  + ]:          8 :               || (tag != ASN1_TAG_OCTET_STRING))
     532                 :          0 :             return ASN1_DER_ERROR;
     533                 :          8 :           break;
     534                 :            :         case TYPE_GENERALSTRING:
     535         [ +  - ]:          3 :           if ((class != ASN1_CLASS_UNIVERSAL)
     536         [ -  + ]:          3 :               || (tag != ASN1_TAG_GENERALSTRING))
     537                 :          0 :             return ASN1_DER_ERROR;
     538                 :          3 :           break;
     539                 :            :         case TYPE_BIT_STRING:
     540 [ +  - ][ -  + ]:          3 :           if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_BIT_STRING))
     541                 :          0 :             return ASN1_DER_ERROR;
     542                 :          3 :           break;
     543                 :            :         case TYPE_SEQUENCE:
     544                 :            :         case TYPE_SEQUENCE_OF:
     545         [ +  - ]:         60 :           if ((class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED))
     546         [ -  + ]:         60 :               || (tag != ASN1_TAG_SEQUENCE))
     547                 :          0 :             return ASN1_DER_ERROR;
     548                 :         60 :           break;
     549                 :            :         case TYPE_SET:
     550                 :            :         case TYPE_SET_OF:
     551         [ +  - ]:         17 :           if ((class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED))
     552         [ -  + ]:         17 :               || (tag != ASN1_TAG_SET))
     553                 :          0 :             return ASN1_DER_ERROR;
     554                 :         17 :           break;
     555                 :            :         case TYPE_ANY:
     556                 :         19 :           counter -= len2;
     557                 :         19 :           break;
     558                 :            :         default:
     559                 :          0 :           return ASN1_DER_ERROR;
     560                 :            :           break;
     561                 :            :         }
     562                 :            :     }
     563                 :            : 
     564                 :        205 :   counter += len2;
     565                 :        205 :   *ret_len = counter;
     566                 :        225 :   return ASN1_SUCCESS;
     567                 :            : }
     568                 :            : 
     569                 :            : static int
     570                 :         21 : _asn1_delete_not_used (ASN1_TYPE node)
     571                 :            : {
     572                 :            :   ASN1_TYPE p, p2;
     573                 :            : 
     574         [ -  + ]:         21 :   if (node == NULL)
     575                 :          0 :     return ASN1_ELEMENT_NOT_FOUND;
     576                 :            : 
     577                 :         21 :   p = node;
     578         [ +  + ]:        314 :   while (p)
     579                 :            :     {
     580         [ +  + ]:        293 :       if (p->type & CONST_NOT_USED)
     581                 :            :         {
     582                 :          3 :           p2 = NULL;
     583         [ +  - ]:          3 :           if (p != node)
     584                 :            :             {
     585                 :          3 :               p2 = _asn1_find_left (p);
     586         [ +  + ]:          3 :               if (!p2)
     587                 :          1 :                 p2 = _asn1_find_up (p);
     588                 :            :             }
     589                 :          3 :           asn1_delete_structure (&p);
     590                 :          3 :           p = p2;
     591                 :            :         }
     592                 :            : 
     593         [ -  + ]:        293 :       if (!p)
     594                 :          0 :         break;                  /* reach node */
     595                 :            : 
     596         [ +  + ]:        293 :       if (p->down)
     597                 :            :         {
     598                 :        115 :           p = p->down;
     599                 :            :         }
     600                 :            :       else
     601                 :            :         {
     602         [ +  + ]:        178 :           if (p == node)
     603                 :          2 :             p = NULL;
     604         [ +  + ]:        176 :           else if (p->right)
     605                 :         99 :             p = p->right;
     606                 :            :           else
     607                 :            :             {
     608                 :            :               while (1)
     609                 :            :                 {
     610                 :        114 :                   p = _asn1_find_up (p);
     611         [ +  + ]:        114 :                   if (p == node)
     612                 :            :                     {
     613                 :         19 :                       p = NULL;
     614                 :         19 :                       break;
     615                 :            :                     }
     616         [ +  + ]:         95 :                   if (p->right)
     617                 :            :                     {
     618                 :         58 :                       p = p->right;
     619                 :         58 :                       break;
     620                 :            :                     }
     621                 :         37 :                 }
     622                 :            :             }
     623                 :            :         }
     624                 :            :     }
     625                 :         21 :   return ASN1_SUCCESS;
     626                 :            : }
     627                 :            : 
     628                 :            : static asn1_retCode
     629                 :          0 : _asn1_extract_der_octet (ASN1_TYPE node, const unsigned char *der,
     630                 :            :                          int der_len)
     631                 :            : {
     632                 :            :   int len2, len3;
     633                 :            :   int counter2, counter_end;
     634                 :            : 
     635                 :          0 :   len2 = asn1_get_length_der (der, der_len, &len3);
     636         [ #  # ]:          0 :   if (len2 < -1)
     637                 :          0 :     return ASN1_DER_ERROR;
     638                 :            : 
     639                 :          0 :   counter2 = len3 + 1;
     640                 :            : 
     641         [ #  # ]:          0 :   if (len2 == -1)
     642                 :          0 :     counter_end = der_len - 2;
     643                 :            :   else
     644                 :          0 :     counter_end = der_len;
     645                 :            : 
     646         [ #  # ]:          0 :   while (counter2 < counter_end)
     647                 :            :     {
     648                 :          0 :       len2 = asn1_get_length_der (der + counter2, der_len - counter2, &len3);
     649                 :            : 
     650         [ #  # ]:          0 :       if (len2 < -1)
     651                 :          0 :         return ASN1_DER_ERROR;
     652                 :            : 
     653         [ #  # ]:          0 :       if (len2 > 0)
     654                 :            :         {
     655                 :          0 :           _asn1_append_value (node, der + counter2 + len3, len2);
     656                 :            :         }
     657                 :            :       else
     658                 :            :         {                       /* indefinite */
     659                 :            : 
     660                 :          0 :           len2 =
     661                 :          0 :             _asn1_extract_der_octet (node, der + counter2 + len3,
     662                 :          0 :                                      der_len - counter2 - len3);
     663         [ #  # ]:          0 :           if (len2 < 0)
     664                 :          0 :             return len2;
     665                 :            :         }
     666                 :            : 
     667                 :          0 :       counter2 += len2 + len3 + 1;
     668                 :            :     }
     669                 :            : 
     670                 :          0 :   return ASN1_SUCCESS;
     671                 :            : }
     672                 :            : 
     673                 :            : static asn1_retCode
     674                 :         11 : _asn1_get_octet_string (const unsigned char *der, ASN1_TYPE node, int *len)
     675                 :            : {
     676                 :            :   int len2, len3, counter, tot_len, indefinite;
     677                 :            : 
     678                 :         11 :   counter = 0;
     679                 :            : 
     680         [ -  + ]:         11 :   if (*(der - 1) & ASN1_CLASS_STRUCTURED)
     681                 :            :     {
     682                 :          0 :       tot_len = 0;
     683                 :          0 :       indefinite = asn1_get_length_der (der, *len, &len3);
     684         [ #  # ]:          0 :       if (indefinite < -1)
     685                 :          0 :         return ASN1_DER_ERROR;
     686                 :            : 
     687                 :          0 :       counter += len3;
     688         [ #  # ]:          0 :       if (indefinite >= 0)
     689                 :          0 :         indefinite += len3;
     690                 :            : 
     691                 :            :       while (1)
     692                 :            :         {
     693         [ #  # ]:          0 :           if (counter > (*len))
     694                 :          0 :             return ASN1_DER_ERROR;
     695                 :            : 
     696         [ #  # ]:          0 :           if (indefinite == -1)
     697                 :            :             {
     698 [ #  # ][ #  # ]:          0 :               if ((der[counter] == 0) && (der[counter + 1] == 0))
     699                 :            :                 {
     700                 :          0 :                   counter += 2;
     701                 :          0 :                   break;
     702                 :            :                 }
     703                 :            :             }
     704         [ #  # ]:          0 :           else if (counter >= indefinite)
     705                 :          0 :             break;
     706                 :            : 
     707         [ #  # ]:          0 :           if (der[counter] != ASN1_TAG_OCTET_STRING)
     708                 :          0 :             return ASN1_DER_ERROR;
     709                 :            : 
     710                 :          0 :           counter++;
     711                 :            : 
     712                 :          0 :           len2 = asn1_get_length_der (der + counter, *len - counter, &len3);
     713         [ #  # ]:          0 :           if (len2 <= 0)
     714                 :          0 :             return ASN1_DER_ERROR;
     715                 :            : 
     716                 :          0 :           counter += len3 + len2;
     717                 :          0 :           tot_len += len2;
     718                 :          0 :         }
     719                 :            : 
     720                 :            :       /* copy */
     721         [ #  # ]:          0 :       if (node)
     722                 :            :         {
     723                 :            :           unsigned char temp[DER_LEN];
     724                 :            :           int ret;
     725                 :            : 
     726                 :          0 :           len2 = sizeof (temp);
     727                 :            : 
     728                 :          0 :           asn1_length_der (tot_len, temp, &len2);
     729                 :          0 :           _asn1_set_value (node, temp, len2);
     730                 :            : 
     731                 :          0 :           tot_len += len2;
     732                 :            : 
     733                 :          0 :           ret = _asn1_extract_der_octet (node, der, *len);
     734         [ #  # ]:          0 :           if (ret != ASN1_SUCCESS)
     735                 :          0 :             return ret;
     736                 :            : 
     737                 :            :         }
     738                 :            :     }
     739                 :            :   else
     740                 :            :     {                           /* NOT STRUCTURED */
     741                 :         11 :       len2 = asn1_get_length_der (der, *len, &len3);
     742         [ -  + ]:         11 :       if (len2 < 0)
     743                 :          0 :         return ASN1_DER_ERROR;
     744         [ +  - ]:         11 :       if (node)
     745                 :         11 :         _asn1_set_value (node, der, len3 + len2);
     746                 :         11 :       counter = len3 + len2;
     747                 :            :     }
     748                 :            : 
     749                 :         11 :   *len = counter;
     750                 :         11 :   return ASN1_SUCCESS;
     751                 :            : 
     752                 :            : }
     753                 :            : 
     754                 :            : static asn1_retCode
     755                 :          2 : _asn1_get_indefinite_length_string (const unsigned char *der, int *len)
     756                 :            : {
     757                 :            :   int len2, len3, counter, indefinite;
     758                 :            :   unsigned long tag;
     759                 :            :   unsigned char class;
     760                 :            : 
     761                 :          2 :   counter = indefinite = 0;
     762                 :            : 
     763                 :            :   while (1)
     764                 :            :     {
     765         [ -  + ]:         10 :       if ((*len) < counter)
     766                 :          0 :         return ASN1_DER_ERROR;
     767                 :            : 
     768 [ +  + ][ +  - ]:         10 :       if ((der[counter] == 0) && (der[counter + 1] == 0))
     769                 :            :         {
     770                 :          2 :           counter += 2;
     771                 :          2 :           indefinite--;
     772         [ +  - ]:          2 :           if (indefinite <= 0)
     773                 :          2 :             break;
     774                 :            :           else
     775                 :          0 :             continue;
     776                 :            :         }
     777                 :            : 
     778         [ -  + ]:          8 :       if (asn1_get_tag_der
     779                 :          8 :           (der + counter, *len - counter, &class, &len2,
     780                 :            :            &tag) != ASN1_SUCCESS)
     781                 :          0 :         return ASN1_DER_ERROR;
     782         [ -  + ]:          8 :       if (counter + len2 > *len)
     783                 :          0 :         return ASN1_DER_ERROR;
     784                 :          8 :       counter += len2;
     785                 :          8 :       len2 = asn1_get_length_der (der + counter, *len - counter, &len3);
     786         [ -  + ]:          8 :       if (len2 < -1)
     787                 :          0 :         return ASN1_DER_ERROR;
     788         [ +  + ]:          8 :       if (len2 == -1)
     789                 :            :         {
     790                 :          2 :           indefinite++;
     791                 :          2 :           counter += 1;
     792                 :            :         }
     793                 :            :       else
     794                 :            :         {
     795                 :          6 :           counter += len2 + len3;
     796                 :            :         }
     797                 :          8 :     }
     798                 :            : 
     799                 :          2 :   *len = counter;
     800                 :          2 :   return ASN1_SUCCESS;
     801                 :            : 
     802                 :            : }
     803                 :            : 
     804                 :            : /**
     805                 :            :  * asn1_der_decoding:
     806                 :            :  * @element: pointer to an ASN1 structure.
     807                 :            :  * @ider: vector that contains the DER encoding.
     808                 :            :  * @len: number of bytes of *@ider: @ider[0]..@ider[len-1].
     809                 :            :  * @errorDescription: null-terminated string contains details when an
     810                 :            :  *   error occurred.
     811                 :            :  *
     812                 :            :  * Fill the structure *@ELEMENT with values of a DER encoding
     813                 :            :  * string. The structure must just be created with function
     814                 :            :  * asn1_create_element().  If an error occurs during the decoding
     815                 :            :  * procedure, the *@ELEMENT is deleted and set equal to
     816                 :            :  * %ASN1_TYPE_EMPTY.
     817                 :            :  *
     818                 :            :  * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
     819                 :            :  *   if @ELEMENT is %ASN1_TYPE_EMPTY, and %ASN1_TAG_ERROR or
     820                 :            :  *   %ASN1_DER_ERROR if the der encoding doesn't match the structure
     821                 :            :  *   name (*@ELEMENT deleted).
     822                 :            :  **/
     823                 :            : asn1_retCode
     824                 :         18 : asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
     825                 :            :                    char *errorDescription)
     826                 :            : {
     827                 :            :   ASN1_TYPE node, p, p2, p3;
     828                 :            :   char temp[128];
     829                 :            :   int counter, len2, len3, len4, move, ris, tlen;
     830                 :            :   unsigned char class;
     831                 :            :   unsigned long tag;
     832                 :            :   int indefinite, result;
     833                 :         18 :   const unsigned char *der = ider;
     834                 :            : 
     835                 :         18 :   node = *element;
     836                 :            : 
     837         [ -  + ]:         18 :   if (node == ASN1_TYPE_EMPTY)
     838                 :          0 :     return ASN1_ELEMENT_NOT_FOUND;
     839                 :            : 
     840         [ -  + ]:         18 :   if (node->type & CONST_OPTION)
     841                 :            :     {
     842                 :          0 :       result = ASN1_GENERIC_ERROR;
     843                 :          0 :       goto cleanup;
     844                 :            :     }
     845                 :            : 
     846                 :         18 :   counter = 0;
     847                 :         18 :   move = DOWN;
     848                 :         18 :   p = node;
     849                 :            :   while (1)
     850                 :            :     {
     851                 :        237 :       ris = ASN1_SUCCESS;
     852         [ +  + ]:        237 :       if (move != UP)
     853                 :            :         {
     854         [ -  + ]:        162 :           if (p->type & CONST_SET)
     855                 :            :             {
     856                 :          0 :               p2 = _asn1_find_up (p);
     857                 :          0 :               len2 = _asn1_strtol (p2->value, NULL, 10);
     858         [ #  # ]:          0 :               if (len2 == -1)
     859                 :            :                 {
     860 [ #  # ][ #  # ]:          0 :                   if (!der[counter] && !der[counter + 1])
     861                 :            :                     {
     862                 :          0 :                       p = p2;
     863                 :          0 :                       move = UP;
     864                 :          0 :                       counter += 2;
     865                 :          0 :                       continue;
     866                 :            :                     }
     867                 :            :                 }
     868         [ #  # ]:          0 :               else if (counter == len2)
     869                 :            :                 {
     870                 :          0 :                   p = p2;
     871                 :          0 :                   move = UP;
     872                 :          0 :                   continue;
     873                 :            :                 }
     874         [ #  # ]:          0 :               else if (counter > len2)
     875                 :            :                 {
     876                 :          0 :                   result = ASN1_DER_ERROR;
     877                 :          0 :                   goto cleanup;
     878                 :            :                 }
     879                 :          0 :               p2 = p2->down;
     880         [ #  # ]:          0 :               while (p2)
     881                 :            :                 {
     882 [ #  # ][ #  # ]:          0 :                   if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
     883                 :            :                     {
     884         [ #  # ]:          0 :                       if (type_field (p2->type) != TYPE_CHOICE)
     885                 :          0 :                         ris =
     886                 :          0 :                           _asn1_extract_tag_der (p2, der + counter,
     887                 :            :                                                  len - counter, &len2);
     888                 :            :                       else
     889                 :            :                         {
     890                 :          0 :                           p3 = p2->down;
     891         [ #  # ]:          0 :                           while (p3)
     892                 :            :                             {
     893                 :          0 :                               ris =
     894                 :          0 :                                 _asn1_extract_tag_der (p3, der + counter,
     895                 :            :                                                        len - counter, &len2);
     896         [ #  # ]:          0 :                               if (ris == ASN1_SUCCESS)
     897                 :          0 :                                 break;
     898                 :          0 :                               p3 = p3->right;
     899                 :            :                             }
     900                 :            :                         }
     901         [ #  # ]:          0 :                       if (ris == ASN1_SUCCESS)
     902                 :            :                         {
     903                 :          0 :                           p2->type &= ~CONST_NOT_USED;
     904                 :          0 :                           p = p2;
     905                 :          0 :                           break;
     906                 :            :                         }
     907                 :            :                     }
     908                 :          0 :                   p2 = p2->right;
     909                 :            :                 }
     910         [ #  # ]:          0 :               if (p2 == NULL)
     911                 :            :                 {
     912                 :          0 :                   result = ASN1_DER_ERROR;
     913                 :          0 :                   goto cleanup;
     914                 :            :                 }
     915                 :            :             }
     916                 :            : 
     917 [ +  + ][ +  + ]:        162 :           if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
     918                 :            :             {
     919                 :         30 :               p2 = _asn1_find_up (p);
     920                 :         30 :               len2 = _asn1_strtol (p2->value, NULL, 10);
     921         [ +  + ]:         30 :               if (counter == len2)
     922                 :            :                 {
     923         [ -  + ]:          4 :                   if (p->right)
     924                 :            :                     {
     925                 :          0 :                       p2 = p->right;
     926                 :          0 :                       move = RIGHT;
     927                 :            :                     }
     928                 :            :                   else
     929                 :          4 :                     move = UP;
     930                 :            : 
     931         [ +  + ]:          4 :                   if (p->type & CONST_OPTION)
     932                 :          3 :                     asn1_delete_structure (&p);
     933                 :            : 
     934                 :          4 :                   p = p2;
     935                 :          4 :                   continue;
     936                 :            :                 }
     937                 :            :             }
     938                 :            : 
     939         [ +  + ]:        158 :           if (type_field (p->type) == TYPE_CHOICE)
     940                 :            :             {
     941         [ +  - ]:          6 :               while (p->down)
     942                 :            :                 {
     943         [ +  - ]:          6 :                   if (counter < len)
     944                 :          6 :                     ris =
     945                 :          6 :                       _asn1_extract_tag_der (p->down, der + counter,
     946                 :            :                                              len - counter, &len2);
     947                 :            :                   else
     948                 :          0 :                     ris = ASN1_DER_ERROR;
     949         [ +  - ]:          6 :                   if (ris == ASN1_SUCCESS)
     950                 :            :                     {
     951         [ +  + ]:         12 :                       while (p->down->right)
     952                 :            :                         {
     953                 :          6 :                           p2 = p->down->right;
     954                 :          6 :                           asn1_delete_structure (&p2);
     955                 :            :                         }
     956                 :          6 :                       break;
     957                 :            :                     }
     958         [ #  # ]:          0 :                   else if (ris == ASN1_ERROR_TYPE_ANY)
     959                 :            :                     {
     960                 :          0 :                       result = ASN1_ERROR_TYPE_ANY;
     961                 :          0 :                       goto cleanup;
     962                 :            :                     }
     963                 :            :                   else
     964                 :            :                     {
     965                 :          0 :                       p2 = p->down;
     966                 :          0 :                       asn1_delete_structure (&p2);
     967                 :            :                     }
     968                 :            :                 }
     969                 :            : 
     970         [ -  + ]:          6 :               if (p->down == NULL)
     971                 :            :                 {
     972         [ #  # ]:          0 :                   if (!(p->type & CONST_OPTION))
     973                 :            :                     {
     974                 :          0 :                       result = ASN1_DER_ERROR;
     975                 :          0 :                       goto cleanup;
     976                 :            :                     }
     977                 :            :                 }
     978                 :            :               else
     979                 :          6 :                 p = p->down;
     980                 :            :             }
     981                 :            : 
     982 [ +  + ][ +  + ]:        158 :           if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
     983                 :            :             {
     984                 :         25 :               p2 = _asn1_find_up (p);
     985                 :         25 :               len2 = _asn1_strtol (p2->value, NULL, 10);
     986 [ +  + ][ -  + ]:         25 :               if ((len2 != -1) && (counter > len2))
     987                 :          0 :                 ris = ASN1_TAG_ERROR;
     988                 :            :             }
     989                 :            : 
     990         [ +  - ]:        158 :           if (ris == ASN1_SUCCESS)
     991                 :        158 :             ris =
     992                 :        158 :               _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
     993         [ +  + ]:        158 :           if (ris != ASN1_SUCCESS)
     994                 :            :             {
     995         [ +  + ]:          9 :               if (p->type & CONST_OPTION)
     996                 :            :                 {
     997                 :          3 :                   p->type |= CONST_NOT_USED;
     998                 :          3 :                   move = RIGHT;
     999                 :            :                 }
    1000         [ +  - ]:          6 :               else if (p->type & CONST_DEFAULT)
    1001                 :            :                 {
    1002                 :          6 :                   _asn1_set_value (p, NULL, 0);
    1003                 :          6 :                   move = RIGHT;
    1004                 :            :                 }
    1005                 :            :               else
    1006                 :            :                 {
    1007         [ #  # ]:          0 :                   if (errorDescription != NULL)
    1008                 :          0 :                     _asn1_error_description_tag_error (p, errorDescription);
    1009                 :            : 
    1010                 :          0 :                   result = ASN1_TAG_ERROR;
    1011                 :          0 :                   goto cleanup;
    1012                 :            :                 }
    1013                 :            :             }
    1014                 :            :           else
    1015                 :        149 :             counter += len2;
    1016                 :            :         }
    1017                 :            : 
    1018         [ +  + ]:        233 :       if (ris == ASN1_SUCCESS)
    1019                 :            :         {
    1020   [ -  +  +  +  :        224 :           switch (type_field (p->type))
          +  +  +  +  +  
                +  +  + ]
    1021                 :            :             {
    1022                 :            :             case TYPE_NULL:
    1023         [ #  # ]:          0 :               if (der[counter])
    1024                 :            :                 {
    1025                 :          0 :                   result = ASN1_DER_ERROR;
    1026                 :          0 :                   goto cleanup;
    1027                 :            :                 }
    1028                 :          0 :               counter++;
    1029                 :          0 :               move = RIGHT;
    1030                 :          0 :               break;
    1031                 :            :             case TYPE_BOOLEAN:
    1032         [ -  + ]:          1 :               if (der[counter++] != 1)
    1033                 :            :                 {
    1034                 :          0 :                   result = ASN1_DER_ERROR;
    1035                 :          0 :                   goto cleanup;
    1036                 :            :                 }
    1037         [ -  + ]:          1 :               if (der[counter++] == 0)
    1038                 :          0 :                 _asn1_set_value (p, "F", 1);
    1039                 :            :               else
    1040                 :          1 :                 _asn1_set_value (p, "T", 1);
    1041                 :          1 :               move = RIGHT;
    1042                 :          1 :               break;
    1043                 :            :             case TYPE_INTEGER:
    1044                 :            :             case TYPE_ENUMERATED:
    1045                 :         23 :               len2 =
    1046                 :         23 :                 asn1_get_length_der (der + counter, len - counter, &len3);
    1047         [ -  + ]:         23 :               if (len2 < 0)
    1048                 :            :                 {
    1049                 :          0 :                   result = ASN1_DER_ERROR;
    1050                 :          0 :                   goto cleanup;
    1051                 :            :                 }
    1052                 :            : 
    1053                 :         23 :               _asn1_set_value (p, der + counter, len3 + len2);
    1054                 :         23 :               counter += len3 + len2;
    1055                 :         23 :               move = RIGHT;
    1056                 :         23 :               break;
    1057                 :            :             case TYPE_OBJECT_ID:
    1058                 :         26 :               result =
    1059                 :         26 :                 _asn1_get_objectid_der (der + counter, len - counter, &len2,
    1060                 :            :                                         temp, sizeof (temp));
    1061         [ -  + ]:         26 :               if (result != ASN1_SUCCESS)
    1062                 :          0 :                 goto cleanup;
    1063                 :            : 
    1064                 :         26 :               tlen = strlen (temp);
    1065         [ +  - ]:         26 :               if (tlen > 0)
    1066                 :         26 :                 _asn1_set_value (p, temp, tlen + 1);
    1067                 :         26 :               counter += len2;
    1068                 :         26 :               move = RIGHT;
    1069                 :         26 :               break;
    1070                 :            :             case TYPE_TIME:
    1071                 :          4 :               result =
    1072                 :          4 :                 _asn1_get_time_der (der + counter, len - counter, &len2, temp,
    1073                 :            :                                     sizeof (temp) - 1);
    1074         [ -  + ]:          4 :               if (result != ASN1_SUCCESS)
    1075                 :          0 :                 goto cleanup;
    1076                 :            : 
    1077                 :          4 :               tlen = strlen (temp);
    1078         [ +  - ]:          4 :               if (tlen > 0)
    1079                 :          4 :                 _asn1_set_value (p, temp, tlen + 1);
    1080                 :          4 :               counter += len2;
    1081                 :          4 :               move = RIGHT;
    1082                 :          4 :               break;
    1083                 :            :             case TYPE_OCTET_STRING:
    1084                 :         10 :               len3 = len - counter;
    1085                 :         10 :               result = _asn1_get_octet_string (der + counter, p, &len3);
    1086         [ -  + ]:         10 :               if (result != ASN1_SUCCESS)
    1087                 :          0 :                 goto cleanup;
    1088                 :            : 
    1089                 :         10 :               counter += len3;
    1090                 :         10 :               move = RIGHT;
    1091                 :         10 :               break;
    1092                 :            :             case TYPE_GENERALSTRING:
    1093                 :          2 :               len2 =
    1094                 :          2 :                 asn1_get_length_der (der + counter, len - counter, &len3);
    1095         [ -  + ]:          2 :               if (len2 < 0)
    1096                 :            :                 {
    1097                 :          0 :                   result = ASN1_DER_ERROR;
    1098                 :          0 :                   goto cleanup;
    1099                 :            :                 }
    1100                 :            : 
    1101                 :          2 :               _asn1_set_value (p, der + counter, len3 + len2);
    1102                 :          2 :               counter += len3 + len2;
    1103                 :          2 :               move = RIGHT;
    1104                 :          2 :               break;
    1105                 :            :             case TYPE_BIT_STRING:
    1106                 :          3 :               len2 =
    1107                 :          3 :                 asn1_get_length_der (der + counter, len - counter, &len3);
    1108         [ -  + ]:          3 :               if (len2 < 0)
    1109                 :            :                 {
    1110                 :          0 :                   result = ASN1_DER_ERROR;
    1111                 :          0 :                   goto cleanup;
    1112                 :            :                 }
    1113                 :            : 
    1114                 :          3 :               _asn1_set_value (p, der + counter, len3 + len2);
    1115                 :          3 :               counter += len3 + len2;
    1116                 :          3 :               move = RIGHT;
    1117                 :          3 :               break;
    1118                 :            :             case TYPE_SEQUENCE:
    1119                 :            :             case TYPE_SET:
    1120         [ +  + ]:         83 :               if (move == UP)
    1121                 :            :                 {
    1122                 :         41 :                   len2 = _asn1_strtol (p->value, NULL, 10);
    1123                 :         41 :                   _asn1_set_value (p, NULL, 0);
    1124         [ +  + ]:         41 :                   if (len2 == -1)
    1125                 :            :                     {           /* indefinite length method */
    1126         [ +  - ]:          3 :                       if (len - counter + 1 > 0)
    1127                 :            :                         {
    1128 [ +  - ][ -  + ]:          3 :                           if ((der[counter]) || der[counter + 1])
    1129                 :            :                             {
    1130                 :          0 :                               result = ASN1_DER_ERROR;
    1131                 :          0 :                               goto cleanup;
    1132                 :            :                             }
    1133                 :            :                         }
    1134                 :            :                       else
    1135                 :            :                         {
    1136                 :          0 :                           result = ASN1_DER_ERROR;
    1137                 :          0 :                           goto cleanup;
    1138                 :            :                         }
    1139                 :          3 :                       counter += 2;
    1140                 :            :                     }
    1141                 :            :                   else
    1142                 :            :                     {           /* definite length method */
    1143         [ -  + ]:         38 :                       if (len2 != counter)
    1144                 :            :                         {
    1145                 :          0 :                           result = ASN1_DER_ERROR;
    1146                 :          0 :                           goto cleanup;
    1147                 :            :                         }
    1148                 :            :                     }
    1149                 :         41 :                   move = RIGHT;
    1150                 :            :                 }
    1151                 :            :               else
    1152                 :            :                 {               /* move==DOWN || move==RIGHT */
    1153                 :         42 :                   len3 =
    1154                 :         42 :                     asn1_get_length_der (der + counter, len - counter, &len2);
    1155         [ -  + ]:         42 :                   if (len3 < -1)
    1156                 :            :                     {
    1157                 :          0 :                       result = ASN1_DER_ERROR;
    1158                 :          0 :                       goto cleanup;
    1159                 :            :                     }
    1160                 :         42 :                   counter += len2;
    1161         [ +  + ]:         42 :                   if (len3 > 0)
    1162                 :            :                     {
    1163                 :         38 :                       _asn1_ltostr (counter + len3, temp);
    1164                 :         38 :                       tlen = strlen (temp);
    1165         [ +  - ]:         38 :                       if (tlen > 0)
    1166                 :         38 :                         _asn1_set_value (p, temp, tlen + 1);
    1167                 :         38 :                       move = DOWN;
    1168                 :            :                     }
    1169         [ +  + ]:          4 :                   else if (len3 == 0)
    1170                 :            :                     {
    1171                 :          1 :                       p2 = p->down;
    1172         [ +  + ]:          3 :                       while (p2)
    1173                 :            :                         {
    1174         [ +  + ]:          2 :                           if (type_field (p2->type) != TYPE_TAG)
    1175                 :            :                             {
    1176                 :          1 :                               p3 = p2->right;
    1177                 :          1 :                               asn1_delete_structure (&p2);
    1178                 :          1 :                               p2 = p3;
    1179                 :            :                             }
    1180                 :            :                           else
    1181                 :          1 :                             p2 = p2->right;
    1182                 :            :                         }
    1183                 :          1 :                       move = RIGHT;
    1184                 :            :                     }
    1185                 :            :                   else
    1186                 :            :                     {           /* indefinite length method */
    1187                 :          3 :                       _asn1_set_value (p, "-1", 3);
    1188                 :          3 :                       move = DOWN;
    1189                 :            :                     }
    1190                 :            :                 }
    1191                 :         83 :               break;
    1192                 :            :             case TYPE_SEQUENCE_OF:
    1193                 :            :             case TYPE_SET_OF:
    1194         [ +  + ]:         44 :               if (move == UP)
    1195                 :            :                 {
    1196                 :         28 :                   len2 = _asn1_strtol (p->value, NULL, 10);
    1197         [ +  + ]:         28 :                   if (len2 == -1)
    1198                 :            :                     {           /* indefinite length method */
    1199         [ -  + ]:          2 :                       if ((counter + 2) > len)
    1200                 :            :                         {
    1201                 :          0 :                           result = ASN1_DER_ERROR;
    1202                 :          0 :                           goto cleanup;
    1203                 :            :                         }
    1204                 :            : 
    1205 [ +  + ][ -  + ]:          2 :                       if ((der[counter]) || der[counter + 1])
    1206                 :            :                         {
    1207                 :          1 :                           _asn1_append_sequence_set (p);
    1208                 :          1 :                           p = p->down;
    1209         [ +  + ]:          3 :                           while (p->right)
    1210                 :          2 :                             p = p->right;
    1211                 :          1 :                           move = RIGHT;
    1212                 :          1 :                           continue;
    1213                 :            :                         }
    1214                 :          1 :                       _asn1_set_value (p, NULL, 0);
    1215                 :          1 :                       counter += 2;
    1216                 :            :                     }
    1217                 :            :                   else
    1218                 :            :                     {           /* definite length method */
    1219         [ +  + ]:         26 :                       if (len2 > counter)
    1220                 :            :                         {
    1221                 :         13 :                           _asn1_append_sequence_set (p);
    1222                 :         13 :                           p = p->down;
    1223         [ +  + ]:         70 :                           while (p->right)
    1224                 :         57 :                             p = p->right;
    1225                 :         13 :                           move = RIGHT;
    1226                 :         13 :                           continue;
    1227                 :            :                         }
    1228                 :         13 :                       _asn1_set_value (p, NULL, 0);
    1229         [ -  + ]:         13 :                       if (len2 != counter)
    1230                 :            :                         {
    1231                 :          0 :                           result = ASN1_DER_ERROR;
    1232                 :          0 :                           goto cleanup;
    1233                 :            :                         }
    1234                 :            :                     }
    1235                 :            :                 }
    1236                 :            :               else
    1237                 :            :                 {               /* move==DOWN || move==RIGHT */
    1238                 :         16 :                   len3 =
    1239                 :         16 :                     asn1_get_length_der (der + counter, len - counter, &len2);
    1240         [ -  + ]:         16 :                   if (len3 < -1)
    1241                 :            :                     {
    1242                 :          0 :                       result = ASN1_DER_ERROR;
    1243                 :          0 :                       goto cleanup;
    1244                 :            :                     }
    1245                 :         16 :                   counter += len2;
    1246         [ +  + ]:         16 :                   if (len3)
    1247                 :            :                     {
    1248         [ +  + ]:         14 :                       if (len3 > 0)
    1249                 :            :                         {       /* definite length method */
    1250                 :         13 :                           _asn1_ltostr (counter + len3, temp);
    1251                 :         13 :                           tlen = strlen (temp);
    1252                 :            : 
    1253         [ +  - ]:         13 :                           if (tlen > 0)
    1254                 :         13 :                             _asn1_set_value (p, temp, tlen + 1);
    1255                 :            :                         }
    1256                 :            :                       else
    1257                 :            :                         {       /* indefinite length method */
    1258                 :          1 :                           _asn1_set_value (p, "-1", 3);
    1259                 :            :                         }
    1260                 :         14 :                       p2 = p->down;
    1261         [ +  + ]:         24 :                       while ((type_field (p2->type) == TYPE_TAG)
    1262         [ +  + ]:         22 :                              || (type_field (p2->type) == TYPE_SIZE))
    1263                 :         10 :                         p2 = p2->right;
    1264         [ +  + ]:         14 :                       if (p2->right == NULL)
    1265                 :         13 :                         _asn1_append_sequence_set (p);
    1266                 :         14 :                       p = p2;
    1267                 :            :                     }
    1268                 :            :                 }
    1269                 :         30 :               move = RIGHT;
    1270                 :         30 :               break;
    1271                 :            :             case TYPE_ANY:
    1272         [ -  + ]:         20 :               if (asn1_get_tag_der
    1273                 :         20 :                   (der + counter, len - counter, &class, &len2,
    1274                 :            :                    &tag) != ASN1_SUCCESS)
    1275                 :            :                 {
    1276                 :          0 :                   result = ASN1_DER_ERROR;
    1277                 :          0 :                   goto cleanup;
    1278                 :            :                 }
    1279                 :            : 
    1280         [ -  + ]:         20 :               if (counter + len2 > len)
    1281                 :            :                 {
    1282                 :          0 :                   result = ASN1_DER_ERROR;
    1283                 :          0 :                   goto cleanup;
    1284                 :            :                 }
    1285                 :         20 :               len4 =
    1286                 :         20 :                 asn1_get_length_der (der + counter + len2,
    1287                 :         20 :                                      len - counter - len2, &len3);
    1288         [ -  + ]:         20 :               if (len4 < -1)
    1289                 :            :                 {
    1290                 :          0 :                   result = ASN1_DER_ERROR;
    1291                 :          0 :                   goto cleanup;
    1292                 :            :                 }
    1293         [ +  + ]:         20 :               if (len4 != -1)
    1294                 :            :                 {
    1295                 :         19 :                   len2 += len4;
    1296                 :         19 :                   _asn1_set_value_octet (p, der + counter, len2 + len3);
    1297                 :         19 :                   counter += len2 + len3;
    1298                 :            :                 }
    1299                 :            :               else
    1300                 :            :                 {               /* indefinite length */
    1301                 :            :                   /* Check indefinite lenth method in an EXPLICIT TAG */
    1302 [ +  - ][ +  - ]:          1 :                   if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
    1303                 :          1 :                     indefinite = 1;
    1304                 :            :                   else
    1305                 :          0 :                     indefinite = 0;
    1306                 :            : 
    1307                 :          1 :                   len2 = len - counter;
    1308                 :          1 :                   result =
    1309                 :          1 :                     _asn1_get_indefinite_length_string (der + counter, &len2);
    1310         [ -  + ]:          1 :                   if (result != ASN1_SUCCESS)
    1311                 :          0 :                     goto cleanup;
    1312                 :            : 
    1313                 :          1 :                   _asn1_set_value_octet (p, der + counter, len2);
    1314                 :          1 :                   counter += len2;
    1315                 :            : 
    1316                 :            :                   /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
    1317                 :            :                      an indefinite length method. */
    1318         [ +  - ]:          1 :                   if (indefinite)
    1319                 :            :                     {
    1320 [ +  - ][ +  - ]:          1 :                       if (!der[counter] && !der[counter + 1])
    1321                 :            :                         {
    1322                 :          1 :                           counter += 2;
    1323                 :            :                         }
    1324                 :            :                       else
    1325                 :            :                         {
    1326                 :          0 :                           result = ASN1_DER_ERROR;
    1327                 :          0 :                           goto cleanup;
    1328                 :            :                         }
    1329                 :            :                     }
    1330                 :            :                 }
    1331                 :         20 :               move = RIGHT;
    1332                 :         20 :               break;
    1333                 :            :             default:
    1334         [ +  + ]:          8 :               move = (move == UP) ? RIGHT : DOWN;
    1335                 :          8 :               break;
    1336                 :            :             }
    1337                 :            :         }
    1338                 :            : 
    1339 [ +  + ][ +  + ]:        219 :       if (p == node && move != DOWN)
    1340                 :         18 :         break;
    1341                 :            : 
    1342         [ +  + ]:        201 :       if (move == DOWN)
    1343                 :            :         {
    1344         [ +  + ]:         43 :           if (p->down)
    1345                 :         41 :             p = p->down;
    1346                 :            :           else
    1347                 :          2 :             move = RIGHT;
    1348                 :            :         }
    1349 [ +  + ][ +  - ]:        201 :       if ((move == RIGHT) && !(p->type & CONST_SET))
    1350                 :            :         {
    1351         [ +  + ]:        160 :           if (p->right)
    1352                 :         89 :             p = p->right;
    1353                 :            :           else
    1354                 :         71 :             move = UP;
    1355                 :            :         }
    1356         [ +  + ]:        201 :       if (move == UP)
    1357                 :         71 :         p = _asn1_find_up (p);
    1358                 :        219 :     }
    1359                 :            : 
    1360                 :         18 :   _asn1_delete_not_used (*element);
    1361                 :            : 
    1362         [ -  + ]:         18 :   if (counter != len)
    1363                 :            :     {
    1364                 :          0 :       result = ASN1_DER_ERROR;
    1365                 :          0 :       goto cleanup;
    1366                 :            :     }
    1367                 :            : 
    1368                 :         18 :   return ASN1_SUCCESS;
    1369                 :            : 
    1370                 :            : cleanup:
    1371                 :          0 :   asn1_delete_structure (element);
    1372                 :         18 :   return result;
    1373                 :            : }
    1374                 :            : 
    1375                 :            : #define FOUND        1
    1376                 :            : #define SAME_BRANCH  2
    1377                 :            : #define OTHER_BRANCH 3
    1378                 :            : #define EXIT         4
    1379                 :            : 
    1380                 :            : /**
    1381                 :            :  * asn1_der_decoding_element:
    1382                 :            :  * @structure: pointer to an ASN1 structure
    1383                 :            :  * @elementName: name of the element to fill
    1384                 :            :  * @ider: vector that contains the DER encoding of the whole structure.
    1385                 :            :  * @len: number of bytes of *der: der[0]..der[len-1]
    1386                 :            :  * @errorDescription: null-terminated string contains details when an
    1387                 :            :  *   error occurred.
    1388                 :            :  *
    1389                 :            :  * Fill the element named @ELEMENTNAME with values of a DER encoding
    1390                 :            :  * string.  The structure must just be created with function
    1391                 :            :  * asn1_create_element().  The DER vector must contain the encoding
    1392                 :            :  * string of the whole @STRUCTURE.  If an error occurs during the
    1393                 :            :  * decoding procedure, the *@STRUCTURE is deleted and set equal to
    1394                 :            :  * %ASN1_TYPE_EMPTY.
    1395                 :            :  *
    1396                 :            :  * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
    1397                 :            :  *   if ELEMENT is %ASN1_TYPE_EMPTY or @elementName == NULL, and
    1398                 :            :  *   %ASN1_TAG_ERROR or %ASN1_DER_ERROR if the der encoding doesn't
    1399                 :            :  *   match the structure @structure (*ELEMENT deleted).
    1400                 :            :  **/
    1401                 :            : asn1_retCode
    1402                 :          3 : asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
    1403                 :            :                            const void *ider, int len, char *errorDescription)
    1404                 :            : {
    1405                 :          3 :   ASN1_TYPE node, p, p2, p3, nodeFound = ASN1_TYPE_EMPTY;
    1406                 :            :   char temp[128], currentName[ASN1_MAX_NAME_SIZE * 10], *dot_p, *char_p;
    1407                 :          3 :   int nameLen = ASN1_MAX_NAME_SIZE * 10 - 1, state;
    1408                 :            :   int counter, len2, len3, len4, move, ris, tlen;
    1409                 :            :   unsigned char class;
    1410                 :            :   unsigned long tag;
    1411                 :            :   int indefinite, result;
    1412                 :          3 :   const unsigned char *der = ider;
    1413                 :            : 
    1414                 :          3 :   node = *structure;
    1415                 :            : 
    1416         [ -  + ]:          3 :   if (node == ASN1_TYPE_EMPTY)
    1417                 :          0 :     return ASN1_ELEMENT_NOT_FOUND;
    1418                 :            : 
    1419         [ -  + ]:          3 :   if (elementName == NULL)
    1420                 :            :     {
    1421                 :          0 :       result = ASN1_ELEMENT_NOT_FOUND;
    1422                 :          0 :       goto cleanup;
    1423                 :            :     }
    1424                 :            : 
    1425         [ -  + ]:          3 :   if (node->type & CONST_OPTION)
    1426                 :            :     {
    1427                 :          0 :       result = ASN1_GENERIC_ERROR;
    1428                 :          0 :       goto cleanup;
    1429                 :            :     }
    1430                 :            : 
    1431         [ -  + ]:          3 :   if ((*structure)->name)
    1432                 :            :     {                           /* Has *structure got a name? */
    1433                 :          0 :       nameLen -= strlen ((*structure)->name);
    1434         [ #  # ]:          0 :       if (nameLen > 0)
    1435                 :          0 :         strcpy (currentName, (*structure)->name);
    1436                 :            :       else
    1437                 :            :         {
    1438                 :          0 :           result = ASN1_MEM_ERROR;
    1439                 :          0 :           goto cleanup;
    1440                 :            :         }
    1441         [ #  # ]:          0 :       if (!(strcmp (currentName, elementName)))
    1442                 :            :         {
    1443                 :          0 :           state = FOUND;
    1444                 :          0 :           nodeFound = *structure;
    1445                 :            :         }
    1446         [ #  # ]:          0 :       else if (!memcmp (currentName, elementName, strlen (currentName)))
    1447                 :          0 :         state = SAME_BRANCH;
    1448                 :            :       else
    1449                 :          0 :         state = OTHER_BRANCH;
    1450                 :            :     }
    1451                 :            :   else
    1452                 :            :     {                           /* *structure doesn't have a name? */
    1453                 :          3 :       currentName[0] = 0;
    1454         [ -  + ]:          3 :       if (elementName[0] == 0)
    1455                 :            :         {
    1456                 :          0 :           state = FOUND;
    1457                 :          0 :           nodeFound = *structure;
    1458                 :            :         }
    1459                 :            :       else
    1460                 :            :         {
    1461                 :          3 :           state = SAME_BRANCH;
    1462                 :            :         }
    1463                 :            :     }
    1464                 :            : 
    1465                 :          3 :   counter = 0;
    1466                 :          3 :   move = DOWN;
    1467                 :          3 :   p = node;
    1468                 :            :   while (1)
    1469                 :            :     {
    1470                 :            : 
    1471                 :          8 :       ris = ASN1_SUCCESS;
    1472                 :            : 
    1473         [ +  - ]:          8 :       if (move != UP)
    1474                 :            :         {
    1475         [ -  + ]:          8 :           if (p->type & CONST_SET)
    1476                 :            :             {
    1477                 :          0 :               p2 = _asn1_find_up (p);
    1478                 :          0 :               len2 = _asn1_strtol (p2->value, NULL, 10);
    1479         [ #  # ]:          0 :               if (counter == len2)
    1480                 :            :                 {
    1481                 :          0 :                   p = p2;
    1482                 :          0 :                   move = UP;
    1483                 :          0 :                   continue;
    1484                 :            :                 }
    1485         [ #  # ]:          0 :               else if (counter > len2)
    1486                 :            :                 {
    1487                 :          0 :                   result = ASN1_DER_ERROR;
    1488                 :          0 :                   goto cleanup;
    1489                 :            :                 }
    1490                 :          0 :               p2 = p2->down;
    1491         [ #  # ]:          0 :               while (p2)
    1492                 :            :                 {
    1493 [ #  # ][ #  # ]:          0 :                   if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
    1494                 :            :                     {
    1495         [ #  # ]:          0 :                       if (type_field (p2->type) != TYPE_CHOICE)
    1496                 :          0 :                         ris =
    1497                 :          0 :                           _asn1_extract_tag_der (p2, der + counter,
    1498                 :            :                                                  len - counter, &len2);
    1499                 :            :                       else
    1500                 :            :                         {
    1501                 :          0 :                           p3 = p2->down;
    1502         [ #  # ]:          0 :                           while (p3)
    1503                 :            :                             {
    1504                 :          0 :                               ris =
    1505                 :          0 :                                 _asn1_extract_tag_der (p3, der + counter,
    1506                 :            :                                                        len - counter, &len2);
    1507         [ #  # ]:          0 :                               if (ris == ASN1_SUCCESS)
    1508                 :          0 :                                 break;
    1509                 :          0 :                               p3 = p3->right;
    1510                 :            :                             }
    1511                 :            :                         }
    1512         [ #  # ]:          0 :                       if (ris == ASN1_SUCCESS)
    1513                 :            :                         {
    1514                 :          0 :                           p2->type &= ~CONST_NOT_USED;
    1515                 :          0 :                           p = p2;
    1516                 :          0 :                           break;
    1517                 :            :                         }
    1518                 :            :                     }
    1519                 :          0 :                   p2 = p2->right;
    1520                 :            :                 }
    1521         [ #  # ]:          0 :               if (p2 == NULL)
    1522                 :            :                 {
    1523                 :          0 :                   result = ASN1_DER_ERROR;
    1524                 :          0 :                   goto cleanup;
    1525                 :            :                 }
    1526                 :            :             }
    1527                 :            : 
    1528 [ +  - ][ +  + ]:          8 :           if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
    1529                 :            :             {
    1530                 :          1 :               p2 = _asn1_find_up (p);
    1531                 :          1 :               len2 = _asn1_strtol (p2->value, NULL, 10);
    1532         [ -  + ]:          1 :               if (counter == len2)
    1533                 :            :                 {
    1534         [ #  # ]:          0 :                   if (p->right)
    1535                 :            :                     {
    1536                 :          0 :                       p2 = p->right;
    1537                 :          0 :                       move = RIGHT;
    1538                 :            :                     }
    1539                 :            :                   else
    1540                 :          0 :                     move = UP;
    1541                 :            : 
    1542         [ #  # ]:          0 :                   if (p->type & CONST_OPTION)
    1543                 :          0 :                     asn1_delete_structure (&p);
    1544                 :            : 
    1545                 :          0 :                   p = p2;
    1546                 :          0 :                   continue;
    1547                 :            :                 }
    1548                 :            :             }
    1549                 :            : 
    1550         [ -  + ]:          8 :           if (type_field (p->type) == TYPE_CHOICE)
    1551                 :            :             {
    1552         [ #  # ]:          0 :               while (p->down)
    1553                 :            :                 {
    1554         [ #  # ]:          0 :                   if (counter < len)
    1555                 :          0 :                     ris =
    1556                 :          0 :                       _asn1_extract_tag_der (p->down, der + counter,
    1557                 :            :                                              len - counter, &len2);
    1558                 :            :                   else
    1559                 :          0 :                     ris = ASN1_DER_ERROR;
    1560         [ #  # ]:          0 :                   if (ris == ASN1_SUCCESS)
    1561                 :            :                     {
    1562         [ #  # ]:          0 :                       while (p->down->right)
    1563                 :            :                         {
    1564                 :          0 :                           p2 = p->down->right;
    1565                 :          0 :                           asn1_delete_structure (&p2);
    1566                 :            :                         }
    1567                 :          0 :                       break;
    1568                 :            :                     }
    1569         [ #  # ]:          0 :                   else if (ris == ASN1_ERROR_TYPE_ANY)
    1570                 :            :                     {
    1571                 :          0 :                       result = ASN1_ERROR_TYPE_ANY;
    1572                 :          0 :                       goto cleanup;
    1573                 :            :                     }
    1574                 :            :                   else
    1575                 :            :                     {
    1576                 :          0 :                       p2 = p->down;
    1577                 :          0 :                       asn1_delete_structure (&p2);
    1578                 :            :                     }
    1579                 :            :                 }
    1580                 :            : 
    1581         [ #  # ]:          0 :               if (p->down == NULL)
    1582                 :            :                 {
    1583         [ #  # ]:          0 :                   if (!(p->type & CONST_OPTION))
    1584                 :            :                     {
    1585                 :          0 :                       result = ASN1_DER_ERROR;
    1586                 :          0 :                       goto cleanup;
    1587                 :            :                     }
    1588                 :            :                 }
    1589                 :            :               else
    1590                 :          0 :                 p = p->down;
    1591                 :            :             }
    1592                 :            : 
    1593 [ +  - ][ +  + ]:          8 :           if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
    1594                 :            :             {
    1595                 :          1 :               p2 = _asn1_find_up (p);
    1596                 :          1 :               len2 = _asn1_strtol (p2->value, NULL, 10);
    1597         [ -  + ]:          1 :               if (counter > len2)
    1598                 :          0 :                 ris = ASN1_TAG_ERROR;
    1599                 :            :             }
    1600                 :            : 
    1601         [ +  - ]:          8 :           if (ris == ASN1_SUCCESS)
    1602                 :          8 :             ris =
    1603                 :          8 :               _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
    1604         [ +  + ]:          8 :           if (ris != ASN1_SUCCESS)
    1605                 :            :             {
    1606         [ -  + ]:          1 :               if (p->type & CONST_OPTION)
    1607                 :            :                 {
    1608                 :          0 :                   p->type |= CONST_NOT_USED;
    1609                 :          0 :                   move = RIGHT;
    1610                 :            :                 }
    1611         [ +  - ]:          1 :               else if (p->type & CONST_DEFAULT)
    1612                 :            :                 {
    1613                 :          1 :                   _asn1_set_value (p, NULL, 0);
    1614                 :          1 :                   move = RIGHT;
    1615                 :            :                 }
    1616                 :            :               else
    1617                 :            :                 {
    1618         [ #  # ]:          0 :                   if (errorDescription != NULL)
    1619                 :          0 :                     _asn1_error_description_tag_error (p, errorDescription);
    1620                 :            : 
    1621                 :          0 :                   result = ASN1_TAG_ERROR;
    1622                 :          0 :                   goto cleanup;
    1623                 :            :                 }
    1624                 :            :             }
    1625                 :            :           else
    1626                 :          7 :             counter += len2;
    1627                 :            :         }
    1628                 :            : 
    1629         [ +  + ]:          8 :       if (ris == ASN1_SUCCESS)
    1630                 :            :         {
    1631   [ -  -  +  -  :          7 :           switch (type_field (p->type))
          -  +  +  -  +  
                -  -  - ]
    1632                 :            :             {
    1633                 :            :             case TYPE_NULL:
    1634         [ #  # ]:          0 :               if (der[counter])
    1635                 :            :                 {
    1636                 :          0 :                   result = ASN1_DER_ERROR;
    1637                 :          0 :                   goto cleanup;
    1638                 :            :                 }
    1639                 :            : 
    1640         [ #  # ]:          0 :               if (p == nodeFound)
    1641                 :          0 :                 state = EXIT;
    1642                 :            : 
    1643                 :          0 :               counter++;
    1644                 :          0 :               move = RIGHT;
    1645                 :          0 :               break;
    1646                 :            :             case TYPE_BOOLEAN:
    1647         [ #  # ]:          0 :               if (der[counter++] != 1)
    1648                 :            :                 {
    1649                 :          0 :                   result = ASN1_DER_ERROR;
    1650                 :          0 :                   goto cleanup;
    1651                 :            :                 }
    1652                 :            : 
    1653         [ #  # ]:          0 :               if (state == FOUND)
    1654                 :            :                 {
    1655         [ #  # ]:          0 :                   if (der[counter++] == 0)
    1656                 :          0 :                     _asn1_set_value (p, "F", 1);
    1657                 :            :                   else
    1658                 :          0 :                     _asn1_set_value (p, "T", 1);
    1659                 :            : 
    1660         [ #  # ]:          0 :                   if (p == nodeFound)
    1661                 :          0 :                     state = EXIT;
    1662                 :            : 
    1663                 :            :                 }
    1664                 :            :               else
    1665                 :          0 :                 counter++;
    1666                 :            : 
    1667                 :          0 :               move = RIGHT;
    1668                 :          0 :               break;
    1669                 :            :             case TYPE_INTEGER:
    1670                 :            :             case TYPE_ENUMERATED:
    1671                 :          2 :               len2 =
    1672                 :          2 :                 asn1_get_length_der (der + counter, len - counter, &len3);
    1673         [ -  + ]:          2 :               if (len2 < 0)
    1674                 :            :                 {
    1675                 :          0 :                   result = ASN1_DER_ERROR;
    1676                 :          0 :                   goto cleanup;
    1677                 :            :                 }
    1678                 :            : 
    1679         [ +  + ]:          2 :               if (state == FOUND)
    1680                 :            :                 {
    1681         [ -  + ]:          1 :                   if (len3 + len2 > len - counter)
    1682                 :            :                     {
    1683                 :          0 :                       result = ASN1_DER_ERROR;
    1684                 :          0 :                       goto cleanup;
    1685                 :            :                     }
    1686                 :          1 :                   _asn1_set_value (p, der + counter, len3 + len2);
    1687                 :            : 
    1688         [ +  - ]:          1 :                   if (p == nodeFound)
    1689                 :          1 :                     state = EXIT;
    1690                 :            :                 }
    1691                 :          2 :               counter += len3 + len2;
    1692                 :          2 :               move = RIGHT;
    1693                 :          2 :               break;
    1694                 :            :             case TYPE_OBJECT_ID:
    1695         [ #  # ]:          0 :               if (state == FOUND)
    1696                 :            :                 {
    1697                 :          0 :                   result =
    1698                 :          0 :                     _asn1_get_objectid_der (der + counter, len - counter,
    1699                 :            :                                             &len2, temp, sizeof (temp));
    1700         [ #  # ]:          0 :                   if (result != ASN1_SUCCESS)
    1701                 :          0 :                     goto cleanup;
    1702                 :            : 
    1703                 :          0 :                   tlen = strlen (temp);
    1704                 :            : 
    1705         [ #  # ]:          0 :                   if (tlen > 0)
    1706                 :          0 :                     _asn1_set_value (p, temp, tlen + 1);
    1707                 :            : 
    1708         [ #  # ]:          0 :                   if (p == nodeFound)
    1709                 :          0 :                     state = EXIT;
    1710                 :            :                 }
    1711                 :            :               else
    1712                 :            :                 {
    1713                 :          0 :                   len2 =
    1714                 :          0 :                     asn1_get_length_der (der + counter, len - counter, &len3);
    1715         [ #  # ]:          0 :                   if (len2 < 0)
    1716                 :            :                     {
    1717                 :          0 :                       result = ASN1_DER_ERROR;
    1718                 :          0 :                       goto cleanup;
    1719                 :            :                     }
    1720                 :          0 :                   len2 += len3;
    1721                 :            :                 }
    1722                 :            : 
    1723                 :          0 :               counter += len2;
    1724                 :          0 :               move = RIGHT;
    1725                 :          0 :               break;
    1726                 :            :             case TYPE_TIME:
    1727         [ #  # ]:          0 :               if (state == FOUND)
    1728                 :            :                 {
    1729                 :          0 :                   result =
    1730                 :          0 :                     _asn1_get_time_der (der + counter, len - counter, &len2,
    1731                 :            :                                         temp, sizeof (temp) - 1);
    1732         [ #  # ]:          0 :                   if (result != ASN1_SUCCESS)
    1733                 :          0 :                     goto cleanup;
    1734                 :            : 
    1735                 :          0 :                   tlen = strlen (temp);
    1736         [ #  # ]:          0 :                   if (tlen > 0)
    1737                 :          0 :                     _asn1_set_value (p, temp, tlen + 1);
    1738                 :            : 
    1739         [ #  # ]:          0 :                   if (p == nodeFound)
    1740                 :          0 :                     state = EXIT;
    1741                 :            :                 }
    1742                 :            :               else
    1743                 :            :                 {
    1744                 :          0 :                   len2 =
    1745                 :          0 :                     asn1_get_length_der (der + counter, len - counter, &len3);
    1746         [ #  # ]:          0 :                   if (len2 < 0)
    1747                 :            :                     {
    1748                 :          0 :                       result = ASN1_DER_ERROR;
    1749                 :          0 :                       goto cleanup;
    1750                 :            :                     }
    1751                 :          0 :                   len2 += len3;
    1752                 :            :                 }
    1753                 :            : 
    1754                 :          0 :               counter += len2;
    1755                 :          0 :               move = RIGHT;
    1756                 :          0 :               break;
    1757                 :            :             case TYPE_OCTET_STRING:
    1758                 :          1 :               len3 = len - counter;
    1759         [ +  - ]:          1 :               if (state == FOUND)
    1760                 :            :                 {
    1761                 :          1 :                   result = _asn1_get_octet_string (der + counter, p, &len3);
    1762         [ +  - ]:          1 :                   if (p == nodeFound)
    1763                 :          1 :                     state = EXIT;
    1764                 :            :                 }
    1765                 :            :               else
    1766                 :          0 :                 result = _asn1_get_octet_string (der + counter, NULL, &len3);
    1767                 :            : 
    1768         [ -  + ]:          1 :               if (result != ASN1_SUCCESS)
    1769                 :          0 :                 goto cleanup;
    1770                 :            : 
    1771                 :          1 :               counter += len3;
    1772                 :          1 :               move = RIGHT;
    1773                 :          1 :               break;
    1774                 :            :             case TYPE_GENERALSTRING:
    1775                 :          1 :               len2 =
    1776                 :          1 :                 asn1_get_length_der (der + counter, len - counter, &len3);
    1777         [ -  + ]:          1 :               if (len2 < 0)
    1778                 :            :                 {
    1779                 :          0 :                   result = ASN1_DER_ERROR;
    1780                 :          0 :                   goto cleanup;
    1781                 :            :                 }
    1782                 :            : 
    1783         [ +  - ]:          1 :               if (state == FOUND)
    1784                 :            :                 {
    1785         [ -  + ]:          1 :                   if (len3 + len2 > len - counter)
    1786                 :            :                     {
    1787                 :          0 :                       result = ASN1_DER_ERROR;
    1788                 :          0 :                       goto cleanup;
    1789                 :            :                     }
    1790                 :          1 :                   _asn1_set_value (p, der + counter, len3 + len2);
    1791                 :            : 
    1792         [ +  - ]:          1 :                   if (p == nodeFound)
    1793                 :          1 :                     state = EXIT;
    1794                 :            :                 }
    1795                 :          1 :               counter += len3 + len2;
    1796                 :          1 :               move = RIGHT;
    1797                 :          1 :               break;
    1798                 :            :             case TYPE_BIT_STRING:
    1799                 :          0 :               len2 =
    1800                 :          0 :                 asn1_get_length_der (der + counter, len - counter, &len3);
    1801         [ #  # ]:          0 :               if (len2 < 0)
    1802                 :            :                 {
    1803                 :          0 :                   result = ASN1_DER_ERROR;
    1804                 :          0 :                   goto cleanup;
    1805                 :            :                 }
    1806         [ #  # ]:          0 :               if (state == FOUND)
    1807                 :            :                 {
    1808         [ #  # ]:          0 :                   if (len3 + len2 > len - counter)
    1809                 :            :                     {
    1810                 :          0 :                       result = ASN1_DER_ERROR;
    1811                 :          0 :                       goto cleanup;
    1812                 :            :                     }
    1813                 :          0 :                   _asn1_set_value (p, der + counter, len3 + len2);
    1814                 :            : 
    1815         [ #  # ]:          0 :                   if (p == nodeFound)
    1816                 :          0 :                     state = EXIT;
    1817                 :            :                 }
    1818                 :          0 :               counter += len3 + len2;
    1819                 :          0 :               move = RIGHT;
    1820                 :          0 :               break;
    1821                 :            :             case TYPE_SEQUENCE:
    1822                 :            :             case TYPE_SET:
    1823         [ -  + ]:          3 :               if (move == UP)
    1824                 :            :                 {
    1825                 :          0 :                   len2 = _asn1_strtol (p->value, NULL, 10);
    1826                 :          0 :                   _asn1_set_value (p, NULL, 0);
    1827         [ #  # ]:          0 :                   if (len2 == -1)
    1828                 :            :                     {           /* indefinite length method */
    1829 [ #  # ][ #  # ]:          0 :                       if ((der[counter]) || der[counter + 1])
    1830                 :            :                         {
    1831                 :          0 :                           result = ASN1_DER_ERROR;
    1832                 :          0 :                           goto cleanup;
    1833                 :            :                         }
    1834                 :          0 :                       counter += 2;
    1835                 :            :                     }
    1836                 :            :                   else
    1837                 :            :                     {           /* definite length method */
    1838         [ #  # ]:          0 :                       if (len2 != counter)
    1839                 :            :                         {
    1840                 :          0 :                           result = ASN1_DER_ERROR;
    1841                 :          0 :                           goto cleanup;
    1842                 :            :                         }
    1843                 :            :                     }
    1844         [ #  # ]:          0 :                   if (p == nodeFound)
    1845                 :          0 :                     state = EXIT;
    1846                 :          0 :                   move = RIGHT;
    1847                 :            :                 }
    1848                 :            :               else
    1849                 :            :                 {               /* move==DOWN || move==RIGHT */
    1850         [ -  + ]:          3 :                   if (state == OTHER_BRANCH)
    1851                 :            :                     {
    1852                 :          0 :                       len3 =
    1853                 :          0 :                         asn1_get_length_der (der + counter, len - counter,
    1854                 :            :                                              &len2);
    1855         [ #  # ]:          0 :                       if (len3 < 0)
    1856                 :            :                         {
    1857                 :          0 :                           result = ASN1_DER_ERROR;
    1858                 :          0 :                           goto cleanup;
    1859                 :            :                         }
    1860                 :          0 :                       counter += len2 + len3;
    1861                 :          0 :                       move = RIGHT;
    1862                 :            :                     }
    1863                 :            :                   else
    1864                 :            :                     {           /*  state==SAME_BRANCH or state==FOUND */
    1865                 :          3 :                       len3 =
    1866                 :          3 :                         asn1_get_length_der (der + counter, len - counter,
    1867                 :            :                                              &len2);
    1868         [ -  + ]:          3 :                       if (len3 < 0)
    1869                 :            :                         {
    1870                 :          0 :                           result = ASN1_DER_ERROR;
    1871                 :          0 :                           goto cleanup;
    1872                 :            :                         }
    1873                 :          3 :                       counter += len2;
    1874         [ +  - ]:          3 :                       if (len3 > 0)
    1875                 :            :                         {
    1876                 :          3 :                           _asn1_ltostr (counter + len3, temp);
    1877                 :          3 :                           tlen = strlen (temp);
    1878                 :            : 
    1879         [ +  - ]:          3 :                           if (tlen > 0)
    1880                 :          3 :                             _asn1_set_value (p, temp, tlen + 1);
    1881                 :          3 :                           move = DOWN;
    1882                 :            :                         }
    1883         [ #  # ]:          0 :                       else if (len3 == 0)
    1884                 :            :                         {
    1885                 :          0 :                           p2 = p->down;
    1886         [ #  # ]:          0 :                           while (p2)
    1887                 :            :                             {
    1888         [ #  # ]:          0 :                               if (type_field (p2->type) != TYPE_TAG)
    1889                 :            :                                 {
    1890                 :          0 :                                   p3 = p2->right;
    1891                 :          0 :                                   asn1_delete_structure (&p2);
    1892                 :          0 :                                   p2 = p3;
    1893                 :            :                                 }
    1894                 :            :                               else
    1895                 :          0 :                                 p2 = p2->right;
    1896                 :            :                             }
    1897                 :          0 :                           move = RIGHT;
    1898                 :            :                         }
    1899                 :            :                       else
    1900                 :            :                         {       /* indefinite length method */
    1901                 :          0 :                           _asn1_set_value (p, "-1", 3);
    1902                 :          0 :                           move = DOWN;
    1903                 :            :                         }
    1904                 :            :                     }
    1905                 :            :                 }
    1906                 :          3 :               break;
    1907                 :            :             case TYPE_SEQUENCE_OF:
    1908                 :            :             case TYPE_SET_OF:
    1909         [ #  # ]:          0 :               if (move == UP)
    1910                 :            :                 {
    1911                 :          0 :                   len2 = _asn1_strtol (p->value, NULL, 10);
    1912         [ #  # ]:          0 :                   if (len2 > counter)
    1913                 :            :                     {
    1914                 :          0 :                       _asn1_append_sequence_set (p);
    1915                 :          0 :                       p = p->down;
    1916         [ #  # ]:          0 :                       while (p->right)
    1917                 :          0 :                         p = p->right;
    1918                 :          0 :                       move = RIGHT;
    1919                 :          0 :                       continue;
    1920                 :            :                     }
    1921                 :          0 :                   _asn1_set_value (p, NULL, 0);
    1922         [ #  # ]:          0 :                   if (len2 != counter)
    1923                 :            :                     {
    1924                 :          0 :                       result = ASN1_DER_ERROR;
    1925                 :          0 :                       goto cleanup;
    1926                 :            :                     }
    1927                 :            : 
    1928         [ #  # ]:          0 :                   if (p == nodeFound)
    1929                 :          0 :                     state = EXIT;
    1930                 :            :                 }
    1931                 :            :               else
    1932                 :            :                 {               /* move==DOWN || move==RIGHT */
    1933         [ #  # ]:          0 :                   if (state == OTHER_BRANCH)
    1934                 :            :                     {
    1935                 :          0 :                       len3 =
    1936                 :          0 :                         asn1_get_length_der (der + counter, len - counter,
    1937                 :            :                                              &len2);
    1938         [ #  # ]:          0 :                       if (len3 < 0)
    1939                 :            :                         {
    1940                 :          0 :                           result = ASN1_DER_ERROR;
    1941                 :          0 :                           goto cleanup;
    1942                 :            :                         }
    1943                 :          0 :                       counter += len2 + len3;
    1944                 :          0 :                       move = RIGHT;
    1945                 :            :                     }
    1946                 :            :                   else
    1947                 :            :                     {           /* state==FOUND or state==SAME_BRANCH */
    1948                 :          0 :                       len3 =
    1949                 :          0 :                         asn1_get_length_der (der + counter, len - counter,
    1950                 :            :                                              &len2);
    1951         [ #  # ]:          0 :                       if (len3 < 0)
    1952                 :            :                         {
    1953                 :          0 :                           result = ASN1_DER_ERROR;
    1954                 :          0 :                           goto cleanup;
    1955                 :            :                         }
    1956                 :          0 :                       counter += len2;
    1957         [ #  # ]:          0 :                       if (len3)
    1958                 :            :                         {
    1959                 :          0 :                           _asn1_ltostr (counter + len3, temp);
    1960                 :          0 :                           tlen = strlen (temp);
    1961                 :            : 
    1962         [ #  # ]:          0 :                           if (tlen > 0)
    1963                 :          0 :                             _asn1_set_value (p, temp, tlen + 1);
    1964                 :          0 :                           p2 = p->down;
    1965         [ #  # ]:          0 :                           while ((type_field (p2->type) == TYPE_TAG)
    1966         [ #  # ]:          0 :                                  || (type_field (p2->type) == TYPE_SIZE))
    1967                 :          0 :                             p2 = p2->right;
    1968         [ #  # ]:          0 :                           if (p2->right == NULL)
    1969                 :          0 :                             _asn1_append_sequence_set (p);
    1970                 :          0 :                           p = p2;
    1971                 :          0 :                           state = FOUND;
    1972                 :            :                         }
    1973                 :            :                     }
    1974                 :            :                 }
    1975                 :            : 
    1976                 :          0 :               break;
    1977                 :            :             case TYPE_ANY:
    1978         [ #  # ]:          0 :               if (asn1_get_tag_der
    1979                 :          0 :                   (der + counter, len - counter, &class, &len2,
    1980                 :            :                    &tag) != ASN1_SUCCESS)
    1981                 :            :                 {
    1982                 :          0 :                   result = ASN1_DER_ERROR;
    1983                 :          0 :                   goto cleanup;
    1984                 :            :                 }
    1985                 :            : 
    1986         [ #  # ]:          0 :               if (counter + len2 > len)
    1987                 :            :                 {
    1988                 :          0 :                   result = ASN1_DER_ERROR;
    1989                 :          0 :                   goto cleanup;
    1990                 :            :                 }
    1991                 :            : 
    1992                 :          0 :               len4 =
    1993                 :          0 :                 asn1_get_length_der (der + counter + len2,
    1994                 :          0 :                                      len - counter - len2, &len3);
    1995         [ #  # ]:          0 :               if (len4 < -1)
    1996                 :            :                 {
    1997                 :          0 :                   result = ASN1_DER_ERROR;
    1998                 :          0 :                   goto cleanup;
    1999                 :            :                 }
    2000                 :            : 
    2001         [ #  # ]:          0 :               if (len4 != -1)
    2002                 :            :                 {
    2003                 :          0 :                   len2 += len4;
    2004         [ #  # ]:          0 :                   if (state == FOUND)
    2005                 :            :                     {
    2006                 :          0 :                       _asn1_set_value_octet (p, der + counter, len2 + len3);
    2007                 :            : 
    2008         [ #  # ]:          0 :                       if (p == nodeFound)
    2009                 :          0 :                         state = EXIT;
    2010                 :            :                     }
    2011                 :          0 :                   counter += len2 + len3;
    2012                 :            :                 }
    2013                 :            :               else
    2014                 :            :                 {               /* indefinite length */
    2015                 :            :                   /* Check indefinite lenth method in an EXPLICIT TAG */
    2016 [ #  # ][ #  # ]:          0 :                   if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
    2017                 :          0 :                     indefinite = 1;
    2018                 :            :                   else
    2019                 :          0 :                     indefinite = 0;
    2020                 :            : 
    2021                 :          0 :                   len2 = len - counter;
    2022                 :          0 :                   result =
    2023                 :          0 :                     _asn1_get_indefinite_length_string (der + counter, &len2);
    2024         [ #  # ]:          0 :                   if (result != ASN1_SUCCESS)
    2025                 :          0 :                     goto cleanup;
    2026                 :            : 
    2027         [ #  # ]:          0 :                   if (state == FOUND)
    2028                 :            :                     {
    2029                 :          0 :                       _asn1_set_value_octet (p, der + counter, len2);
    2030                 :            : 
    2031         [ #  # ]:          0 :                       if (p == nodeFound)
    2032                 :          0 :                         state = EXIT;
    2033                 :            :                     }
    2034                 :            : 
    2035                 :          0 :                   counter += len2;
    2036                 :            : 
    2037                 :            :                   /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
    2038                 :            :                      an indefinite length method. */
    2039         [ #  # ]:          0 :                   if (indefinite)
    2040                 :            :                     {
    2041 [ #  # ][ #  # ]:          0 :                       if (!der[counter] && !der[counter + 1])
    2042                 :            :                         {
    2043                 :          0 :                           counter += 2;
    2044                 :            :                         }
    2045                 :            :                       else
    2046                 :            :                         {
    2047                 :          0 :                           result = ASN1_DER_ERROR;
    2048                 :          0 :                           goto cleanup;
    2049                 :            :                         }
    2050                 :            :                     }
    2051                 :            :                 }
    2052                 :          0 :               move = RIGHT;
    2053                 :          0 :               break;
    2054                 :            : 
    2055                 :            :             default:
    2056         [ #  # ]:          0 :               move = (move == UP) ? RIGHT : DOWN;
    2057                 :          0 :               break;
    2058                 :            :             }
    2059                 :            :         }
    2060                 :            : 
    2061 [ +  + ][ +  - ]:          8 :       if ((p == node && move != DOWN) || (state == EXIT))
                 [ +  + ]
    2062                 :            :         break;
    2063                 :            : 
    2064         [ +  + ]:          5 :       if (move == DOWN)
    2065                 :            :         {
    2066         [ +  - ]:          3 :           if (p->down)
    2067                 :            :             {
    2068                 :          3 :               p = p->down;
    2069                 :            : 
    2070         [ +  - ]:          3 :               if (state != FOUND)
    2071                 :            :                 {
    2072                 :          3 :                   nameLen -= strlen (p->name) + 1;
    2073         [ +  - ]:          3 :                   if (nameLen > 0)
    2074                 :            :                     {
    2075         [ -  + ]:          3 :                       if (currentName[0])
    2076                 :          0 :                         strcat (currentName, ".");
    2077                 :          3 :                       strcat (currentName, p->name);
    2078                 :            :                     }
    2079                 :            :                   else
    2080                 :            :                     {
    2081                 :          0 :                       result = ASN1_MEM_ERROR;
    2082                 :          0 :                       goto cleanup;
    2083                 :            :                     }
    2084         [ +  + ]:          3 :                   if (!(strcmp (currentName, elementName)))
    2085                 :            :                     {
    2086                 :          1 :                       state = FOUND;
    2087                 :          1 :                       nodeFound = p;
    2088                 :            :                     }
    2089                 :            :                   else
    2090         [ -  + ]:          2 :                     if (!memcmp
    2091                 :          2 :                         (currentName, elementName, strlen (currentName)))
    2092                 :          0 :                     state = SAME_BRANCH;
    2093                 :            :                   else
    2094                 :          2 :                     state = OTHER_BRANCH;
    2095                 :            :                 }
    2096                 :            :             }
    2097                 :            :           else
    2098                 :          0 :             move = RIGHT;
    2099                 :            :         }
    2100                 :            : 
    2101 [ +  + ][ +  - ]:          5 :       if ((move == RIGHT) && !(p->type & CONST_SET))
    2102                 :            :         {
    2103         [ +  - ]:          2 :           if (p->right)
    2104                 :            :             {
    2105                 :          2 :               p = p->right;
    2106                 :            : 
    2107         [ +  - ]:          2 :               if (state != FOUND)
    2108                 :            :                 {
    2109                 :          2 :                   dot_p = char_p = currentName;
    2110         [ -  + ]:          2 :                   while ((char_p = strchr (char_p, '.')))
    2111                 :            :                     {
    2112                 :          0 :                       dot_p = char_p++;
    2113                 :          0 :                       dot_p++;
    2114                 :            :                     }
    2115                 :            : 
    2116                 :          2 :                   nameLen += strlen (currentName) - (dot_p - currentName);
    2117                 :          2 :                   *dot_p = 0;
    2118                 :            : 
    2119                 :          2 :                   nameLen -= strlen (p->name);
    2120         [ +  - ]:          2 :                   if (nameLen > 0)
    2121                 :          2 :                     strcat (currentName, p->name);
    2122                 :            :                   else
    2123                 :            :                     {
    2124                 :          0 :                       result = ASN1_MEM_ERROR;
    2125                 :          0 :                       goto cleanup;
    2126                 :            :                     }
    2127                 :            : 
    2128         [ +  - ]:          2 :                   if (!(strcmp (currentName, elementName)))
    2129                 :            :                     {
    2130                 :          2 :                       state = FOUND;
    2131                 :          2 :                       nodeFound = p;
    2132                 :            :                     }
    2133                 :            :                   else
    2134         [ #  # ]:          0 :                     if (!memcmp
    2135                 :          0 :                         (currentName, elementName, strlen (currentName)))
    2136                 :          0 :                     state = SAME_BRANCH;
    2137                 :            :                   else
    2138                 :          0 :                     state = OTHER_BRANCH;
    2139                 :            :                 }
    2140                 :            :             }
    2141                 :            :           else
    2142                 :          0 :             move = UP;
    2143                 :            :         }
    2144                 :            : 
    2145         [ -  + ]:          5 :       if (move == UP)
    2146                 :            :         {
    2147                 :          0 :           p = _asn1_find_up (p);
    2148                 :            : 
    2149         [ #  # ]:          0 :           if (state != FOUND)
    2150                 :            :             {
    2151                 :          0 :               dot_p = char_p = currentName;
    2152         [ #  # ]:          0 :               while ((char_p = strchr (char_p, '.')))
    2153                 :            :                 {
    2154                 :          0 :                   dot_p = char_p++;
    2155                 :          0 :                   dot_p++;
    2156                 :            :                 }
    2157                 :            : 
    2158                 :          0 :               nameLen += strlen (currentName) - (dot_p - currentName);
    2159                 :          0 :               *dot_p = 0;
    2160                 :            : 
    2161         [ #  # ]:          0 :               if (!(strcmp (currentName, elementName)))
    2162                 :            :                 {
    2163                 :          0 :                   state = FOUND;
    2164                 :          0 :                   nodeFound = p;
    2165                 :            :                 }
    2166                 :            :               else
    2167         [ #  # ]:          0 :                 if (!memcmp (currentName, elementName, strlen (currentName)))
    2168                 :          0 :                 state = SAME_BRANCH;
    2169                 :            :               else
    2170                 :          0 :                 state = OTHER_BRANCH;
    2171                 :            :             }
    2172                 :            :         }
    2173                 :          5 :     }
    2174                 :            : 
    2175                 :          3 :   _asn1_delete_not_used (*structure);
    2176                 :            : 
    2177         [ -  + ]:          3 :   if (counter > len)
    2178                 :            :     {
    2179                 :          0 :       result = ASN1_DER_ERROR;
    2180                 :          0 :       goto cleanup;
    2181                 :            :     }
    2182                 :            : 
    2183                 :          3 :   return ASN1_SUCCESS;
    2184                 :            : 
    2185                 :            : cleanup:
    2186                 :          0 :   asn1_delete_structure (structure);
    2187                 :          3 :   return result;
    2188                 :            : }
    2189                 :            : 
    2190                 :            : /**
    2191                 :            :  * asn1_der_decoding_startEnd:
    2192                 :            :  * @element: pointer to an ASN1 element
    2193                 :            :  * @ider: vector that contains the DER encoding.
    2194                 :            :  * @len: number of bytes of *@ider: @ider[0]..@ider[len-1]
    2195                 :            :  * @name_element: an element of NAME structure.
    2196                 :            :  * @start: the position of the first byte of NAME_ELEMENT decoding
    2197                 :            :  *   (@ider[*start])
    2198                 :            :  * @end: the position of the last byte of NAME_ELEMENT decoding
    2199                 :            :  *  (@ider[*end])
    2200                 :            :  *
    2201                 :            :  * Find the start and end point of an element in a DER encoding
    2202                 :            :  * string. I mean that if you have a der encoding and you have already
    2203                 :            :  * used the function asn1_der_decoding() to fill a structure, it may
    2204                 :            :  * happen that you want to find the piece of string concerning an
    2205                 :            :  * element of the structure.
    2206                 :            :  *
    2207                 :            :  * One example is the sequence "tbsCertificate" inside an X509
    2208                 :            :  * certificate.
    2209                 :            :  *
    2210                 :            :  * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
    2211                 :            :  *   if ELEMENT is %ASN1_TYPE EMPTY or @name_element is not a valid
    2212                 :            :  *   element, %ASN1_TAG_ERROR or %ASN1_DER_ERROR if the der encoding
    2213                 :            :  *   doesn't match the structure ELEMENT.
    2214                 :            :  **/
    2215                 :            : asn1_retCode
    2216                 :         14 : asn1_der_decoding_startEnd (ASN1_TYPE element, const void *ider, int len,
    2217                 :            :                             const char *name_element, int *start, int *end)
    2218                 :            : {
    2219                 :            :   ASN1_TYPE node, node_to_find, p, p2, p3;
    2220                 :            :   int counter, len2, len3, len4, move, ris;
    2221                 :            :   unsigned char class;
    2222                 :            :   unsigned long tag;
    2223                 :            :   int indefinite;
    2224                 :         14 :   const unsigned char *der = ider;
    2225                 :            : 
    2226                 :         14 :   node = element;
    2227                 :            : 
    2228         [ -  + ]:         14 :   if (node == ASN1_TYPE_EMPTY)
    2229                 :          0 :     return ASN1_ELEMENT_NOT_FOUND;
    2230                 :            : 
    2231                 :         14 :   node_to_find = asn1_find_node (node, name_element);
    2232                 :            : 
    2233         [ -  + ]:         14 :   if (node_to_find == NULL)
    2234                 :          0 :     return ASN1_ELEMENT_NOT_FOUND;
    2235                 :            : 
    2236         [ +  + ]:         14 :   if (node_to_find == node)
    2237                 :            :     {
    2238                 :          2 :       *start = 0;
    2239                 :          2 :       *end = len - 1;
    2240                 :          2 :       return ASN1_SUCCESS;
    2241                 :            :     }
    2242                 :            : 
    2243         [ -  + ]:         12 :   if (node->type & CONST_OPTION)
    2244                 :          0 :     return ASN1_GENERIC_ERROR;
    2245                 :            : 
    2246                 :         12 :   counter = 0;
    2247                 :         12 :   move = DOWN;
    2248                 :         12 :   p = node;
    2249                 :            :   while (1)
    2250                 :            :     {
    2251                 :         59 :       ris = ASN1_SUCCESS;
    2252                 :            : 
    2253         [ +  + ]:         59 :       if (move != UP)
    2254                 :            :         {
    2255         [ -  + ]:         53 :           if (p->type & CONST_SET)
    2256                 :            :             {
    2257                 :          0 :               p2 = _asn1_find_up (p);
    2258                 :          0 :               len2 = _asn1_strtol (p2->value, NULL, 10);
    2259         [ #  # ]:          0 :               if (len2 == -1)
    2260                 :            :                 {
    2261 [ #  # ][ #  # ]:          0 :                   if (!der[counter] && !der[counter + 1])
    2262                 :            :                     {
    2263                 :          0 :                       p = p2;
    2264                 :          0 :                       move = UP;
    2265                 :          0 :                       counter += 2;
    2266                 :          0 :                       continue;
    2267                 :            :                     }
    2268                 :            :                 }
    2269         [ #  # ]:          0 :               else if (counter == len2)
    2270                 :            :                 {
    2271                 :          0 :                   p = p2;
    2272                 :          0 :                   move = UP;
    2273                 :          0 :                   continue;
    2274                 :            :                 }
    2275         [ #  # ]:          0 :               else if (counter > len2)
    2276                 :          0 :                 return ASN1_DER_ERROR;
    2277                 :          0 :               p2 = p2->down;
    2278         [ #  # ]:          0 :               while (p2)
    2279                 :            :                 {
    2280 [ #  # ][ #  # ]:          0 :                   if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
    2281                 :            :                     {           /* CONTROLLARE */
    2282         [ #  # ]:          0 :                       if (type_field (p2->type) != TYPE_CHOICE)
    2283                 :          0 :                         ris =
    2284                 :          0 :                           _asn1_extract_tag_der (p2, der + counter,
    2285                 :            :                                                  len - counter, &len2);
    2286                 :            :                       else
    2287                 :            :                         {
    2288                 :          0 :                           p3 = p2->down;
    2289                 :          0 :                           ris =
    2290                 :          0 :                             _asn1_extract_tag_der (p3, der + counter,
    2291                 :            :                                                    len - counter, &len2);
    2292                 :            :                         }
    2293         [ #  # ]:          0 :                       if (ris == ASN1_SUCCESS)
    2294                 :            :                         {
    2295                 :          0 :                           p2->type &= ~CONST_NOT_USED;
    2296                 :          0 :                           p = p2;
    2297                 :          0 :                           break;
    2298                 :            :                         }
    2299                 :            :                     }
    2300                 :          0 :                   p2 = p2->right;
    2301                 :            :                 }
    2302         [ #  # ]:          0 :               if (p2 == NULL)
    2303                 :          0 :                 return ASN1_DER_ERROR;
    2304                 :            :             }
    2305                 :            : 
    2306         [ +  + ]:         53 :           if (p == node_to_find)
    2307                 :         12 :             *start = counter;
    2308                 :            : 
    2309         [ -  + ]:         53 :           if (type_field (p->type) == TYPE_CHOICE)
    2310                 :            :             {
    2311                 :          0 :               p = p->down;
    2312                 :          0 :               ris =
    2313                 :          0 :                 _asn1_extract_tag_der (p, der + counter, len - counter,
    2314                 :            :                                        &len2);
    2315         [ #  # ]:          0 :               if (p == node_to_find)
    2316                 :          0 :                 *start = counter;
    2317                 :            :             }
    2318                 :            : 
    2319         [ +  - ]:         53 :           if (ris == ASN1_SUCCESS)
    2320                 :         53 :             ris =
    2321                 :         53 :               _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
    2322         [ +  + ]:         53 :           if (ris != ASN1_SUCCESS)
    2323                 :            :             {
    2324         [ -  + ]:          4 :               if (p->type & CONST_OPTION)
    2325                 :            :                 {
    2326                 :          0 :                   p->type |= CONST_NOT_USED;
    2327                 :          0 :                   move = RIGHT;
    2328                 :            :                 }
    2329         [ +  - ]:          4 :               else if (p->type & CONST_DEFAULT)
    2330                 :            :                 {
    2331                 :          4 :                   move = RIGHT;
    2332                 :            :                 }
    2333                 :            :               else
    2334                 :            :                 {
    2335                 :          0 :                   return ASN1_TAG_ERROR;
    2336                 :            :                 }
    2337                 :            :             }
    2338                 :            :           else
    2339                 :         49 :             counter += len2;
    2340                 :            :         }
    2341                 :            : 
    2342         [ +  + ]:         59 :       if (ris == ASN1_SUCCESS)
    2343                 :            :         {
    2344   [ -  -  +  +  :         55 :           switch (type_field (p->type))
          -  -  -  -  +  
                +  -  + ]
    2345                 :            :             {
    2346                 :            :             case TYPE_NULL:
    2347         [ #  # ]:          0 :               if (der[counter])
    2348                 :          0 :                 return ASN1_DER_ERROR;
    2349                 :          0 :               counter++;
    2350                 :          0 :               move = RIGHT;
    2351                 :          0 :               break;
    2352                 :            :             case TYPE_BOOLEAN:
    2353         [ #  # ]:          0 :               if (der[counter++] != 1)
    2354                 :          0 :                 return ASN1_DER_ERROR;
    2355                 :          0 :               counter++;
    2356                 :          0 :               move = RIGHT;
    2357                 :          0 :               break;
    2358                 :            :             case TYPE_INTEGER:
    2359                 :            :             case TYPE_ENUMERATED:
    2360                 :         12 :               len2 =
    2361                 :         12 :                 asn1_get_length_der (der + counter, len - counter, &len3);
    2362         [ -  + ]:         12 :               if (len2 < 0)
    2363                 :          0 :                 return ASN1_DER_ERROR;
    2364                 :         12 :               counter += len3 + len2;
    2365                 :         12 :               move = RIGHT;
    2366                 :         12 :               break;
    2367                 :            :             case TYPE_OBJECT_ID:
    2368                 :          7 :               len2 =
    2369                 :          7 :                 asn1_get_length_der (der + counter, len - counter, &len3);
    2370         [ -  + ]:          7 :               if (len2 < 0)
    2371                 :          0 :                 return ASN1_DER_ERROR;
    2372                 :          7 :               counter += len2 + len3;
    2373                 :          7 :               move = RIGHT;
    2374                 :          7 :               break;
    2375                 :            :             case TYPE_TIME:
    2376                 :          0 :               len2 =
    2377                 :          0 :                 asn1_get_length_der (der + counter, len - counter, &len3);
    2378         [ #  # ]:          0 :               if (len2 < 0)
    2379                 :          0 :                 return ASN1_DER_ERROR;
    2380                 :          0 :               counter += len2 + len3;
    2381                 :          0 :               move = RIGHT;
    2382                 :          0 :               break;
    2383                 :            :             case TYPE_OCTET_STRING:
    2384                 :          0 :               len3 = len - counter;
    2385                 :          0 :               ris = _asn1_get_octet_string (der + counter, NULL, &len3);
    2386         [ #  # ]:          0 :               if (ris != ASN1_SUCCESS)
    2387                 :          0 :                 return ris;
    2388                 :          0 :               counter += len3;
    2389                 :          0 :               move = RIGHT;
    2390                 :          0 :               break;
    2391                 :            :             case TYPE_GENERALSTRING:
    2392                 :          0 :               len2 =
    2393                 :          0 :                 asn1_get_length_der (der + counter, len - counter, &len3);
    2394         [ #  # ]:          0 :               if (len2 < 0)
    2395                 :          0 :                 return ASN1_DER_ERROR;
    2396                 :          0 :               counter += len3 + len2;
    2397                 :          0 :               move = RIGHT;
    2398                 :          0 :               break;
    2399                 :            :             case TYPE_BIT_STRING:
    2400                 :          0 :               len2 =
    2401                 :          0 :                 asn1_get_length_der (der + counter, len - counter, &len3);
    2402         [ #  # ]:          0 :               if (len2 < 0)
    2403                 :          0 :                 return ASN1_DER_ERROR;
    2404                 :          0 :               counter += len3 + len2;
    2405                 :          0 :               move = RIGHT;
    2406                 :          0 :               break;
    2407                 :            :             case TYPE_SEQUENCE:
    2408                 :            :             case TYPE_SET:
    2409         [ +  + ]:         24 :               if (move != UP)
    2410                 :            :                 {
    2411                 :         20 :                   len3 =
    2412                 :         20 :                     asn1_get_length_der (der + counter, len - counter, &len2);
    2413         [ -  + ]:         20 :                   if (len3 < -1)
    2414                 :          0 :                     return ASN1_DER_ERROR;
    2415                 :         20 :                   counter += len2;
    2416         [ +  + ]:         20 :                   if (len3 == 0)
    2417                 :          4 :                     move = RIGHT;
    2418                 :            :                   else
    2419                 :         16 :                     move = DOWN;
    2420                 :            :                 }
    2421                 :            :               else
    2422                 :            :                 {
    2423 [ +  - ][ +  - ]:          4 :                   if (!der[counter] && !der[counter + 1])       /* indefinite length method */
    2424                 :          4 :                     counter += 2;
    2425                 :          4 :                   move = RIGHT;
    2426                 :            :                 }
    2427                 :         24 :               break;
    2428                 :            :             case TYPE_SEQUENCE_OF:
    2429                 :            :             case TYPE_SET_OF:
    2430         [ +  + ]:          8 :               if (move != UP)
    2431                 :            :                 {
    2432                 :          6 :                   len3 =
    2433                 :          6 :                     asn1_get_length_der (der + counter, len - counter, &len2);
    2434         [ -  + ]:          6 :                   if (len3 < -1)
    2435                 :          0 :                     return ASN1_DER_ERROR;
    2436                 :          6 :                   counter += len2;
    2437 [ +  + ][ -  + ]:          6 :                   if ((len3 == -1) && !der[counter] && !der[counter + 1])
                 [ #  # ]
    2438                 :          0 :                     counter += 2;
    2439         [ +  + ]:          6 :                   else if (len3)
    2440                 :            :                     {
    2441                 :          3 :                       p2 = p->down;
    2442 [ -  + ][ -  + ]:          3 :                       while ((type_field (p2->type) == TYPE_TAG) ||
    2443                 :          3 :                              (type_field (p2->type) == TYPE_SIZE))
    2444                 :          0 :                         p2 = p2->right;
    2445                 :          6 :                       p = p2;
    2446                 :            :                     }
    2447                 :            :                 }
    2448                 :            :               else
    2449                 :            :                 {
    2450 [ +  - ][ +  - ]:          2 :                   if (!der[counter] && !der[counter + 1])       /* indefinite length method */
    2451                 :          2 :                     counter += 2;
    2452                 :            :                 }
    2453                 :          8 :               move = RIGHT;
    2454                 :          8 :               break;
    2455                 :            :             case TYPE_ANY:
    2456         [ #  # ]:          0 :               if (asn1_get_tag_der
    2457                 :          0 :                   (der + counter, len - counter, &class, &len2,
    2458                 :            :                    &tag) != ASN1_SUCCESS)
    2459                 :          0 :                 return ASN1_DER_ERROR;
    2460         [ #  # ]:          0 :               if (counter + len2 > len)
    2461                 :          0 :                 return ASN1_DER_ERROR;
    2462                 :            : 
    2463                 :          0 :               len4 =
    2464                 :          0 :                 asn1_get_length_der (der + counter + len2,
    2465                 :          0 :                                      len - counter - len2, &len3);
    2466         [ #  # ]:          0 :               if (len4 < -1)
    2467                 :          0 :                 return ASN1_DER_ERROR;
    2468                 :            : 
    2469         [ #  # ]:          0 :               if (len4 != -1)
    2470                 :            :                 {
    2471                 :          0 :                   counter += len2 + len4 + len3;
    2472                 :            :                 }
    2473                 :            :               else
    2474                 :            :                 {               /* indefinite length */
    2475                 :            :                   /* Check indefinite lenth method in an EXPLICIT TAG */
    2476 [ #  # ][ #  # ]:          0 :                   if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
    2477                 :          0 :                     indefinite = 1;
    2478                 :            :                   else
    2479                 :          0 :                     indefinite = 0;
    2480                 :            : 
    2481                 :          0 :                   len2 = len - counter;
    2482                 :          0 :                   ris =
    2483                 :          0 :                     _asn1_get_indefinite_length_string (der + counter, &len2);
    2484         [ #  # ]:          0 :                   if (ris != ASN1_SUCCESS)
    2485                 :          0 :                     return ris;
    2486                 :          0 :                   counter += len2;
    2487                 :            : 
    2488                 :            :                   /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
    2489                 :            :                      an indefinite length method. */
    2490         [ #  # ]:          0 :                   if (indefinite)
    2491                 :            :                     {
    2492 [ #  # ][ #  # ]:          0 :                       if (!der[counter] && !der[counter + 1])
    2493                 :          0 :                         counter += 2;
    2494                 :            :                       else
    2495                 :          0 :                         return ASN1_DER_ERROR;
    2496                 :            :                     }
    2497                 :            :                 }
    2498                 :          0 :               move = RIGHT;
    2499                 :          0 :               break;
    2500                 :            :             default:
    2501         [ -  + ]:          4 :               move = (move == UP) ? RIGHT : DOWN;
    2502                 :          4 :               break;
    2503                 :            :             }
    2504                 :            :         }
    2505                 :            : 
    2506 [ +  + ][ +  + ]:         59 :       if ((p == node_to_find) && (move == RIGHT))
    2507                 :            :         {
    2508                 :         12 :           *end = counter - 1;
    2509                 :         12 :           return ASN1_SUCCESS;
    2510                 :            :         }
    2511                 :            : 
    2512 [ +  + ][ -  + ]:         47 :       if (p == node && move != DOWN)
    2513                 :          0 :         break;
    2514                 :            : 
    2515         [ +  + ]:         47 :       if (move == DOWN)
    2516                 :            :         {
    2517         [ +  + ]:         20 :           if (p->down)
    2518                 :         16 :             p = p->down;
    2519                 :            :           else
    2520                 :          4 :             move = RIGHT;
    2521                 :            :         }
    2522 [ +  + ][ +  - ]:         47 :       if ((move == RIGHT) && !(p->type & CONST_SET))
    2523                 :            :         {
    2524         [ +  + ]:         31 :           if (p->right)
    2525                 :         25 :             p = p->right;
    2526                 :            :           else
    2527                 :          6 :             move = UP;
    2528                 :            :         }
    2529         [ +  + ]:         47 :       if (move == UP)
    2530                 :          6 :         p = _asn1_find_up (p);
    2531                 :         47 :     }
    2532                 :            : 
    2533                 :         14 :   return ASN1_ELEMENT_NOT_FOUND;
    2534                 :            : }
    2535                 :            : 
    2536                 :            : /**
    2537                 :            :  * asn1_expand_any_defined_by:
    2538                 :            :  * @definitions: ASN1 definitions
    2539                 :            :  * @element: pointer to an ASN1 structure
    2540                 :            :  *
    2541                 :            :  * Expands every "ANY DEFINED BY" element of a structure created from
    2542                 :            :  * a DER decoding process (asn1_der_decoding function). The element
    2543                 :            :  * ANY must be defined by an OBJECT IDENTIFIER. The type used to
    2544                 :            :  * expand the element ANY is the first one following the definition of
    2545                 :            :  * the actual value of the OBJECT IDENTIFIER.
    2546                 :            :  *
    2547                 :            :  * Returns: %ASN1_SUCCESS if Substitution OK, %ASN1_ERROR_TYPE_ANY if
    2548                 :            :  *   some "ANY DEFINED BY" element couldn't be expanded due to a
    2549                 :            :  *   problem in OBJECT_ID -> TYPE association, or other error codes
    2550                 :            :  *   depending on DER decoding.
    2551                 :            :  **/
    2552                 :            : asn1_retCode
    2553                 :          1 : asn1_expand_any_defined_by (ASN1_TYPE definitions, ASN1_TYPE * element)
    2554                 :            : {
    2555                 :            :   char definitionsName[ASN1_MAX_NAME_SIZE], name[2 * ASN1_MAX_NAME_SIZE + 1],
    2556                 :            :     value[ASN1_MAX_NAME_SIZE];
    2557                 :          1 :   asn1_retCode retCode = ASN1_SUCCESS, result;
    2558                 :            :   int len, len2, len3;
    2559                 :          1 :   ASN1_TYPE p, p2, p3, aux = ASN1_TYPE_EMPTY;
    2560                 :            :   char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
    2561                 :            : 
    2562 [ +  - ][ -  + ]:          1 :   if ((definitions == ASN1_TYPE_EMPTY) || (*element == ASN1_TYPE_EMPTY))
    2563                 :          0 :     return ASN1_ELEMENT_NOT_FOUND;
    2564                 :            : 
    2565                 :          1 :   strcpy (definitionsName, definitions->name);
    2566                 :          1 :   strcat (definitionsName, ".");
    2567                 :            : 
    2568                 :          1 :   p = *element;
    2569         [ +  + ]:         14 :   while (p)
    2570                 :            :     {
    2571                 :            : 
    2572         [ +  + ]:         13 :       switch (type_field (p->type))
    2573                 :            :         {
    2574                 :            :         case TYPE_ANY:
    2575 [ +  - ][ +  - ]:          1 :           if ((p->type & CONST_DEFINED_BY) && (p->value))
    2576                 :            :             {
    2577                 :            :               /* search the "DEF_BY" element */
    2578                 :          1 :               p2 = p->down;
    2579 [ +  - ][ -  + ]:          1 :               while ((p2) && (type_field (p2->type) != TYPE_CONSTANT))
    2580                 :          0 :                 p2 = p2->right;
    2581                 :            : 
    2582         [ -  + ]:          1 :               if (!p2)
    2583                 :            :                 {
    2584                 :          0 :                   retCode = ASN1_ERROR_TYPE_ANY;
    2585                 :          0 :                   break;
    2586                 :            :                 }
    2587                 :            : 
    2588                 :          1 :               p3 = _asn1_find_up (p);
    2589                 :            : 
    2590         [ -  + ]:          1 :               if (!p3)
    2591                 :            :                 {
    2592                 :          0 :                   retCode = ASN1_ERROR_TYPE_ANY;
    2593                 :          0 :                   break;
    2594                 :            :                 }
    2595                 :            : 
    2596                 :          1 :               p3 = p3->down;
    2597         [ +  - ]:          4 :               while (p3)
    2598                 :            :                 {
    2599 [ +  - ][ +  + ]:          4 :                   if ((p3->name) && !(strcmp (p3->name, p2->name)))
    2600                 :          1 :                     break;
    2601                 :          3 :                   p3 = p3->right;
    2602                 :            :                 }
    2603                 :            : 
    2604 [ +  - ][ +  - ]:          1 :               if ((!p3) || (type_field (p3->type) != TYPE_OBJECT_ID) ||
                 [ -  + ]
    2605                 :          1 :                   (p3->value == NULL))
    2606                 :            :                 {
    2607                 :            : 
    2608                 :          0 :                   p3 = _asn1_find_up (p);
    2609                 :          0 :                   p3 = _asn1_find_up (p3);
    2610                 :            : 
    2611         [ #  # ]:          0 :                   if (!p3)
    2612                 :            :                     {
    2613                 :          0 :                       retCode = ASN1_ERROR_TYPE_ANY;
    2614                 :          0 :                       break;
    2615                 :            :                     }
    2616                 :            : 
    2617                 :          0 :                   p3 = p3->down;
    2618                 :            : 
    2619         [ #  # ]:          0 :                   while (p3)
    2620                 :            :                     {
    2621 [ #  # ][ #  # ]:          0 :                       if ((p3->name) && !(strcmp (p3->name, p2->name)))
    2622                 :          0 :                         break;
    2623                 :          0 :                       p3 = p3->right;
    2624                 :            :                     }
    2625                 :            : 
    2626 [ #  # ][ #  # ]:          0 :                   if ((!p3) || (type_field (p3->type) != TYPE_OBJECT_ID) ||
                 [ #  # ]
    2627                 :          0 :                       (p3->value == NULL))
    2628                 :            :                     {
    2629                 :          0 :                       retCode = ASN1_ERROR_TYPE_ANY;
    2630                 :          0 :                       break;
    2631                 :            :                     }
    2632                 :            :                 }
    2633                 :            : 
    2634                 :            :               /* search the OBJECT_ID into definitions */
    2635                 :          1 :               p2 = definitions->down;
    2636         [ +  - ]:         23 :               while (p2)
    2637                 :            :                 {
    2638 [ +  + ][ +  + ]:         23 :                   if ((type_field (p2->type) == TYPE_OBJECT_ID) &&
    2639                 :          6 :                       (p2->type & CONST_ASSIGN))
    2640                 :            :                     {
    2641                 :          4 :                       strcpy (name, definitionsName);
    2642                 :          4 :                       strcat (name, p2->name);
    2643                 :            : 
    2644                 :          4 :                       len = ASN1_MAX_NAME_SIZE;
    2645                 :          4 :                       result =
    2646                 :            :                         asn1_read_value (definitions, name, value, &len);
    2647                 :            : 
    2648         [ +  - ]:          4 :                       if ((result == ASN1_SUCCESS)
    2649         [ +  + ]:          4 :                           && (!_asn1_strcmp (p3->value, value)))
    2650                 :            :                         {
    2651                 :          1 :                           p2 = p2->right;    /* pointer to the structure to
    2652                 :            :                                                    use for expansion */
    2653 [ +  - ][ -  + ]:          1 :                           while ((p2) && (p2->type & CONST_ASSIGN))
    2654                 :          0 :                             p2 = p2->right;
    2655                 :            : 
    2656         [ +  - ]:          1 :                           if (p2)
    2657                 :            :                             {
    2658                 :          1 :                               strcpy (name, definitionsName);
    2659                 :          1 :                               strcat (name, p2->name);
    2660                 :            : 
    2661                 :          1 :                               result =
    2662                 :            :                                 asn1_create_element (definitions, name, &aux);
    2663         [ +  - ]:          1 :                               if (result == ASN1_SUCCESS)
    2664                 :            :                                 {
    2665                 :          1 :                                   _asn1_set_name (aux, p->name);
    2666                 :          1 :                                   len2 =
    2667                 :          1 :                                     asn1_get_length_der (p->value,
    2668                 :          1 :                                                          p->value_len, &len3);
    2669         [ -  + ]:          1 :                                   if (len2 < 0)
    2670                 :          0 :                                     return ASN1_DER_ERROR;
    2671                 :            : 
    2672                 :          1 :                                   result =
    2673                 :          1 :                                     asn1_der_decoding (&aux, p->value + len3,
    2674                 :            :                                                        len2,
    2675                 :            :                                                        errorDescription);
    2676         [ +  - ]:          1 :                                   if (result == ASN1_SUCCESS)
    2677                 :            :                                     {
    2678                 :            : 
    2679                 :          1 :                                       _asn1_set_right (aux, p->right);
    2680                 :          1 :                                       _asn1_set_right (p, aux);
    2681                 :            : 
    2682                 :          1 :                                       result = asn1_delete_structure (&p);
    2683         [ +  - ]:          1 :                                       if (result == ASN1_SUCCESS)
    2684                 :            :                                         {
    2685                 :          1 :                                           p = aux;
    2686                 :          1 :                                           aux = ASN1_TYPE_EMPTY;
    2687                 :          1 :                                           break;
    2688                 :            :                                         }
    2689                 :            :                                       else
    2690                 :            :                                         {       /* error with asn1_delete_structure */
    2691                 :          0 :                                           asn1_delete_structure (&aux);
    2692                 :          0 :                                           retCode = result;
    2693                 :          0 :                                           break;
    2694                 :            :                                         }
    2695                 :            :                                     }
    2696                 :            :                                   else
    2697                 :            :                                     {   /* error with asn1_der_decoding */
    2698                 :          0 :                                       retCode = result;
    2699                 :          0 :                                       break;
    2700                 :            :                                     }
    2701                 :            :                                 }
    2702                 :            :                               else
    2703                 :            :                                 {       /* error with asn1_create_element */
    2704                 :          0 :                                   retCode = result;
    2705                 :          0 :                                   break;
    2706                 :            :                                 }
    2707                 :            :                             }
    2708                 :            :                           else
    2709                 :            :                             {   /* error with the pointer to the structure to exapand */
    2710                 :          0 :                               retCode = ASN1_ERROR_TYPE_ANY;
    2711                 :          0 :                               break;
    2712                 :            :                             }
    2713                 :            :                         }
    2714                 :            :                     }
    2715                 :         22 :                   p2 = p2->right;
    2716                 :            :                 }               /* end while */
    2717                 :            : 
    2718         [ -  + ]:          1 :               if (!p2)
    2719                 :            :                 {
    2720                 :          0 :                   retCode = ASN1_ERROR_TYPE_ANY;
    2721                 :          0 :                   break;
    2722                 :            :                 }
    2723                 :            : 
    2724                 :            :             }
    2725                 :          1 :           break;
    2726                 :            :         default:
    2727                 :         12 :           break;
    2728                 :            :         }
    2729                 :            : 
    2730                 :            : 
    2731         [ +  + ]:         13 :       if (p->down)
    2732                 :            :         {
    2733                 :          3 :           p = p->down;
    2734                 :            :         }
    2735         [ -  + ]:         10 :       else if (p == *element)
    2736                 :            :         {
    2737                 :          0 :           p = NULL;
    2738                 :          0 :           break;
    2739                 :            :         }
    2740         [ +  + ]:         10 :       else if (p->right)
    2741                 :          7 :         p = p->right;
    2742                 :            :       else
    2743                 :            :         {
    2744                 :            :           while (1)
    2745                 :            :             {
    2746                 :          3 :               p = _asn1_find_up (p);
    2747         [ +  + ]:          3 :               if (p == *element)
    2748                 :            :                 {
    2749                 :          1 :                   p = NULL;
    2750                 :          1 :                   break;
    2751                 :            :                 }
    2752         [ +  - ]:          2 :               if (p->right)
    2753                 :            :                 {
    2754                 :          2 :                   p = p->right;
    2755                 :          2 :                   break;
    2756                 :            :                 }
    2757                 :          0 :             }
    2758                 :            :         }
    2759                 :            :     }
    2760                 :            : 
    2761                 :          1 :   return retCode;
    2762                 :            : }
    2763                 :            : 
    2764                 :            : /**
    2765                 :            :  * asn1_expand_octet_string:
    2766                 :            :  * @definitions: ASN1 definitions
    2767                 :            :  * @element: pointer to an ASN1 structure
    2768                 :            :  * @octetName: name of the OCTECT STRING field to expand.
    2769                 :            :  * @objectName: name of the OBJECT IDENTIFIER field to use to define
    2770                 :            :  *    the type for expansion.
    2771                 :            :  *
    2772                 :            :  * Expands an "OCTET STRING" element of a structure created from a DER
    2773                 :            :  * decoding process (the asn1_der_decoding() function).  The type used
    2774                 :            :  * for expansion is the first one following the definition of the
    2775                 :            :  * actual value of the OBJECT IDENTIFIER indicated by OBJECTNAME.
    2776                 :            :  *
    2777                 :            :  * Returns: %ASN1_SUCCESS if substitution OK, %ASN1_ELEMENT_NOT_FOUND
    2778                 :            :  *   if @objectName or @octetName are not correct,
    2779                 :            :  *   %ASN1_VALUE_NOT_VALID if it wasn't possible to find the type to
    2780                 :            :  *   use for expansion, or other errors depending on DER decoding.
    2781                 :            :  **/
    2782                 :            : asn1_retCode
    2783                 :          2 : asn1_expand_octet_string (ASN1_TYPE definitions, ASN1_TYPE * element,
    2784                 :            :                           const char *octetName, const char *objectName)
    2785                 :            : {
    2786                 :            :   char name[2 * ASN1_MAX_NAME_SIZE + 1], value[ASN1_MAX_NAME_SIZE];
    2787                 :          2 :   asn1_retCode retCode = ASN1_SUCCESS, result;
    2788                 :            :   int len, len2, len3;
    2789                 :          2 :   ASN1_TYPE p2, aux = ASN1_TYPE_EMPTY;
    2790                 :          2 :   ASN1_TYPE octetNode = ASN1_TYPE_EMPTY, objectNode = ASN1_TYPE_EMPTY;
    2791                 :            :   char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
    2792                 :            : 
    2793 [ +  - ][ -  + ]:          2 :   if ((definitions == ASN1_TYPE_EMPTY) || (*element == ASN1_TYPE_EMPTY))
    2794                 :          0 :     return ASN1_ELEMENT_NOT_FOUND;
    2795                 :            : 
    2796                 :          2 :   octetNode = asn1_find_node (*element, octetName);
    2797         [ -  + ]:          2 :   if (octetNode == ASN1_TYPE_EMPTY)
    2798                 :          0 :     return ASN1_ELEMENT_NOT_FOUND;
    2799         [ -  + ]:          2 :   if (type_field (octetNode->type) != TYPE_OCTET_STRING)
    2800                 :          0 :     return ASN1_ELEMENT_NOT_FOUND;
    2801         [ -  + ]:          2 :   if (octetNode->value == NULL)
    2802                 :          0 :     return ASN1_VALUE_NOT_FOUND;
    2803                 :            : 
    2804                 :          2 :   objectNode = asn1_find_node (*element, objectName);
    2805         [ -  + ]:          2 :   if (objectNode == ASN1_TYPE_EMPTY)
    2806                 :          0 :     return ASN1_ELEMENT_NOT_FOUND;
    2807                 :            : 
    2808         [ -  + ]:          2 :   if (type_field (objectNode->type) != TYPE_OBJECT_ID)
    2809                 :          0 :     return ASN1_ELEMENT_NOT_FOUND;
    2810                 :            : 
    2811         [ -  + ]:          2 :   if (objectNode->value == NULL)
    2812                 :          0 :     return ASN1_VALUE_NOT_FOUND;
    2813                 :            : 
    2814                 :            : 
    2815                 :            :   /* search the OBJECT_ID into definitions */
    2816                 :          2 :   p2 = definitions->down;
    2817         [ +  - ]:         41 :   while (p2)
    2818                 :            :     {
    2819 [ +  + ][ +  + ]:         41 :       if ((type_field (p2->type) == TYPE_OBJECT_ID) &&
    2820                 :          9 :           (p2->type & CONST_ASSIGN))
    2821                 :            :         {
    2822                 :          5 :           strcpy (name, definitions->name);
    2823                 :          5 :           strcat (name, ".");
    2824                 :          5 :           strcat (name, p2->name);
    2825                 :            : 
    2826                 :          5 :           len = sizeof (value);
    2827                 :          5 :           result = asn1_read_value (definitions, name, value, &len);
    2828                 :            : 
    2829         [ +  - ]:          5 :           if ((result == ASN1_SUCCESS)
    2830         [ +  + ]:          5 :               && (!_asn1_strcmp (objectNode->value, value)))
    2831                 :            :             {
    2832                 :            : 
    2833                 :          2 :               p2 = p2->right;        /* pointer to the structure to
    2834                 :            :                                    use for expansion */
    2835 [ +  - ][ -  + ]:          2 :               while ((p2) && (p2->type & CONST_ASSIGN))
    2836                 :          0 :                 p2 = p2->right;
    2837                 :            : 
    2838         [ +  - ]:          2 :               if (p2)
    2839                 :            :                 {
    2840                 :          2 :                   strcpy (name, definitions->name);
    2841                 :          2 :                   strcat (name, ".");
    2842                 :          2 :                   strcat (name, p2->name);
    2843                 :            : 
    2844                 :          2 :                   result = asn1_create_element (definitions, name, &aux);
    2845         [ +  - ]:          2 :                   if (result == ASN1_SUCCESS)
    2846                 :            :                     {
    2847                 :          2 :                       _asn1_set_name (aux, octetNode->name);
    2848                 :          2 :                       len2 =
    2849                 :          2 :                         asn1_get_length_der (octetNode->value,
    2850                 :          2 :                                              octetNode->value_len, &len3);
    2851         [ -  + ]:          2 :                       if (len2 < 0)
    2852                 :          0 :                         return ASN1_DER_ERROR;
    2853                 :            : 
    2854                 :          2 :                       result =
    2855                 :          2 :                         asn1_der_decoding (&aux, octetNode->value + len3,
    2856                 :            :                                            len2, errorDescription);
    2857         [ +  - ]:          2 :                       if (result == ASN1_SUCCESS)
    2858                 :            :                         {
    2859                 :            : 
    2860                 :          2 :                           _asn1_set_right (aux, octetNode->right);
    2861                 :          2 :                           _asn1_set_right (octetNode, aux);
    2862                 :            : 
    2863                 :          2 :                           result = asn1_delete_structure (&octetNode);
    2864         [ +  - ]:          2 :                           if (result == ASN1_SUCCESS)
    2865                 :            :                             {
    2866                 :          2 :                               aux = ASN1_TYPE_EMPTY;
    2867                 :          2 :                               break;
    2868                 :            :                             }
    2869                 :            :                           else
    2870                 :            :                             {   /* error with asn1_delete_structure */
    2871                 :          0 :                               asn1_delete_structure (&aux);
    2872                 :          0 :                               retCode = result;
    2873                 :          0 :                               break;
    2874                 :            :                             }
    2875                 :            :                         }
    2876                 :            :                       else
    2877                 :            :                         {       /* error with asn1_der_decoding */
    2878                 :          0 :                           retCode = result;
    2879                 :          0 :                           break;
    2880                 :            :                         }
    2881                 :            :                     }
    2882                 :            :                   else
    2883                 :            :                     {           /* error with asn1_create_element */
    2884                 :          0 :                       retCode = result;
    2885                 :          0 :                       break;
    2886                 :            :                     }
    2887                 :            :                 }
    2888                 :            :               else
    2889                 :            :                 {               /* error with the pointer to the structure to exapand */
    2890                 :          0 :                   retCode = ASN1_VALUE_NOT_VALID;
    2891                 :          0 :                   break;
    2892                 :            :                 }
    2893                 :            :             }
    2894                 :            :         }
    2895                 :            : 
    2896                 :         39 :       p2 = p2->right;
    2897                 :            : 
    2898                 :            :     }
    2899                 :            : 
    2900         [ -  + ]:          2 :   if (!p2)
    2901                 :          0 :     retCode = ASN1_VALUE_NOT_VALID;
    2902                 :            : 
    2903                 :          2 :   return retCode;
    2904                 :            : }

Generated by: LCOV version 1.9