LCOV - code coverage report
Current view: top level - lib - coding.c (source / functions) Hit Total Coverage
Test: GNU Libtasn1 Lines: 396 520 76.2 %
Date: 2013-03-24 Functions: 11 13 84.6 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 238 339 70.2 %

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

Generated by: LCOV version 1.9