LCOV - code coverage report
Current view: top level - src - cms-parser.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 441 0.0 %
Date: 2016-09-12 12:20:35 Functions: 0 11 0.0 %

          Line data    Source code
       1             : /* cms-parse.c - parse cryptographic message syntax
       2             :  *      Copyright (C) 2001, 2012 g10 Code GmbH
       3             :  *
       4             :  * This file is part of KSBA.
       5             :  *
       6             :  * KSBA is free software; you can redistribute it and/or modify
       7             :  * it under the terms of either
       8             :  *
       9             :  *   - the GNU Lesser General Public License as published by the Free
      10             :  *     Software Foundation; either version 3 of the License, or (at
      11             :  *     your option) any later version.
      12             :  *
      13             :  * or
      14             :  *
      15             :  *   - the GNU General Public License as published by the Free
      16             :  *     Software Foundation; either version 2 of the License, or (at
      17             :  *     your option) any later version.
      18             :  *
      19             :  * or both in parallel, as here.
      20             :  *
      21             :  * KSBA is distributed in the hope that it will be useful, but WITHOUT
      22             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
      23             :  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
      24             :  * License for more details.
      25             :  *
      26             :  * You should have received a copies of the GNU General Public License
      27             :  * and the GNU Lesser General Public License along with this program;
      28             :  * if not, see <http://www.gnu.org/licenses/>.
      29             :  */
      30             : 
      31             : /*
      32             :    We handle CMS by using a handcrafted parser for the outer
      33             :    structures and the generic parser of the parts we can handle in
      34             :    memory.  Extending the generic parser to allow hooks for indefinite
      35             :    length objects and to auto select the object depending on the
      36             :    content type OID is too complicated.
      37             : */
      38             : 
      39             : 
      40             : #include <config.h>
      41             : #include <stdio.h>
      42             : #include <stdlib.h>
      43             : #include <string.h>
      44             : #include <assert.h>
      45             : #include "util.h"
      46             : 
      47             : #include "cms.h"
      48             : #include "asn1-func.h" /* need some constants */
      49             : #include "ber-decoder.h"
      50             : #include "ber-help.h"
      51             : #include "keyinfo.h"
      52             : 
      53             : static int
      54           0 : read_byte (ksba_reader_t reader)
      55             : {
      56             :   unsigned char buf;
      57             :   size_t nread;
      58             :   int rc;
      59             : 
      60             :   do
      61           0 :     rc = ksba_reader_read (reader, &buf, 1, &nread);
      62           0 :   while (!rc && !nread);
      63           0 :   return rc? -1: buf;
      64             : }
      65             : 
      66             : /* read COUNT bytes into buffer.  Return 0 on success */
      67             : static int
      68           0 : read_buffer (ksba_reader_t reader, char *buffer, size_t count)
      69             : {
      70             :   size_t nread;
      71             : 
      72           0 :   while (count)
      73             :     {
      74           0 :       if (ksba_reader_read (reader, buffer, count, &nread))
      75           0 :         return -1;
      76           0 :       buffer += nread;
      77           0 :       count -= nread;
      78             :     }
      79           0 :   return 0;
      80             : }
      81             : 
      82             : /* Create a new decoder and run it for the given element */
      83             : static gpg_error_t
      84           0 : create_and_run_decoder (ksba_reader_t reader, const char *elem_name,
      85             :                         unsigned int flags,
      86             :                         AsnNode *r_root,
      87             :                         unsigned char **r_image, size_t *r_imagelen)
      88             : {
      89             :   gpg_error_t err;
      90             :   ksba_asn_tree_t cms_tree;
      91             :   BerDecoder decoder;
      92             : 
      93           0 :   err = ksba_asn_create_tree ("cms", &cms_tree);
      94           0 :   if (err)
      95           0 :     return err;
      96             : 
      97           0 :   decoder = _ksba_ber_decoder_new ();
      98           0 :   if (!decoder)
      99             :     {
     100           0 :       ksba_asn_tree_release (cms_tree);
     101           0 :       return gpg_error (GPG_ERR_ENOMEM);
     102             :     }
     103             : 
     104           0 :   err = _ksba_ber_decoder_set_reader (decoder, reader);
     105           0 :   if (err)
     106             :     {
     107           0 :       ksba_asn_tree_release (cms_tree);
     108           0 :       _ksba_ber_decoder_release (decoder);
     109           0 :       return err;
     110             :     }
     111             : 
     112           0 :   err = _ksba_ber_decoder_set_module (decoder, cms_tree);
     113           0 :   if (err)
     114             :     {
     115           0 :       ksba_asn_tree_release (cms_tree);
     116           0 :       _ksba_ber_decoder_release (decoder);
     117           0 :       return err;
     118             :     }
     119             : 
     120           0 :   err = _ksba_ber_decoder_decode (decoder, elem_name, flags,
     121             :                                   r_root, r_image, r_imagelen);
     122             : 
     123           0 :   _ksba_ber_decoder_release (decoder);
     124           0 :   ksba_asn_tree_release (cms_tree);
     125           0 :   return err;
     126             : }
     127             : 
     128             : 
     129             : 
     130             : /* Parse this structure and return the oid of the content.  The read
     131             :    position is then located at the value of content.  This fucntion is
     132             :    the core for parsing ContentInfo and EncapsulatedContentInfo.
     133             : 
     134             :    ContentInfo ::= SEQUENCE {
     135             :       contentType ContentType,
     136             :       content [0] EXPLICIT ANY DEFINED BY contentType
     137             :    }
     138             :    ContentType ::= OBJECT IDENTIFIER
     139             : 
     140             :    Returns: 0 on success or an error code. Other values are returned
     141             :    by the parameters.
     142             : 
     143             : */
     144             : static gpg_error_t
     145           0 : parse_content_info (ksba_reader_t reader,
     146             :                     unsigned long *r_len, int *r_ndef,
     147             :                     char **r_oid, int *has_content)
     148             : {
     149             :   struct tag_info ti;
     150             :   gpg_error_t err;
     151             :   int content_ndef;
     152             :   unsigned long content_len;
     153             :   unsigned char oidbuf[100]; /* pretty large for an OID */
     154           0 :   char *oid = NULL;
     155             : 
     156             :   /* read the sequence triplet */
     157           0 :   err = _ksba_ber_read_tl (reader, &ti);
     158           0 :   if (err)
     159           0 :     return err;
     160           0 :   if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
     161           0 :          && ti.is_constructed) )
     162           0 :     return gpg_error (GPG_ERR_INV_CMS_OBJ);
     163           0 :   content_len = ti.length;
     164           0 :   content_ndef = ti.ndef;
     165           0 :   if (!content_ndef && content_len < 3)
     166           0 :     return gpg_error (GPG_ERR_TOO_SHORT); /* to encode an OID */
     167             : 
     168             :   /* read the OID */
     169           0 :   err = _ksba_ber_read_tl (reader, &ti);
     170           0 :   if (err)
     171           0 :     return err;
     172           0 :   if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_OBJECT_ID
     173           0 :          && !ti.is_constructed && ti.length) )
     174           0 :     return gpg_error (GPG_ERR_INV_CMS_OBJ);
     175           0 :   if (!content_ndef)
     176             :     {
     177           0 :       if (content_len < ti.nhdr)
     178           0 :         return gpg_error (GPG_ERR_BAD_BER); /* triplet header larger that sequence */
     179           0 :       content_len -= ti.nhdr;
     180           0 :       if (content_len < ti.length)
     181           0 :         return gpg_error (GPG_ERR_BAD_BER); /* triplet larger that sequence */
     182           0 :       content_len -= ti.length;
     183             :     }
     184             : 
     185           0 :   if (ti.length >= DIM(oidbuf))
     186           0 :     return gpg_error (GPG_ERR_TOO_LARGE);
     187           0 :   err = read_buffer (reader, oidbuf, ti.length);
     188           0 :   if (err)
     189           0 :     return err;
     190           0 :   oid = ksba_oid_to_str (oidbuf, ti.length);
     191           0 :   if (!oid)
     192           0 :     return gpg_error (GPG_ERR_ENOMEM);
     193             : 
     194           0 :   if (!content_ndef && !content_len)
     195             :     { /* no data */
     196           0 :       *has_content = 0;
     197             :     }
     198             :   else
     199             :     { /* now read the explicit tag 0 which is optional */
     200           0 :       err = _ksba_ber_read_tl (reader, &ti);
     201           0 :       if (err)
     202             :         {
     203           0 :           xfree (oid);
     204           0 :           return err;
     205             :         }
     206             : 
     207           0 :       if ( ti.class == CLASS_CONTEXT && ti.tag == 0 && ti.is_constructed )
     208             :         {
     209           0 :           *has_content = 1;
     210             :         }
     211           0 :       else if ( ti.class == CLASS_UNIVERSAL && ti.tag == 0 && !ti.is_constructed )
     212             :         {
     213           0 :           *has_content = 0; /* this is optional - allow NUL tag */
     214             :         }
     215             :       else /* neither [0] nor NULL */
     216             :         {
     217           0 :           xfree (oid);
     218           0 :           return gpg_error (GPG_ERR_INV_CMS_OBJ);
     219             :         }
     220           0 :       if (!content_ndef)
     221             :         {
     222           0 :           if (content_len < ti.nhdr)
     223           0 :             return gpg_error (GPG_ERR_BAD_BER); /* triplet header larger that sequence */
     224           0 :           content_len -= ti.nhdr;
     225           0 :           if (!ti.ndef && content_len < ti.length)
     226           0 :             return gpg_error (GPG_ERR_BAD_BER); /* triplet larger that sequence */
     227             :         }
     228             :     }
     229           0 :   *r_len = content_len;
     230           0 :   *r_ndef = content_ndef;
     231           0 :   *r_oid = oid;
     232           0 :   return 0;
     233             : }
     234             : 
     235             : 
     236             : /* Parse this structure and return the oid of the content as well as
     237             :    the algorithm identifier.  The read position is then located at the
     238             :    value of the octect string.
     239             : 
     240             :    EncryptedContentInfo ::= SEQUENCE {
     241             :      contentType OBJECT IDENTIFIER,
     242             :      contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
     243             :      encryptedContent [0] IMPLICIT OCTET STRING OPTIONAL }
     244             : 
     245             :    Returns: 0 on success or an error code. Other values are returned
     246             :    by the parameters.
     247             : */
     248             : static gpg_error_t
     249           0 : parse_encrypted_content_info (ksba_reader_t reader,
     250             :                               unsigned long *r_len, int *r_ndef,
     251             :                               char **r_cont_oid, char **r_algo_oid,
     252             :                               char **r_algo_parm, size_t *r_algo_parmlen,
     253             :                               int *has_content)
     254             : {
     255             :   struct tag_info ti;
     256             :   gpg_error_t err;
     257             :   int content_ndef;
     258             :   unsigned long content_len;
     259             :   unsigned char tmpbuf[500]; /* for OID or algorithmIdentifier */
     260           0 :   char *cont_oid = NULL;
     261           0 :   char *algo_oid = NULL;
     262           0 :   char *algo_parm = NULL;
     263             :   size_t algo_parmlen;
     264             :   size_t nread;
     265             : 
     266             :   /* Fixme: release oids in case of errors */
     267             : 
     268             :   /* read the sequence triplet */
     269           0 :   err = _ksba_ber_read_tl (reader, &ti);
     270           0 :   if (err)
     271           0 :     return err;
     272           0 :   if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
     273           0 :          && ti.is_constructed) )
     274           0 :     return gpg_error (GPG_ERR_INV_CMS_OBJ);
     275           0 :   content_len = ti.length;
     276           0 :   content_ndef = ti.ndef;
     277           0 :   if (!content_ndef && content_len < 3)
     278           0 :     return gpg_error (GPG_ERR_TOO_SHORT); /* to encode an OID */
     279             : 
     280             :   /* read the OID */
     281           0 :   err = _ksba_ber_read_tl (reader, &ti);
     282           0 :   if (err)
     283           0 :     return err;
     284           0 :   if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_OBJECT_ID
     285           0 :          && !ti.is_constructed && ti.length) )
     286           0 :     return gpg_error (GPG_ERR_INV_CMS_OBJ);
     287           0 :   if (!content_ndef)
     288             :     {
     289           0 :       if (content_len < ti.nhdr)
     290           0 :         return gpg_error (GPG_ERR_BAD_BER); /* triplet header larger that sequence */
     291           0 :       content_len -= ti.nhdr;
     292           0 :       if (content_len < ti.length)
     293           0 :         return gpg_error (GPG_ERR_BAD_BER); /* triplet larger that sequence */
     294           0 :       content_len -= ti.length;
     295             :     }
     296           0 :   if (ti.length >= DIM(tmpbuf))
     297           0 :     return gpg_error (GPG_ERR_TOO_LARGE);
     298           0 :   err = read_buffer (reader, tmpbuf, ti.length);
     299           0 :   if (err)
     300           0 :     return err;
     301           0 :   cont_oid = ksba_oid_to_str (tmpbuf, ti.length);
     302           0 :   if (!cont_oid)
     303           0 :     return gpg_error (GPG_ERR_ENOMEM);
     304             : 
     305             :   /* read the algorithmIdentifier */
     306           0 :   err = _ksba_ber_read_tl (reader, &ti);
     307           0 :   if (err)
     308           0 :     return err;
     309           0 :   if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
     310           0 :          && ti.is_constructed) )
     311           0 :     return gpg_error (GPG_ERR_INV_CMS_OBJ);
     312           0 :   if (!content_ndef)
     313             :     {
     314           0 :       if (content_len < ti.nhdr)
     315           0 :         return gpg_error (GPG_ERR_BAD_BER); /* triplet header larger that sequence */
     316           0 :       content_len -= ti.nhdr;
     317           0 :       if (content_len < ti.length)
     318           0 :         return gpg_error (GPG_ERR_BAD_BER); /* triplet larger that sequence */
     319           0 :       content_len -= ti.length;
     320             :     }
     321           0 :   if (ti.nhdr + ti.length >= DIM(tmpbuf))
     322           0 :     return gpg_error (GPG_ERR_TOO_LARGE);
     323           0 :   memcpy (tmpbuf, ti.buf, ti.nhdr);
     324           0 :   err = read_buffer (reader, tmpbuf+ti.nhdr, ti.length);
     325           0 :   if (err)
     326           0 :     return err;
     327           0 :   err = _ksba_parse_algorithm_identifier2 (tmpbuf, ti.nhdr+ti.length,
     328             :                                            &nread,&algo_oid,
     329             :                                            &algo_parm, &algo_parmlen);
     330           0 :   if (err)
     331           0 :     return err;
     332           0 :   assert (nread <= ti.nhdr + ti.length);
     333           0 :   if (nread < ti.nhdr + ti.length)
     334           0 :     return gpg_error (GPG_ERR_TOO_SHORT);
     335             : 
     336             :   /* the optional encryptedDataInfo */
     337           0 :   *has_content = 0;
     338           0 :   if (content_ndef || content_len)
     339             :     { /* now read the implicit tag 0.  Actually this is optional but
     340             :          in that case we don't expect to have a content_len - well, it
     341             :          may be the end tag */
     342           0 :       err = _ksba_ber_read_tl (reader, &ti);
     343           0 :       if (err)
     344             :         {
     345           0 :           xfree (cont_oid);
     346           0 :           xfree (algo_oid);
     347           0 :           return err;
     348             :         }
     349             : 
     350             :       /* Note: the tag may either denote a constructed or a primitve
     351             :          object.  Actually this should match the use of NDEF header
     352             :          but we don't ceck that */
     353           0 :       if ( ti.class == CLASS_CONTEXT && ti.tag == 0 )
     354             :         {
     355           0 :           *has_content = 1;
     356           0 :           if (!content_ndef)
     357             :             {
     358           0 :               if (content_len < ti.nhdr)
     359           0 :                 return gpg_error (GPG_ERR_BAD_BER);
     360           0 :               content_len -= ti.nhdr;
     361           0 :               if (!ti.ndef && content_len < ti.length)
     362           0 :                 return gpg_error (GPG_ERR_BAD_BER);
     363             :             }
     364             :         }
     365             :       else /* not what we want - push it back */
     366             :         {
     367           0 :           *has_content = 0;
     368           0 :           err = ksba_reader_unread (reader, ti.buf, ti.nhdr);
     369           0 :           if (err)
     370           0 :             return err;
     371             :         }
     372             :     }
     373           0 :   *r_len = content_len;
     374           0 :   *r_ndef = content_ndef;
     375           0 :   *r_cont_oid = cont_oid;
     376           0 :   *r_algo_oid = algo_oid;
     377           0 :   *r_algo_parm = algo_parm;
     378           0 :   *r_algo_parmlen = algo_parmlen;
     379           0 :   return 0;
     380             : }
     381             : 
     382             : 
     383             : 
     384             : /* Parse this structure and return the oid of the content.  The read
     385             :    position is then located at the value of content.
     386             : 
     387             :    ContentInfo ::= SEQUENCE {
     388             :       contentType ContentType,
     389             :       content [0] EXPLICIT ANY DEFINED BY contentType
     390             :    }
     391             :    ContentType ::= OBJECT IDENTIFIER
     392             : 
     393             :    Returns: 0 on success or an error code.  On success the OID and the
     394             :    length values are stored in the cms structure.
     395             : */
     396             : gpg_error_t
     397           0 : _ksba_cms_parse_content_info (ksba_cms_t cms)
     398             : {
     399             :   gpg_error_t err;
     400             :   int has_content;
     401             :   int content_ndef;
     402             :   unsigned long content_len;
     403             :   char *oid;
     404             : 
     405           0 :   err = parse_content_info (cms->reader, &content_len, &content_ndef,
     406             :                             &oid, &has_content);
     407           0 :   if (err)
     408             :     { /* return a more meaningful error message.  This way the caller
     409             :          can pass arbitrary data to the function and get back an error
     410             :          that this is not CMS instead of the the not very detailed BER
     411             :          Error. */
     412           0 :       if (gpg_err_code (err) == GPG_ERR_BAD_BER
     413           0 :           || gpg_err_code (err) == GPG_ERR_INV_CMS_OBJ
     414           0 :           || gpg_err_code (err) == GPG_ERR_TOO_SHORT)
     415           0 :         err = gpg_error (GPG_ERR_NO_CMS_OBJ);
     416           0 :       return err;
     417             :     }
     418           0 :   if (!has_content)
     419           0 :     return gpg_error (GPG_ERR_NO_CMS_OBJ); /* It is not optional here */
     420           0 :   cms->content.length = content_len;
     421           0 :   cms->content.ndef = content_ndef;
     422           0 :   xfree (cms->content.oid);
     423           0 :   cms->content.oid = oid;
     424           0 :   return 0;
     425             : }
     426             : 
     427             : 
     428             : 
     429             : /* parse a SEQUENCE and the first element which is expected to be the
     430             :    CMS version.  Return the version and the length info */
     431             : static gpg_error_t
     432           0 : parse_cms_version (ksba_reader_t reader, int *r_version,
     433             :                    unsigned long *r_len, int *r_ndef)
     434             : {
     435             :   struct tag_info ti;
     436             :   gpg_error_t err;
     437             :   unsigned long data_len;
     438             :   int data_ndef;
     439             :   int c;
     440             : 
     441             :   /* read the sequence triplet */
     442           0 :   err = _ksba_ber_read_tl (reader, &ti);
     443           0 :   if (err)
     444           0 :     return err;
     445           0 :   if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
     446           0 :          && ti.is_constructed) )
     447           0 :     return gpg_error (GPG_ERR_INV_CMS_OBJ);
     448           0 :   data_len = ti.length;
     449           0 :   data_ndef = ti.ndef;
     450           0 :   if (!data_ndef && data_len < 3)
     451           0 :     return gpg_error (GPG_ERR_TOO_SHORT); /*to encode the version*/
     452             : 
     453             :   /* read the version integer */
     454           0 :   err = _ksba_ber_read_tl (reader, &ti);
     455           0 :   if (err)
     456           0 :     return err;
     457           0 :   if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_INTEGER
     458           0 :          && !ti.is_constructed && ti.length) )
     459           0 :     return gpg_error (GPG_ERR_INV_CMS_OBJ);
     460           0 :   if (!data_ndef)
     461             :     {
     462           0 :       if (data_len < ti.nhdr)
     463           0 :         return gpg_error (GPG_ERR_BAD_BER); /* triplet header larger that sequence */
     464           0 :       data_len -= ti.nhdr;
     465           0 :       if (data_len < ti.length)
     466           0 :         return gpg_error (GPG_ERR_BAD_BER); /* triplet larger that sequence */
     467           0 :       data_len -= ti.length;
     468             :     }
     469           0 :   if (ti.length != 1)
     470           0 :     return gpg_error (GPG_ERR_UNSUPPORTED_CMS_VERSION);
     471           0 :   if ( (c=read_byte (reader)) == -1)
     472             :     {
     473           0 :       err = ksba_reader_error (reader);
     474           0 :       return err? err : gpg_error (GPG_ERR_GENERAL);
     475             :     }
     476           0 :   if ( !(c == 0 || c == 1 || c == 2 || c == 3 || c == 4) )
     477           0 :     return gpg_error (GPG_ERR_UNSUPPORTED_CMS_VERSION);
     478           0 :   *r_version = c;
     479           0 :   *r_len = data_len;
     480           0 :   *r_ndef = data_ndef;
     481           0 :   return 0;
     482             : }
     483             : 
     484             : 
     485             : 
     486             : 
     487             : /* Parse a structure:
     488             : 
     489             :    SignedData ::= SEQUENCE {
     490             :      version INTEGER  { v0(0), v1(1), v2(2), v3(3), v4(4) }),
     491             :      digestAlgorithms SET OF AlgorithmIdentifier,
     492             :      encapContentInfo EncapsulatedContentInfo,
     493             :      certificates [0] IMPLICIT CertificateSet OPTIONAL,
     494             :      crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
     495             :      signerInfos SignerInfos }
     496             : 
     497             :    AlgorithmIdentifier ::= SEQUENCE {
     498             :     algorithm    OBJECT IDENTIFIER,
     499             :     parameters   ANY DEFINED BY algorithm OPTIONAL
     500             :    }
     501             : 
     502             : */
     503             : gpg_error_t
     504           0 : _ksba_cms_parse_signed_data_part_1 (ksba_cms_t cms)
     505             : {
     506             :   struct tag_info ti;
     507             :   gpg_error_t err;
     508             :   int signed_data_ndef;
     509             :   unsigned long signed_data_len;
     510             :   int algo_set_ndef;
     511             :   unsigned long algo_set_len;
     512             :   int encap_cont_ndef;
     513             :   unsigned long encap_cont_len;
     514             :   int has_content;
     515             :   char *oid;
     516             :   char *p, *buffer;
     517             :   unsigned long off, len;
     518             : 
     519           0 :   err = parse_cms_version (cms->reader, &cms->cms_version,
     520             :                            &signed_data_len, &signed_data_ndef);
     521           0 :   if (err)
     522           0 :     return err;
     523             : 
     524             :   /* read the SET OF algorithmIdentifiers */
     525           0 :   err = _ksba_ber_read_tl (cms->reader, &ti);
     526           0 :   if (err)
     527           0 :     return err;
     528           0 :   if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SET
     529           0 :          && ti.is_constructed) )
     530           0 :     return gpg_error (GPG_ERR_INV_CMS_OBJ);  /* not the expected SET tag */
     531           0 :   if (!signed_data_ndef)
     532             :     {
     533           0 :       if (signed_data_len < ti.nhdr)
     534           0 :         return gpg_error (GPG_ERR_BAD_BER); /* triplet header larger that sequence */
     535           0 :       signed_data_len -= ti.nhdr;
     536           0 :       if (!ti.ndef && signed_data_len < ti.length)
     537           0 :         return gpg_error (GPG_ERR_BAD_BER); /* triplet larger that sequence */
     538           0 :       signed_data_len -= ti.length;
     539             :     }
     540           0 :   algo_set_len = ti.length;
     541           0 :   algo_set_ndef = ti.ndef;
     542             : 
     543             :   /* fixme: we are not able to read ndef length algorithm indentifiers. */
     544           0 :   if (algo_set_ndef)
     545           0 :     return gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
     546             :   /* read the entire sequence into a buffer (add one to avoid malloc(0)) */
     547           0 :   buffer = xtrymalloc (algo_set_len + 1);
     548           0 :   if (!buffer)
     549           0 :     return gpg_error (GPG_ERR_ENOMEM);
     550           0 :   if (read_buffer (cms->reader, buffer, algo_set_len))
     551             :     {
     552           0 :       xfree (buffer);
     553           0 :       err = ksba_reader_error (cms->reader);
     554           0 :       return err? err: gpg_error (GPG_ERR_GENERAL);
     555             :     }
     556           0 :   p = buffer;
     557           0 :   while (algo_set_len)
     558             :     {
     559             :       size_t nread;
     560             :       struct oidlist_s *ol;
     561             : 
     562           0 :       err = _ksba_parse_algorithm_identifier (p, algo_set_len, &nread, &oid);
     563           0 :       if (err)
     564             :         {
     565           0 :           xfree (buffer);
     566           0 :           return err;
     567             :         }
     568           0 :       assert (nread <= algo_set_len);
     569           0 :       algo_set_len -= nread;
     570           0 :       p += nread;
     571             :       /* store the oid */
     572           0 :       ol = xtrymalloc (sizeof *ol);
     573           0 :       if (!ol)
     574             :         {
     575           0 :           xfree (oid);
     576           0 :           return gpg_error (GPG_ERR_ENOMEM);
     577             :         }
     578           0 :       ol->oid = oid;
     579           0 :       ol->next = cms->digest_algos;
     580           0 :       cms->digest_algos = ol;
     581             :     }
     582           0 :   xfree (buffer); buffer = NULL;
     583             : 
     584             :   /* Now for the encapsulatedContentInfo */
     585           0 :   off = ksba_reader_tell (cms->reader);
     586           0 :   err = parse_content_info (cms->reader,
     587             :                             &encap_cont_len, &encap_cont_ndef,
     588             :                             &oid, &has_content);
     589           0 :   if (err)
     590           0 :     return err;
     591           0 :   cms->inner_cont_len = encap_cont_len;
     592           0 :   cms->inner_cont_ndef = encap_cont_ndef;
     593           0 :   cms->inner_cont_oid = oid;
     594           0 :   cms->detached_data = !has_content;
     595           0 :   if (!signed_data_ndef)
     596             :     {
     597           0 :       len = ksba_reader_tell (cms->reader) - off;
     598           0 :       if (signed_data_len < len)
     599           0 :         return gpg_error (GPG_ERR_BAD_BER); /* parsed content info larger that sequence */
     600           0 :       signed_data_len -= len;
     601           0 :       if (!encap_cont_ndef && signed_data_len < encap_cont_len)
     602           0 :         return gpg_error (GPG_ERR_BAD_BER); /* triplet larger that sequence */
     603             :     }
     604             : 
     605             :   /* We have to stop here so that the caller can set up the hashing etc. */
     606           0 :   return 0;
     607             : }
     608             : 
     609             : /* Continue parsing of the structure we started to parse with the
     610             :    part_1 function.  We expect to be right at the certificates tag.  */
     611             : gpg_error_t
     612           0 : _ksba_cms_parse_signed_data_part_2 (ksba_cms_t cms)
     613             : {
     614             :   struct tag_info ti;
     615             :   gpg_error_t err;
     616             :   struct signer_info_s *si, **si_tail;
     617             : 
     618             :   /* read the next triplet which is either a [0], a [1] or a SET OF
     619             :      (signerInfo) */
     620           0 :   err = _ksba_ber_read_tl (cms->reader, &ti);
     621           0 :   if (err)
     622           0 :     return err;
     623           0 :   if (ti.class == CLASS_UNIVERSAL && !ti.tag && !ti.is_constructed)
     624             :     {
     625             :       /* well, there might be still an end tag pending; eat it -
     626             :          fixme: we should keep track of this to catch invalid
     627             :          encodings */
     628           0 :       err = _ksba_ber_read_tl (cms->reader, &ti);
     629           0 :       if (err)
     630           0 :         return err;
     631             :     }
     632             : 
     633           0 :   if (ti.class == CLASS_CONTEXT && ti.tag == 0 && ti.is_constructed)
     634             :     {  /* Implicit SET OF certificateSet with elements of CHOICE, but
     635             :           we assume the first choice which is a Certificate; all other
     636             :           choices are obsolete.  We are now parsing a set of
     637             :           certificates which we do by utilizing the ksba_cert code. */
     638             :       ksba_cert_t cert;
     639             :       int expect_endtag;
     640             : 
     641           0 :       expect_endtag = !!ti.ndef;
     642             : 
     643             :       for (;;)
     644             :         {
     645             :           struct certlist_s *cl;
     646             : 
     647             :           /* First see whether this is really a sequence */
     648           0 :           err = _ksba_ber_read_tl (cms->reader, &ti);
     649           0 :           if (err)
     650           0 :             return err;
     651           0 :           if (expect_endtag && !ti.class && ti.tag == TYPE_NULL )
     652             :             {
     653             :               /* This is an end tag.  Read the next tag but don't fail
     654             :                  if this is just an EOF.  */
     655           0 :               err = _ksba_ber_read_tl (cms->reader, &ti);
     656           0 :               if (err)
     657             :                 {
     658           0 :                   if (gpg_err_code (err) == GPG_ERR_EOF)
     659           0 :                     err = 0;
     660           0 :                   return err;
     661             :                 }
     662           0 :               break;
     663             :             }
     664           0 :           if (!(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
     665           0 :                 && ti.is_constructed))
     666             :             break; /* not a sequence, so we are ready with the set */
     667             : 
     668             :           /* We must unread so that the standard parser sees the sequence */
     669           0 :           err = ksba_reader_unread (cms->reader, ti.buf, ti.nhdr);
     670           0 :           if (err)
     671           0 :             return err;
     672             :           /* Use the standard certificate parser */
     673           0 :           err = ksba_cert_new (&cert);
     674           0 :           if (err)
     675           0 :             return err;
     676           0 :           err = ksba_cert_read_der (cert, cms->reader);
     677           0 :           if (err)
     678             :             {
     679           0 :               ksba_cert_release (cert);
     680           0 :               return err;
     681             :             }
     682           0 :           cl = xtrycalloc (1, sizeof *cl);
     683           0 :           if (!cl)
     684             :             {
     685           0 :               ksba_cert_release (cert);
     686           0 :               return gpg_error (GPG_ERR_ENOMEM);
     687             :             }
     688           0 :           cl->cert = cert;
     689           0 :           cl->next = cms->cert_list;
     690           0 :           cms->cert_list = cl;
     691           0 :         }
     692             :     }
     693             : 
     694           0 :   if (ti.class == CLASS_CONTEXT && ti.tag == 1 && ti.is_constructed)
     695             :     {  /* implicit SET OF certificateList.  We should delegate the
     696             :           parsing to a - not yet existing - ksba_crl module.  CRLs are
     697             :           quite important for other applications too so we should
     698             :           provide a nice interface */
     699             :       int expect_endtag;
     700             : 
     701             : 
     702           0 :       expect_endtag = !!ti.ndef;
     703             : 
     704             :       /* FIXME this is just dummy read code */
     705             :        /* fprintf (stderr,"WARNING: Can't handle CRLs yet\n"); */
     706             :       for (;;)
     707             :         {
     708             :           /* first see whether this is really a sequence */
     709           0 :           err = _ksba_ber_read_tl (cms->reader, &ti);
     710           0 :           if (err)
     711           0 :             return err;
     712           0 :           if (expect_endtag && !ti.class && ti.tag == TYPE_NULL )
     713             :             {
     714             :               /* This is an end tag.  Read the next tag but don't fail
     715             :                  if this is just an EOF.  */
     716           0 :               err = _ksba_ber_read_tl (cms->reader, &ti);
     717           0 :               if (err)
     718             :                 {
     719           0 :                   if (gpg_err_code (err) == GPG_ERR_EOF)
     720           0 :                     err = 0;
     721           0 :                   return err;
     722             :                 }
     723           0 :               break;
     724             :             }
     725           0 :           if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
     726           0 :                  && ti.is_constructed))
     727             :             break; /* not a sequence, so we are ready with the set */
     728             : 
     729           0 :           while (ti.length)
     730             :             {
     731             :               size_t n, nread;
     732             :               char dummy[256];
     733             : 
     734           0 :               n = ti.length > DIM(dummy) ? DIM(dummy): ti.length;
     735           0 :               err = ksba_reader_read (cms->reader, dummy, n, &nread);
     736           0 :               if (err)
     737           0 :                 return err;
     738           0 :               ti.length -= nread;
     739             :             }
     740           0 :         }
     741             :     }
     742             : 
     743             :   /* expect a SET OF signerInfo */
     744           0 :   if ( !(ti.class == CLASS_UNIVERSAL
     745           0 :          && ti.tag == TYPE_SET && ti.is_constructed))
     746           0 :     return gpg_error (GPG_ERR_INV_CMS_OBJ);
     747             : 
     748           0 :   si_tail = &cms->signer_info;
     749             : 
     750           0 :   while (ti.length)
     751             :     {
     752             :       size_t off1, off2;
     753             : 
     754           0 :       off1 = ksba_reader_tell (cms->reader);
     755           0 :       si = xtrycalloc (1, sizeof *si);
     756           0 :       if (!si)
     757           0 :         return gpg_error (GPG_ERR_ENOMEM);
     758             : 
     759           0 :       err = create_and_run_decoder (cms->reader,
     760             :                                     "CryptographicMessageSyntax.SignerInfo",
     761             :                                     0,
     762             :                                     &si->root, &si->image, &si->imagelen);
     763             :       /* The signerInfo might be an empty set in the case of a certs-only
     764             :          signature.  Thus we have to allow for EOF here */
     765           0 :       if (gpg_err_code (err) == GPG_ERR_EOF)
     766             :         {
     767           0 :           xfree (si);
     768           0 :           err = 0;
     769           0 :           break;
     770             :         }
     771           0 :       if (err)
     772             :         {
     773           0 :           xfree (si);
     774           0 :           return err;
     775             :         }
     776             : 
     777           0 :       *si_tail = si;
     778           0 :       si_tail = &si->next;
     779             : 
     780           0 :       off2 = ksba_reader_tell (cms->reader);
     781           0 :       if ( (off2 - off1) > ti.length )
     782           0 :         ti.length = 0;
     783             :       else
     784           0 :         ti.length -= off2 - off1;
     785             :     }
     786             : 
     787           0 :   return 0;
     788             : }
     789             : 
     790             : 
     791             : 
     792             : 
     793             : 
     794             : /* Parse the structure:
     795             : 
     796             :    EnvelopedData ::= SEQUENCE {
     797             :      version INTEGER  { v0(0), v1(1), v2(2), v3(3), v4(4) }),
     798             :      originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
     799             :      recipientInfos RecipientInfos,
     800             :      encryptedContentInfo EncryptedContentInfo,
     801             :      unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL }
     802             : 
     803             :    OriginatorInfo ::= SEQUENCE {
     804             :      certs [0] IMPLICIT CertificateSet OPTIONAL,
     805             :      crls [1] IMPLICIT CertificateRevocationLists OPTIONAL }
     806             : 
     807             :    RecipientInfos ::= SET OF RecipientInfo
     808             : 
     809             :    EncryptedContentInfo ::= SEQUENCE {
     810             :      contentType ContentType,
     811             :      contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
     812             :      encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL }
     813             : 
     814             :    EncryptedContent ::= OCTET STRING
     815             : 
     816             :  We stop parsing so that the next read will be the first byte of the
     817             :  encryptedContent or (if there is no content) the unprotectedAttrs.
     818             : */
     819             : gpg_error_t
     820           0 : _ksba_cms_parse_enveloped_data_part_1 (ksba_cms_t cms)
     821             : {
     822             :   struct tag_info ti;
     823             :   gpg_error_t err;
     824             :   int env_data_ndef;
     825             :   unsigned long env_data_len;
     826             :   int encr_cont_ndef;
     827             :   unsigned long encr_cont_len;
     828             :   int has_content;
     829             :   unsigned long off, len;
     830           0 :   char *cont_oid = NULL;
     831           0 :   char *algo_oid = NULL;
     832           0 :   char *algo_parm = NULL;
     833             :   size_t algo_parmlen;
     834             :   struct value_tree_s *vt, **vtend;
     835             : 
     836             :   /* get the version */
     837           0 :   err = parse_cms_version (cms->reader, &cms->cms_version,
     838             :                            &env_data_len, &env_data_ndef);
     839           0 :   if (err)
     840           0 :     return err;
     841             : 
     842             :   /* read the next triplet which is either a [0] for originatorInfos
     843             :      or a SET_OF (recipientInfo) */
     844           0 :   err = _ksba_ber_read_tl (cms->reader, &ti);
     845           0 :   if (err)
     846           0 :     return err;
     847             : 
     848           0 :   if (ti.class == CLASS_CONTEXT && ti.tag == 0 && ti.is_constructed)
     849             :     { /* originatorInfo - but we skip it for now */
     850             :       /* well, raise an error */
     851           0 :       return gpg_error (GPG_ERR_UNSUPPORTED_CMS_OBJ);
     852             :     }
     853             : 
     854             :   /* Next one is the SET OF recipientInfos */
     855           0 :   if ( !(ti.class == CLASS_UNIVERSAL
     856           0 :          && ti.tag == TYPE_SET && ti.is_constructed))
     857           0 :     return gpg_error (GPG_ERR_INV_CMS_OBJ);
     858             : 
     859           0 :   vtend = &cms->recp_info;
     860           0 :   if (ti.ndef)
     861             :     {
     862             :       for (;;)
     863             :         {
     864             :           struct tag_info ti2;
     865             : 
     866           0 :           err = _ksba_ber_read_tl (cms->reader, &ti2);
     867           0 :           if (err)
     868           0 :             return err;
     869             : 
     870           0 :           if (!ti2.class && !ti2.tag)
     871           0 :             break; /* End tag found: ready.  */
     872             : 
     873             :           /* Not an end tag:  Push it back and run the decoder.  */
     874           0 :           err = ksba_reader_unread (cms->reader, ti2.buf, ti2.nhdr);
     875           0 :           if (err)
     876           0 :             return err;
     877             : 
     878           0 :           vt = xtrycalloc (1, sizeof *vt);
     879           0 :           if (!vt)
     880           0 :             return gpg_error_from_syserror ();
     881             : 
     882           0 :           err = create_and_run_decoder
     883             :             (cms->reader,
     884             :              "CryptographicMessageSyntax.KeyTransRecipientInfo",
     885             :              BER_DECODER_FLAG_FAST_STOP,
     886             :              &vt->root, &vt->image, &vt->imagelen);
     887           0 :           if (err)
     888             :             {
     889           0 :               xfree (vt);
     890           0 :               return err;
     891             :             }
     892             : 
     893           0 :           *vtend = vt;
     894           0 :           vtend = &vt->next;
     895           0 :         }
     896             :     }
     897             :   else
     898             :     {
     899           0 :       while (ti.length)
     900             :         {
     901             :           size_t off1, off2;
     902             : 
     903           0 :           off1 = ksba_reader_tell (cms->reader);
     904           0 :           vt = xtrycalloc (1, sizeof *vt);
     905           0 :           if (!vt)
     906           0 :             return gpg_error_from_syserror ();
     907             : 
     908           0 :           err = create_and_run_decoder
     909             :             (cms->reader,
     910             :              "CryptographicMessageSyntax.KeyTransRecipientInfo",
     911             :              0,
     912             :              &vt->root, &vt->image, &vt->imagelen);
     913           0 :           if (err)
     914             :             {
     915           0 :               xfree (vt);
     916           0 :               return err;
     917             :             }
     918             : 
     919           0 :           *vtend = vt;
     920           0 :           vtend = &vt->next;
     921             : 
     922           0 :           off2 = ksba_reader_tell (cms->reader);
     923           0 :           if ( (off2 - off1) > ti.length )
     924           0 :             ti.length = 0;
     925             :           else
     926           0 :             ti.length -= off2 - off1;
     927             :         }
     928             :     }
     929             : 
     930             :   /* Now for the encryptedContentInfo */
     931           0 :   off = ksba_reader_tell (cms->reader);
     932           0 :   err = parse_encrypted_content_info (cms->reader,
     933             :                                       &encr_cont_len, &encr_cont_ndef,
     934             :                                       &cont_oid,
     935             :                                       &algo_oid,
     936             :                                       &algo_parm, &algo_parmlen,
     937             :                                       &has_content);
     938           0 :   if (err)
     939           0 :     return err;
     940           0 :   cms->inner_cont_len = encr_cont_len;
     941           0 :   cms->inner_cont_ndef = encr_cont_ndef;
     942           0 :   cms->inner_cont_oid = cont_oid;
     943           0 :   cms->detached_data = !has_content;
     944           0 :   cms->encr_algo_oid = algo_oid;
     945           0 :   cms->encr_iv = algo_parm; algo_parm = NULL;
     946           0 :   cms->encr_ivlen = algo_parmlen;
     947           0 :   if (!env_data_ndef)
     948             :     {
     949           0 :       len = ksba_reader_tell (cms->reader) - off;
     950           0 :       if (env_data_len < len)
     951           0 :         return gpg_error (GPG_ERR_BAD_BER); /* parsed content info larger that sequence */
     952           0 :       env_data_len -= len;
     953           0 :       if (!encr_cont_ndef && env_data_len < encr_cont_len)
     954           0 :         return gpg_error (GPG_ERR_BAD_BER); /* triplet larger that sequence */
     955             :     }
     956             : 
     957           0 :   return 0;
     958             : }
     959             : 
     960             : 
     961             : /* handle the unprotected attributes */
     962             : gpg_error_t
     963           0 : _ksba_cms_parse_enveloped_data_part_2 (ksba_cms_t cms)
     964             : {
     965             :   (void)cms;
     966             :   /* FIXME */
     967           0 :   return 0;
     968             : }

Generated by: LCOV version 1.11