LCOV - code coverage report
Current view: top level - libtasn1-2.x/lib - coding.c (source / functions) Hit Total Coverage
Test: GNU Libtasn1 Lines: 425 564 75.4 %
Date: 2012-09-24 Functions: 10 12 83.3 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 252 347 72.6 %

           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: coding.c                                    */
      25                 :            : /* Description: Functions to create a DER coding of  */
      26                 :            : /*   an ASN1 type.                                   */
      27                 :            : /*****************************************************/
      28                 :            : 
      29                 :            : #include <int.h>
      30                 :            : #include "parser_aux.h"
      31                 :            : #include <gstr.h>
      32                 :            : #include "element.h"
      33                 :            : #include <structure.h>
      34                 :            : 
      35                 :            : #define MAX_TAG_LEN 16
      36                 :            : 
      37                 :            : /******************************************************/
      38                 :            : /* Function : _asn1_error_description_value_not_found */
      39                 :            : /* Description: creates the ErrorDescription string   */
      40                 :            : /* for the ASN1_VALUE_NOT_FOUND error.                */
      41                 :            : /* Parameters:                                        */
      42                 :            : /*   node: node of the tree where the value is NULL.  */
      43                 :            : /*   ErrorDescription: string returned.               */
      44                 :            : /* Return:                                            */
      45                 :            : /******************************************************/
      46                 :            : static void
      47                 :          0 : _asn1_error_description_value_not_found (ASN1_TYPE node,
      48                 :            :                                          char *ErrorDescription)
      49                 :            : {
      50                 :            : 
      51         [ #  # ]:          0 :   if (ErrorDescription == NULL)
      52                 :          0 :     return;
      53                 :            : 
      54                 :          0 :   Estrcpy (ErrorDescription, ":: value of element '");
      55                 :          0 :   _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription),
      56                 :            :                            ASN1_MAX_ERROR_DESCRIPTION_SIZE - 40);
      57                 :          0 :   Estrcat (ErrorDescription, "' not found");
      58                 :            : 
      59                 :            : }
      60                 :            : 
      61                 :            : /**
      62                 :            :  * asn1_length_der:
      63                 :            :  * @len: value to convert.
      64                 :            :  * @ans: string returned.
      65                 :            :  * @ans_len: number of meaningful bytes of ANS (ans[0]..ans[ans_len-1]).
      66                 :            :  *
      67                 :            :  * Creates the DER coding for the LEN parameter (only the length).
      68                 :            :  * The @ans buffer is pre-allocated and must have room for the output.
      69                 :            :  **/
      70                 :            : void
      71                 :        440 : asn1_length_der (unsigned long int len, unsigned char *ans, int *ans_len)
      72                 :            : {
      73                 :            :   int k;
      74                 :            :   unsigned char temp[SIZEOF_UNSIGNED_LONG_INT];
      75                 :            : 
      76         [ +  + ]:        440 :   if (len < 128)
      77                 :            :     {
      78                 :            :       /* short form */
      79         [ +  + ]:        429 :       if (ans != NULL)
      80                 :        330 :         ans[0] = (unsigned char) len;
      81                 :        429 :       *ans_len = 1;
      82                 :            :     }
      83                 :            :   else
      84                 :            :     {
      85                 :            :       /* Long form */
      86                 :         11 :       k = 0;
      87         [ +  + ]:         34 :       while (len)
      88                 :            :         {
      89                 :         23 :           temp[k++] = len & 0xFF;
      90                 :         23 :           len = len >> 8;
      91                 :            :         }
      92                 :         11 :       *ans_len = k + 1;
      93         [ +  + ]:         11 :       if (ans != NULL)
      94                 :            :         {
      95                 :         10 :           ans[0] = ((unsigned char) k & 0x7F) + 128;
      96         [ +  + ]:         31 :           while (k--)
      97                 :         21 :             ans[*ans_len - 1 - k] = temp[k];
      98                 :            :         }
      99                 :            :     }
     100                 :        440 : }
     101                 :            : 
     102                 :            : /******************************************************/
     103                 :            : /* Function : _asn1_tag_der                           */
     104                 :            : /* Description: creates the DER coding for the CLASS  */
     105                 :            : /* and TAG parameters.                                */
     106                 :            : /* Parameters:                                        */
     107                 :            : /*   class: value to convert.                         */
     108                 :            : /*   tag_value: value to convert.                     */
     109                 :            : /*   ans: string returned.                            */
     110                 :            : /*   ans_len: number of meaningful bytes of ANS       */
     111                 :            : /*            (ans[0]..ans[ans_len-1]).               */
     112                 :            : /* Return:                                            */
     113                 :            : /******************************************************/
     114                 :            : static void
     115                 :        222 : _asn1_tag_der (unsigned char class, unsigned int tag_value,
     116                 :            :                unsigned char *ans, int *ans_len)
     117                 :            : {
     118                 :            :   int k;
     119                 :            :   unsigned char temp[SIZEOF_UNSIGNED_INT];
     120                 :            : 
     121         [ +  - ]:        222 :   if (tag_value < 31)
     122                 :            :     {
     123                 :            :       /* short form */
     124                 :        222 :       ans[0] = (class & 0xE0) + ((unsigned char) (tag_value & 0x1F));
     125                 :        222 :       *ans_len = 1;
     126                 :            :     }
     127                 :            :   else
     128                 :            :     {
     129                 :            :       /* Long form */
     130                 :          0 :       ans[0] = (class & 0xE0) + 31;
     131                 :          0 :       k = 0;
     132         [ #  # ]:          0 :       while (tag_value)
     133                 :            :         {
     134                 :          0 :           temp[k++] = tag_value & 0x7F;
     135                 :          0 :           tag_value = tag_value >> 7;
     136                 :            :         }
     137                 :          0 :       *ans_len = k + 1;
     138         [ #  # ]:          0 :       while (k--)
     139                 :          0 :         ans[*ans_len - 1 - k] = temp[k] + 128;
     140                 :          0 :       ans[*ans_len - 1] -= 128;
     141                 :            :     }
     142                 :        222 : }
     143                 :            : 
     144                 :            : /**
     145                 :            :  * asn1_octet_der:
     146                 :            :  * @str: OCTET string.
     147                 :            :  * @str_len: STR length (str[0]..str[str_len-1]).
     148                 :            :  * @der: string returned.
     149                 :            :  * @der_len: number of meaningful bytes of DER (der[0]..der[ans_len-1]).
     150                 :            :  *
     151                 :            :  * Creates the DER coding for an OCTET type (length included).
     152                 :            :  **/
     153                 :            : void
     154                 :        181 : asn1_octet_der (const unsigned char *str, int str_len,
     155                 :            :                 unsigned char *der, int *der_len)
     156                 :            : {
     157                 :            :   int len_len;
     158                 :            : 
     159 [ +  - ][ -  + ]:        181 :   if (der == NULL || str_len < 0)
     160                 :        181 :     return;
     161                 :        181 :   asn1_length_der (str_len, der, &len_len);
     162                 :        181 :   memcpy (der + len_len, str, str_len);
     163                 :        181 :   *der_len = str_len + len_len;
     164                 :            : }
     165                 :            : 
     166                 :            : /******************************************************/
     167                 :            : /* Function : _asn1_time_der                          */
     168                 :            : /* Description: creates the DER coding for a TIME     */
     169                 :            : /* type (length included).                            */
     170                 :            : /* Parameters:                                        */
     171                 :            : /*   str: TIME null-terminated string.                */
     172                 :            : /*   der: string returned.                            */
     173                 :            : /*   der_len: number of meaningful bytes of DER       */
     174                 :            : /*            (der[0]..der[ans_len-1]). Initially it  */
     175                 :            : /*            if must store the lenght of DER.        */
     176                 :            : /* Return:                                            */
     177                 :            : /*   ASN1_MEM_ERROR when DER isn't big enough         */
     178                 :            : /*   ASN1_SUCCESS otherwise                           */
     179                 :            : /******************************************************/
     180                 :            : static asn1_retCode
     181                 :          6 : _asn1_time_der (unsigned char *str, unsigned char *der, int *der_len)
     182                 :            : {
     183                 :            :   int len_len;
     184                 :            :   int max_len;
     185                 :          6 :   int str_len = _asn1_strlen (str);
     186                 :            : 
     187                 :          6 :   max_len = *der_len;
     188                 :            : 
     189         [ +  + ]:          6 :   asn1_length_der (str_len, (max_len > 0) ? der : NULL, &len_len);
     190                 :            : 
     191         [ +  + ]:          6 :   if ((len_len + str_len) <= max_len)
     192                 :          4 :     memcpy (der + len_len, str, str_len);
     193                 :          6 :   *der_len = len_len + str_len;
     194                 :            : 
     195         [ +  + ]:          6 :   if ((*der_len) > max_len)
     196                 :          2 :     return ASN1_MEM_ERROR;
     197                 :            : 
     198                 :          6 :   return ASN1_SUCCESS;
     199                 :            : }
     200                 :            : 
     201                 :            : 
     202                 :            : /*
     203                 :            : void
     204                 :            : _asn1_get_utctime_der(unsigned char *der,int *der_len,unsigned char *str)
     205                 :            : {
     206                 :            :   int len_len,str_len;
     207                 :            :   char temp[20];
     208                 :            : 
     209                 :            :   if(str==NULL) return;
     210                 :            :   str_len=asn1_get_length_der(der,*der_len,&len_len);
     211                 :            :   if (str_len<0) return;
     212                 :            :   memcpy(temp,der+len_len,str_len);
     213                 :            :   *der_len=str_len+len_len;
     214                 :            :   switch(str_len){
     215                 :            :   case 11:
     216                 :            :     temp[10]=0;
     217                 :            :     strcat(temp,"00+0000");
     218                 :            :     break;
     219                 :            :   case 13:
     220                 :            :     temp[12]=0;
     221                 :            :     strcat(temp,"+0000");
     222                 :            :     break;
     223                 :            :   case 15:
     224                 :            :     temp[15]=0;
     225                 :            :     memmove(temp+12,temp+10,6);
     226                 :            :     temp[10]=temp[11]='0';
     227                 :            :     break;
     228                 :            :   case 17:
     229                 :            :     temp[17]=0;
     230                 :            :     break;
     231                 :            :   default:
     232                 :            :     return;
     233                 :            :   }
     234                 :            :   strcpy(str,temp);
     235                 :            : }
     236                 :            : */
     237                 :            : 
     238                 :            : /******************************************************/
     239                 :            : /* Function : _asn1_objectid_der                      */
     240                 :            : /* Description: creates the DER coding for an         */
     241                 :            : /* OBJECT IDENTIFIER  type (length included).         */
     242                 :            : /* Parameters:                                        */
     243                 :            : /*   str: OBJECT IDENTIFIER null-terminated string.   */
     244                 :            : /*   der: string returned.                            */
     245                 :            : /*   der_len: number of meaningful bytes of DER       */
     246                 :            : /*            (der[0]..der[ans_len-1]). Initially it  */
     247                 :            : /*            must store the length of DER.           */
     248                 :            : /* Return:                                            */
     249                 :            : /*   ASN1_MEM_ERROR when DER isn't big enough         */
     250                 :            : /*   ASN1_SUCCESS otherwise                           */
     251                 :            : /******************************************************/
     252                 :            : static asn1_retCode
     253                 :         35 : _asn1_objectid_der (unsigned char *str, unsigned char *der, int *der_len)
     254                 :            : {
     255                 :            :   int len_len, counter, k, first, max_len;
     256                 :            :   char *temp, *n_end, *n_start;
     257                 :            :   unsigned char bit7;
     258                 :         35 :   unsigned long val, val1 = 0;
     259                 :         35 :   int str_len = _asn1_strlen (str);
     260                 :            : 
     261                 :         35 :   max_len = *der_len;
     262                 :            : 
     263                 :         35 :   temp = _asn1_malloc (str_len + 2);
     264         [ -  + ]:         35 :   if (temp == NULL)
     265                 :          0 :     return ASN1_MEM_ALLOC_ERROR;
     266                 :            : 
     267                 :         35 :   memcpy (temp, str, str_len);
     268                 :         35 :   temp[str_len] = '.';
     269                 :         35 :   temp[str_len + 1] = 0;
     270                 :            : 
     271                 :         35 :   counter = 0;
     272                 :         35 :   n_start = temp;
     273         [ +  + ]:        184 :   while ((n_end = strchr (n_start, '.')))
     274                 :            :     {
     275                 :        149 :       *n_end = 0;
     276                 :        149 :       val = strtoul (n_start, NULL, 10);
     277                 :        149 :       counter++;
     278                 :            : 
     279         [ +  + ]:        149 :       if (counter == 1)
     280                 :         35 :         val1 = val;
     281         [ +  + ]:        114 :       else if (counter == 2)
     282                 :            :         {
     283         [ +  + ]:         35 :           if (max_len > 0)
     284                 :         24 :             der[0] = 40 * val1 + val;
     285                 :         35 :           *der_len = 1;
     286                 :            :         }
     287                 :            :       else
     288                 :            :         {
     289                 :         79 :           first = 0;
     290         [ +  + ]:        474 :           for (k = 4; k >= 0; k--)
     291                 :            :             {
     292                 :        395 :               bit7 = (val >> (k * 7)) & 0x7F;
     293 [ +  + ][ +  - ]:        395 :               if (bit7 || first || !k)
                 [ -  + ]
     294                 :            :                 {
     295         [ +  + ]:         88 :                   if (k)
     296                 :          9 :                     bit7 |= 0x80;
     297         [ +  + ]:         88 :                   if (max_len > (*der_len))
     298                 :         60 :                     der[*der_len] = bit7;
     299                 :         88 :                   (*der_len)++;
     300                 :         88 :                   first = 1;
     301                 :            :                 }
     302                 :            :             }
     303                 :            : 
     304                 :            :         }
     305                 :        149 :       n_start = n_end + 1;
     306                 :            :     }
     307                 :            : 
     308                 :         35 :   asn1_length_der (*der_len, NULL, &len_len);
     309         [ +  + ]:         35 :   if (max_len >= (*der_len + len_len))
     310                 :            :     {
     311                 :         24 :       memmove (der + len_len, der, *der_len);
     312                 :         24 :       asn1_length_der (*der_len, der, &len_len);
     313                 :            :     }
     314                 :         35 :   *der_len += len_len;
     315                 :            : 
     316                 :         35 :   _asn1_free (temp);
     317                 :            : 
     318         [ +  + ]:         35 :   if (max_len < (*der_len))
     319                 :         11 :     return ASN1_MEM_ERROR;
     320                 :            : 
     321                 :         35 :   return ASN1_SUCCESS;
     322                 :            : }
     323                 :            : 
     324                 :            : 
     325                 :            : static const unsigned char bit_mask[] =
     326                 :            :   { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80 };
     327                 :            : 
     328                 :            : /**
     329                 :            :  * asn1_bit_der:
     330                 :            :  * @str: BIT string.
     331                 :            :  * @bit_len: number of meaningful bits in STR.
     332                 :            :  * @der: string returned.
     333                 :            :  * @der_len: number of meaningful bytes of DER
     334                 :            :  *   (der[0]..der[ans_len-1]).
     335                 :            :  *
     336                 :            :  * Creates the DER coding for a BIT STRING type (length and pad
     337                 :            :  * included).
     338                 :            :  **/
     339                 :            : void
     340                 :         44 : asn1_bit_der (const unsigned char *str, int bit_len,
     341                 :            :               unsigned char *der, int *der_len)
     342                 :            : {
     343                 :            :   int len_len, len_byte, len_pad;
     344                 :            : 
     345         [ -  + ]:         44 :   if (der == NULL)
     346                 :         44 :     return;
     347                 :         44 :   len_byte = bit_len >> 3;
     348                 :         44 :   len_pad = 8 - (bit_len & 7);
     349         [ +  + ]:         44 :   if (len_pad == 8)
     350                 :          6 :     len_pad = 0;
     351                 :            :   else
     352                 :         38 :     len_byte++;
     353                 :         44 :   asn1_length_der (len_byte + 1, der, &len_len);
     354                 :         44 :   der[len_len] = len_pad;
     355                 :         44 :   memcpy (der + len_len + 1, str, len_byte);
     356                 :         44 :   der[len_len + len_byte] &= bit_mask[len_pad];
     357                 :         44 :   *der_len = len_byte + len_len + 1;
     358                 :            : }
     359                 :            : 
     360                 :            : 
     361                 :            : /******************************************************/
     362                 :            : /* Function : _asn1_complete_explicit_tag             */
     363                 :            : /* Description: add the length coding to the EXPLICIT */
     364                 :            : /* tags.                                              */
     365                 :            : /* Parameters:                                        */
     366                 :            : /*   node: pointer to the tree element.               */
     367                 :            : /*   der: string with the DER coding of the whole tree*/
     368                 :            : /*   counter: number of meaningful bytes of DER       */
     369                 :            : /*            (der[0]..der[*counter-1]).              */
     370                 :            : /*   max_len: size of der vector                      */
     371                 :            : /* Return:                                            */
     372                 :            : /*   ASN1_MEM_ERROR if der vector isn't big enough,   */
     373                 :            : /*   otherwise ASN1_SUCCESS.                          */
     374                 :            : /******************************************************/
     375                 :            : static asn1_retCode
     376                 :        222 : _asn1_complete_explicit_tag (ASN1_TYPE node, unsigned char *der,
     377                 :            :                              int *counter, int *max_len)
     378                 :            : {
     379                 :            :   ASN1_TYPE p;
     380                 :            :   int is_tag_implicit, len2, len3;
     381                 :            :   unsigned char temp[SIZEOF_UNSIGNED_INT];
     382                 :            : 
     383                 :        222 :   is_tag_implicit = 0;
     384                 :            : 
     385         [ +  + ]:        222 :   if (node->type & CONST_TAG)
     386                 :            :     {
     387                 :         31 :       p = node->down;
     388                 :            :       /* When there are nested tags we must complete them reverse to
     389                 :            :          the order they were created. This is because completing a tag
     390                 :            :          modifies all data within it, including the incomplete tags
     391                 :            :          which store buffer positions -- simon@josefsson.org 2002-09-06
     392                 :            :        */
     393         [ +  + ]:         71 :       while (p->right)
     394                 :         40 :         p = p->right;
     395 [ +  - ][ +  + ]:        102 :       while (p && p != node->down->left)
     396                 :            :         {
     397         [ +  + ]:         71 :           if (type_field (p->type) == TYPE_TAG)
     398                 :            :             {
     399         [ +  + ]:         34 :               if (p->type & CONST_EXPLICIT)
     400                 :            :                 {
     401                 :          9 :                   len2 = strtol (p->name, NULL, 10);
     402                 :          9 :                   _asn1_set_name (p, NULL);
     403                 :          9 :                   asn1_length_der (*counter - len2, temp, &len3);
     404         [ +  + ]:          9 :                   if (len3 <= (*max_len))
     405                 :            :                     {
     406                 :          6 :                       memmove (der + len2 + len3, der + len2,
     407                 :          6 :                                *counter - len2);
     408                 :          6 :                       memcpy (der + len2, temp, len3);
     409                 :            :                     }
     410                 :          9 :                   *max_len -= len3;
     411                 :          9 :                   *counter += len3;
     412                 :          9 :                   is_tag_implicit = 0;
     413                 :            :                 }
     414                 :            :               else
     415                 :            :                 {               /* CONST_IMPLICIT */
     416         [ +  - ]:         25 :                   if (!is_tag_implicit)
     417                 :            :                     {
     418                 :         25 :                       is_tag_implicit = 1;
     419                 :            :                     }
     420                 :            :                 }
     421                 :            :             }
     422                 :         71 :           p = p->left;
     423                 :            :         }
     424                 :            :     }
     425                 :            : 
     426         [ +  + ]:        222 :   if (*max_len < 0)
     427                 :         80 :     return ASN1_MEM_ERROR;
     428                 :            : 
     429                 :        222 :   return ASN1_SUCCESS;
     430                 :            : }
     431                 :            : 
     432                 :            : 
     433                 :            : /******************************************************/
     434                 :            : /* Function : _asn1_insert_tag_der                    */
     435                 :            : /* Description: creates the DER coding of tags of one */
     436                 :            : /* NODE.                                              */
     437                 :            : /* Parameters:                                        */
     438                 :            : /*   node: pointer to the tree element.               */
     439                 :            : /*   der: string returned                             */
     440                 :            : /*   counter: number of meaningful bytes of DER       */
     441                 :            : /*            (counter[0]..der[*counter-1]).          */
     442                 :            : /*   max_len: size of der vector                      */
     443                 :            : /* Return:                                            */
     444                 :            : /*   ASN1_GENERIC_ERROR if the type is unknown,       */
     445                 :            : /*   ASN1_MEM_ERROR if der vector isn't big enough,   */
     446                 :            : /*   otherwise ASN1_SUCCESS.                          */
     447                 :            : /******************************************************/
     448                 :            : static asn1_retCode
     449                 :        252 : _asn1_insert_tag_der (ASN1_TYPE node, unsigned char *der, int *counter,
     450                 :            :                       int *max_len)
     451                 :            : {
     452                 :            :   ASN1_TYPE p;
     453                 :            :   int tag_len, is_tag_implicit;
     454                 :        252 :   unsigned char class, class_implicit = 0, temp[SIZEOF_UNSIGNED_INT * 3 + 1];
     455                 :        252 :   unsigned long tag_implicit = 0;
     456                 :            :   unsigned char tag_der[MAX_TAG_LEN];
     457                 :            : 
     458                 :        252 :   is_tag_implicit = 0;
     459                 :            : 
     460         [ +  + ]:        252 :   if (node->type & CONST_TAG)
     461                 :            :     {
     462                 :         43 :       p = node->down;
     463         [ +  + ]:        156 :       while (p)
     464                 :            :         {
     465         [ +  + ]:        113 :           if (type_field (p->type) == TYPE_TAG)
     466                 :            :             {
     467         [ +  + ]:         46 :               if (p->type & CONST_APPLICATION)
     468                 :          3 :                 class = ASN1_CLASS_APPLICATION;
     469         [ +  + ]:         43 :               else if (p->type & CONST_UNIVERSAL)
     470                 :          3 :                 class = ASN1_CLASS_UNIVERSAL;
     471         [ -  + ]:         40 :               else if (p->type & CONST_PRIVATE)
     472                 :          0 :                 class = ASN1_CLASS_PRIVATE;
     473                 :            :               else
     474                 :         40 :                 class = ASN1_CLASS_CONTEXT_SPECIFIC;
     475                 :            : 
     476         [ +  + ]:         46 :               if (p->type & CONST_EXPLICIT)
     477                 :            :                 {
     478         [ -  + ]:          9 :                   if (is_tag_implicit)
     479                 :          0 :                     _asn1_tag_der (class_implicit, tag_implicit, tag_der,
     480                 :            :                                    &tag_len);
     481                 :            :                   else
     482                 :          9 :                     _asn1_tag_der (class | ASN1_CLASS_STRUCTURED,
     483                 :          9 :                                    _asn1_strtoul (p->value, NULL, 10),
     484                 :            :                                    tag_der, &tag_len);
     485                 :            : 
     486                 :          9 :                   *max_len -= tag_len;
     487         [ +  + ]:          9 :                   if (*max_len >= 0)
     488                 :          6 :                     memcpy (der + *counter, tag_der, tag_len);
     489                 :          9 :                   *counter += tag_len;
     490                 :            : 
     491                 :          9 :                   _asn1_ltostr (*counter, (char *) temp);
     492                 :          9 :                   _asn1_set_name (p, (const char *) temp);
     493                 :            : 
     494                 :          9 :                   is_tag_implicit = 0;
     495                 :            :                 }
     496                 :            :               else
     497                 :            :                 {               /* CONST_IMPLICIT */
     498         [ +  - ]:         37 :                   if (!is_tag_implicit)
     499                 :            :                     {
     500 [ +  + ][ +  - ]:         37 :                       if ((type_field (node->type) == TYPE_SEQUENCE) ||
     501         [ +  - ]:         30 :                           (type_field (node->type) == TYPE_SEQUENCE_OF) ||
     502         [ +  + ]:         30 :                           (type_field (node->type) == TYPE_SET) ||
     503                 :         30 :                           (type_field (node->type) == TYPE_SET_OF))
     504                 :         10 :                         class |= ASN1_CLASS_STRUCTURED;
     505                 :         37 :                       class_implicit = class;
     506                 :         37 :                       tag_implicit = _asn1_strtoul (p->value, NULL, 10);
     507                 :         37 :                       is_tag_implicit = 1;
     508                 :            :                     }
     509                 :            :                 }
     510                 :            :             }
     511                 :        113 :           p = p->right;
     512                 :            :         }
     513                 :            :     }
     514                 :            : 
     515         [ +  + ]:        252 :   if (is_tag_implicit)
     516                 :            :     {
     517                 :         37 :       _asn1_tag_der (class_implicit, tag_implicit, tag_der, &tag_len);
     518                 :            :     }
     519                 :            :   else
     520                 :            :     {
     521   [ -  +  +  +  :        215 :       switch (type_field (node->type))
          +  +  +  +  +  
          +  +  -  +  +  
                      - ]
     522                 :            :         {
     523                 :            :         case TYPE_NULL:
     524                 :          0 :           _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_NULL, tag_der,
     525                 :            :                          &tag_len);
     526                 :          0 :           break;
     527                 :            :         case TYPE_BOOLEAN:
     528                 :          6 :           _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_BOOLEAN, tag_der,
     529                 :            :                          &tag_len);
     530                 :          6 :           break;
     531                 :            :         case TYPE_INTEGER:
     532                 :         46 :           _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_INTEGER, tag_der,
     533                 :            :                          &tag_len);
     534                 :         46 :           break;
     535                 :            :         case TYPE_ENUMERATED:
     536                 :          3 :           _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_ENUMERATED, tag_der,
     537                 :            :                          &tag_len);
     538                 :          3 :           break;
     539                 :            :         case TYPE_OBJECT_ID:
     540                 :         32 :           _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_OBJECT_ID, tag_der,
     541                 :            :                          &tag_len);
     542                 :         32 :           break;
     543                 :            :         case TYPE_TIME:
     544         [ +  + ]:          6 :           if (node->type & CONST_UTC)
     545                 :            :             {
     546                 :          3 :               _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_UTCTime, tag_der,
     547                 :            :                              &tag_len);
     548                 :            :             }
     549                 :            :           else
     550                 :          3 :             _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_GENERALIZEDTime,
     551                 :            :                            tag_der, &tag_len);
     552                 :          6 :           break;
     553                 :            :         case TYPE_OCTET_STRING:
     554                 :         10 :           _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_OCTET_STRING, tag_der,
     555                 :            :                          &tag_len);
     556                 :         10 :           break;
     557                 :            :         case TYPE_GENERALSTRING:
     558                 :          6 :           _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_GENERALSTRING,
     559                 :            :                          tag_der, &tag_len);
     560                 :          6 :           break;
     561                 :            :         case TYPE_BIT_STRING:
     562                 :          3 :           _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_BIT_STRING, tag_der,
     563                 :            :                          &tag_len);
     564                 :          3 :           break;
     565                 :            :         case TYPE_SEQUENCE:
     566                 :            :         case TYPE_SEQUENCE_OF:
     567                 :         51 :           _asn1_tag_der (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
     568                 :            :                          ASN1_TAG_SEQUENCE, tag_der, &tag_len);
     569                 :         51 :           break;
     570                 :            :         case TYPE_SET:
     571                 :            :         case TYPE_SET_OF:
     572                 :         13 :           _asn1_tag_der (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
     573                 :            :                          ASN1_TAG_SET, tag_der, &tag_len);
     574                 :         13 :           break;
     575                 :            :         case TYPE_TAG:
     576                 :          0 :           tag_len = 0;
     577                 :          0 :           break;
     578                 :            :         case TYPE_CHOICE:
     579                 :         15 :           tag_len = 0;
     580                 :         15 :           break;
     581                 :            :         case TYPE_ANY:
     582                 :         24 :           tag_len = 0;
     583                 :         24 :           break;
     584                 :            :         default:
     585                 :          0 :           return ASN1_GENERIC_ERROR;
     586                 :            :         }
     587                 :            :     }
     588                 :            : 
     589                 :        252 :   *max_len -= tag_len;
     590         [ +  + ]:        252 :   if (*max_len >= 0)
     591                 :        178 :     memcpy (der + *counter, tag_der, tag_len);
     592                 :        252 :   *counter += tag_len;
     593                 :            : 
     594         [ +  + ]:        252 :   if (*max_len < 0)
     595                 :         74 :     return ASN1_MEM_ERROR;
     596                 :            : 
     597                 :        252 :   return ASN1_SUCCESS;
     598                 :            : }
     599                 :            : 
     600                 :            : /******************************************************/
     601                 :            : /* Function : _asn1_ordering_set                      */
     602                 :            : /* Description: puts the elements of a SET type in    */
     603                 :            : /* the correct order according to DER rules.          */
     604                 :            : /* Parameters:                                        */
     605                 :            : /*   der: string with the DER coding.                 */
     606                 :            : /*   node: pointer to the SET element.                */
     607                 :            : /* Return:                                            */
     608                 :            : /******************************************************/
     609                 :            : static void
     610                 :          0 : _asn1_ordering_set (unsigned char *der, int der_len, ASN1_TYPE node)
     611                 :            : {
     612                 :            :   struct vet
     613                 :            :   {
     614                 :            :     int end;
     615                 :            :     unsigned long value;
     616                 :            :     struct vet *next, *prev;
     617                 :            :   };
     618                 :            : 
     619                 :            :   int counter, len, len2;
     620                 :            :   struct vet *first, *last, *p_vet, *p2_vet;
     621                 :            :   ASN1_TYPE p;
     622                 :            :   unsigned char class, *temp;
     623                 :            :   unsigned long tag;
     624                 :            : 
     625                 :          0 :   counter = 0;
     626                 :            : 
     627         [ #  # ]:          0 :   if (type_field (node->type) != TYPE_SET)
     628                 :          0 :     return;
     629                 :            : 
     630                 :          0 :   p = node->down;
     631         [ #  # ]:          0 :   while ((type_field (p->type) == TYPE_TAG)
     632         [ #  # ]:          0 :          || (type_field (p->type) == TYPE_SIZE))
     633                 :          0 :     p = p->right;
     634                 :            : 
     635 [ #  # ][ #  # ]:          0 :   if ((p == NULL) || (p->right == NULL))
     636                 :          0 :     return;
     637                 :            : 
     638                 :          0 :   first = last = NULL;
     639         [ #  # ]:          0 :   while (p)
     640                 :            :     {
     641                 :          0 :       p_vet = (struct vet *) _asn1_malloc (sizeof (struct vet));
     642         [ #  # ]:          0 :       if (p_vet == NULL)
     643                 :          0 :         return;
     644                 :            : 
     645                 :          0 :       p_vet->next = NULL;
     646                 :          0 :       p_vet->prev = last;
     647         [ #  # ]:          0 :       if (first == NULL)
     648                 :          0 :         first = p_vet;
     649                 :            :       else
     650                 :          0 :         last->next = p_vet;
     651                 :          0 :       last = p_vet;
     652                 :            : 
     653                 :            :       /* tag value calculation */
     654         [ #  # ]:          0 :       if (asn1_get_tag_der
     655                 :          0 :           (der + counter, der_len - counter, &class, &len2,
     656                 :            :            &tag) != ASN1_SUCCESS)
     657                 :          0 :         return;
     658                 :          0 :       p_vet->value = (class << 24) | tag;
     659                 :          0 :       counter += len2;
     660                 :            : 
     661                 :            :       /* extraction and length */
     662                 :          0 :       len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
     663         [ #  # ]:          0 :       if (len2 < 0)
     664                 :          0 :         return;
     665                 :          0 :       counter += len + len2;
     666                 :            : 
     667                 :          0 :       p_vet->end = counter;
     668                 :          0 :       p = p->right;
     669                 :            :     }
     670                 :            : 
     671                 :          0 :   p_vet = first;
     672                 :            : 
     673         [ #  # ]:          0 :   while (p_vet)
     674                 :            :     {
     675                 :          0 :       p2_vet = p_vet->next;
     676                 :          0 :       counter = 0;
     677         [ #  # ]:          0 :       while (p2_vet)
     678                 :            :         {
     679         [ #  # ]:          0 :           if (p_vet->value > p2_vet->value)
     680                 :            :             {
     681                 :            :               /* change position */
     682                 :          0 :               temp = (unsigned char *) _asn1_malloc (p_vet->end - counter);
     683         [ #  # ]:          0 :               if (temp == NULL)
     684                 :          0 :                 return;
     685                 :            : 
     686                 :          0 :               memcpy (temp, der + counter, p_vet->end - counter);
     687                 :          0 :               memcpy (der + counter, der + p_vet->end,
     688                 :          0 :                       p2_vet->end - p_vet->end);
     689                 :          0 :               memcpy (der + counter + p2_vet->end - p_vet->end, temp,
     690                 :          0 :                       p_vet->end - counter);
     691                 :          0 :               _asn1_free (temp);
     692                 :            : 
     693                 :          0 :               tag = p_vet->value;
     694                 :          0 :               p_vet->value = p2_vet->value;
     695                 :          0 :               p2_vet->value = tag;
     696                 :            : 
     697                 :          0 :               p_vet->end = counter + (p2_vet->end - p_vet->end);
     698                 :            :             }
     699                 :          0 :           counter = p_vet->end;
     700                 :            : 
     701                 :          0 :           p2_vet = p2_vet->next;
     702                 :          0 :           p_vet = p_vet->next;
     703                 :            :         }
     704                 :            : 
     705         [ #  # ]:          0 :       if (p_vet != first)
     706                 :          0 :         p_vet->prev->next = NULL;
     707                 :            :       else
     708                 :          0 :         first = NULL;
     709                 :          0 :       _asn1_free (p_vet);
     710                 :          0 :       p_vet = first;
     711                 :            :     }
     712                 :            : }
     713                 :            : 
     714                 :            : /******************************************************/
     715                 :            : /* Function : _asn1_ordering_set_of                   */
     716                 :            : /* Description: puts the elements of a SET OF type in */
     717                 :            : /* the correct order according to DER rules.          */
     718                 :            : /* Parameters:                                        */
     719                 :            : /*   der: string with the DER coding.                 */
     720                 :            : /*   node: pointer to the SET OF element.             */
     721                 :            : /* Return:                                            */
     722                 :            : /******************************************************/
     723                 :            : static void
     724                 :          9 : _asn1_ordering_set_of (unsigned char *der, int der_len, ASN1_TYPE node)
     725                 :            : {
     726                 :            :   struct vet
     727                 :            :   {
     728                 :            :     int end;
     729                 :            :     struct vet *next, *prev;
     730                 :            :   };
     731                 :            : 
     732                 :            :   int counter, len, len2, change;
     733                 :            :   struct vet *first, *last, *p_vet, *p2_vet;
     734                 :            :   ASN1_TYPE p;
     735                 :            :   unsigned char *temp, class;
     736                 :            :   unsigned long k, max;
     737                 :            : 
     738                 :          9 :   counter = 0;
     739                 :            : 
     740         [ -  + ]:          9 :   if (type_field (node->type) != TYPE_SET_OF)
     741                 :          0 :     return;
     742                 :            : 
     743                 :          9 :   p = node->down;
     744         [ +  + ]:         13 :   while ((type_field (p->type) == TYPE_TAG)
     745         [ +  + ]:         11 :          || (type_field (p->type) == TYPE_SIZE))
     746                 :          4 :     p = p->right;
     747                 :          9 :   p = p->right;
     748                 :            : 
     749 [ +  + ][ -  + ]:          9 :   if ((p == NULL) || (p->right == NULL))
     750                 :          2 :     return;
     751                 :            : 
     752                 :          7 :   first = last = NULL;
     753         [ +  + ]:         17 :   while (p)
     754                 :            :     {
     755                 :         12 :       p_vet = (struct vet *) _asn1_malloc (sizeof (struct vet));
     756         [ -  + ]:         12 :       if (p_vet == NULL)
     757                 :          0 :         return;
     758                 :            : 
     759                 :         12 :       p_vet->next = NULL;
     760                 :         12 :       p_vet->prev = last;
     761         [ +  + ]:         12 :       if (first == NULL)
     762                 :          7 :         first = p_vet;
     763                 :            :       else
     764                 :          5 :         last->next = p_vet;
     765                 :         12 :       last = p_vet;
     766                 :            : 
     767                 :            :       /* extraction of tag and length */
     768         [ +  - ]:         12 :       if (der_len - counter > 0)
     769                 :            :         {
     770                 :            : 
     771         [ +  + ]:         12 :           if (asn1_get_tag_der
     772                 :         12 :               (der + counter, der_len - counter, &class, &len,
     773                 :            :                NULL) != ASN1_SUCCESS)
     774                 :          1 :             return;
     775                 :         11 :           counter += len;
     776                 :            : 
     777                 :         11 :           len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
     778         [ +  + ]:         11 :           if (len2 < 0)
     779                 :          1 :             return;
     780                 :         10 :           counter += len + len2;
     781                 :            :         }
     782                 :            : 
     783                 :         10 :       p_vet->end = counter;
     784                 :         10 :       p = p->right;
     785                 :            :     }
     786                 :            : 
     787                 :          5 :   p_vet = first;
     788                 :            : 
     789         [ +  + ]:         19 :   while (p_vet)
     790                 :            :     {
     791                 :         10 :       p2_vet = p_vet->next;
     792                 :         10 :       counter = 0;
     793         [ +  + ]:         15 :       while (p2_vet)
     794                 :            :         {
     795         [ -  + ]:          5 :           if ((p_vet->end - counter) > (p2_vet->end - p_vet->end))
     796                 :          0 :             max = p_vet->end - counter;
     797                 :            :           else
     798                 :          5 :             max = p2_vet->end - p_vet->end;
     799                 :            : 
     800                 :          5 :           change = -1;
     801         [ +  - ]:         16 :           for (k = 0; k < max; k++)
     802         [ +  + ]:         16 :             if (der[counter + k] > der[p_vet->end + k])
     803                 :            :               {
     804                 :          2 :                 change = 1;
     805                 :          2 :                 break;
     806                 :            :               }
     807         [ +  + ]:         14 :             else if (der[counter + k] < der[p_vet->end + k])
     808                 :            :               {
     809                 :          3 :                 change = 0;
     810                 :          3 :                 break;
     811                 :            :               }
     812                 :            : 
     813         [ -  + ]:          5 :           if ((change == -1)
     814         [ #  # ]:          0 :               && ((p_vet->end - counter) > (p2_vet->end - p_vet->end)))
     815                 :          0 :             change = 1;
     816                 :            : 
     817         [ +  + ]:          5 :           if (change == 1)
     818                 :            :             {
     819                 :            :               /* change position */
     820                 :          2 :               temp = (unsigned char *) _asn1_malloc (p_vet->end - counter);
     821         [ -  + ]:          2 :               if (temp == NULL)
     822                 :          0 :                 return;
     823                 :            : 
     824                 :          2 :               memcpy (temp, der + counter, (p_vet->end) - counter);
     825                 :          2 :               memcpy (der + counter, der + (p_vet->end),
     826                 :          2 :                       (p2_vet->end) - (p_vet->end));
     827                 :          2 :               memcpy (der + counter + (p2_vet->end) - (p_vet->end), temp,
     828                 :          2 :                       (p_vet->end) - counter);
     829                 :          2 :               _asn1_free (temp);
     830                 :            : 
     831                 :          2 :               p_vet->end = counter + (p2_vet->end - p_vet->end);
     832                 :            :             }
     833                 :          5 :           counter = p_vet->end;
     834                 :            : 
     835                 :          5 :           p2_vet = p2_vet->next;
     836                 :          5 :           p_vet = p_vet->next;
     837                 :            :         }
     838                 :            : 
     839         [ +  + ]:         10 :       if (p_vet != first)
     840                 :          5 :         p_vet->prev->next = NULL;
     841                 :            :       else
     842                 :          5 :         first = NULL;
     843                 :         10 :       _asn1_free (p_vet);
     844                 :         10 :       p_vet = first;
     845                 :            :     }
     846                 :            : }
     847                 :            : 
     848                 :            : /**
     849                 :            :  * asn1_der_coding:
     850                 :            :  * @element: pointer to an ASN1 element
     851                 :            :  * @name: the name of the structure you want to encode (it must be
     852                 :            :  *   inside *POINTER).
     853                 :            :  * @ider: vector that will contain the DER encoding. DER must be a
     854                 :            :  *   pointer to memory cells already allocated.
     855                 :            :  * @len: number of bytes of *@ider: @ider[0]..@ider[len-1], Initialy
     856                 :            :  *   holds the sizeof of der vector.
     857                 :            :  * @errorDescription : return the error description or an empty
     858                 :            :  *   string if success.
     859                 :            :  *
     860                 :            :  * Creates the DER encoding for the NAME structure (inside *POINTER
     861                 :            :  * structure).
     862                 :            :  *
     863                 :            :  * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
     864                 :            :  *   if @name is not a valid element, %ASN1_VALUE_NOT_FOUND if there
     865                 :            :  *   is an element without a value, %ASN1_MEM_ERROR if the @ider
     866                 :            :  *   vector isn't big enough and in this case @len will contain the
     867                 :            :  *   length needed.
     868                 :            :  **/
     869                 :            : asn1_retCode
     870                 :         47 : asn1_der_coding (ASN1_TYPE element, const char *name, void *ider, int *len,
     871                 :            :                  char *ErrorDescription)
     872                 :            : {
     873                 :            :   ASN1_TYPE node, p, p2;
     874                 :            :   unsigned char temp[SIZEOF_UNSIGNED_LONG_INT * 3 + 1];
     875                 :            :   int counter, counter_old, len2, len3, tlen, move, max_len, max_len_old;
     876                 :            :   asn1_retCode err;
     877                 :         47 :   unsigned char *der = ider;
     878                 :            : 
     879                 :         47 :   node = asn1_find_node (element, name);
     880         [ -  + ]:         47 :   if (node == NULL)
     881                 :          0 :     return ASN1_ELEMENT_NOT_FOUND;
     882                 :            : 
     883                 :            :   /* Node is now a locally allocated variable.
     884                 :            :    * That is because in some point we modify the
     885                 :            :    * structure, and I don't know why! --nmav
     886                 :            :    */
     887                 :         47 :   node = _asn1_copy_structure3 (node);
     888         [ -  + ]:         47 :   if (node == NULL)
     889                 :          0 :     return ASN1_ELEMENT_NOT_FOUND;
     890                 :            : 
     891                 :         47 :   max_len = *len;
     892                 :            : 
     893                 :         47 :   counter = 0;
     894                 :         47 :   move = DOWN;
     895                 :         47 :   p = node;
     896                 :            :   while (1)
     897                 :            :     {
     898                 :            : 
     899                 :        335 :       counter_old = counter;
     900                 :        335 :       max_len_old = max_len;
     901         [ +  + ]:        335 :       if (move != UP)
     902                 :            :         {
     903                 :        252 :           err = _asn1_insert_tag_der (p, der, &counter, &max_len);
     904 [ +  + ][ -  + ]:        252 :           if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
     905                 :          0 :             goto error;
     906                 :            :         }
     907   [ -  +  +  +  :        335 :       switch (type_field (p->type))
          +  +  +  +  +  
                +  +  + ]
     908                 :            :         {
     909                 :            :         case TYPE_NULL:
     910                 :          0 :           max_len--;
     911         [ #  # ]:          0 :           if (max_len >= 0)
     912                 :          0 :             der[counter] = 0;
     913                 :          0 :           counter++;
     914                 :          0 :           move = RIGHT;
     915                 :          0 :           break;
     916                 :            :         case TYPE_BOOLEAN:
     917 [ +  + ][ +  - ]:          6 :           if ((p->type & CONST_DEFAULT) && (p->value == NULL))
     918                 :            :             {
     919                 :          3 :               counter = counter_old;
     920                 :          3 :               max_len = max_len_old;
     921                 :            :             }
     922                 :            :           else
     923                 :            :             {
     924         [ -  + ]:          3 :               if (p->value == NULL)
     925                 :            :                 {
     926                 :          0 :                   _asn1_error_description_value_not_found (p,
     927                 :            :                                                            ErrorDescription);
     928                 :          0 :                   err = ASN1_VALUE_NOT_FOUND;
     929                 :          0 :                   goto error;
     930                 :            :                 }
     931                 :          3 :               max_len -= 2;
     932         [ +  + ]:          3 :               if (max_len >= 0)
     933                 :            :                 {
     934                 :          2 :                   der[counter++] = 1;
     935         [ -  + ]:          2 :                   if (p->value[0] == 'F')
     936                 :          0 :                     der[counter++] = 0;
     937                 :            :                   else
     938                 :          2 :                     der[counter++] = 0xFF;
     939                 :            :                 }
     940                 :            :               else
     941                 :          1 :                 counter += 2;
     942                 :            :             }
     943                 :          6 :           move = RIGHT;
     944                 :          6 :           break;
     945                 :            :         case TYPE_INTEGER:
     946                 :            :         case TYPE_ENUMERATED:
     947 [ +  + ][ +  + ]:         58 :           if ((p->type & CONST_DEFAULT) && (p->value == NULL))
     948                 :            :             {
     949                 :          6 :               counter = counter_old;
     950                 :          6 :               max_len = max_len_old;
     951                 :            :             }
     952                 :            :           else
     953                 :            :             {
     954         [ -  + ]:         52 :               if (p->value == NULL)
     955                 :            :                 {
     956                 :          0 :                   _asn1_error_description_value_not_found (p,
     957                 :            :                                                            ErrorDescription);
     958                 :          0 :                   err = ASN1_VALUE_NOT_FOUND;
     959                 :          0 :                   goto error;
     960                 :            :                 }
     961                 :         52 :               len2 = asn1_get_length_der (p->value, p->value_len, &len3);
     962         [ -  + ]:         52 :               if (len2 < 0)
     963                 :            :                 {
     964                 :          0 :                   err = ASN1_DER_ERROR;
     965                 :          0 :                   goto error;
     966                 :            :                 }
     967                 :         52 :               max_len -= len2 + len3;
     968         [ +  + ]:         52 :               if (max_len >= 0)
     969                 :         37 :                 memcpy (der + counter, p->value, len3 + len2);
     970                 :         52 :               counter += len3 + len2;
     971                 :            :             }
     972                 :         58 :           move = RIGHT;
     973                 :         58 :           break;
     974                 :            :         case TYPE_OBJECT_ID:
     975 [ +  + ][ +  + ]:         41 :           if ((p->type & CONST_DEFAULT) && (p->value == NULL))
     976                 :            :             {
     977                 :          6 :               counter = counter_old;
     978                 :          6 :               max_len = max_len_old;
     979                 :            :             }
     980                 :            :           else
     981                 :            :             {
     982         [ -  + ]:         35 :               if (p->value == NULL)
     983                 :            :                 {
     984                 :          0 :                   _asn1_error_description_value_not_found (p,
     985                 :            :                                                            ErrorDescription);
     986                 :          0 :                   err = ASN1_VALUE_NOT_FOUND;
     987                 :          0 :                   goto error;
     988                 :            :                 }
     989                 :         35 :               len2 = max_len;
     990                 :         35 :               err = _asn1_objectid_der (p->value, der + counter, &len2);
     991 [ +  + ][ -  + ]:         35 :               if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
     992                 :          0 :                 goto error;
     993                 :            : 
     994                 :         35 :               max_len -= len2;
     995                 :         35 :               counter += len2;
     996                 :            :             }
     997                 :         41 :           move = RIGHT;
     998                 :         41 :           break;
     999                 :            :         case TYPE_TIME:
    1000         [ -  + ]:          6 :           if (p->value == NULL)
    1001                 :            :             {
    1002                 :          0 :               _asn1_error_description_value_not_found (p, ErrorDescription);
    1003                 :          0 :               err = ASN1_VALUE_NOT_FOUND;
    1004                 :          0 :               goto error;
    1005                 :            :             }
    1006                 :          6 :           len2 = max_len;
    1007                 :          6 :           err = _asn1_time_der (p->value, der + counter, &len2);
    1008 [ +  + ][ -  + ]:          6 :           if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
    1009                 :          0 :             goto error;
    1010                 :            : 
    1011                 :          6 :           max_len -= len2;
    1012                 :          6 :           counter += len2;
    1013                 :          6 :           move = RIGHT;
    1014                 :          6 :           break;
    1015                 :            :         case TYPE_OCTET_STRING:
    1016         [ -  + ]:         16 :           if (p->value == NULL)
    1017                 :            :             {
    1018                 :          0 :               _asn1_error_description_value_not_found (p, ErrorDescription);
    1019                 :          0 :               err = ASN1_VALUE_NOT_FOUND;
    1020                 :          0 :               goto error;
    1021                 :            :             }
    1022                 :         16 :           len2 = asn1_get_length_der (p->value, p->value_len, &len3);
    1023         [ -  + ]:         16 :           if (len2 < 0)
    1024                 :            :             {
    1025                 :          0 :               err = ASN1_DER_ERROR;
    1026                 :          0 :               goto error;
    1027                 :            :             }
    1028                 :         16 :           max_len -= len2 + len3;
    1029         [ +  + ]:         16 :           if (max_len >= 0)
    1030                 :         10 :             memcpy (der + counter, p->value, len3 + len2);
    1031                 :         16 :           counter += len3 + len2;
    1032                 :         16 :           move = RIGHT;
    1033                 :         16 :           break;
    1034                 :            :         case TYPE_GENERALSTRING:
    1035         [ -  + ]:          6 :           if (p->value == NULL)
    1036                 :            :             {
    1037                 :          0 :               _asn1_error_description_value_not_found (p, ErrorDescription);
    1038                 :          0 :               err = ASN1_VALUE_NOT_FOUND;
    1039                 :          0 :               goto error;
    1040                 :            :             }
    1041                 :          6 :           len2 = asn1_get_length_der (p->value, p->value_len, &len3);
    1042         [ -  + ]:          6 :           if (len2 < 0)
    1043                 :            :             {
    1044                 :          0 :               err = ASN1_DER_ERROR;
    1045                 :          0 :               goto error;
    1046                 :            :             }
    1047                 :          6 :           max_len -= len2 + len3;
    1048         [ +  + ]:          6 :           if (max_len >= 0)
    1049                 :          4 :             memcpy (der + counter, p->value, len3 + len2);
    1050                 :          6 :           counter += len3 + len2;
    1051                 :          6 :           move = RIGHT;
    1052                 :          6 :           break;
    1053                 :            :         case TYPE_BIT_STRING:
    1054         [ -  + ]:          3 :           if (p->value == NULL)
    1055                 :            :             {
    1056                 :          0 :               _asn1_error_description_value_not_found (p, ErrorDescription);
    1057                 :          0 :               err = ASN1_VALUE_NOT_FOUND;
    1058                 :          0 :               goto error;
    1059                 :            :             }
    1060                 :          3 :           len2 = asn1_get_length_der (p->value, p->value_len, &len3);
    1061         [ -  + ]:          3 :           if (len2 < 0)
    1062                 :            :             {
    1063                 :          0 :               err = ASN1_DER_ERROR;
    1064                 :          0 :               goto error;
    1065                 :            :             }
    1066                 :          3 :           max_len -= len2 + len3;
    1067         [ +  + ]:          3 :           if (max_len >= 0)
    1068                 :          2 :             memcpy (der + counter, p->value, len3 + len2);
    1069                 :          3 :           counter += len3 + len2;
    1070                 :          3 :           move = RIGHT;
    1071                 :          3 :           break;
    1072                 :            :         case TYPE_SEQUENCE:
    1073                 :            :         case TYPE_SET:
    1074         [ +  + ]:        114 :           if (move != UP)
    1075                 :            :             {
    1076                 :         57 :               _asn1_ltostr (counter, (char *) temp);
    1077                 :         57 :               tlen = _asn1_strlen (temp);
    1078         [ +  - ]:         57 :               if (tlen > 0)
    1079                 :         57 :                 _asn1_set_value (p, temp, tlen + 1);
    1080         [ -  + ]:         57 :               if (p->down == NULL)
    1081                 :            :                 {
    1082                 :          0 :                   move = UP;
    1083                 :          0 :                   continue;
    1084                 :            :                 }
    1085                 :            :               else
    1086                 :            :                 {
    1087                 :         57 :                   p2 = p->down;
    1088 [ +  + ][ +  + ]:         64 :                   while (p2 && (type_field (p2->type) == TYPE_TAG))
    1089                 :          7 :                     p2 = p2->right;
    1090         [ +  + ]:         57 :                   if (p2)
    1091                 :            :                     {
    1092                 :         54 :                       p = p2;
    1093                 :         54 :                       move = RIGHT;
    1094                 :         54 :                       continue;
    1095                 :            :                     }
    1096                 :          3 :                   move = UP;
    1097                 :          3 :                   continue;
    1098                 :            :                 }
    1099                 :            :             }
    1100                 :            :           else
    1101                 :            :             {                   /* move==UP */
    1102                 :         57 :               len2 = _asn1_strtol (p->value, NULL, 10);
    1103                 :         57 :               _asn1_set_value (p, NULL, 0);
    1104 [ -  + ][ #  # ]:         57 :               if ((type_field (p->type) == TYPE_SET) && (max_len >= 0))
    1105                 :          0 :                 _asn1_ordering_set (der + len2, max_len - len2, p);
    1106                 :         57 :               asn1_length_der (counter - len2, temp, &len3);
    1107                 :         57 :               max_len -= len3;
    1108         [ +  + ]:         57 :               if (max_len >= 0)
    1109                 :            :                 {
    1110                 :         29 :                   memmove (der + len2 + len3, der + len2, counter - len2);
    1111                 :         29 :                   memcpy (der + len2, temp, len3);
    1112                 :            :                 }
    1113                 :         57 :               counter += len3;
    1114                 :         57 :               move = RIGHT;
    1115                 :            :             }
    1116                 :         57 :           break;
    1117                 :            :         case TYPE_SEQUENCE_OF:
    1118                 :            :         case TYPE_SET_OF:
    1119         [ +  + ]:         28 :           if (move != UP)
    1120                 :            :             {
    1121                 :         17 :               _asn1_ltostr (counter, (char *) temp);
    1122                 :         17 :               tlen = _asn1_strlen (temp);
    1123                 :            : 
    1124         [ +  - ]:         17 :               if (tlen > 0)
    1125                 :         17 :                 _asn1_set_value (p, temp, tlen + 1);
    1126                 :         17 :               p = p->down;
    1127         [ +  + ]:         26 :               while ((type_field (p->type) == TYPE_TAG)
    1128         [ +  + ]:         20 :                      || (type_field (p->type) == TYPE_SIZE))
    1129                 :          9 :                 p = p->right;
    1130         [ +  + ]:         17 :               if (p->right)
    1131                 :            :                 {
    1132                 :         11 :                   p = p->right;
    1133                 :         11 :                   move = RIGHT;
    1134                 :         11 :                   continue;
    1135                 :            :                 }
    1136                 :            :               else
    1137                 :          6 :                 p = _asn1_find_up (p);
    1138                 :          6 :               move = UP;
    1139                 :            :             }
    1140         [ +  - ]:         17 :           if (move == UP)
    1141                 :            :             {
    1142                 :         17 :               len2 = _asn1_strtol (p->value, NULL, 10);
    1143                 :         17 :               _asn1_set_value (p, NULL, 0);
    1144         [ +  + ]:         17 :               if ((type_field (p->type) == TYPE_SET_OF)
    1145         [ +  + ]:         16 :                   && (max_len - len2 > 0))
    1146                 :            :                 {
    1147                 :          9 :                   _asn1_ordering_set_of (der + len2, max_len - len2, p);
    1148                 :            :                 }
    1149                 :         17 :               asn1_length_der (counter - len2, temp, &len3);
    1150                 :         17 :               max_len -= len3;
    1151         [ +  + ]:         17 :               if (max_len >= 0)
    1152                 :            :                 {
    1153                 :         12 :                   memmove (der + len2 + len3, der + len2, counter - len2);
    1154                 :         12 :                   memcpy (der + len2, temp, len3);
    1155                 :            :                 }
    1156                 :         17 :               counter += len3;
    1157                 :         17 :               move = RIGHT;
    1158                 :            :             }
    1159                 :         17 :           break;
    1160                 :            :         case TYPE_ANY:
    1161         [ -  + ]:         27 :           if (p->value == NULL)
    1162                 :            :             {
    1163                 :          0 :               _asn1_error_description_value_not_found (p, ErrorDescription);
    1164                 :          0 :               err = ASN1_VALUE_NOT_FOUND;
    1165                 :          0 :               goto error;
    1166                 :            :             }
    1167                 :         27 :           len2 = asn1_get_length_der (p->value, p->value_len, &len3);
    1168         [ -  + ]:         27 :           if (len2 < 0)
    1169                 :            :             {
    1170                 :          0 :               err = ASN1_DER_ERROR;
    1171                 :          0 :               goto error;
    1172                 :            :             }
    1173                 :         27 :           max_len -= len2;
    1174         [ +  + ]:         27 :           if (max_len >= 0)
    1175                 :         18 :             memcpy (der + counter, p->value + len3, len2);
    1176                 :         27 :           counter += len2;
    1177                 :         27 :           move = RIGHT;
    1178                 :         27 :           break;
    1179                 :            :         default:
    1180         [ +  + ]:         30 :           move = (move == UP) ? RIGHT : DOWN;
    1181                 :         30 :           break;
    1182                 :            :         }
    1183                 :            : 
    1184 [ +  + ][ +  + ]:        267 :       if ((move != DOWN) && (counter != counter_old))
    1185                 :            :         {
    1186                 :        222 :           err = _asn1_complete_explicit_tag (p, der, &counter, &max_len);
    1187 [ +  + ][ -  + ]:        222 :           if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
    1188                 :          0 :             goto error;
    1189                 :            :         }
    1190                 :            : 
    1191 [ +  + ][ +  + ]:        267 :       if (p == node && move != DOWN)
    1192                 :         47 :         break;
    1193                 :            : 
    1194         [ +  + ]:        220 :       if (move == DOWN)
    1195                 :            :         {
    1196         [ +  - ]:         15 :           if (p->down)
    1197                 :         15 :             p = p->down;
    1198                 :            :           else
    1199                 :          0 :             move = RIGHT;
    1200                 :            :         }
    1201         [ +  + ]:        220 :       if (move == RIGHT)
    1202                 :            :         {
    1203         [ +  + ]:        205 :           if (p->right)
    1204                 :        125 :             p = p->right;
    1205                 :            :           else
    1206                 :         80 :             move = UP;
    1207                 :            :         }
    1208         [ +  + ]:        220 :       if (move == UP)
    1209                 :         80 :         p = _asn1_find_up (p);
    1210                 :        288 :     }
    1211                 :            : 
    1212                 :         47 :   *len = counter;
    1213                 :            : 
    1214         [ +  + ]:         47 :   if (max_len < 0)
    1215                 :            :     {
    1216                 :         25 :       err = ASN1_MEM_ERROR;
    1217                 :         25 :       goto error;
    1218                 :            :     }
    1219                 :            : 
    1220                 :         22 :   err = ASN1_SUCCESS;
    1221                 :            : 
    1222                 :            : error:
    1223                 :         47 :   asn1_delete_structure (&node);
    1224                 :         47 :   return err;
    1225                 :            : }

Generated by: LCOV version 1.9