"Fossies" - the Fresh Open Source Software Archive

Member "libksba-1.6.0/src/cms.c" (2 Jun 2021, 108840 Bytes) of package /linux/privat/libksba-1.6.0.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "cms.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.5.1_vs_1.6.0.

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