LCOV - code coverage report
Current view: top level - src - cms.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 1616 0.0 %
Date: 2016-12-09 14:04:45 Functions: 0 53 0.0 %

          Line data    Source code
       1             : /* cms.c - cryptographic message syntax main functions
       2             :  * Copyright (C) 2001, 2003, 2004, 2008, 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             : #include <config.h>
      32             : #include <stdio.h>
      33             : #include <stdlib.h>
      34             : #include <string.h>
      35             : #include <assert.h>
      36             : #include <errno.h>
      37             : 
      38             : #include "util.h"
      39             : 
      40             : #include "cms.h"
      41             : #include "convert.h"
      42             : #include "keyinfo.h"
      43             : #include "der-encoder.h"
      44             : #include "ber-help.h"
      45             : #include "sexp-parse.h"
      46             : #include "cert.h" /* need to access cert->root and cert->image */
      47             : 
      48             : static gpg_error_t ct_parse_data (ksba_cms_t cms);
      49             : static gpg_error_t ct_parse_signed_data (ksba_cms_t cms);
      50             : static gpg_error_t ct_parse_enveloped_data (ksba_cms_t cms);
      51             : static gpg_error_t ct_parse_digested_data (ksba_cms_t cms);
      52             : static gpg_error_t ct_parse_encrypted_data (ksba_cms_t cms);
      53             : static gpg_error_t ct_build_data (ksba_cms_t cms);
      54             : static gpg_error_t ct_build_signed_data (ksba_cms_t cms);
      55             : static gpg_error_t ct_build_enveloped_data (ksba_cms_t cms);
      56             : static gpg_error_t ct_build_digested_data (ksba_cms_t cms);
      57             : static gpg_error_t ct_build_encrypted_data (ksba_cms_t cms);
      58             : 
      59             : static struct {
      60             :   const char *oid;
      61             :   ksba_content_type_t ct;
      62             :   gpg_error_t (*parse_handler)(ksba_cms_t);
      63             :   gpg_error_t (*build_handler)(ksba_cms_t);
      64             : } content_handlers[] = {
      65             :   {  "1.2.840.113549.1.7.1", KSBA_CT_DATA,
      66             :      ct_parse_data   , ct_build_data                  },
      67             :   {  "1.2.840.113549.1.7.2", KSBA_CT_SIGNED_DATA,
      68             :      ct_parse_signed_data   , ct_build_signed_data    },
      69             :   {  "1.2.840.113549.1.7.3", KSBA_CT_ENVELOPED_DATA,
      70             :      ct_parse_enveloped_data, ct_build_enveloped_data },
      71             :   {  "1.2.840.113549.1.7.5", KSBA_CT_DIGESTED_DATA,
      72             :      ct_parse_digested_data , ct_build_digested_data  },
      73             :   {  "1.2.840.113549.1.7.6", KSBA_CT_ENCRYPTED_DATA,
      74             :      ct_parse_encrypted_data, ct_build_encrypted_data },
      75             :   {  "1.2.840.113549.1.9.16.1.2", KSBA_CT_AUTH_DATA   },
      76             :   { NULL }
      77             : };
      78             : 
      79             : static const char oidstr_contentType[] = "1.2.840.113549.1.9.3";
      80             : /*static char oid_contentType[9] = "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x03";*/
      81             : 
      82             : static const char oidstr_messageDigest[] = "1.2.840.113549.1.9.4";
      83             : static const char oid_messageDigest[9] ="\x2A\x86\x48\x86\xF7\x0D\x01\x09\x04";
      84             : 
      85             : static const char oidstr_signingTime[] = "1.2.840.113549.1.9.5";
      86             : static const char oid_signingTime[9] = "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x05";
      87             : 
      88             : static const char oidstr_smimeCapabilities[] = "1.2.840.113549.1.9.15";
      89             : 
      90             : 
      91             : 
      92             : /* Helper for read_and_hash_cont().  */
      93             : static gpg_error_t
      94           0 : read_hash_block (ksba_cms_t cms, unsigned long nleft)
      95             : {
      96             :   gpg_error_t err;
      97             :   char buffer[4096];
      98             :   size_t n, nread;
      99             : 
     100           0 :   while (nleft)
     101             :     {
     102           0 :       n = nleft < sizeof (buffer)? nleft : sizeof (buffer);
     103           0 :       err = ksba_reader_read (cms->reader, buffer, n, &nread);
     104           0 :       if (err)
     105           0 :         return err;
     106           0 :       nleft -= nread;
     107           0 :       if (cms->hash_fnc)
     108           0 :         cms->hash_fnc (cms->hash_fnc_arg, buffer, nread);
     109           0 :       if (cms->writer)
     110           0 :         err = ksba_writer_write (cms->writer, buffer, nread);
     111           0 :       if (err)
     112           0 :         return err;
     113             :     }
     114           0 :   return 0;
     115             : }
     116             : 
     117             : 
     118             : /* Copy all the bytes from the reader to the writer and hash them if a
     119             :    a hash function has been set.  The writer may be NULL to just do
     120             :    the hashing */
     121             : static gpg_error_t
     122           0 : read_and_hash_cont (ksba_cms_t cms)
     123             : {
     124           0 :   gpg_error_t err = 0;
     125             :   unsigned long nleft;
     126             :   struct tag_info ti;
     127             : 
     128           0 :   if (cms->inner_cont_ndef)
     129             :     {
     130             :       for (;;)
     131             :         {
     132           0 :           err = _ksba_ber_read_tl (cms->reader, &ti);
     133           0 :           if (err)
     134           0 :             return err;
     135             : 
     136           0 :           if (ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_OCTET_STRING
     137           0 :               && !ti.is_constructed)
     138             :             { /* next chunk */
     139           0 :               nleft = ti.length;
     140           0 :               err = read_hash_block (cms, nleft);
     141           0 :               if (err)
     142           0 :                 return err;
     143             :             }
     144           0 :           else if (ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_OCTET_STRING
     145           0 :                    && ti.is_constructed)
     146             :             { /* next chunk is constructed */
     147             :               for (;;)
     148             :                 {
     149           0 :                   err = _ksba_ber_read_tl (cms->reader, &ti);
     150           0 :                   if (err)
     151           0 :                     return err;
     152           0 :                   if (ti.class == CLASS_UNIVERSAL
     153           0 :                       && ti.tag == TYPE_OCTET_STRING
     154           0 :                       && !ti.is_constructed)
     155             :                     {
     156           0 :                       nleft = ti.length;
     157           0 :                       err = read_hash_block (cms, nleft);
     158           0 :                       if (err)
     159           0 :                         return err;
     160             :                     }
     161           0 :                   else if (ti.class == CLASS_UNIVERSAL && !ti.tag
     162           0 :                            && !ti.is_constructed)
     163             :                     break; /* ready with this chunk */
     164             :                   else
     165           0 :                     return gpg_error (GPG_ERR_ENCODING_PROBLEM);
     166             :                 }
     167             :             }
     168           0 :           else if (ti.class == CLASS_UNIVERSAL && !ti.tag
     169           0 :                    && !ti.is_constructed)
     170           0 :             return 0; /* ready */
     171             :           else
     172           0 :             return gpg_error (GPG_ERR_ENCODING_PROBLEM);
     173             :         }
     174             :     }
     175             :   else
     176             :     {
     177             :       /* This is basically the same as above but we allow for
     178             :          arbitrary types.  Not sure whether it is really needed but
     179             :          right in the beginning of gnupg 1.9 we had at least one
     180             :          message with didn't used octet strings.  Not ethat we don't
     181             :          do proper NLEFT checking but well why should we validate
     182             :          these things?  Well, it might be nice to have such a feature
     183             :          but then we should write a more general mechanism to do
     184             :          that.  */
     185           0 :       nleft = cms->inner_cont_len;
     186             :       /* First read the octet string but allow all types here */
     187           0 :       err = _ksba_ber_read_tl (cms->reader, &ti);
     188           0 :       if (err)
     189           0 :         return err;
     190           0 :       if (nleft < ti.nhdr)
     191           0 :         return gpg_error (GPG_ERR_ENCODING_PROBLEM);
     192           0 :       nleft -= ti.nhdr;
     193             : 
     194           0 :       if (ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_OCTET_STRING
     195           0 :           && ti.is_constructed)
     196             :         { /* Next chunk is constructed */
     197             :           for (;;)
     198             :             {
     199           0 :               err = _ksba_ber_read_tl (cms->reader, &ti);
     200           0 :               if (err)
     201           0 :                 return err;
     202           0 :               if (ti.class == CLASS_UNIVERSAL
     203           0 :                   && ti.tag == TYPE_OCTET_STRING
     204           0 :                   && !ti.is_constructed)
     205             :                 {
     206           0 :                   nleft = ti.length;
     207           0 :                   err = read_hash_block (cms, nleft);
     208           0 :                   if (err)
     209           0 :                     return err;
     210             :                 }
     211           0 :               else if (ti.class == CLASS_UNIVERSAL && !ti.tag
     212           0 :                        && !ti.is_constructed)
     213             :                 break; /* Ready with this chunk */
     214             :               else
     215           0 :                 return gpg_error (GPG_ERR_ENCODING_PROBLEM);
     216             :             }
     217             :         }
     218           0 :       else if (ti.class == CLASS_UNIVERSAL && !ti.tag
     219           0 :                && !ti.is_constructed)
     220           0 :         return 0; /* ready */
     221             :       else
     222             :         {
     223           0 :           err = read_hash_block (cms, nleft);
     224           0 :           if (err)
     225           0 :             return err;
     226             :         }
     227             :     }
     228           0 :   return 0;
     229             : }
     230             : 
     231             : 
     232             : 
     233             : /* Copy all the encrypted bytes from the reader to the writer.
     234             :    Handles indefinite length encoding */
     235             : static gpg_error_t
     236           0 : read_encrypted_cont (ksba_cms_t cms)
     237             : {
     238           0 :   gpg_error_t err = 0;
     239             :   unsigned long nleft;
     240             :   char buffer[4096];
     241             :   size_t n, nread;
     242             : 
     243           0 :   if (cms->inner_cont_ndef)
     244             :     {
     245             :       struct tag_info ti;
     246             : 
     247             :       /* fixme: this ist mostly a duplicate of the code in
     248             :          read_and_hash_cont(). */
     249             :       for (;;)
     250             :         {
     251           0 :           err = _ksba_ber_read_tl (cms->reader, &ti);
     252           0 :           if (err)
     253           0 :             return err;
     254             : 
     255           0 :           if (ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_OCTET_STRING
     256           0 :               && !ti.is_constructed)
     257             :             { /* next chunk */
     258           0 :               nleft = ti.length;
     259           0 :               while (nleft)
     260             :                 {
     261           0 :                   n = nleft < sizeof (buffer)? nleft : sizeof (buffer);
     262           0 :                   err = ksba_reader_read (cms->reader, buffer, n, &nread);
     263           0 :                   if (err)
     264           0 :                     return err;
     265           0 :                   nleft -= nread;
     266           0 :                   err = ksba_writer_write (cms->writer, buffer, nread);
     267           0 :                   if (err)
     268           0 :                     return err;
     269             :                 }
     270             :             }
     271           0 :           else if (ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_OCTET_STRING
     272           0 :                    && ti.is_constructed)
     273             :             { /* next chunk is constructed */
     274             :               for (;;)
     275             :                 {
     276           0 :                   err = _ksba_ber_read_tl (cms->reader, &ti);
     277           0 :                   if (err)
     278           0 :                     return err;
     279           0 :                   if (ti.class == CLASS_UNIVERSAL
     280           0 :                       && ti.tag == TYPE_OCTET_STRING
     281           0 :                       && !ti.is_constructed)
     282             :                     {
     283           0 :                       nleft = ti.length;
     284           0 :                       while (nleft)
     285             :                         {
     286           0 :                           n = nleft < sizeof (buffer)? nleft : sizeof (buffer);
     287           0 :                           err = ksba_reader_read (cms->reader, buffer, n, &nread);
     288           0 :                           if (err)
     289           0 :                             return err;
     290           0 :                           nleft -= nread;
     291           0 :                           if (cms->writer)
     292           0 :                             err = ksba_writer_write (cms->writer, buffer, nread);
     293           0 :                           if (err)
     294           0 :                             return err;
     295             :                         }
     296             :                     }
     297           0 :                   else if (ti.class == CLASS_UNIVERSAL && !ti.tag
     298           0 :                            && !ti.is_constructed)
     299             :                     break; /* ready with this chunk */
     300             :                   else
     301           0 :                     return gpg_error (GPG_ERR_ENCODING_PROBLEM);
     302             :                 }
     303             :             }
     304           0 :           else if (ti.class == CLASS_UNIVERSAL && !ti.tag
     305           0 :                    && !ti.is_constructed)
     306           0 :             return 0; /* ready */
     307             :           else
     308           0 :             return gpg_error (GPG_ERR_ENCODING_PROBLEM);
     309             :         }
     310             :     }
     311             :   else
     312             :     {
     313           0 :       nleft = cms->inner_cont_len;
     314           0 :       while (nleft)
     315             :         {
     316           0 :           n = nleft < sizeof (buffer)? nleft : sizeof (buffer);
     317           0 :           err = ksba_reader_read (cms->reader, buffer, n, &nread);
     318           0 :           if (err)
     319           0 :             return err;
     320           0 :           nleft -= nread;
     321           0 :           err = ksba_writer_write (cms->writer, buffer, nread);
     322           0 :           if (err)
     323           0 :             return err;
     324             :         }
     325             :     }
     326           0 :   return 0;
     327             : }
     328             : 
     329             : /* copy data from reader to writer.  Assume that it is an octet string
     330             :    and insert undefinite length headers where needed */
     331             : static gpg_error_t
     332           0 : write_encrypted_cont (ksba_cms_t cms)
     333             : {
     334           0 :   gpg_error_t err = 0;
     335             :   char buffer[4096];
     336             :   size_t nread;
     337             : 
     338             :   /* we do it the simple way: the parts are made up from the chunks we
     339             :      got from the read function.
     340             : 
     341             :      Fixme: We should write the tag here, and write a definite length
     342             :      header if everything fits into our local buffer.  Actually pretty
     343             :      simple to do, but I am too lazy right now. */
     344           0 :   while (!(err = ksba_reader_read (cms->reader, buffer,
     345             :                                    sizeof buffer, &nread)) )
     346             :     {
     347           0 :       err = _ksba_ber_write_tl (cms->writer, TYPE_OCTET_STRING,
     348             :                                 CLASS_UNIVERSAL, 0, nread);
     349           0 :       if (!err)
     350           0 :         err = ksba_writer_write (cms->writer, buffer, nread);
     351             :     }
     352           0 :   if (gpg_err_code (err) == GPG_ERR_EOF) /* write the end tag */
     353           0 :       err = _ksba_ber_write_tl (cms->writer, 0, 0, 0, 0);
     354             : 
     355           0 :   return err;
     356             : }
     357             : 
     358             : 
     359             : /* Figure out whether the data read from READER is a CMS object and
     360             :    return its content type.  This function does only peek at the
     361             :    READER and tries to identify the type with best effort.  Because of
     362             :    the ubiquity of the stupid and insecure pkcs#12 format, the
     363             :    function will also identify those files and return KSBA_CT_PKCS12;
     364             :    there is and will be no other pkcs#12 support in this library. */
     365             : ksba_content_type_t
     366           0 : ksba_cms_identify (ksba_reader_t reader)
     367             : {
     368             :   struct tag_info ti;
     369             :   unsigned char buffer[24];
     370             :   const unsigned char*p;
     371             :   size_t n, count;
     372             :   char *oid;
     373             :   int i;
     374           0 :   int maybe_p12 = 0;
     375             : 
     376           0 :   if (!reader)
     377           0 :     return KSBA_CT_NONE; /* oops */
     378             : 
     379             :   /* This is a common example of a CMS object - it is obvious that we
     380             :      only need to read a few bytes to get to the OID:
     381             :   30 82 0B 59 06 09 2A 86 48 86 F7 0D 01 07 02 A0 82 0B 4A 30 82 0B 46 02
     382             :   ----------- ++++++++++++++++++++++++++++++++
     383             :   SEQUENCE    OID (signedData)
     384             :   (2 byte len)
     385             : 
     386             :      For a pkcs12 message we have this:
     387             : 
     388             :   30 82 08 59 02 01 03 30 82 08 1F 06 09 2A 86 48 86 F7 0D 01 07 01 A0 82
     389             :   ----------- ++++++++ ----------- ++++++++++++++++++++++++++++++++
     390             :   SEQUENCE    INTEGER  SEQUENCE    OID (data)
     391             : 
     392             :     This we need to read at least 22 bytes, we add 2 bytes to cope with
     393             :     length headers store with 4 bytes.
     394             :   */
     395             : 
     396           0 :   for (count = sizeof buffer; count; count -= n)
     397             :     {
     398           0 :       if (ksba_reader_read (reader, buffer+sizeof (buffer)-count, count, &n))
     399           0 :         return KSBA_CT_NONE; /* too short */
     400             :     }
     401           0 :   n = sizeof buffer;
     402           0 :   if (ksba_reader_unread (reader, buffer, n))
     403           0 :     return KSBA_CT_NONE; /* oops */
     404             : 
     405           0 :   p = buffer;
     406           0 :   if (_ksba_ber_parse_tl (&p, &n, &ti))
     407           0 :     return KSBA_CT_NONE;
     408           0 :   if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
     409           0 :          && ti.is_constructed) )
     410           0 :     return KSBA_CT_NONE;
     411           0 :   if (_ksba_ber_parse_tl (&p, &n, &ti))
     412           0 :     return KSBA_CT_NONE;
     413           0 :   if ( ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_INTEGER
     414           0 :        && !ti.is_constructed && ti.length == 1 && n && *p == 3)
     415             :     {
     416           0 :       maybe_p12 = 1;
     417           0 :       p++;
     418           0 :       n--;
     419           0 :       if (_ksba_ber_parse_tl (&p, &n, &ti))
     420           0 :         return KSBA_CT_NONE;
     421           0 :       if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
     422           0 :              && ti.is_constructed) )
     423           0 :         return KSBA_CT_NONE;
     424           0 :       if (_ksba_ber_parse_tl (&p, &n, &ti))
     425           0 :         return KSBA_CT_NONE;
     426             :     }
     427           0 :   if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_OBJECT_ID
     428           0 :          && !ti.is_constructed && ti.length) || ti.length > n)
     429           0 :     return KSBA_CT_NONE;
     430           0 :   oid = ksba_oid_to_str (p, ti.length);
     431           0 :   if (!oid)
     432           0 :     return KSBA_CT_NONE; /* out of core */
     433           0 :   for (i=0; content_handlers[i].oid; i++)
     434             :     {
     435           0 :       if (!strcmp (content_handlers[i].oid, oid))
     436           0 :         break;
     437             :     }
     438           0 :   if (!content_handlers[i].oid)
     439           0 :     return KSBA_CT_NONE; /* unknown */
     440           0 :   if (maybe_p12 && (content_handlers[i].ct == KSBA_CT_DATA
     441           0 :                     || content_handlers[i].ct == KSBA_CT_SIGNED_DATA))
     442           0 :       return KSBA_CT_PKCS12;
     443           0 :   return content_handlers[i].ct;
     444             : }
     445             : 
     446             : 
     447             : 
     448             : /**
     449             :  * ksba_cms_new:
     450             :  *
     451             :  * Create a new and empty CMS object
     452             :  *
     453             :  * Return value: A CMS object or an error code.
     454             :  **/
     455             : gpg_error_t
     456           0 : ksba_cms_new (ksba_cms_t *r_cms)
     457             : {
     458           0 :   *r_cms = xtrycalloc (1, sizeof **r_cms);
     459           0 :   if (!*r_cms)
     460           0 :     return gpg_error_from_errno (errno);
     461           0 :   return 0;
     462             : }
     463             : 
     464             : /* Release a list of value trees. */
     465             : static void
     466           0 : release_value_tree (struct value_tree_s *tree)
     467             : {
     468           0 :   while (tree)
     469             :     {
     470           0 :       struct value_tree_s *tmp = tree->next;
     471           0 :       _ksba_asn_release_nodes (tree->root);
     472           0 :       xfree (tree->image);
     473           0 :       xfree (tree);
     474           0 :       tree = tmp;
     475             :     }
     476           0 : }
     477             : 
     478             : /**
     479             :  * ksba_cms_release:
     480             :  * @cms: A CMS object
     481             :  *
     482             :  * Release a CMS object.
     483             :  **/
     484             : void
     485           0 : ksba_cms_release (ksba_cms_t cms)
     486             : {
     487           0 :   if (!cms)
     488           0 :     return;
     489           0 :   xfree (cms->content.oid);
     490           0 :   while (cms->digest_algos)
     491             :     {
     492           0 :       struct oidlist_s *ol = cms->digest_algos->next;
     493           0 :       xfree (cms->digest_algos->oid);
     494           0 :       xfree (cms->digest_algos);
     495           0 :       cms->digest_algos = ol;
     496             :     }
     497           0 :   while (cms->cert_list)
     498             :     {
     499           0 :       struct certlist_s *cl = cms->cert_list->next;
     500           0 :       ksba_cert_release (cms->cert_list->cert);
     501           0 :       xfree (cms->cert_list->enc_val.algo);
     502           0 :       xfree (cms->cert_list->enc_val.value);
     503           0 :       xfree (cms->cert_list);
     504           0 :       cms->cert_list = cl;
     505             :     }
     506           0 :   while (cms->cert_info_list)
     507             :     {
     508           0 :       struct certlist_s *cl = cms->cert_info_list->next;
     509           0 :       ksba_cert_release (cms->cert_info_list->cert);
     510           0 :       xfree (cms->cert_info_list->enc_val.algo);
     511           0 :       xfree (cms->cert_info_list->enc_val.value);
     512           0 :       xfree (cms->cert_info_list);
     513           0 :       cms->cert_info_list = cl;
     514             :     }
     515           0 :   xfree (cms->inner_cont_oid);
     516           0 :   xfree (cms->encr_algo_oid);
     517           0 :   xfree (cms->encr_iv);
     518           0 :   xfree (cms->data.digest);
     519           0 :   while (cms->signer_info)
     520             :     {
     521           0 :       struct signer_info_s *tmp = cms->signer_info->next;
     522           0 :       _ksba_asn_release_nodes (cms->signer_info->root);
     523           0 :       xfree (cms->signer_info->image);
     524           0 :       xfree (cms->signer_info->cache.digest_algo);
     525           0 :       xfree (cms->signer_info);
     526           0 :       cms->signer_info = tmp;
     527             :     }
     528           0 :   release_value_tree (cms->recp_info);
     529           0 :   while (cms->sig_val)
     530             :     {
     531           0 :       struct sig_val_s *tmp = cms->sig_val->next;
     532           0 :       xfree (cms->sig_val->algo);
     533           0 :       xfree (cms->sig_val->value);
     534           0 :       xfree (cms->sig_val);
     535           0 :       cms->sig_val = tmp;
     536             :     }
     537           0 :   while (cms->capability_list)
     538             :     {
     539           0 :       struct oidparmlist_s *tmp = cms->capability_list->next;
     540           0 :       xfree (cms->capability_list->oid);
     541           0 :       xfree (cms->capability_list);
     542           0 :       cms->capability_list = tmp;
     543             :     }
     544             : 
     545           0 :   xfree (cms);
     546             : }
     547             : 
     548             : 
     549             : gpg_error_t
     550           0 : ksba_cms_set_reader_writer (ksba_cms_t cms, ksba_reader_t r, ksba_writer_t w)
     551             : {
     552           0 :   if (!cms || !(r || w))
     553           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     554           0 :   if ((r && cms->reader) || (w && cms->writer) )
     555           0 :     return gpg_error (GPG_ERR_CONFLICT); /* already set */
     556             : 
     557           0 :   cms->reader = r;
     558           0 :   cms->writer = w;
     559           0 :   return 0;
     560             : }
     561             : 
     562             : 
     563             : 
     564             : gpg_error_t
     565           0 : ksba_cms_parse (ksba_cms_t cms, ksba_stop_reason_t *r_stopreason)
     566             : {
     567             :   gpg_error_t err;
     568             :   int i;
     569             : 
     570           0 :   if (!cms || !r_stopreason)
     571           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     572             : 
     573           0 :   *r_stopreason = KSBA_SR_RUNNING;
     574           0 :   if (!cms->stop_reason)
     575             :     { /* Initial state: start parsing */
     576           0 :       err = _ksba_cms_parse_content_info (cms);
     577           0 :       if (err)
     578           0 :         return err;
     579           0 :       for (i=0; content_handlers[i].oid; i++)
     580             :         {
     581           0 :           if (!strcmp (content_handlers[i].oid, cms->content.oid))
     582           0 :             break;
     583             :         }
     584           0 :       if (!content_handlers[i].oid)
     585           0 :         return gpg_error (GPG_ERR_UNKNOWN_CMS_OBJ);
     586           0 :       if (!content_handlers[i].parse_handler)
     587           0 :         return gpg_error (GPG_ERR_UNSUPPORTED_CMS_OBJ);
     588           0 :       cms->content.ct      = content_handlers[i].ct;
     589           0 :       cms->content.handler = content_handlers[i].parse_handler;
     590           0 :       cms->stop_reason = KSBA_SR_GOT_CONTENT;
     591             :     }
     592           0 :   else if (cms->content.handler)
     593             :     {
     594           0 :       err = cms->content.handler (cms);
     595           0 :       if (err)
     596           0 :         return err;
     597             :     }
     598             :   else
     599           0 :     return gpg_error (GPG_ERR_UNSUPPORTED_CMS_OBJ);
     600             : 
     601           0 :   *r_stopreason = cms->stop_reason;
     602           0 :   return 0;
     603             : }
     604             : 
     605             : gpg_error_t
     606           0 : ksba_cms_build (ksba_cms_t cms, ksba_stop_reason_t *r_stopreason)
     607             : {
     608             :   gpg_error_t err;
     609             : 
     610           0 :   if (!cms || !r_stopreason)
     611           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     612             : 
     613           0 :   *r_stopreason = KSBA_SR_RUNNING;
     614           0 :   if (!cms->stop_reason)
     615             :     { /* Initial state: check that the content handler is known */
     616           0 :       if (!cms->writer)
     617           0 :         return gpg_error (GPG_ERR_MISSING_ACTION);
     618           0 :       if (!cms->content.handler)
     619           0 :         return gpg_error (GPG_ERR_MISSING_ACTION);
     620           0 :       if (!cms->inner_cont_oid)
     621           0 :         return gpg_error (GPG_ERR_MISSING_ACTION);
     622           0 :       cms->stop_reason = KSBA_SR_GOT_CONTENT;
     623             :     }
     624           0 :   else if (cms->content.handler)
     625             :     {
     626           0 :       err = cms->content.handler (cms);
     627           0 :       if (err)
     628           0 :         return err;
     629             :     }
     630             :   else
     631           0 :     return gpg_error (GPG_ERR_UNSUPPORTED_CMS_OBJ);
     632             : 
     633           0 :   *r_stopreason = cms->stop_reason;
     634           0 :   return 0;
     635             : }
     636             : 
     637             : 
     638             : 
     639             : 
     640             : /* Return the content type.  A WHAT of 0 returns the real content type
     641             :    whereas a 1 returns the inner content type.
     642             : */
     643             : ksba_content_type_t
     644           0 : ksba_cms_get_content_type (ksba_cms_t cms, int what)
     645             : {
     646             :   int i;
     647             : 
     648           0 :   if (!cms)
     649           0 :     return 0;
     650           0 :   if (!what)
     651           0 :     return cms->content.ct;
     652             : 
     653           0 :   if (what == 1 && cms->inner_cont_oid)
     654             :     {
     655           0 :       for (i=0; content_handlers[i].oid; i++)
     656             :         {
     657           0 :           if (!strcmp (content_handlers[i].oid, cms->inner_cont_oid))
     658           0 :             return content_handlers[i].ct;
     659             :         }
     660             :     }
     661           0 :   return 0;
     662             : }
     663             : 
     664             : 
     665             : /* Return the object ID of the current cms.  This is a constant string
     666             :    valid as long as the context is valid and no new parse is
     667             :    started. */
     668             : const char *
     669           0 : ksba_cms_get_content_oid (ksba_cms_t cms, int what)
     670             : {
     671           0 :   if (!cms)
     672           0 :     return NULL;
     673           0 :   if (!what)
     674           0 :     return cms->content.oid;
     675           0 :   if (what == 1)
     676           0 :     return cms->inner_cont_oid;
     677           0 :   if (what == 2)
     678           0 :     return cms->encr_algo_oid;
     679           0 :   return NULL;
     680             : }
     681             : 
     682             : 
     683             : /* Copy the initialization vector into iv and its len into ivlen.
     684             :    The caller should provide a suitable large buffer */
     685             : gpg_error_t
     686           0 : ksba_cms_get_content_enc_iv (ksba_cms_t cms, void *iv,
     687             :                              size_t maxivlen, size_t *ivlen)
     688             : {
     689           0 :   if (!cms || !iv || !ivlen)
     690           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     691           0 :   if (!cms->encr_ivlen)
     692           0 :     return gpg_error (GPG_ERR_NO_DATA);
     693           0 :   if (cms->encr_ivlen > maxivlen)
     694           0 :     return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
     695           0 :   memcpy (iv, cms->encr_iv, cms->encr_ivlen);
     696           0 :   *ivlen = cms->encr_ivlen;
     697           0 :   return 0;
     698             : }
     699             : 
     700             : 
     701             : /**
     702             :  * ksba_cert_get_digest_algo_list:
     703             :  * @cert: Initialized certificate object
     704             :  * @idx: enumerator
     705             :  *
     706             :  * Figure out the the digest algorithm used for the signature and
     707             :  * return its OID.  Note that the algos returned are just hints on
     708             :  * what to hash.
     709             :  *
     710             :  * Return value: NULL for no more algorithms or a string valid as long
     711             :  * as the the cms object is valid.
     712             :  **/
     713             : const char *
     714           0 : ksba_cms_get_digest_algo_list (ksba_cms_t cms, int idx)
     715             : {
     716             :   struct oidlist_s *ol;
     717             : 
     718           0 :   if (!cms)
     719           0 :     return NULL;
     720             : 
     721           0 :   for (ol=cms->digest_algos; ol && idx; ol = ol->next, idx-- )
     722             :     ;
     723           0 :   if (!ol)
     724           0 :     return NULL;
     725           0 :   return ol->oid;
     726             : }
     727             : 
     728             : 
     729             : /**
     730             :  * ksba_cms_get_issuer_serial:
     731             :  * @cms: CMS object
     732             :  * @idx: index number
     733             :  * @r_issuer: returns the issuer
     734             :  * @r_serial: returns the serial number
     735             :  *
     736             :  * This functions returns the issuer and serial number either from the
     737             :  * sid or the rid elements of a CMS object.
     738             :  *
     739             :  * Return value: 0 on success or an error code.  An error code of -1
     740             :  * is returned to indicate that there is no issuer with that idx,
     741             :  * GPG_ERR_No_Data is returned to indicate that there is no issuer at
     742             :  * all.
     743             :  **/
     744             : gpg_error_t
     745           0 : ksba_cms_get_issuer_serial (ksba_cms_t cms, int idx,
     746             :                             char **r_issuer, ksba_sexp_t *r_serial)
     747             : {
     748             :   gpg_error_t err;
     749             :   const char *issuer_path, *serial_path;
     750             :   AsnNode root;
     751             :   const unsigned char *image;
     752             :   AsnNode n;
     753             : 
     754           0 :   if (!cms)
     755           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     756           0 :   if (idx < 0)
     757           0 :     return gpg_error (GPG_ERR_INV_INDEX);
     758             : 
     759           0 :   if (cms->signer_info)
     760             :     {
     761             :       struct signer_info_s *si;
     762             : 
     763           0 :       for (si=cms->signer_info; si && idx; si = si->next, idx-- )
     764             :         ;
     765           0 :       if (!si)
     766           0 :         return -1;
     767             : 
     768           0 :       issuer_path = "SignerInfo.sid.issuerAndSerialNumber.issuer";
     769           0 :       serial_path = "SignerInfo.sid.issuerAndSerialNumber.serialNumber";
     770           0 :       root = si->root;
     771           0 :       image = si->image;
     772             :     }
     773           0 :   else if (cms->recp_info)
     774             :     {
     775             :       struct value_tree_s *tmp;
     776             : 
     777           0 :       issuer_path = "KeyTransRecipientInfo.rid.issuerAndSerialNumber.issuer";
     778           0 :       serial_path = "KeyTransRecipientInfo.rid.issuerAndSerialNumber.serialNumber";
     779           0 :       for (tmp=cms->recp_info; tmp && idx; tmp=tmp->next, idx-- )
     780             :         ;
     781           0 :       if (!tmp)
     782           0 :         return -1;
     783           0 :       root = tmp->root;
     784           0 :       image = tmp->image;
     785             :     }
     786             :   else
     787           0 :     return gpg_error (GPG_ERR_NO_DATA);
     788             : 
     789           0 :   if (r_issuer)
     790             :     {
     791           0 :       n = _ksba_asn_find_node (root, issuer_path);
     792           0 :       if (!n || !n->down)
     793           0 :         return gpg_error (GPG_ERR_NO_VALUE);
     794           0 :       n = n->down; /* dereference the choice node */
     795             : 
     796           0 :       if (n->off == -1)
     797             :         {
     798             : /*            fputs ("get_issuer problem at node:\n", stderr); */
     799             : /*            _ksba_asn_node_dump_all (n, stderr); */
     800           0 :           return gpg_error (GPG_ERR_GENERAL);
     801             :         }
     802           0 :       err = _ksba_dn_to_str (image, n, r_issuer);
     803           0 :       if (err)
     804           0 :         return err;
     805             :     }
     806             : 
     807           0 :   if (r_serial)
     808             :     {
     809             :       char numbuf[22];
     810             :       int numbuflen;
     811             :       unsigned char *p;
     812             : 
     813             :       /* fixme: we do not release the r_issuer stuff on error */
     814           0 :       n = _ksba_asn_find_node (root, serial_path);
     815           0 :       if (!n)
     816           0 :         return gpg_error (GPG_ERR_NO_VALUE);
     817             : 
     818           0 :       if (n->off == -1)
     819             :         {
     820             : /*            fputs ("get_serial problem at node:\n", stderr); */
     821             : /*            _ksba_asn_node_dump_all (n, stderr); */
     822           0 :           return gpg_error (GPG_ERR_GENERAL);
     823             :         }
     824             : 
     825           0 :       sprintf (numbuf,"(%u:", (unsigned int)n->len);
     826           0 :       numbuflen = strlen (numbuf);
     827           0 :       p = xtrymalloc (numbuflen + n->len + 2);
     828           0 :       if (!p)
     829           0 :         return gpg_error (GPG_ERR_ENOMEM);
     830           0 :       strcpy (p, numbuf);
     831           0 :       memcpy (p+numbuflen, image + n->off + n->nhdr, n->len);
     832           0 :       p[numbuflen + n->len] = ')';
     833           0 :       p[numbuflen + n->len + 1] = 0;
     834           0 :       *r_serial = p;
     835             :     }
     836             : 
     837           0 :   return 0;
     838             : }
     839             : 
     840             : 
     841             : 
     842             : /**
     843             :  * ksba_cms_get_digest_algo:
     844             :  * @cms: CMS object
     845             :  * @idx: index of signer
     846             :  *
     847             :  * Figure out the the digest algorithm used by the signer @idx return
     848             :  * its OID.  This is the algorithm acually used to calculate the
     849             :  * signature.
     850             :  *
     851             :  * Return value: NULL for no such signer or a constn string valid as
     852             :  * long as the CMS object lives.
     853             :  **/
     854             : const char *
     855           0 : ksba_cms_get_digest_algo (ksba_cms_t cms, int idx)
     856             : {
     857             :   AsnNode n;
     858             :   char *algo;
     859             :   struct signer_info_s *si;
     860             : 
     861           0 :   if (!cms)
     862           0 :     return NULL;
     863           0 :   if (!cms->signer_info)
     864           0 :     return NULL;
     865           0 :   if (idx < 0)
     866           0 :     return NULL;
     867             : 
     868           0 :   for (si=cms->signer_info; si && idx; si = si->next, idx-- )
     869             :     ;
     870           0 :   if (!si)
     871           0 :     return NULL;
     872             : 
     873           0 :   if (si->cache.digest_algo)
     874           0 :     return si->cache.digest_algo;
     875             : 
     876           0 :   n = _ksba_asn_find_node (si->root, "SignerInfo.digestAlgorithm.algorithm");
     877           0 :   algo = _ksba_oid_node_to_str (si->image, n);
     878           0 :   if (algo)
     879             :     {
     880           0 :       si->cache.digest_algo = algo;
     881             :     }
     882           0 :   return algo;
     883             : }
     884             : 
     885             : 
     886             : /**
     887             :  * ksba_cms_get_cert:
     888             :  * @cms: CMS object
     889             :  * @idx: enumerator
     890             :  *
     891             :  * Get the certificate out of a CMS.  The caller should use this in a
     892             :  * loop to get all certificates.  The returned certificate is a
     893             :  * shallow copy of the original one; the caller must still use
     894             :  * ksba_cert_release() to free it.
     895             :  *
     896             :  * Return value: A Certificate object or NULL for end of list or error
     897             :  **/
     898             : ksba_cert_t
     899           0 : ksba_cms_get_cert (ksba_cms_t cms, int idx)
     900             : {
     901             :   struct certlist_s *cl;
     902             : 
     903           0 :   if (!cms || idx < 0)
     904           0 :     return NULL;
     905             : 
     906           0 :   for (cl=cms->cert_list; cl && idx; cl = cl->next, idx--)
     907             :     ;
     908           0 :   if (!cl)
     909           0 :     return NULL;
     910           0 :   ksba_cert_ref (cl->cert);
     911           0 :   return cl->cert;
     912             : }
     913             : 
     914             : 
     915             : /*
     916             :    Return the extension attribute messageDigest
     917             : */
     918             : gpg_error_t
     919           0 : ksba_cms_get_message_digest (ksba_cms_t cms, int idx,
     920             :                              char **r_digest, size_t *r_digest_len)
     921             : {
     922             :   AsnNode nsiginfo, n;
     923             :   struct signer_info_s *si;
     924             : 
     925           0 :   if (!cms || !r_digest || !r_digest_len)
     926           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     927           0 :   if (!cms->signer_info)
     928           0 :     return gpg_error (GPG_ERR_NO_DATA);
     929           0 :   if (idx < 0)
     930           0 :     return gpg_error (GPG_ERR_INV_INDEX);
     931             : 
     932           0 :   for (si=cms->signer_info; si && idx; si = si->next, idx-- )
     933             :     ;
     934           0 :   if (!si)
     935           0 :     return -1;
     936             : 
     937             : 
     938           0 :   *r_digest = NULL;
     939           0 :   *r_digest_len = 0;
     940           0 :   nsiginfo = _ksba_asn_find_node (si->root, "SignerInfo.signedAttrs");
     941           0 :   if (!nsiginfo)
     942           0 :     return gpg_error (GPG_ERR_BUG);
     943             : 
     944           0 :   n = _ksba_asn_find_type_value (si->image, nsiginfo, 0,
     945             :                                  oid_messageDigest, DIM(oid_messageDigest));
     946           0 :   if (!n)
     947           0 :     return 0; /* this is okay, because the element is optional */
     948             : 
     949             :   /* check that there is only one */
     950           0 :   if (_ksba_asn_find_type_value (si->image, nsiginfo, 1,
     951             :                                  oid_messageDigest, DIM(oid_messageDigest)))
     952           0 :     return gpg_error (GPG_ERR_DUP_VALUE);
     953             : 
     954             :   /* the value is is a SET OF OCTECT STRING but the set must have
     955             :      excactly one OCTECT STRING.  (rfc2630 11.2) */
     956           0 :   if ( !(n->type == TYPE_SET_OF && n->down
     957           0 :          && n->down->type == TYPE_OCTET_STRING && !n->down->right))
     958           0 :     return gpg_error (GPG_ERR_INV_CMS_OBJ);
     959           0 :   n = n->down;
     960           0 :   if (n->off == -1)
     961           0 :     return gpg_error (GPG_ERR_BUG);
     962             : 
     963           0 :   *r_digest_len = n->len;
     964           0 :   *r_digest = xtrymalloc (n->len);
     965           0 :   if (!*r_digest)
     966           0 :     return gpg_error (GPG_ERR_ENOMEM);
     967           0 :   memcpy (*r_digest, si->image + n->off + n->nhdr, n->len);
     968           0 :   return 0;
     969             : }
     970             : 
     971             : 
     972             : /* Return the extension attribute signing time, which may be empty for no
     973             :    signing time available. */
     974             : gpg_error_t
     975           0 : ksba_cms_get_signing_time (ksba_cms_t cms, int idx, ksba_isotime_t r_sigtime)
     976             : {
     977             :   AsnNode nsiginfo, n;
     978             :   struct signer_info_s *si;
     979             : 
     980           0 :   if (!cms)
     981           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     982           0 :   *r_sigtime = 0;
     983           0 :   if (!cms->signer_info)
     984           0 :     return gpg_error (GPG_ERR_NO_DATA);
     985           0 :   if (idx < 0)
     986           0 :     return gpg_error (GPG_ERR_INV_INDEX);
     987             : 
     988           0 :   for (si=cms->signer_info; si && idx; si = si->next, idx-- )
     989             :     ;
     990           0 :   if (!si)
     991           0 :     return -1;
     992             : 
     993           0 :   *r_sigtime = 0;
     994           0 :   nsiginfo = _ksba_asn_find_node (si->root, "SignerInfo.signedAttrs");
     995           0 :   if (!nsiginfo)
     996           0 :     return 0; /* This is okay because signedAttribs are optional. */
     997             : 
     998           0 :   n = _ksba_asn_find_type_value (si->image, nsiginfo, 0,
     999             :                                  oid_signingTime, DIM(oid_signingTime));
    1000           0 :   if (!n)
    1001           0 :     return 0; /* This is okay because signing time is optional. */
    1002             : 
    1003             :   /* check that there is only one */
    1004           0 :   if (_ksba_asn_find_type_value (si->image, nsiginfo, 1,
    1005             :                                  oid_signingTime, DIM(oid_signingTime)))
    1006           0 :     return gpg_error (GPG_ERR_DUP_VALUE);
    1007             : 
    1008             :   /* the value is is a SET OF CHOICE but the set must have
    1009             :      excactly one CHOICE of generalized or utctime.  (rfc2630 11.3) */
    1010           0 :   if ( !(n->type == TYPE_SET_OF && n->down
    1011           0 :          && (n->down->type == TYPE_GENERALIZED_TIME
    1012           0 :              || n->down->type == TYPE_UTC_TIME)
    1013           0 :          && !n->down->right))
    1014           0 :     return gpg_error (GPG_ERR_INV_CMS_OBJ);
    1015           0 :   n = n->down;
    1016           0 :   if (n->off == -1)
    1017           0 :     return gpg_error (GPG_ERR_BUG);
    1018             : 
    1019           0 :   return _ksba_asntime_to_iso (si->image + n->off + n->nhdr, n->len,
    1020           0 :                                n->type == TYPE_UTC_TIME, r_sigtime);
    1021             : }
    1022             : 
    1023             : 
    1024             : /* Return a list of OIDs stored as signed attributes for the signature
    1025             :    number IDX.  All the values (OIDs) for the the requested OID REQOID
    1026             :    are returned delimited by a linefeed.  Caller must free that
    1027             :    list. -1 is returned when IDX is larger than the number of
    1028             :    signatures, GPG_ERR_No_Data is returned when there is no such
    1029             :    attribute for the given signer. */
    1030             : gpg_error_t
    1031           0 : ksba_cms_get_sigattr_oids (ksba_cms_t cms, int idx,
    1032             :                            const char *reqoid, char **r_value)
    1033             : {
    1034             :   gpg_error_t err;
    1035             :   AsnNode nsiginfo, n;
    1036             :   struct signer_info_s *si;
    1037             :   unsigned char *reqoidbuf;
    1038             :   size_t reqoidlen;
    1039           0 :   char *retstr = NULL;
    1040             :   int i;
    1041             : 
    1042           0 :   if (!cms || !r_value)
    1043           0 :     return gpg_error (GPG_ERR_INV_VALUE);
    1044           0 :   if (!cms->signer_info)
    1045           0 :     return gpg_error (GPG_ERR_NO_DATA);
    1046           0 :   if (idx < 0)
    1047           0 :     return gpg_error (GPG_ERR_INV_INDEX);
    1048           0 :   *r_value = NULL;
    1049             : 
    1050           0 :   for (si=cms->signer_info; si && idx; si = si->next, idx-- )
    1051             :     ;
    1052           0 :   if (!si)
    1053           0 :     return -1; /* no more signers */
    1054             : 
    1055           0 :   nsiginfo = _ksba_asn_find_node (si->root, "SignerInfo.signedAttrs");
    1056           0 :   if (!nsiginfo)
    1057           0 :     return -1; /* this is okay, because signedAttribs are optional */
    1058             : 
    1059           0 :   err = ksba_oid_from_str (reqoid, &reqoidbuf, &reqoidlen);
    1060           0 :   if(err)
    1061           0 :     return err;
    1062             : 
    1063           0 :   for (i=0; (n = _ksba_asn_find_type_value (si->image, nsiginfo,
    1064           0 :                                             i, reqoidbuf, reqoidlen)); i++)
    1065             :     {
    1066             :       char *line, *p;
    1067             : 
    1068             :       /* the value is is a SET OF OBJECT ID but the set must have
    1069             :          excactly one OBJECT ID.  (rfc2630 11.1) */
    1070           0 :       if ( !(n->type == TYPE_SET_OF && n->down
    1071           0 :              && n->down->type == TYPE_OBJECT_ID && !n->down->right))
    1072             :         {
    1073           0 :           xfree (reqoidbuf);
    1074           0 :           xfree (retstr);
    1075           0 :           return gpg_error (GPG_ERR_INV_CMS_OBJ);
    1076             :         }
    1077           0 :       n = n->down;
    1078           0 :       if (n->off == -1)
    1079             :         {
    1080           0 :           xfree (reqoidbuf);
    1081           0 :           xfree (retstr);
    1082           0 :           return gpg_error (GPG_ERR_BUG);
    1083             :         }
    1084             : 
    1085           0 :       p = _ksba_oid_node_to_str (si->image, n);
    1086           0 :       if (!p)
    1087             :         {
    1088           0 :           xfree (reqoidbuf);
    1089           0 :           xfree (retstr);
    1090           0 :           return gpg_error (GPG_ERR_INV_CMS_OBJ);
    1091             :         }
    1092             : 
    1093           0 :       if (!retstr)
    1094           0 :         line = retstr = xtrymalloc (strlen (p) + 2);
    1095             :       else
    1096             :         {
    1097           0 :           char *tmp = xtryrealloc (retstr,
    1098             :                                    strlen (retstr) + 1 + strlen (p) + 2);
    1099           0 :           if (!tmp)
    1100           0 :             line = NULL;
    1101             :           else
    1102             :             {
    1103           0 :               retstr = tmp;
    1104           0 :               line = stpcpy (retstr + strlen (retstr), "\n");
    1105             :             }
    1106             :         }
    1107           0 :       if (!line)
    1108             :         {
    1109           0 :           xfree (reqoidbuf);
    1110           0 :           xfree (retstr);
    1111           0 :           xfree (p);
    1112           0 :           return gpg_error (GPG_ERR_ENOMEM);
    1113             :         }
    1114           0 :       strcpy (line, p);
    1115           0 :       xfree (p);
    1116             :     }
    1117           0 :   xfree (reqoidbuf);
    1118           0 :   if (!n && !i)
    1119           0 :     return -1; /* no such attribute */
    1120           0 :   *r_value = retstr;
    1121           0 :   return 0;
    1122             : }
    1123             : 
    1124             : 
    1125             : /**
    1126             :  * ksba_cms_get_sig_val:
    1127             :  * @cms: CMS object
    1128             :  * @idx: index of signer
    1129             :  *
    1130             :  * Return the actual signature of signer @idx in a format suitable to
    1131             :  * be used as input to Libgcrypt's verification function.  The caller
    1132             :  * must free the returned string.
    1133             :  *
    1134             :  * Return value: NULL or a string with a S-Exp.
    1135             :  **/
    1136             : ksba_sexp_t
    1137           0 : ksba_cms_get_sig_val (ksba_cms_t cms, int idx)
    1138             : {
    1139             :   AsnNode n, n2;
    1140             :   gpg_error_t err;
    1141             :   ksba_sexp_t string;
    1142             :   struct signer_info_s *si;
    1143             : 
    1144           0 :   if (!cms)
    1145           0 :     return NULL;
    1146           0 :   if (!cms->signer_info)
    1147           0 :     return NULL;
    1148           0 :   if (idx < 0)
    1149           0 :     return NULL;
    1150             : 
    1151           0 :   for (si=cms->signer_info; si && idx; si = si->next, idx-- )
    1152             :     ;
    1153           0 :   if (!si)
    1154           0 :     return NULL;
    1155             : 
    1156           0 :   n = _ksba_asn_find_node (si->root, "SignerInfo.signatureAlgorithm");
    1157           0 :   if (!n)
    1158           0 :       return NULL;
    1159           0 :   if (n->off == -1)
    1160             :     {
    1161             : /*        fputs ("ksba_cms_get_sig_val problem at node:\n", stderr); */
    1162             : /*        _ksba_asn_node_dump_all (n, stderr); */
    1163           0 :       return NULL;
    1164             :     }
    1165             : 
    1166           0 :   n2 = n->right; /* point to the actual value */
    1167           0 :   err = _ksba_sigval_to_sexp (si->image + n->off,
    1168           0 :                               n->nhdr + n->len
    1169           0 :                               + ((!n2||n2->off == -1)? 0:(n2->nhdr+n2->len)),
    1170             :                               &string);
    1171           0 :   if (err)
    1172           0 :       return NULL;
    1173             : 
    1174           0 :   return string;
    1175             : }
    1176             : 
    1177             : 
    1178             : /**
    1179             :  * ksba_cms_get_enc_val:
    1180             :  * @cms: CMS object
    1181             :  * @idx: index of recipient info
    1182             :  *
    1183             :  * Return the encrypted value (the session key) of recipient @idx in a
    1184             :  * format suitable to be used as input to Libgcrypt's decryption
    1185             :  * function.  The caller must free the returned string.
    1186             :  *
    1187             :  * Return value: NULL or a string with a S-Exp.
    1188             :  **/
    1189             : ksba_sexp_t
    1190           0 : ksba_cms_get_enc_val (ksba_cms_t cms, int idx)
    1191             : {
    1192             :   AsnNode n, n2;
    1193             :   gpg_error_t err;
    1194             :   ksba_sexp_t string;
    1195             :   struct value_tree_s *vt;
    1196             : 
    1197           0 :   if (!cms)
    1198           0 :     return NULL;
    1199           0 :   if (!cms->recp_info)
    1200           0 :     return NULL;
    1201           0 :   if (idx < 0)
    1202           0 :     return NULL;
    1203             : 
    1204           0 :   for (vt=cms->recp_info; vt && idx; vt=vt->next, idx--)
    1205             :     ;
    1206           0 :   if (!vt)
    1207           0 :     return NULL; /* No value at this IDX */
    1208             : 
    1209             : 
    1210           0 :   n = _ksba_asn_find_node (vt->root,
    1211             :                            "KeyTransRecipientInfo.keyEncryptionAlgorithm");
    1212           0 :   if (!n)
    1213           0 :       return NULL;
    1214           0 :   if (n->off == -1)
    1215             :     {
    1216             : /*        fputs ("ksba_cms_get_enc_val problem at node:\n", stderr); */
    1217             : /*        _ksba_asn_node_dump_all (n, stderr); */
    1218           0 :       return NULL;
    1219             :     }
    1220             : 
    1221           0 :   n2 = n->right; /* point to the actual value */
    1222           0 :   err = _ksba_encval_to_sexp (vt->image + n->off,
    1223           0 :                               n->nhdr + n->len
    1224           0 :                               + ((!n2||n2->off == -1)? 0:(n2->nhdr+n2->len)),
    1225             :                               &string);
    1226           0 :   if (err)
    1227           0 :       return NULL;
    1228             : 
    1229           0 :   return string;
    1230             : }
    1231             : 
    1232             : 
    1233             : 
    1234             : 
    1235             : 
    1236             : /* Provide a hash function so that we are able to hash the data */
    1237             : void
    1238           0 : ksba_cms_set_hash_function (ksba_cms_t cms,
    1239             :                             void (*hash_fnc)(void *, const void *, size_t),
    1240             :                             void *hash_fnc_arg)
    1241             : {
    1242           0 :   if (cms)
    1243             :     {
    1244           0 :       cms->hash_fnc = hash_fnc;
    1245           0 :       cms->hash_fnc_arg = hash_fnc_arg;
    1246             :     }
    1247           0 : }
    1248             : 
    1249             : 
    1250             : /* hash the signed attributes of the given signer */
    1251             : gpg_error_t
    1252           0 : ksba_cms_hash_signed_attrs (ksba_cms_t cms, int idx)
    1253             : {
    1254             :   AsnNode n;
    1255             :   struct signer_info_s *si;
    1256             : 
    1257           0 :   if (!cms)
    1258           0 :     return gpg_error (GPG_ERR_INV_VALUE);
    1259           0 :   if (!cms->hash_fnc)
    1260           0 :     return gpg_error (GPG_ERR_MISSING_ACTION);
    1261           0 :   if (idx < 0)
    1262           0 :     return -1;
    1263             : 
    1264           0 :   for (si=cms->signer_info; si && idx; si = si->next, idx-- )
    1265             :     ;
    1266           0 :   if (!si)
    1267           0 :     return -1;
    1268             : 
    1269           0 :   n = _ksba_asn_find_node (si->root, "SignerInfo.signedAttrs");
    1270           0 :   if (!n || n->off == -1)
    1271           0 :     return gpg_error (GPG_ERR_NO_VALUE);
    1272             : 
    1273             :   /* We don't hash the implicit tag [0] but a SET tag */
    1274           0 :   cms->hash_fnc (cms->hash_fnc_arg, "\x31", 1);
    1275           0 :   cms->hash_fnc (cms->hash_fnc_arg,
    1276           0 :                  si->image + n->off + 1, n->nhdr + n->len - 1);
    1277             : 
    1278           0 :   return 0;
    1279             : }
    1280             : 
    1281             : 
    1282             : /*
    1283             :   Code to create CMS structures
    1284             : */
    1285             : 
    1286             : 
    1287             : /**
    1288             :  * ksba_cms_set_content_type:
    1289             :  * @cms: A CMS object
    1290             :  * @what: 0 for content type, 1 for inner content type
    1291             :  * @type: Tyep constant
    1292             :  *
    1293             :  * Set the content type used for build operations.  This should be the
    1294             :  * first operation before starting to create a CMS message.
    1295             :  *
    1296             :  * Return value: 0 on success or an error code
    1297             :  **/
    1298             : gpg_error_t
    1299           0 : ksba_cms_set_content_type (ksba_cms_t cms, int what, ksba_content_type_t type)
    1300             : {
    1301             :   int i;
    1302             :   char *oid;
    1303             : 
    1304           0 :   if (!cms || what < 0 || what > 1 )
    1305           0 :     return gpg_error (GPG_ERR_INV_VALUE);
    1306             : 
    1307           0 :   for (i=0; content_handlers[i].oid; i++)
    1308             :     {
    1309           0 :       if (content_handlers[i].ct == type)
    1310           0 :         break;
    1311             :     }
    1312           0 :   if (!content_handlers[i].oid)
    1313           0 :     return gpg_error (GPG_ERR_UNKNOWN_CMS_OBJ);
    1314           0 :   if (!content_handlers[i].build_handler)
    1315           0 :     return gpg_error (GPG_ERR_UNSUPPORTED_CMS_OBJ);
    1316           0 :   oid = xtrystrdup (content_handlers[i].oid);
    1317           0 :   if (!oid)
    1318           0 :     return gpg_error (GPG_ERR_ENOMEM);
    1319             : 
    1320           0 :   if (!what)
    1321             :     {
    1322           0 :       cms->content.oid     = oid;
    1323           0 :       cms->content.ct      = content_handlers[i].ct;
    1324           0 :       cms->content.handler = content_handlers[i].build_handler;
    1325             :     }
    1326             :   else
    1327             :     {
    1328           0 :       cms->inner_cont_oid = oid;
    1329             :     }
    1330             : 
    1331           0 :   return 0;
    1332             : }
    1333             : 
    1334             : 
    1335             : /**
    1336             :  * ksba_cms_add_digest_algo:
    1337             :  * @cms:  A CMS object
    1338             :  * @oid: A stringified object OID describing the hash algorithm
    1339             :  *
    1340             :  * Set the algorithm to be used for creating the hash. Note, that we
    1341             :  * currently can't do a per-signer hash.
    1342             :  *
    1343             :  * Return value: 0 on success or an error code
    1344             :  **/
    1345             : gpg_error_t
    1346           0 : ksba_cms_add_digest_algo (ksba_cms_t cms, const char *oid)
    1347             : {
    1348             :   struct oidlist_s *ol;
    1349             : 
    1350           0 :   if (!cms || !oid)
    1351           0 :     return gpg_error (GPG_ERR_INV_VALUE);
    1352             : 
    1353           0 :   ol = xtrymalloc (sizeof *ol);
    1354           0 :   if (!ol)
    1355           0 :     return gpg_error (GPG_ERR_ENOMEM);
    1356             : 
    1357           0 :   ol->oid = xtrystrdup (oid);
    1358           0 :   if (!ol->oid)
    1359             :     {
    1360           0 :       xfree (ol);
    1361           0 :       return gpg_error (GPG_ERR_ENOMEM);
    1362             :     }
    1363           0 :   ol->next = cms->digest_algos;
    1364           0 :   cms->digest_algos = ol;
    1365           0 :   return 0;
    1366             : }
    1367             : 
    1368             : 
    1369             : /**
    1370             :  * ksba_cms_add_signer:
    1371             :  * @cms: A CMS object
    1372             :  * @cert: A certificate used to describe the signer.
    1373             :  *
    1374             :  * This functions starts assembly of a new signed data content or adds
    1375             :  * another signer to the list of signers.
    1376             :  *
    1377             :  * Return value: 0 on success or an error code.
    1378             :  **/
    1379             : gpg_error_t
    1380           0 : ksba_cms_add_signer (ksba_cms_t cms, ksba_cert_t cert)
    1381             : {
    1382             :   struct certlist_s *cl, *cl2;
    1383             : 
    1384           0 :   if (!cms)
    1385           0 :     return gpg_error (GPG_ERR_INV_VALUE);
    1386             : 
    1387           0 :   cl = xtrycalloc (1,sizeof *cl);
    1388           0 :   if (!cl)
    1389           0 :       return gpg_error (GPG_ERR_ENOMEM);
    1390             : 
    1391           0 :   ksba_cert_ref (cert);
    1392           0 :   cl->cert = cert;
    1393           0 :   if (!cms->cert_list)
    1394           0 :     cms->cert_list = cl;
    1395             :   else
    1396             :     {
    1397           0 :       for (cl2=cms->cert_list; cl2->next; cl2 = cl2->next)
    1398             :         ;
    1399           0 :       cl2->next = cl;
    1400             :     }
    1401           0 :   return 0;
    1402             : }
    1403             : 
    1404             : /**
    1405             :  * ksba_cms_add_cert:
    1406             :  * @cms: A CMS object
    1407             :  * @cert: A certificate to be send along with the signed data.
    1408             :  *
    1409             :  * This functions adds a certificate to the list of certificates send
    1410             :  * along with the signed data.  Using this is optional but it is very
    1411             :  * common to include at least the certificate of the signer it self.
    1412             :  *
    1413             :  * Return value: 0 on success or an error code.
    1414             :  **/
    1415             : gpg_error_t
    1416           0 : ksba_cms_add_cert (ksba_cms_t cms, ksba_cert_t cert)
    1417             : {
    1418             :   struct certlist_s *cl;
    1419             : 
    1420           0 :   if (!cms || !cert)
    1421           0 :     return gpg_error (GPG_ERR_INV_VALUE);
    1422             : 
    1423             :   /* first check whether this is a duplicate. */
    1424           0 :   for (cl = cms->cert_info_list; cl; cl = cl->next)
    1425             :     {
    1426           0 :       if (!_ksba_cert_cmp (cert, cl->cert))
    1427           0 :         return 0; /* duplicate */
    1428             :     }
    1429             : 
    1430             :   /* Okay, add it. */
    1431           0 :   cl = xtrycalloc (1,sizeof *cl);
    1432           0 :   if (!cl)
    1433           0 :       return gpg_error (GPG_ERR_ENOMEM);
    1434             : 
    1435           0 :   ksba_cert_ref (cert);
    1436           0 :   cl->cert = cert;
    1437           0 :   cl->next = cms->cert_info_list;
    1438           0 :   cms->cert_info_list = cl;
    1439           0 :   return 0;
    1440             : }
    1441             : 
    1442             : 
    1443             : /* Add an S/MIME capability as an extended attribute to the message.
    1444             :    This function is to be called for each capability in turn. The
    1445             :    first capability added will receive the highest priority.  CMS is
    1446             :    the context, OID the object identifier of the capability and if DER
    1447             :    is not NULL it is used as the DER-encoded parameters of the
    1448             :    capability; the length of that DER object is given in DERLEN.
    1449             :    DERLEN should be 0 if DER is NULL.
    1450             : 
    1451             :    The function returns 0 on success or an error code.
    1452             : */
    1453             : gpg_error_t
    1454           0 : ksba_cms_add_smime_capability (ksba_cms_t cms, const char *oid,
    1455             :                                const unsigned char *der, size_t derlen)
    1456             : {
    1457             :   gpg_error_t err;
    1458             :   struct oidparmlist_s *opl, *opl2;
    1459             : 
    1460           0 :   if (!cms || !oid)
    1461           0 :     return gpg_error (GPG_ERR_INV_VALUE);
    1462             : 
    1463           0 :   if (!der)
    1464           0 :     derlen = 0;
    1465             : 
    1466           0 :   opl = xtrymalloc (sizeof *opl + derlen - 1);
    1467           0 :   if (!opl)
    1468           0 :     return gpg_error_from_errno (errno);
    1469           0 :   opl->next = NULL;
    1470           0 :   opl->oid = xtrystrdup (oid);
    1471           0 :   if (!opl->oid)
    1472             :     {
    1473           0 :       err = gpg_error_from_errno (errno);
    1474           0 :       xfree (opl);
    1475           0 :       return err;
    1476             :     }
    1477           0 :   opl->parmlen = derlen;
    1478           0 :   if (der)
    1479           0 :     memcpy (opl->parm, der, derlen);
    1480             : 
    1481             :   /* Append it to maintain the desired order. */
    1482           0 :   if (!cms->capability_list)
    1483           0 :     cms->capability_list = opl;
    1484             :   else
    1485             :     {
    1486           0 :       for (opl2=cms->capability_list; opl2->next; opl2 = opl2->next)
    1487             :         ;
    1488           0 :       opl2->next = opl;
    1489             :     }
    1490             : 
    1491           0 :   return 0;
    1492             : }
    1493             : 
    1494             : 
    1495             : 
    1496             : /**
    1497             :  * ksba_cms_set_message_digest:
    1498             :  * @cms: A CMS object
    1499             :  * @idx: The index of the signer
    1500             :  * @digest: a message digest
    1501             :  * @digest_len: the length of the message digest
    1502             :  *
    1503             :  * Set a message digest into the signedAttributes of the signer with
    1504             :  * the index IDX.  The index of a signer is determined by the sequence
    1505             :  * of ksba_cms_add_signer() calls; the first signer has the index 0.
    1506             :  * This function is to be used when the hash value of the data has
    1507             :  * been calculated and before the create function requests the sign
    1508             :  * operation.
    1509             :  *
    1510             :  * Return value: 0 on success or an error code
    1511             :  **/
    1512             : gpg_error_t
    1513           0 : ksba_cms_set_message_digest (ksba_cms_t cms, int idx,
    1514             :                              const unsigned char *digest, size_t digest_len)
    1515             : {
    1516             :   struct certlist_s *cl;
    1517             : 
    1518           0 :   if (!cms || !digest)
    1519           0 :     return gpg_error (GPG_ERR_INV_VALUE);
    1520           0 :   if (!digest_len || digest_len > DIM(cl->msg_digest))
    1521           0 :     return gpg_error (GPG_ERR_INV_VALUE);
    1522           0 :   if (idx < 0)
    1523           0 :     return gpg_error (GPG_ERR_INV_INDEX);
    1524             : 
    1525           0 :   for (cl=cms->cert_list; cl && idx; cl = cl->next, idx--)
    1526             :     ;
    1527           0 :   if (!cl)
    1528           0 :     return gpg_error (GPG_ERR_INV_INDEX); /* no certificate to store it */
    1529           0 :   cl->msg_digest_len = digest_len;
    1530           0 :   memcpy (cl->msg_digest, digest, digest_len);
    1531           0 :   return 0;
    1532             : }
    1533             : 
    1534             : /**
    1535             :  * ksba_cms_set_signing_time:
    1536             :  * @cms: A CMS object
    1537             :  * @idx: The index of the signer
    1538             :  * @sigtime: a time or an empty value to use the current time
    1539             :  *
    1540             :  * Set a signing time into the signedAttributes of the signer with
    1541             :  * the index IDX.  The index of a signer is determined by the sequence
    1542             :  * of ksba_cms_add_signer() calls; the first signer has the index 0.
    1543             :  *
    1544             :  * Return value: 0 on success or an error code
    1545             :  **/
    1546             : gpg_error_t
    1547           0 : ksba_cms_set_signing_time (ksba_cms_t cms, int idx, const ksba_isotime_t sigtime)
    1548             : {
    1549             :   struct certlist_s *cl;
    1550             : 
    1551           0 :   if (!cms)
    1552           0 :     return gpg_error (GPG_ERR_INV_VALUE);
    1553           0 :   if (idx < 0)
    1554           0 :     return gpg_error (GPG_ERR_INV_INDEX);
    1555             : 
    1556           0 :   for (cl=cms->cert_list; cl && idx; cl = cl->next, idx--)
    1557             :     ;
    1558           0 :   if (!cl)
    1559           0 :     return gpg_error (GPG_ERR_INV_INDEX); /* no certificate to store it */
    1560             : 
    1561             :   /* Fixme: We might want to check the validity of the passed time
    1562             :      string. */
    1563           0 :   if (!*sigtime)
    1564           0 :     _ksba_current_time (cl->signing_time);
    1565             :   else
    1566           0 :     _ksba_copy_time (cl->signing_time, sigtime);
    1567           0 :   return 0;
    1568             : }
    1569             : 
    1570             : 
    1571             : /*
    1572             :   r_sig  = (sig-val
    1573             :               (<algo>
    1574             :                 (<param_name1> <mpi>)
    1575             :                 ...
    1576             :                 (<param_namen> <mpi>)
    1577             :               ))
    1578             :   The sexp must be in canonical form.
    1579             :   Note the <algo> must be given as a stringified OID or the special
    1580             :   string "rsa".
    1581             : 
    1582             :   Note that IDX is only used for consistency checks.
    1583             :  */
    1584             : gpg_error_t
    1585           0 : ksba_cms_set_sig_val (ksba_cms_t cms, int idx, ksba_const_sexp_t sigval)
    1586             : {
    1587             :   const unsigned char *s;
    1588             :   unsigned long n;
    1589             :   struct sig_val_s *sv, **sv_tail;
    1590             :   int i;
    1591             : 
    1592           0 :   if (!cms)
    1593           0 :     return gpg_error (GPG_ERR_INV_VALUE);
    1594           0 :   if (idx < 0)
    1595           0 :     return gpg_error (GPG_ERR_INV_INDEX); /* only one signer for now */
    1596             : 
    1597           0 :   s = sigval;
    1598           0 :   if (*s != '(')
    1599           0 :     return gpg_error (GPG_ERR_INV_SEXP);
    1600           0 :   s++;
    1601             : 
    1602           0 :   for (i=0, sv_tail=&cms->sig_val; *sv_tail; sv_tail=&(*sv_tail)->next, i++)
    1603             :     ;
    1604           0 :   if (i != idx)
    1605           0 :     return gpg_error (GPG_ERR_INV_INDEX);
    1606             : 
    1607           0 :   if (!(n = snext (&s)))
    1608           0 :     return gpg_error (GPG_ERR_INV_SEXP);
    1609           0 :   if (!smatch (&s, 7, "sig-val"))
    1610           0 :     return gpg_error (GPG_ERR_UNKNOWN_SEXP);
    1611           0 :   if (*s != '(')
    1612           0 :     return gpg_error (digitp (s)? GPG_ERR_UNKNOWN_SEXP : GPG_ERR_INV_SEXP);
    1613           0 :   s++;
    1614             : 
    1615             :   /* Break out the algorithm ID. */
    1616           0 :   if (!(n = snext (&s)))
    1617           0 :     return gpg_error (GPG_ERR_INV_SEXP);
    1618             : 
    1619           0 :   sv = xtrycalloc (1, sizeof *sv);
    1620           0 :   if (!sv)
    1621           0 :     return gpg_error (GPG_ERR_ENOMEM);
    1622           0 :   if (n==3 && s[0] == 'r' && s[1] == 's' && s[2] == 'a')
    1623             :     { /* kludge to allow "rsa" to be passed as algorithm name */
    1624           0 :       sv->algo = xtrystrdup ("1.2.840.113549.1.1.1");
    1625           0 :       if (!sv->algo)
    1626             :         {
    1627           0 :           xfree (sv);
    1628           0 :           return gpg_error (GPG_ERR_ENOMEM);
    1629             :         }
    1630             :     }
    1631             :   else
    1632             :     {
    1633           0 :       sv->algo = xtrymalloc (n+1);
    1634           0 :       if (!sv->algo)
    1635             :         {
    1636           0 :           xfree (sv);
    1637           0 :           return gpg_error (GPG_ERR_ENOMEM);
    1638             :         }
    1639           0 :       memcpy (sv->algo, s, n);
    1640           0 :       sv->algo[n] = 0;
    1641             :     }
    1642           0 :   s += n;
    1643             : 
    1644             :   /* And now the values - FIXME: For now we only support one */
    1645             :   /* fixme: start loop */
    1646           0 :   if (*s != '(')
    1647             :     {
    1648           0 :       xfree (sv->algo);
    1649           0 :       xfree (sv);
    1650           0 :       return gpg_error (digitp (s)? GPG_ERR_UNKNOWN_SEXP : GPG_ERR_INV_SEXP);
    1651             :     }
    1652           0 :   s++;
    1653             : 
    1654           0 :   if (!(n = snext (&s)))
    1655             :     {
    1656           0 :       xfree (sv->algo);
    1657           0 :       xfree (sv);
    1658           0 :       return gpg_error (GPG_ERR_INV_SEXP);
    1659             :     }
    1660           0 :   s += n; /* ignore the name of the parameter */
    1661             : 
    1662           0 :   if (!digitp(s))
    1663             :     {
    1664           0 :       xfree (sv->algo);
    1665           0 :       xfree (sv);
    1666             :       /* May also be an invalid S-EXP.  */
    1667           0 :       return gpg_error (GPG_ERR_UNKNOWN_SEXP);
    1668             :     }
    1669             : 
    1670           0 :   if (!(n = snext (&s)))
    1671             :     {
    1672           0 :       xfree (sv->algo);
    1673           0 :       xfree (sv);
    1674           0 :       return gpg_error (GPG_ERR_INV_SEXP);
    1675             :     }
    1676             : 
    1677           0 :   if (n > 1 && !*s)
    1678             :     { /* We might have a leading zero due to the way we encode
    1679             :          MPIs - this zero should not go into the OCTECT STRING.  */
    1680           0 :       s++;
    1681           0 :       n--;
    1682             :     }
    1683           0 :   sv->value = xtrymalloc (n);
    1684           0 :   if (!sv->value)
    1685             :     {
    1686           0 :       xfree (sv->algo);
    1687           0 :       xfree (sv);
    1688           0 :       return gpg_error (GPG_ERR_ENOMEM);
    1689             :     }
    1690           0 :   memcpy (sv->value, s, n);
    1691           0 :   sv->valuelen = n;
    1692           0 :   s += n;
    1693           0 :   if ( *s != ')')
    1694             :     {
    1695           0 :       xfree (sv->value);
    1696           0 :       xfree (sv->algo);
    1697           0 :       xfree (sv);
    1698           0 :       return gpg_error (GPG_ERR_UNKNOWN_SEXP); /* but may also be an invalid one */
    1699             :     }
    1700           0 :   s++;
    1701             :   /* fixme: end loop over parameters */
    1702             : 
    1703             :   /* we need 2 closing parenthesis */
    1704           0 :   if ( *s != ')' || s[1] != ')')
    1705             :     {
    1706           0 :       xfree (sv->value);
    1707           0 :       xfree (sv->algo);
    1708           0 :       xfree (sv);
    1709           0 :       return gpg_error (GPG_ERR_INV_SEXP);
    1710             :     }
    1711             : 
    1712           0 :   *sv_tail = sv;
    1713           0 :   return 0;
    1714             : }
    1715             : 
    1716             : 
    1717             : /* Set the content encryption algorithm to OID and optionally set the
    1718             :    initialization vector to IV */
    1719             : gpg_error_t
    1720           0 : ksba_cms_set_content_enc_algo (ksba_cms_t cms,
    1721             :                                const char *oid,
    1722             :                                const void *iv, size_t ivlen)
    1723             : {
    1724           0 :   if (!cms || !oid)
    1725           0 :     return gpg_error (GPG_ERR_INV_VALUE);
    1726             : 
    1727           0 :   xfree (cms->encr_iv);
    1728           0 :   cms->encr_iv = NULL;
    1729           0 :   cms->encr_ivlen = 0;
    1730             : 
    1731           0 :   cms->encr_algo_oid = xtrystrdup (oid);
    1732           0 :   if (!cms->encr_algo_oid)
    1733           0 :     return gpg_error (GPG_ERR_ENOMEM);
    1734             : 
    1735           0 :   if (iv)
    1736             :     {
    1737           0 :       cms->encr_iv = xtrymalloc (ivlen);
    1738           0 :       if (!cms->encr_iv)
    1739           0 :         return gpg_error (GPG_ERR_ENOMEM);
    1740           0 :       memcpy (cms->encr_iv, iv, ivlen);
    1741           0 :       cms->encr_ivlen = ivlen;
    1742             :     }
    1743           0 :   return 0;
    1744             : }
    1745             : 
    1746             : 
    1747             : /*
    1748             :  * encval is expected to be a canonical encoded  S-Exp of this form:
    1749             :  *  (enc-val
    1750             :  *      (<algo>
    1751             :  *         (<param_name1> <mpi>)
    1752             :  *          ...
    1753             :  *         (<param_namen> <mpi>)
    1754             :  *      ))
    1755             :  *
    1756             :  * Note the <algo> must be given as a stringified OID or the special
    1757             :  * string "rsa" */
    1758             : gpg_error_t
    1759           0 : ksba_cms_set_enc_val (ksba_cms_t cms, int idx, ksba_const_sexp_t encval)
    1760             : {
    1761             :   /*FIXME: This shares most code with ...set_sig_val */
    1762             :   struct certlist_s *cl;
    1763             :   const char *s, *endp;
    1764             :   unsigned long n;
    1765             : 
    1766           0 :   if (!cms)
    1767           0 :     return gpg_error (GPG_ERR_INV_VALUE);
    1768           0 :   if (idx < 0)
    1769           0 :     return gpg_error (GPG_ERR_INV_INDEX);
    1770           0 :   for (cl=cms->cert_list; cl && idx; cl = cl->next, idx--)
    1771             :     ;
    1772           0 :   if (!cl)
    1773           0 :     return gpg_error (GPG_ERR_INV_INDEX); /* no certificate to store the value */
    1774             : 
    1775           0 :   s = encval;
    1776           0 :   if (*s != '(')
    1777           0 :     return gpg_error (GPG_ERR_INV_SEXP);
    1778           0 :   s++;
    1779             : 
    1780           0 :   n = strtoul (s, (char**)&endp, 10);
    1781           0 :   s = endp;
    1782           0 :   if (!n || *s!=':')
    1783           0 :     return gpg_error (GPG_ERR_INV_SEXP); /* we don't allow empty lengths */
    1784           0 :   s++;
    1785           0 :   if (n != 7 || memcmp (s, "enc-val", 7))
    1786           0 :     return gpg_error (GPG_ERR_UNKNOWN_SEXP);
    1787           0 :   s += 7;
    1788           0 :   if (*s != '(')
    1789           0 :     return gpg_error (digitp (s)? GPG_ERR_UNKNOWN_SEXP : GPG_ERR_INV_SEXP);
    1790           0 :   s++;
    1791             : 
    1792             :   /* break out the algorithm ID */
    1793           0 :   n = strtoul (s, (char**)&endp, 10);
    1794           0 :   s = endp;
    1795           0 :   if (!n || *s != ':')
    1796           0 :     return gpg_error (GPG_ERR_INV_SEXP); /* we don't allow empty lengths */
    1797           0 :   s++;
    1798           0 :   xfree (cl->enc_val.algo);
    1799           0 :   if (n==3 && s[0] == 'r' && s[1] == 's' && s[2] == 'a')
    1800             :     { /* kludge to allow "rsa" to be passed as algorithm name */
    1801           0 :       cl->enc_val.algo = xtrystrdup ("1.2.840.113549.1.1.1");
    1802           0 :       if (!cl->enc_val.algo)
    1803           0 :         return gpg_error (GPG_ERR_ENOMEM);
    1804             :     }
    1805             :   else
    1806             :     {
    1807           0 :       cl->enc_val.algo = xtrymalloc (n+1);
    1808           0 :       if (!cl->enc_val.algo)
    1809           0 :         return gpg_error (GPG_ERR_ENOMEM);
    1810           0 :       memcpy (cl->enc_val.algo, s, n);
    1811           0 :       cl->enc_val.algo[n] = 0;
    1812             :     }
    1813           0 :   s += n;
    1814             : 
    1815             :   /* And now the values - FIXME: For now we only support one */
    1816             :   /* fixme: start loop */
    1817           0 :   if (*s != '(')
    1818           0 :     return gpg_error (digitp (s)? GPG_ERR_UNKNOWN_SEXP : GPG_ERR_INV_SEXP);
    1819           0 :   s++;
    1820           0 :   n = strtoul (s, (char**)&endp, 10);
    1821           0 :   s = endp;
    1822           0 :   if (!n || *s != ':')
    1823           0 :     return gpg_error (GPG_ERR_INV_SEXP);
    1824           0 :   s++;
    1825           0 :   s += n; /* ignore the name of the parameter */
    1826             : 
    1827           0 :   if (!digitp(s))
    1828           0 :     return gpg_error (GPG_ERR_UNKNOWN_SEXP); /* but may also be an invalid one */
    1829           0 :   n = strtoul (s, (char**)&endp, 10);
    1830           0 :   s = endp;
    1831           0 :   if (!n || *s != ':')
    1832           0 :     return gpg_error (GPG_ERR_INV_SEXP);
    1833           0 :   s++;
    1834           0 :   if (n > 1 && !*s)
    1835             :     { /* We might have a leading zero due to the way we encode
    1836             :          MPIs - this zero should not go into the OCTECT STRING.  */
    1837           0 :       s++;
    1838           0 :       n--;
    1839             :     }
    1840           0 :   xfree (cl->enc_val.value);
    1841           0 :   cl->enc_val.value = xtrymalloc (n);
    1842           0 :   if (!cl->enc_val.value)
    1843           0 :     return gpg_error (GPG_ERR_ENOMEM);
    1844           0 :   memcpy (cl->enc_val.value, s, n);
    1845           0 :   cl->enc_val.valuelen = n;
    1846           0 :   s += n;
    1847           0 :   if ( *s != ')')
    1848           0 :     return gpg_error (GPG_ERR_UNKNOWN_SEXP); /* but may also be an invalid one */
    1849           0 :   s++;
    1850             :   /* fixme: end loop over parameters */
    1851             : 
    1852             :   /* we need 2 closing parenthesis */
    1853           0 :   if ( *s != ')' || s[1] != ')')
    1854           0 :     return gpg_error (GPG_ERR_INV_SEXP);
    1855             : 
    1856           0 :   return 0;
    1857             : }
    1858             : 
    1859             : 
    1860             : 
    1861             : 
    1862             : /**
    1863             :  * ksba_cms_add_recipient:
    1864             :  * @cms: A CMS object
    1865             :  * @cert: A certificate used to describe the recipient.
    1866             :  *
    1867             :  * This functions starts assembly of a new enveloped data content or adds
    1868             :  * another recipient to the list of recipients.
    1869             :  *
    1870             :  * Note: after successful completion of this function ownership of
    1871             :  * @cert is transferred to @cms.
    1872             :  *
    1873             :  * Return value: 0 on success or an error code.
    1874             :  **/
    1875             : gpg_error_t
    1876           0 : ksba_cms_add_recipient (ksba_cms_t cms, ksba_cert_t cert)
    1877             : {
    1878             :   /* for now we use the same structure */
    1879           0 :   return ksba_cms_add_signer (cms, cert);
    1880             : }
    1881             : 
    1882             : 
    1883             : 
    1884             : 
    1885             : /*
    1886             :    Content handler for parsing messages
    1887             : */
    1888             : 
    1889             : static gpg_error_t
    1890           0 : ct_parse_data (ksba_cms_t cms)
    1891             : {
    1892             :   (void)cms;
    1893           0 :   return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
    1894             : }
    1895             : 
    1896             : 
    1897             : static gpg_error_t
    1898           0 : ct_parse_signed_data (ksba_cms_t cms)
    1899             : {
    1900             :   enum {
    1901             :     sSTART,
    1902             :     sGOT_HASH,
    1903             :     sIN_DATA,
    1904             :     sERROR
    1905           0 :   } state = sERROR;
    1906           0 :   ksba_stop_reason_t stop_reason = cms->stop_reason;
    1907           0 :   gpg_error_t err = 0;
    1908             : 
    1909           0 :   cms->stop_reason = KSBA_SR_RUNNING;
    1910             : 
    1911             :   /* Calculate state from last reason and do some checks */
    1912           0 :   if (stop_reason == KSBA_SR_GOT_CONTENT)
    1913             :     {
    1914           0 :       state = sSTART;
    1915             :     }
    1916           0 :   else if (stop_reason == KSBA_SR_NEED_HASH)
    1917             :     {
    1918           0 :       state = sGOT_HASH;
    1919             :     }
    1920           0 :   else if (stop_reason == KSBA_SR_BEGIN_DATA)
    1921             :     {
    1922           0 :       if (!cms->hash_fnc)
    1923           0 :         err = gpg_error (GPG_ERR_MISSING_ACTION);
    1924             :       else
    1925           0 :         state = sIN_DATA;
    1926             :     }
    1927           0 :   else if (stop_reason == KSBA_SR_END_DATA)
    1928             :     {
    1929           0 :       state = sGOT_HASH;
    1930             :     }
    1931           0 :   else if (stop_reason == KSBA_SR_RUNNING)
    1932           0 :     err = gpg_error (GPG_ERR_INV_STATE);
    1933           0 :   else if (stop_reason)
    1934           0 :     err = gpg_error (GPG_ERR_BUG);
    1935             : 
    1936           0 :   if (err)
    1937           0 :     return err;
    1938             : 
    1939             :   /* Do the action */
    1940           0 :   if (state == sSTART)
    1941           0 :     err = _ksba_cms_parse_signed_data_part_1 (cms);
    1942           0 :   else if (state == sGOT_HASH)
    1943           0 :     err = _ksba_cms_parse_signed_data_part_2 (cms);
    1944           0 :   else if (state == sIN_DATA)
    1945           0 :     err = read_and_hash_cont (cms);
    1946             :   else
    1947           0 :     err = gpg_error (GPG_ERR_INV_STATE);
    1948             : 
    1949           0 :   if (err)
    1950           0 :     return err;
    1951             : 
    1952             :   /* Calculate new stop reason */
    1953           0 :   if (state == sSTART)
    1954             :     {
    1955           0 :       if (cms->detached_data && !cms->data.digest)
    1956             :         { /* We use this stop reason to inform the caller about a
    1957             :              detached signatures.  Actually there is no need for him
    1958             :              to hash the data now, he can do this also later. */
    1959           0 :           stop_reason = KSBA_SR_NEED_HASH;
    1960             :         }
    1961             :       else
    1962             :         { /* The user must now provide a hash function so that we can
    1963             :              hash the data in the next round */
    1964           0 :           stop_reason = KSBA_SR_BEGIN_DATA;
    1965             :         }
    1966             :     }
    1967           0 :   else if (state == sIN_DATA)
    1968           0 :     stop_reason = KSBA_SR_END_DATA;
    1969           0 :   else if (state ==sGOT_HASH)
    1970           0 :     stop_reason = KSBA_SR_READY;
    1971             : 
    1972           0 :   cms->stop_reason = stop_reason;
    1973           0 :   return 0;
    1974             : }
    1975             : 
    1976             : 
    1977             : static gpg_error_t
    1978           0 : ct_parse_enveloped_data (ksba_cms_t cms)
    1979             : {
    1980             :   enum {
    1981             :     sSTART,
    1982             :     sREST,
    1983             :     sINDATA,
    1984             :     sERROR
    1985           0 :   } state = sERROR;
    1986           0 :   ksba_stop_reason_t stop_reason = cms->stop_reason;
    1987           0 :   gpg_error_t err = 0;
    1988             : 
    1989           0 :   cms->stop_reason = KSBA_SR_RUNNING;
    1990             : 
    1991             :   /* Calculate state from last reason and do some checks */
    1992           0 :   if (stop_reason == KSBA_SR_GOT_CONTENT)
    1993             :     {
    1994           0 :       state = sSTART;
    1995             :     }
    1996           0 :   else if (stop_reason == KSBA_SR_DETACHED_DATA)
    1997             :     {
    1998           0 :       state = sREST;
    1999             :     }
    2000           0 :   else if (stop_reason == KSBA_SR_BEGIN_DATA)
    2001             :     {
    2002           0 :       state = sINDATA;
    2003             :     }
    2004           0 :   else if (stop_reason == KSBA_SR_END_DATA)
    2005             :     {
    2006           0 :       state = sREST;
    2007             :     }
    2008           0 :   else if (stop_reason == KSBA_SR_RUNNING)
    2009           0 :     err = gpg_error (GPG_ERR_INV_STATE);
    2010           0 :   else if (stop_reason)
    2011           0 :     err = gpg_error (GPG_ERR_BUG);
    2012             : 
    2013           0 :   if (err)
    2014           0 :     return err;
    2015             : 
    2016             :   /* Do the action */
    2017           0 :   if (state == sSTART)
    2018           0 :     err = _ksba_cms_parse_enveloped_data_part_1 (cms);
    2019           0 :   else if (state == sREST)
    2020           0 :     err = _ksba_cms_parse_enveloped_data_part_2 (cms);
    2021           0 :   else if (state == sINDATA)
    2022           0 :     err = read_encrypted_cont (cms);
    2023             :   else
    2024           0 :     err = gpg_error (GPG_ERR_INV_STATE);
    2025             : 
    2026           0 :   if (err)
    2027           0 :     return err;
    2028             : 
    2029             :   /* Calculate new stop reason */
    2030           0 :   if (state == sSTART)
    2031             :     {
    2032           0 :       stop_reason = cms->detached_data? KSBA_SR_DETACHED_DATA
    2033           0 :                                       : KSBA_SR_BEGIN_DATA;
    2034             :     }
    2035           0 :   else if (state == sINDATA)
    2036           0 :     stop_reason = KSBA_SR_END_DATA;
    2037           0 :   else if (state ==sREST)
    2038           0 :     stop_reason = KSBA_SR_READY;
    2039             : 
    2040           0 :   cms->stop_reason = stop_reason;
    2041           0 :   return 0;
    2042             : }
    2043             : 
    2044             : 
    2045             : static gpg_error_t
    2046           0 : ct_parse_digested_data (ksba_cms_t cms)
    2047             : {
    2048             :   (void)cms;
    2049           0 :   return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
    2050             : }
    2051             : 
    2052             : 
    2053             : static gpg_error_t
    2054           0 : ct_parse_encrypted_data (ksba_cms_t cms)
    2055             : {
    2056             :   (void)cms;
    2057           0 :   return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
    2058             : }
    2059             : 
    2060             : 
    2061             : 
    2062             : /*
    2063             :    Content handlers for building messages
    2064             : */
    2065             : 
    2066             : static gpg_error_t
    2067           0 : ct_build_data (ksba_cms_t cms)
    2068             : {
    2069             :   (void)cms;
    2070           0 :   return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
    2071             : }
    2072             : 
    2073             : 
    2074             : 
    2075             : /* Write everything up to the encapsulated data content type. */
    2076             : static gpg_error_t
    2077           0 : build_signed_data_header (ksba_cms_t cms)
    2078             : {
    2079             :   gpg_error_t err;
    2080             :   unsigned char *buf;
    2081             :   const char *s;
    2082             :   size_t len;
    2083             :   int i;
    2084             : 
    2085             :   /* Write the outer contentInfo. */
    2086           0 :   err = _ksba_ber_write_tl (cms->writer, TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, 0);
    2087           0 :   if (err)
    2088           0 :     return err;
    2089           0 :   err = ksba_oid_from_str (cms->content.oid, &buf, &len);
    2090           0 :   if (err)
    2091           0 :     return err;
    2092           0 :   err = _ksba_ber_write_tl (cms->writer,
    2093             :                             TYPE_OBJECT_ID, CLASS_UNIVERSAL, 0, len);
    2094           0 :   if (!err)
    2095           0 :     err = ksba_writer_write (cms->writer, buf, len);
    2096           0 :   xfree (buf);
    2097           0 :   if (err)
    2098           0 :     return err;
    2099             : 
    2100           0 :   err = _ksba_ber_write_tl (cms->writer, 0, CLASS_CONTEXT, 1, 0);
    2101           0 :   if (err)
    2102           0 :     return err;
    2103             : 
    2104             :   /* The SEQUENCE */
    2105           0 :   err = _ksba_ber_write_tl (cms->writer, TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, 0);
    2106           0 :   if (err)
    2107           0 :     return err;
    2108             : 
    2109             :   /* figure out the CMSVersion to be used */
    2110             :   if (0 /* fixme: have_attribute_certificates
    2111             :            || encapsulated_content != data
    2112             :            || any_signer_info_is_version_3*/ )
    2113             :     s = "\x03";
    2114             :   else
    2115           0 :     s = "\x01";
    2116           0 :   err = _ksba_ber_write_tl (cms->writer, TYPE_INTEGER, CLASS_UNIVERSAL, 0, 1);
    2117           0 :   if (err)
    2118           0 :     return err;
    2119           0 :   err = ksba_writer_write (cms->writer, s, 1);
    2120           0 :   if (err)
    2121           0 :     return err;
    2122             : 
    2123             :   /* SET OF DigestAlgorithmIdentifier */
    2124             :   {
    2125             :     unsigned char *value;
    2126             :     size_t valuelen;
    2127             :     ksba_writer_t tmpwrt;
    2128             : 
    2129           0 :     err = ksba_writer_new (&tmpwrt);
    2130           0 :     if (err)
    2131           0 :       return err;
    2132           0 :     err = ksba_writer_set_mem (tmpwrt, 512);
    2133           0 :     if (err)
    2134             :       {
    2135           0 :         ksba_writer_release (tmpwrt);
    2136           0 :         return err;
    2137             :       }
    2138             : 
    2139           0 :     for (i=0; (s = ksba_cms_get_digest_algo_list (cms, i)); i++)
    2140             :       {
    2141             :         int j;
    2142             :         const char *s2;
    2143             : 
    2144             :         /* (make sure not to write duplicates) */
    2145           0 :         for (j=0; j < i && (s2=ksba_cms_get_digest_algo_list (cms, j)); j++)
    2146             :           {
    2147           0 :             if (!strcmp (s, s2))
    2148           0 :               break;
    2149             :           }
    2150           0 :         if (j == i)
    2151             :           {
    2152           0 :             err = _ksba_der_write_algorithm_identifier (tmpwrt, s, NULL, 0);
    2153           0 :             if (err)
    2154             :               {
    2155           0 :                 ksba_writer_release (tmpwrt);
    2156           0 :                 return err;
    2157             :               }
    2158             :           }
    2159             :       }
    2160             : 
    2161           0 :     value = ksba_writer_snatch_mem (tmpwrt, &valuelen);
    2162           0 :     ksba_writer_release (tmpwrt);
    2163           0 :     if (!value)
    2164             :       {
    2165           0 :         err = gpg_error (GPG_ERR_ENOMEM);
    2166           0 :         return err;
    2167             :       }
    2168           0 :     err = _ksba_ber_write_tl (cms->writer, TYPE_SET, CLASS_UNIVERSAL,
    2169             :                               1, valuelen);
    2170           0 :     if (!err)
    2171           0 :       err = ksba_writer_write (cms->writer, value, valuelen);
    2172           0 :     xfree (value);
    2173           0 :     if (err)
    2174           0 :       return err;
    2175             :   }
    2176             : 
    2177             : 
    2178             : 
    2179             :   /* Write the (inner) encapsulatedContentInfo */
    2180             :   /* if we have a detached signature we don't need to use undefinite
    2181             :      length here - but it doesn't matter either */
    2182           0 :   err = _ksba_ber_write_tl (cms->writer, TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, 0);
    2183           0 :   if (err)
    2184           0 :     return err;
    2185           0 :   err = ksba_oid_from_str (cms->inner_cont_oid, &buf, &len);
    2186           0 :   if (err)
    2187           0 :     return err;
    2188           0 :   err = _ksba_ber_write_tl (cms->writer,
    2189             :                             TYPE_OBJECT_ID, CLASS_UNIVERSAL, 0, len);
    2190           0 :   if (!err)
    2191           0 :     err = ksba_writer_write (cms->writer, buf, len);
    2192           0 :   xfree (buf);
    2193           0 :   if (err)
    2194           0 :     return err;
    2195             : 
    2196           0 :   if ( !cms->detached_data)
    2197             :     { /* write the tag */
    2198           0 :       err = _ksba_ber_write_tl (cms->writer, 0, CLASS_CONTEXT, 1, 0);
    2199           0 :       if (err)
    2200           0 :         return err;
    2201             :     }
    2202             : 
    2203           0 :   return err;
    2204             : }
    2205             : 
    2206             : /* Set the issuer/serial from the cert to the node.
    2207             :    mode 0: sid
    2208             :    mode 1: rid
    2209             :  */
    2210             : static gpg_error_t
    2211           0 : set_issuer_serial (AsnNode info, ksba_cert_t cert, int mode)
    2212             : {
    2213             :   gpg_error_t err;
    2214             :   AsnNode dst, src;
    2215             : 
    2216           0 :   if (!info || !cert)
    2217           0 :     return gpg_error (GPG_ERR_INV_VALUE);
    2218             : 
    2219           0 :   src = _ksba_asn_find_node (cert->root,
    2220             :                              "Certificate.tbsCertificate.serialNumber");
    2221           0 :   dst = _ksba_asn_find_node (info,
    2222             :                              mode?
    2223             :                              "rid.issuerAndSerialNumber.serialNumber":
    2224             :                              "sid.issuerAndSerialNumber.serialNumber");
    2225           0 :   err = _ksba_der_copy_tree (dst, src, cert->image);
    2226           0 :   if (err)
    2227           0 :     return err;
    2228             : 
    2229           0 :   src = _ksba_asn_find_node (cert->root,
    2230             :                              "Certificate.tbsCertificate.issuer");
    2231           0 :   dst = _ksba_asn_find_node (info,
    2232             :                              mode?
    2233             :                              "rid.issuerAndSerialNumber.issuer":
    2234             :                              "sid.issuerAndSerialNumber.issuer");
    2235           0 :   err = _ksba_der_copy_tree (dst, src, cert->image);
    2236           0 :   if (err)
    2237           0 :     return err;
    2238             : 
    2239           0 :   return 0;
    2240             : }
    2241             : 
    2242             : 
    2243             : /* Store the sequence of capabilities at NODE */
    2244             : static gpg_error_t
    2245           0 : store_smime_capability_sequence (AsnNode node,
    2246             :                                  struct oidparmlist_s *capabilities)
    2247             : {
    2248             :   gpg_error_t err;
    2249             :   struct oidparmlist_s *cap, *cap2;
    2250             :   unsigned char *value;
    2251             :   size_t valuelen;
    2252             :   ksba_writer_t tmpwrt;
    2253             : 
    2254           0 :   err = ksba_writer_new (&tmpwrt);
    2255           0 :   if (err)
    2256           0 :     return err;
    2257           0 :   err = ksba_writer_set_mem (tmpwrt, 512);
    2258           0 :   if (err)
    2259             :     {
    2260           0 :       ksba_writer_release (tmpwrt);
    2261           0 :       return err;
    2262             :     }
    2263             : 
    2264           0 :   for (cap=capabilities; cap; cap = cap->next)
    2265             :     {
    2266             :       /* (avoid writing duplicates) */
    2267           0 :       for (cap2=capabilities; cap2 != cap; cap2 = cap2->next)
    2268             :         {
    2269           0 :           if (!strcmp (cap->oid, cap2->oid)
    2270           0 :               && cap->parmlen && cap->parmlen == cap2->parmlen
    2271           0 :               && !memcmp (cap->parm, cap2->parm, cap->parmlen))
    2272           0 :             break; /* Duplicate found. */
    2273             :         }
    2274           0 :       if (cap2 == cap)
    2275             :         {
    2276             :           /* RFC3851 requires that a missing parameter must not be
    2277             :              encoded as NULL.  This is in contrast to all other usages
    2278             :              of the algorithm identifier where ist is allowed and in
    2279             :              some profiles (e.g. tmttv2) even explicitly suggested to
    2280             :              use NULL.  */
    2281           0 :           err = _ksba_der_write_algorithm_identifier
    2282           0 :                  (tmpwrt, cap->oid,
    2283           0 :                   cap->parmlen?cap->parm:(const void*)"", cap->parmlen);
    2284           0 :           if (err)
    2285             :             {
    2286           0 :               ksba_writer_release (tmpwrt);
    2287           0 :               return err;
    2288             :             }
    2289             :         }
    2290             :     }
    2291             : 
    2292           0 :   value = ksba_writer_snatch_mem (tmpwrt, &valuelen);
    2293           0 :   if (!value)
    2294           0 :     err = gpg_error (GPG_ERR_ENOMEM);
    2295           0 :   if (!err)
    2296           0 :     err = _ksba_der_store_sequence (node, value, valuelen);
    2297           0 :   xfree (value);
    2298           0 :   ksba_writer_release (tmpwrt);
    2299           0 :   return err;
    2300             : }
    2301             : 
    2302             : 
    2303             : /* An object used to construct the signed attributes. */
    2304             : struct attrarray_s {
    2305             :   AsnNode root;
    2306             :   unsigned char *image;
    2307             :   size_t imagelen;
    2308             : };
    2309             : 
    2310             : 
    2311             : /* Thank you ASN.1 committee for allowing us to employ a sort to make
    2312             :    that DER encoding even more complicate. */
    2313             : static int
    2314           0 : compare_attrarray (const void *a_v, const void *b_v)
    2315             : {
    2316           0 :   const struct attrarray_s *a = a_v;
    2317           0 :   const struct attrarray_s *b = b_v;
    2318             :   const unsigned char *ap, *bp;
    2319             :   size_t an, bn;
    2320             : 
    2321           0 :   ap = a->image;
    2322           0 :   an = a->imagelen;
    2323           0 :   bp = b->image;
    2324           0 :   bn = b->imagelen;
    2325           0 :   for (; an && bn; an--, bn--, ap++, bp++ )
    2326           0 :     if (*ap != *bp)
    2327           0 :       return *ap - *bp;
    2328             : 
    2329           0 :   return (an == bn)? 0 : (an > bn)? 1 : -1;
    2330             : }
    2331             : 
    2332             : 
    2333             : 
    2334             : 
    2335             : /* Write the END of data NULL tag and everything we can write before
    2336             :    the user can calculate the signature */
    2337             : static gpg_error_t
    2338           0 : build_signed_data_attributes (ksba_cms_t cms)
    2339             : {
    2340             :   gpg_error_t err;
    2341             :   int signer;
    2342           0 :   ksba_asn_tree_t cms_tree = NULL;
    2343             :   struct certlist_s *certlist;
    2344             :   struct oidlist_s *digestlist;
    2345             :   struct signer_info_s *si, **si_tail;
    2346           0 :   AsnNode root = NULL;
    2347             :   struct attrarray_s attrarray[4];
    2348           0 :   int attridx = 0;
    2349             :   int i;
    2350             : 
    2351           0 :   memset (attrarray, 0, sizeof (attrarray));
    2352             : 
    2353             :   /* Write the End tag */
    2354           0 :   err = _ksba_ber_write_tl (cms->writer, 0, 0, 0, 0);
    2355           0 :   if (err)
    2356           0 :     return err;
    2357             : 
    2358           0 :   if (cms->signer_info)
    2359           0 :     return gpg_error (GPG_ERR_CONFLICT); /* This list must be empty at
    2360             :                                             this point. */
    2361             : 
    2362             :   /* Write optional certificates */
    2363           0 :   if (cms->cert_info_list)
    2364             :     {
    2365           0 :       unsigned long totallen = 0;
    2366             :       const unsigned char *der;
    2367             :       size_t n;
    2368             : 
    2369           0 :       for (certlist = cms->cert_info_list; certlist; certlist = certlist->next)
    2370             :         {
    2371           0 :           if (!ksba_cert_get_image (certlist->cert, &n))
    2372           0 :             return gpg_error (GPG_ERR_GENERAL); /* User passed an
    2373             :                                                    unitialized cert */
    2374           0 :           totallen += n;
    2375             :         }
    2376             : 
    2377           0 :       err = _ksba_ber_write_tl (cms->writer, 0, CLASS_CONTEXT, 1, totallen);
    2378           0 :       if (err)
    2379           0 :         return err;
    2380             : 
    2381           0 :       for (certlist = cms->cert_info_list; certlist; certlist = certlist->next)
    2382             :         {
    2383           0 :           if (!(der=ksba_cert_get_image (certlist->cert, &n)))
    2384           0 :             return gpg_error (GPG_ERR_BUG);
    2385           0 :           err = ksba_writer_write (cms->writer, der, n);
    2386           0 :           if (err )
    2387           0 :             return err;
    2388             :         }
    2389             :     }
    2390             : 
    2391             :   /* If we ever support it, here is the right place to do it:
    2392             :      Write the optional CRLs */
    2393             : 
    2394             :   /* Now we have to prepare the signer info.  For now we will just build the
    2395             :      signedAttributes, so that the user can do the signature calculation */
    2396           0 :   err = ksba_asn_create_tree ("cms", &cms_tree);
    2397           0 :   if (err)
    2398           0 :     return err;
    2399             : 
    2400           0 :   certlist = cms->cert_list;
    2401           0 :   if (!certlist)
    2402             :     {
    2403           0 :       err = gpg_error (GPG_ERR_MISSING_VALUE); /* oops */
    2404           0 :       goto leave;
    2405             :     }
    2406           0 :   digestlist = cms->digest_algos;
    2407           0 :   if (!digestlist)
    2408             :     {
    2409           0 :       err = gpg_error (GPG_ERR_MISSING_VALUE); /* oops */
    2410           0 :       goto leave;
    2411             :     }
    2412             : 
    2413           0 :   si_tail = &cms->signer_info;
    2414           0 :   for (signer=0; certlist;
    2415           0 :        signer++, certlist = certlist->next, digestlist = digestlist->next)
    2416             :     {
    2417             :       AsnNode attr;
    2418             :       AsnNode n;
    2419             :       unsigned char *image;
    2420             :       size_t imagelen;
    2421             : 
    2422           0 :       for (i = 0; i < attridx; i++)
    2423             :         {
    2424           0 :           _ksba_asn_release_nodes (attrarray[i].root);
    2425           0 :           xfree (attrarray[i].image);
    2426             :         }
    2427           0 :       attridx = 0;
    2428           0 :       memset (attrarray, 0, sizeof (attrarray));
    2429             : 
    2430           0 :       if (!digestlist)
    2431             :         {
    2432           0 :           err = gpg_error (GPG_ERR_MISSING_VALUE); /* oops */
    2433           0 :           goto leave;
    2434             :         }
    2435             : 
    2436           0 :       if (!certlist->cert || !digestlist->oid)
    2437             :         {
    2438           0 :           err = gpg_error (GPG_ERR_BUG);
    2439           0 :           goto leave;
    2440             :         }
    2441             : 
    2442             :       /* Include the pretty important message digest. */
    2443           0 :       attr = _ksba_asn_expand_tree (cms_tree->parse_tree,
    2444             :                                     "CryptographicMessageSyntax.Attribute");
    2445           0 :       if (!attr)
    2446             :         {
    2447           0 :           err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
    2448           0 :           goto leave;
    2449             :         }
    2450           0 :       n = _ksba_asn_find_node (attr, "Attribute.attrType");
    2451           0 :       if (!n)
    2452             :         {
    2453           0 :           err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
    2454           0 :           goto leave;
    2455             :         }
    2456           0 :       err = _ksba_der_store_oid (n, oidstr_messageDigest);
    2457           0 :       if (err)
    2458           0 :         goto leave;
    2459           0 :       n = _ksba_asn_find_node (attr, "Attribute.attrValues");
    2460           0 :       if (!n || !n->down)
    2461           0 :         return gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
    2462           0 :       n = n->down; /* fixme: ugly hack */
    2463           0 :       assert (certlist && certlist->msg_digest_len);
    2464           0 :       err = _ksba_der_store_octet_string (n, certlist->msg_digest,
    2465           0 :                                           certlist->msg_digest_len);
    2466           0 :       if (err)
    2467           0 :         goto leave;
    2468           0 :       err = _ksba_der_encode_tree (attr, &image, &imagelen);
    2469           0 :       if (err)
    2470           0 :         goto leave;
    2471           0 :       attrarray[attridx].root = attr;
    2472           0 :       attrarray[attridx].image = image;
    2473           0 :       attrarray[attridx].imagelen = imagelen;
    2474           0 :       attridx++;
    2475             : 
    2476             :       /* Include the content-type attribute. */
    2477           0 :       attr = _ksba_asn_expand_tree (cms_tree->parse_tree,
    2478             :                                     "CryptographicMessageSyntax.Attribute");
    2479           0 :       if (!attr)
    2480             :         {
    2481           0 :           err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
    2482           0 :           goto leave;
    2483             :         }
    2484           0 :       n = _ksba_asn_find_node (attr, "Attribute.attrType");
    2485           0 :       if (!n)
    2486             :         {
    2487           0 :           err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
    2488           0 :           goto leave;
    2489             :         }
    2490           0 :       err = _ksba_der_store_oid (n, oidstr_contentType);
    2491           0 :       if (err)
    2492           0 :         goto leave;
    2493           0 :       n = _ksba_asn_find_node (attr, "Attribute.attrValues");
    2494           0 :       if (!n || !n->down)
    2495             :         {
    2496           0 :           err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
    2497           0 :           goto leave;
    2498             :         }
    2499           0 :       n = n->down; /* fixme: ugly hack */
    2500           0 :       err = _ksba_der_store_oid (n, cms->inner_cont_oid);
    2501           0 :       if (err)
    2502           0 :         goto leave;
    2503           0 :       err = _ksba_der_encode_tree (attr, &image, &imagelen);
    2504           0 :       if (err)
    2505           0 :         goto leave;
    2506           0 :       attrarray[attridx].root = attr;
    2507           0 :       attrarray[attridx].image = image;
    2508           0 :       attrarray[attridx].imagelen = imagelen;
    2509           0 :       attridx++;
    2510             : 
    2511             :       /* Include the signing time */
    2512           0 :       if (certlist->signing_time)
    2513             :         {
    2514           0 :           attr = _ksba_asn_expand_tree (cms_tree->parse_tree,
    2515             :                                      "CryptographicMessageSyntax.Attribute");
    2516           0 :           if (!attr)
    2517             :             {
    2518           0 :               err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
    2519           0 :               goto leave;
    2520             :             }
    2521           0 :           n = _ksba_asn_find_node (attr, "Attribute.attrType");
    2522           0 :           if (!n)
    2523             :             {
    2524           0 :               err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
    2525           0 :               goto leave;
    2526             :             }
    2527           0 :           err = _ksba_der_store_oid (n, oidstr_signingTime);
    2528           0 :           if (err)
    2529           0 :             goto leave;
    2530           0 :           n = _ksba_asn_find_node (attr, "Attribute.attrValues");
    2531           0 :           if (!n || !n->down)
    2532             :             {
    2533           0 :               err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
    2534           0 :               goto leave;
    2535             :             }
    2536           0 :           n = n->down; /* fixme: ugly hack */
    2537           0 :           err = _ksba_der_store_time (n, certlist->signing_time);
    2538           0 :           if (err)
    2539           0 :             goto leave;
    2540           0 :           err = _ksba_der_encode_tree (attr, &image, &imagelen);
    2541           0 :           if (err)
    2542           0 :             goto leave;
    2543             :           /* We will use the attributes again - so save them */
    2544           0 :           attrarray[attridx].root = attr;
    2545           0 :           attrarray[attridx].image = image;
    2546           0 :           attrarray[attridx].imagelen = imagelen;
    2547           0 :           attridx++;
    2548             :         }
    2549             : 
    2550             :       /* Include the S/MIME capabilities with the first signer. */
    2551           0 :       if (cms->capability_list && !signer)
    2552             :         {
    2553           0 :           attr = _ksba_asn_expand_tree (cms_tree->parse_tree,
    2554             :                                     "CryptographicMessageSyntax.Attribute");
    2555           0 :           if (!attr)
    2556             :             {
    2557           0 :               err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
    2558           0 :               goto leave;
    2559             :             }
    2560           0 :           n = _ksba_asn_find_node (attr, "Attribute.attrType");
    2561           0 :           if (!n)
    2562             :             {
    2563           0 :               err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
    2564           0 :               goto leave;
    2565             :             }
    2566           0 :           err = _ksba_der_store_oid (n, oidstr_smimeCapabilities);
    2567           0 :           if (err)
    2568           0 :             goto leave;
    2569           0 :           n = _ksba_asn_find_node (attr, "Attribute.attrValues");
    2570           0 :           if (!n || !n->down)
    2571             :             {
    2572           0 :               err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
    2573           0 :               goto leave;
    2574             :             }
    2575           0 :           n = n->down; /* fixme: ugly hack */
    2576           0 :           err = store_smime_capability_sequence (n, cms->capability_list);
    2577           0 :           if (err)
    2578           0 :             goto leave;
    2579           0 :           err = _ksba_der_encode_tree (attr, &image, &imagelen);
    2580           0 :           if (err)
    2581           0 :             goto leave;
    2582           0 :           attrarray[attridx].root = attr;
    2583           0 :           attrarray[attridx].image = image;
    2584           0 :           attrarray[attridx].imagelen = imagelen;
    2585           0 :           attridx++;
    2586             :         }
    2587             : 
    2588             :       /* Arggh.  That silly ASN.1 DER encoding rules: We need to sort
    2589             :          the SET values. */
    2590           0 :       qsort (attrarray, attridx, sizeof (struct attrarray_s),
    2591             :              compare_attrarray);
    2592             : 
    2593             :       /* Now copy them to an SignerInfo tree.  This tree is not
    2594             :          complete but suitable for ksba_cms_hash_signed_attributes() */
    2595           0 :       root = _ksba_asn_expand_tree (cms_tree->parse_tree,
    2596             :                                     "CryptographicMessageSyntax.SignerInfo");
    2597           0 :       n = _ksba_asn_find_node (root, "SignerInfo.signedAttrs");
    2598           0 :       if (!n || !n->down)
    2599             :         {
    2600           0 :           err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
    2601           0 :           goto leave;
    2602             :         }
    2603             :       /* This is another ugly hack to move to the element we want */
    2604           0 :       for (n = n->down->down; n && n->type != TYPE_SEQUENCE; n = n->right)
    2605             :         ;
    2606           0 :       if (!n)
    2607             :         {
    2608           0 :           err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
    2609           0 :           goto leave;
    2610             :         }
    2611             : 
    2612           0 :       assert (attridx <= DIM (attrarray));
    2613           0 :       for (i=0; i < attridx; i++)
    2614             :         {
    2615           0 :           if (i)
    2616             :             {
    2617           0 :               if ( !(n=_ksba_asn_insert_copy (n)))
    2618             :                 {
    2619           0 :                   err = gpg_error (GPG_ERR_ENOMEM);
    2620           0 :                   goto leave;
    2621             :                 }
    2622             :             }
    2623           0 :           err = _ksba_der_copy_tree (n, attrarray[i].root, attrarray[i].image);
    2624           0 :           if (err)
    2625           0 :             goto leave;
    2626           0 :           _ksba_asn_release_nodes (attrarray[i].root);
    2627           0 :           free (attrarray[i].image);
    2628           0 :           attrarray[i].root = NULL;
    2629           0 :           attrarray[i].image = NULL;
    2630             :         }
    2631             : 
    2632           0 :       err = _ksba_der_encode_tree (root, &image, NULL);
    2633           0 :       if (err)
    2634           0 :         goto leave;
    2635             : 
    2636           0 :       si = xtrycalloc (1, sizeof *si);
    2637           0 :       if (!si)
    2638           0 :         return gpg_error (GPG_ERR_ENOMEM);
    2639           0 :       si->root = root;
    2640           0 :       root = NULL;
    2641           0 :       si->image = image;
    2642             :       /* Hmmm, we don't set the length of the image. */
    2643           0 :       *si_tail = si;
    2644           0 :       si_tail = &si->next;
    2645             :     }
    2646             : 
    2647             :  leave:
    2648           0 :   _ksba_asn_release_nodes (root);
    2649           0 :   ksba_asn_tree_release (cms_tree);
    2650           0 :   for (i = 0; i < attridx; i++)
    2651             :     {
    2652           0 :       _ksba_asn_release_nodes (attrarray[i].root);
    2653           0 :       xfree (attrarray[i].image);
    2654             :     }
    2655             : 
    2656           0 :   return err;
    2657             : }
    2658             : 
    2659             : 
    2660             : 
    2661             : 
    2662             : /* The user has calculated the signatures and we can therefore write
    2663             :    everything left over to do. */
    2664             : static gpg_error_t
    2665           0 : build_signed_data_rest (ksba_cms_t cms)
    2666             : {
    2667             :   gpg_error_t err;
    2668             :   int signer;
    2669           0 :   ksba_asn_tree_t cms_tree = NULL;
    2670             :   struct certlist_s *certlist;
    2671             :   struct oidlist_s *digestlist;
    2672             :   struct signer_info_s *si;
    2673             :   struct sig_val_s *sv;
    2674           0 :   ksba_writer_t tmpwrt = NULL;
    2675           0 :   AsnNode root = NULL;
    2676             : 
    2677             :   /* Now we can really write the signer info */
    2678           0 :   err = ksba_asn_create_tree ("cms", &cms_tree);
    2679           0 :   if (err)
    2680           0 :     return err;
    2681             : 
    2682           0 :   certlist = cms->cert_list;
    2683           0 :   if (!certlist)
    2684             :     {
    2685           0 :       err = gpg_error (GPG_ERR_MISSING_VALUE); /* oops */
    2686           0 :       return err;
    2687             :     }
    2688             : 
    2689             :   /* To construct the set we use a temporary writer object. */
    2690           0 :   err = ksba_writer_new (&tmpwrt);
    2691           0 :   if (err)
    2692           0 :     goto leave;
    2693           0 :   err = ksba_writer_set_mem (tmpwrt, 2048);
    2694           0 :   if (err)
    2695           0 :     goto leave;
    2696             : 
    2697           0 :   digestlist = cms->digest_algos;
    2698           0 :   si = cms->signer_info;
    2699           0 :   sv = cms->sig_val;
    2700             : 
    2701           0 :   for (signer=0; certlist;
    2702           0 :        signer++,
    2703           0 :          certlist = certlist->next,
    2704           0 :          digestlist = digestlist->next,
    2705           0 :          si = si->next,
    2706           0 :          sv = sv->next)
    2707             :     {
    2708             :       AsnNode n, n2;
    2709             :       unsigned char *image;
    2710             :       size_t imagelen;
    2711             : 
    2712           0 :       if (!digestlist || !si || !sv)
    2713             :         {
    2714           0 :           err = gpg_error (GPG_ERR_MISSING_VALUE); /* oops */
    2715           0 :           goto leave;
    2716             :         }
    2717           0 :       if (!certlist->cert || !digestlist->oid)
    2718             :         {
    2719           0 :           err = gpg_error (GPG_ERR_BUG);
    2720           0 :           goto leave;
    2721             :         }
    2722             : 
    2723           0 :       root = _ksba_asn_expand_tree (cms_tree->parse_tree,
    2724             :                                     "CryptographicMessageSyntax.SignerInfo");
    2725             : 
    2726             :       /* We store a version of 1 because we use the issuerAndSerialNumber */
    2727           0 :       n = _ksba_asn_find_node (root, "SignerInfo.version");
    2728           0 :       if (!n)
    2729             :         {
    2730           0 :           err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
    2731           0 :           goto leave;
    2732             :         }
    2733           0 :       err = _ksba_der_store_integer (n, "\x00\x00\x00\x01\x01");
    2734           0 :       if (err)
    2735           0 :         goto leave;
    2736             : 
    2737             :       /* Store the sid */
    2738           0 :       n = _ksba_asn_find_node (root, "SignerInfo.sid");
    2739           0 :       if (!n)
    2740             :         {
    2741           0 :           err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
    2742           0 :           goto leave;
    2743             :         }
    2744             : 
    2745           0 :       err = set_issuer_serial (n, certlist->cert, 0);
    2746           0 :       if (err)
    2747           0 :         goto leave;
    2748             : 
    2749             :       /* store the digestAlgorithm */
    2750           0 :       n = _ksba_asn_find_node (root, "SignerInfo.digestAlgorithm.algorithm");
    2751           0 :       if (!n)
    2752             :         {
    2753           0 :           err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
    2754           0 :           goto leave;
    2755             :         }
    2756           0 :       err = _ksba_der_store_oid (n, digestlist->oid);
    2757           0 :       if (err)
    2758           0 :         goto leave;
    2759           0 :       n = _ksba_asn_find_node (root, "SignerInfo.digestAlgorithm.parameters");
    2760           0 :       if (!n)
    2761             :         {
    2762           0 :           err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
    2763           0 :           goto leave;
    2764             :         }
    2765           0 :       err = _ksba_der_store_null (n);
    2766           0 :       if (err)
    2767           0 :         goto leave;
    2768             : 
    2769             :       /* and the signed attributes */
    2770           0 :       n = _ksba_asn_find_node (root, "SignerInfo.signedAttrs");
    2771           0 :       if (!n || !n->down)
    2772             :         {
    2773           0 :           err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
    2774           0 :           goto leave;
    2775             :         }
    2776           0 :       assert (si->root);
    2777           0 :       assert (si->image);
    2778           0 :       n2 = _ksba_asn_find_node (si->root, "SignerInfo.signedAttrs");
    2779           0 :       if (!n2 || !n->down)
    2780             :         {
    2781           0 :           err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
    2782           0 :           goto leave;
    2783             :         }
    2784           0 :       err = _ksba_der_copy_tree (n, n2, si->image);
    2785           0 :       if (err)
    2786           0 :         goto leave;
    2787           0 :       image = NULL;
    2788             : 
    2789             :       /* store the signatureAlgorithm */
    2790           0 :       n = _ksba_asn_find_node (root,
    2791             :                                "SignerInfo.signatureAlgorithm.algorithm");
    2792           0 :       if (!n)
    2793             :         {
    2794           0 :           err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
    2795           0 :           goto leave;
    2796             :         }
    2797           0 :       if (!sv->algo)
    2798             :         {
    2799           0 :           err = gpg_error (GPG_ERR_MISSING_VALUE);
    2800           0 :           goto leave;
    2801             :         }
    2802           0 :       err = _ksba_der_store_oid (n, sv->algo);
    2803           0 :       if (err)
    2804           0 :         goto leave;
    2805           0 :       n = _ksba_asn_find_node (root,
    2806             :                                "SignerInfo.signatureAlgorithm.parameters");
    2807           0 :       if (!n)
    2808             :         {
    2809           0 :           err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
    2810           0 :           goto leave;
    2811             :         }
    2812           0 :       err = _ksba_der_store_null (n);
    2813           0 :       if (err)
    2814           0 :         goto leave;
    2815             : 
    2816             :       /* store the signature  */
    2817           0 :       if (!sv->value)
    2818             :         {
    2819           0 :           err = gpg_error (GPG_ERR_MISSING_VALUE);
    2820           0 :           goto leave;
    2821             :         }
    2822           0 :       n = _ksba_asn_find_node (root, "SignerInfo.signature");
    2823           0 :       if (!n)
    2824             :         {
    2825           0 :           err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
    2826           0 :           goto leave;
    2827             :         }
    2828           0 :       err = _ksba_der_store_octet_string (n, sv->value, sv->valuelen);
    2829           0 :       if (err)
    2830           0 :         goto leave;
    2831             : 
    2832             :       /* Make the DER encoding and write it out. */
    2833           0 :       err = _ksba_der_encode_tree (root, &image, &imagelen);
    2834           0 :       if (err)
    2835           0 :         goto leave;
    2836             : 
    2837           0 :       err = ksba_writer_write (tmpwrt, image, imagelen);
    2838           0 :       xfree (image);
    2839           0 :       if (err)
    2840           0 :         goto leave;
    2841             :     }
    2842             : 
    2843             :   /* Write out the SET filled with all signer infos */
    2844             :   {
    2845             :     unsigned char *value;
    2846             :     size_t valuelen;
    2847             : 
    2848           0 :     value = ksba_writer_snatch_mem (tmpwrt, &valuelen);
    2849           0 :     if (!value)
    2850             :       {
    2851           0 :         err = gpg_error (GPG_ERR_ENOMEM);
    2852           0 :         goto leave;
    2853             :       }
    2854           0 :     err = _ksba_ber_write_tl (cms->writer, TYPE_SET, CLASS_UNIVERSAL,
    2855             :                               1, valuelen);
    2856           0 :     if (!err)
    2857           0 :       err = ksba_writer_write (cms->writer, value, valuelen);
    2858           0 :     xfree (value);
    2859           0 :     if (err)
    2860           0 :       goto leave;
    2861             :   }
    2862             : 
    2863             :   /* Write 3 end tags */
    2864           0 :   err = _ksba_ber_write_tl (cms->writer, 0, 0, 0, 0);
    2865           0 :   if (!err)
    2866           0 :     err = _ksba_ber_write_tl (cms->writer, 0, 0, 0, 0);
    2867           0 :   if (!err)
    2868           0 :     err = _ksba_ber_write_tl (cms->writer, 0, 0, 0, 0);
    2869             : 
    2870             :  leave:
    2871           0 :   ksba_asn_tree_release (cms_tree);
    2872           0 :   _ksba_asn_release_nodes (root);
    2873           0 :   ksba_writer_release (tmpwrt);
    2874             : 
    2875           0 :   return err;
    2876             : }
    2877             : 
    2878             : 
    2879             : 
    2880             : 
    2881             : static gpg_error_t
    2882           0 : ct_build_signed_data (ksba_cms_t cms)
    2883             : {
    2884             :   enum {
    2885             :     sSTART,
    2886             :     sDATAREADY,
    2887             :     sGOTSIG,
    2888             :     sERROR
    2889           0 :   } state = sERROR;
    2890             :   ksba_stop_reason_t stop_reason;
    2891           0 :   gpg_error_t err = 0;
    2892             : 
    2893           0 :   stop_reason = cms->stop_reason;
    2894           0 :   cms->stop_reason = KSBA_SR_RUNNING;
    2895             : 
    2896             :   /* Calculate state from last reason and do some checks */
    2897           0 :   if (stop_reason == KSBA_SR_GOT_CONTENT)
    2898             :     {
    2899           0 :       state = sSTART;
    2900             :     }
    2901           0 :   else if (stop_reason == KSBA_SR_BEGIN_DATA)
    2902             :     {
    2903             :       /* fixme: check that the message digest has been set */
    2904           0 :       state = sDATAREADY;
    2905             :     }
    2906           0 :   else if (stop_reason == KSBA_SR_END_DATA)
    2907           0 :     state = sDATAREADY;
    2908           0 :   else if (stop_reason == KSBA_SR_NEED_SIG)
    2909             :     {
    2910           0 :       if (!cms->sig_val)
    2911           0 :         err = gpg_error (GPG_ERR_MISSING_ACTION); /* No ksba_cms_set_sig_val () called */
    2912           0 :       state = sGOTSIG;
    2913             :     }
    2914           0 :   else if (stop_reason == KSBA_SR_RUNNING)
    2915           0 :     err = gpg_error (GPG_ERR_INV_STATE);
    2916           0 :   else if (stop_reason)
    2917           0 :     err = gpg_error (GPG_ERR_BUG);
    2918             : 
    2919           0 :   if (err)
    2920           0 :     return err;
    2921             : 
    2922             :   /* Do the action */
    2923           0 :   if (state == sSTART)
    2924             :     {
    2925             :       /* figure out whether a detached signature is requested */
    2926           0 :       if (cms->cert_list && cms->cert_list->msg_digest_len)
    2927           0 :         cms->detached_data = 1;
    2928             :       else
    2929           0 :         cms->detached_data = 0;
    2930             :       /* and start encoding */
    2931           0 :       err = build_signed_data_header (cms);
    2932             :     }
    2933           0 :   else if (state == sDATAREADY)
    2934             :     {
    2935           0 :       if (!cms->detached_data)
    2936           0 :         err = _ksba_ber_write_tl (cms->writer, 0, 0, 0, 0);
    2937           0 :       if (!err)
    2938           0 :         err = build_signed_data_attributes (cms);
    2939             :     }
    2940           0 :   else if (state == sGOTSIG)
    2941           0 :     err = build_signed_data_rest (cms);
    2942             :   else
    2943           0 :     err = gpg_error (GPG_ERR_INV_STATE);
    2944             : 
    2945           0 :   if (err)
    2946           0 :     return err;
    2947             : 
    2948             :   /* Calculate new stop reason */
    2949           0 :   if (state == sSTART)
    2950             :     {
    2951             :       /* user should write the data and calculate the hash or do
    2952             :          nothing in case of END_DATA */
    2953           0 :       stop_reason = cms->detached_data? KSBA_SR_END_DATA
    2954           0 :                                       : KSBA_SR_BEGIN_DATA;
    2955             :     }
    2956           0 :   else if (state == sDATAREADY)
    2957           0 :     stop_reason = KSBA_SR_NEED_SIG;
    2958           0 :   else if (state == sGOTSIG)
    2959           0 :     stop_reason = KSBA_SR_READY;
    2960             : 
    2961           0 :   cms->stop_reason = stop_reason;
    2962           0 :   return 0;
    2963             : }
    2964             : 
    2965             : 
    2966             : /* write everything up to the encryptedContentInfo including the tag */
    2967             : static gpg_error_t
    2968           0 : build_enveloped_data_header (ksba_cms_t cms)
    2969             : {
    2970             :   gpg_error_t err;
    2971             :   int recpno;
    2972           0 :   ksba_asn_tree_t cms_tree = NULL;
    2973             :   struct certlist_s *certlist;
    2974             :   unsigned char *buf;
    2975             :   const char *s;
    2976             :   size_t len;
    2977           0 :   ksba_writer_t tmpwrt = NULL;
    2978             : 
    2979             :   /* Write the outer contentInfo */
    2980             :   /* fixme: code is shared with signed_data_header */
    2981           0 :   err = _ksba_ber_write_tl (cms->writer, TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, 0);
    2982           0 :   if (err)
    2983           0 :     return err;
    2984           0 :   err = ksba_oid_from_str (cms->content.oid, &buf, &len);
    2985           0 :   if (err)
    2986           0 :     return err;
    2987           0 :   err = _ksba_ber_write_tl (cms->writer,
    2988             :                             TYPE_OBJECT_ID, CLASS_UNIVERSAL, 0, len);
    2989           0 :   if (!err)
    2990           0 :     err = ksba_writer_write (cms->writer, buf, len);
    2991           0 :   xfree (buf);
    2992           0 :   if (err)
    2993           0 :     return err;
    2994             : 
    2995           0 :   err = _ksba_ber_write_tl (cms->writer, 0, CLASS_CONTEXT, 1, 0);
    2996           0 :   if (err)
    2997           0 :     return err;
    2998             : 
    2999             :   /* The SEQUENCE */
    3000           0 :   err = _ksba_ber_write_tl (cms->writer, TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, 0);
    3001           0 :   if (err)
    3002           0 :     return err;
    3003             : 
    3004             :   /* figure out the CMSVersion to be used (from rfc2630):
    3005             :      version is the syntax version number.  If originatorInfo is
    3006             :      present, then version shall be 2.  If any of the RecipientInfo
    3007             :      structures included have a version other than 0, then the version
    3008             :      shall be 2.  If unprotectedAttrs is present, then version shall
    3009             :      be 2.  If originatorInfo is absent, all of the RecipientInfo
    3010             :      structures are version 0, and unprotectedAttrs is absent, then
    3011             :      version shall be 0.
    3012             : 
    3013             :      For SPHINX the version number must be 0.
    3014             :   */
    3015           0 :   s = "\x00";
    3016           0 :   err = _ksba_ber_write_tl (cms->writer, TYPE_INTEGER, CLASS_UNIVERSAL, 0, 1);
    3017           0 :   if (err)
    3018           0 :     return err;
    3019           0 :   err = ksba_writer_write (cms->writer, s, 1);
    3020           0 :   if (err)
    3021           0 :     return err;
    3022             : 
    3023             :   /* Note: originatorInfo is not yet implemented and must not be used
    3024             :      for SPHINX */
    3025             : 
    3026             :   /* Now we write the recipientInfo */
    3027           0 :   err = ksba_asn_create_tree ("cms", &cms_tree);
    3028           0 :   if (err)
    3029           0 :     return err;
    3030             : 
    3031           0 :   certlist = cms->cert_list;
    3032           0 :   if (!certlist)
    3033             :     {
    3034           0 :       err = gpg_error (GPG_ERR_MISSING_VALUE); /* oops */
    3035           0 :       goto leave;
    3036             :     }
    3037             : 
    3038             :   /* To construct the set we use a temporary writer object */
    3039           0 :   err = ksba_writer_new (&tmpwrt);
    3040           0 :   if (err)
    3041           0 :     goto leave;
    3042           0 :   err = ksba_writer_set_mem (tmpwrt, 2048);
    3043           0 :   if (err)
    3044           0 :     goto leave;
    3045             : 
    3046           0 :   for (recpno=0; certlist; recpno++, certlist = certlist->next)
    3047             :     {
    3048             :       AsnNode root, n;
    3049             :       unsigned char *image;
    3050             :       size_t imagelen;
    3051             : 
    3052           0 :       if (!certlist->cert)
    3053             :         {
    3054           0 :           err = gpg_error (GPG_ERR_BUG);
    3055           0 :           goto leave;
    3056             :         }
    3057             : 
    3058           0 :       root = _ksba_asn_expand_tree (cms_tree->parse_tree,
    3059             :                                 "CryptographicMessageSyntax.RecipientInfo");
    3060             : 
    3061             :       /* We store a version of 0 because we are only allowed to use
    3062             :          the issuerAndSerialNumber for SPHINX */
    3063           0 :       n = _ksba_asn_find_node (root, "RecipientInfo.ktri.version");
    3064           0 :       if (!n)
    3065             :         {
    3066           0 :           err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
    3067           0 :           goto leave;
    3068             :         }
    3069           0 :       err = _ksba_der_store_integer (n, "\x00\x00\x00\x01\x00");
    3070           0 :       if (err)
    3071           0 :         goto leave;
    3072             : 
    3073             :       /* Store the rid */
    3074           0 :       n = _ksba_asn_find_node (root, "RecipientInfo.ktri.rid");
    3075           0 :       if (!n)
    3076             :         {
    3077           0 :           err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
    3078           0 :           goto leave;
    3079             :         }
    3080             : 
    3081           0 :       err = set_issuer_serial (n, certlist->cert, 1);
    3082           0 :       if (err)
    3083           0 :         goto leave;
    3084             : 
    3085             :       /* store the keyEncryptionAlgorithm */
    3086           0 :       if (!certlist->enc_val.algo || !certlist->enc_val.value)
    3087           0 :         return gpg_error (GPG_ERR_MISSING_VALUE);
    3088           0 :       n = _ksba_asn_find_node (root,
    3089             :                   "RecipientInfo.ktri.keyEncryptionAlgorithm.algorithm");
    3090           0 :       if (!n)
    3091             :         {
    3092           0 :           err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
    3093           0 :           goto leave;
    3094             :         }
    3095           0 :       err = _ksba_der_store_oid (n, certlist->enc_val.algo);
    3096           0 :       if (err)
    3097           0 :         goto leave;
    3098           0 :       n = _ksba_asn_find_node (root,
    3099             :                   "RecipientInfo.ktri.keyEncryptionAlgorithm.parameters");
    3100           0 :       if (!n)
    3101             :         {
    3102           0 :           err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
    3103           0 :           goto leave;
    3104             :         }
    3105             : 
    3106             :       /* Now store NULL for the optional parameters.  From Peter
    3107             :        * Gutmann's X.509 style guide:
    3108             :        *
    3109             :        *   Another pitfall to be aware of is that algorithms which
    3110             :        *   have no parameters have this specified as a NULL value
    3111             :        *   rather than omitting the parameters field entirely.  The
    3112             :        *   reason for this is that when the 1988 syntax for
    3113             :        *   AlgorithmIdentifier was translated into the 1997 syntax,
    3114             :        *   the OPTIONAL associated with the AlgorithmIdentifier
    3115             :        *   parameters got lost.  Later it was recovered via a defect
    3116             :        *   report, but by then everyone thought that algorithm
    3117             :        *   parameters were mandatory.  Because of this the algorithm
    3118             :        *   parameters should be specified as NULL, regardless of what
    3119             :        *   you read elsewhere.
    3120             :        *
    3121             :        *        The trouble is that things *never* get better, they just
    3122             :        *        stay the same, only more so
    3123             :        *            -- Terry Pratchett, "Eric"
    3124             :        *
    3125             :        * Although this is about signing, we always do it.  Versions of
    3126             :        * Libksba before 1.0.6 had a bug writing out the NULL tag here,
    3127             :        * thus in reality we used to be correct according to the
    3128             :        * standards despite we didn't intended so.
    3129             :        */
    3130             : 
    3131           0 :       err = _ksba_der_store_null (n);
    3132           0 :       if (err)
    3133           0 :         goto leave;
    3134             : 
    3135             :       /* store the encryptedKey  */
    3136           0 :       if (!certlist->enc_val.value)
    3137             :         {
    3138           0 :           err = gpg_error (GPG_ERR_MISSING_VALUE);
    3139           0 :           goto leave;
    3140             :         }
    3141           0 :       n = _ksba_asn_find_node (root, "RecipientInfo.ktri.encryptedKey");
    3142           0 :       if (!n)
    3143             :         {
    3144           0 :           err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
    3145           0 :           goto leave;
    3146             :         }
    3147           0 :       err = _ksba_der_store_octet_string (n,
    3148           0 :                                           certlist->enc_val.value,
    3149             :                                           certlist->enc_val.valuelen);
    3150           0 :       if (err)
    3151           0 :         goto leave;
    3152             : 
    3153             : 
    3154             :       /* Make the DER encoding and write it out */
    3155           0 :       err = _ksba_der_encode_tree (root, &image, &imagelen);
    3156           0 :       if (err)
    3157           0 :           goto leave;
    3158             : 
    3159           0 :       err = ksba_writer_write (tmpwrt, image, imagelen);
    3160           0 :       if (err)
    3161           0 :         goto leave;
    3162             : 
    3163           0 :       xfree (image);
    3164           0 :       _ksba_asn_release_nodes (root);
    3165             :     }
    3166             : 
    3167           0 :   ksba_asn_tree_release (cms_tree);
    3168           0 :   cms_tree = NULL;
    3169             : 
    3170             :   /* Write out the SET filled with all recipient infos */
    3171             :   {
    3172             :     unsigned char *value;
    3173             :     size_t valuelen;
    3174             : 
    3175           0 :     value = ksba_writer_snatch_mem (tmpwrt, &valuelen);
    3176           0 :     if (!value)
    3177             :       {
    3178           0 :         err = gpg_error (GPG_ERR_ENOMEM);
    3179           0 :         goto leave;
    3180             :       }
    3181           0 :     ksba_writer_release (tmpwrt);
    3182           0 :     tmpwrt = NULL;
    3183           0 :     err = _ksba_ber_write_tl (cms->writer, TYPE_SET, CLASS_UNIVERSAL,
    3184             :                               1, valuelen);
    3185           0 :     if (!err)
    3186           0 :       err = ksba_writer_write (cms->writer, value, valuelen);
    3187           0 :     xfree (value);
    3188           0 :     if (err)
    3189           0 :       goto leave;
    3190             :   }
    3191             : 
    3192             : 
    3193             :   /* Write the (inner) encryptedContentInfo */
    3194           0 :   err = _ksba_ber_write_tl (cms->writer, TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, 0);
    3195           0 :   if (err)
    3196           0 :     return err;
    3197           0 :   err = ksba_oid_from_str (cms->inner_cont_oid, &buf, &len);
    3198           0 :   if (err)
    3199           0 :     return err;
    3200           0 :   err = _ksba_ber_write_tl (cms->writer,
    3201             :                             TYPE_OBJECT_ID, CLASS_UNIVERSAL, 0, len);
    3202           0 :   if (!err)
    3203           0 :     err = ksba_writer_write (cms->writer, buf, len);
    3204           0 :   xfree (buf);
    3205           0 :   if (err)
    3206           0 :     return err;
    3207             : 
    3208             :   /* and the encryptionAlgorithm */
    3209           0 :   err = _ksba_der_write_algorithm_identifier (cms->writer,
    3210           0 :                                               cms->encr_algo_oid,
    3211           0 :                                               cms->encr_iv,
    3212             :                                               cms->encr_ivlen);
    3213           0 :   if (err)
    3214           0 :     return err;
    3215             : 
    3216             :   /* write the tag for the encrypted data, it is an implicit octect
    3217             :      string in constructed form and indefinite length */
    3218           0 :   err = _ksba_ber_write_tl (cms->writer, 0, CLASS_CONTEXT, 1, 0);
    3219           0 :   if (err)
    3220           0 :     return err;
    3221             : 
    3222             :   /* Now the encrypted data should be written */
    3223             : 
    3224             :  leave:
    3225           0 :   ksba_writer_release (tmpwrt);
    3226           0 :   ksba_asn_tree_release (cms_tree);
    3227           0 :   return err;
    3228             : }
    3229             : 
    3230             : 
    3231             : static gpg_error_t
    3232           0 : ct_build_enveloped_data (ksba_cms_t cms)
    3233             : {
    3234             :   enum {
    3235             :     sSTART,
    3236             :     sINDATA,
    3237             :     sREST,
    3238             :     sERROR
    3239           0 :   } state = sERROR;
    3240             :   ksba_stop_reason_t stop_reason;
    3241           0 :   gpg_error_t err = 0;
    3242             : 
    3243           0 :   stop_reason = cms->stop_reason;
    3244           0 :   cms->stop_reason = KSBA_SR_RUNNING;
    3245             : 
    3246             :   /* Calculate state from last reason and do some checks */
    3247           0 :   if (stop_reason == KSBA_SR_GOT_CONTENT)
    3248           0 :     state = sSTART;
    3249           0 :   else if (stop_reason == KSBA_SR_BEGIN_DATA)
    3250           0 :     state = sINDATA;
    3251           0 :   else if (stop_reason == KSBA_SR_END_DATA)
    3252           0 :     state = sREST;
    3253           0 :   else if (stop_reason == KSBA_SR_RUNNING)
    3254           0 :     err = gpg_error (GPG_ERR_INV_STATE);
    3255           0 :   else if (stop_reason)
    3256           0 :     err = gpg_error (GPG_ERR_BUG);
    3257             : 
    3258           0 :   if (err)
    3259           0 :     return err;
    3260             : 
    3261             :   /* Do the action */
    3262           0 :   if (state == sSTART)
    3263           0 :     err = build_enveloped_data_header (cms);
    3264           0 :   else if (state == sINDATA)
    3265           0 :     err = write_encrypted_cont (cms);
    3266           0 :   else if (state == sREST)
    3267             :     {
    3268             :       /* SPHINX does not allow for unprotectedAttributes */
    3269             : 
    3270             :       /* Write 5 end tags */
    3271           0 :       err = _ksba_ber_write_tl (cms->writer, 0, 0, 0, 0);
    3272           0 :       if (!err)
    3273           0 :         err = _ksba_ber_write_tl (cms->writer, 0, 0, 0, 0);
    3274           0 :       if (!err)
    3275           0 :         err = _ksba_ber_write_tl (cms->writer, 0, 0, 0, 0);
    3276           0 :       if (!err)
    3277           0 :         err = _ksba_ber_write_tl (cms->writer, 0, 0, 0, 0);
    3278             :     }
    3279             :   else
    3280           0 :     err = gpg_error (GPG_ERR_INV_STATE);
    3281             : 
    3282           0 :   if (err)
    3283           0 :     return err;
    3284             : 
    3285             :   /* Calculate new stop reason */
    3286           0 :   if (state == sSTART)
    3287             :     { /* user should now write the encrypted data */
    3288           0 :       stop_reason = KSBA_SR_BEGIN_DATA;
    3289             :     }
    3290           0 :   else if (state == sINDATA)
    3291             :     { /* tell the user that we wrote everything */
    3292           0 :       stop_reason = KSBA_SR_END_DATA;
    3293             :     }
    3294           0 :   else if (state == sREST)
    3295             :     {
    3296           0 :       stop_reason = KSBA_SR_READY;
    3297             :     }
    3298             : 
    3299           0 :   cms->stop_reason = stop_reason;
    3300           0 :   return 0;
    3301             : }
    3302             : 
    3303             : 
    3304             : static gpg_error_t
    3305           0 : ct_build_digested_data (ksba_cms_t cms)
    3306             : {
    3307             :   (void)cms;
    3308           0 :   return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
    3309             : }
    3310             : 
    3311             : 
    3312             : static gpg_error_t
    3313           0 : ct_build_encrypted_data (ksba_cms_t cms)
    3314             : {
    3315             :   (void)cms;
    3316           0 :   return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
    3317             : }

Generated by: LCOV version 1.12