LCOV - code coverage report
Current view: top level - sm - sign.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 376 0.0 %
Date: 2015-11-05 17:10:59 Functions: 0 6 0.0 %

          Line data    Source code
       1             : /* sign.c - Sign a message
       2             :  * Copyright (C) 2001, 2002, 2003, 2008,
       3             :  *               2010 Free Software Foundation, Inc.
       4             :  *
       5             :  * This file is part of GnuPG.
       6             :  *
       7             :  * GnuPG is free software; you can redistribute it and/or modify
       8             :  * it under the terms of the GNU General Public License as published by
       9             :  * the Free Software Foundation; either version 3 of the License, or
      10             :  * (at your option) any later version.
      11             :  *
      12             :  * GnuPG is distributed in the hope that it will be useful,
      13             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :  * GNU General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU General Public License
      18             :  * along with this program; if not, see <http://www.gnu.org/licenses/>.
      19             :  */
      20             : 
      21             : #include <config.h>
      22             : #include <stdio.h>
      23             : #include <stdlib.h>
      24             : #include <string.h>
      25             : #include <errno.h>
      26             : #include <unistd.h>
      27             : #include <time.h>
      28             : #include <assert.h>
      29             : 
      30             : #include "gpgsm.h"
      31             : #include <gcrypt.h>
      32             : #include <ksba.h>
      33             : 
      34             : #include "keydb.h"
      35             : #include "i18n.h"
      36             : 
      37             : 
      38             : /* Hash the data and return if something was hashed.  Return -1 on error.  */
      39             : static int
      40           0 : hash_data (int fd, gcry_md_hd_t md)
      41             : {
      42             :   estream_t fp;
      43             :   char buffer[4096];
      44             :   int nread;
      45           0 :   int rc = 0;
      46             : 
      47           0 :   fp = es_fdopen_nc (fd, "rb");
      48           0 :   if (!fp)
      49             :     {
      50           0 :       log_error ("fdopen(%d) failed: %s\n", fd, strerror (errno));
      51           0 :       return -1;
      52             :     }
      53             : 
      54             :   do
      55             :     {
      56           0 :       nread = es_fread (buffer, 1, DIM(buffer), fp);
      57           0 :       gcry_md_write (md, buffer, nread);
      58             :     }
      59           0 :   while (nread);
      60           0 :   if (es_ferror (fp))
      61             :     {
      62           0 :       log_error ("read error on fd %d: %s\n", fd, strerror (errno));
      63           0 :       rc = -1;
      64             :     }
      65           0 :   es_fclose (fp);
      66           0 :   return rc;
      67             : }
      68             : 
      69             : 
      70             : static int
      71           0 : hash_and_copy_data (int fd, gcry_md_hd_t md, ksba_writer_t writer)
      72             : {
      73             :   gpg_error_t err;
      74             :   estream_t fp;
      75             :   char buffer[4096];
      76             :   int nread;
      77           0 :   int rc = 0;
      78           0 :   int any = 0;
      79             : 
      80           0 :   fp = es_fdopen_nc (fd, "rb");
      81           0 :   if (!fp)
      82             :     {
      83           0 :       gpg_error_t tmperr = gpg_error_from_syserror ();
      84           0 :       log_error ("fdopen(%d) failed: %s\n", fd, strerror (errno));
      85           0 :       return tmperr;
      86             :     }
      87             : 
      88             :   do
      89             :     {
      90           0 :       nread = es_fread (buffer, 1, DIM(buffer), fp);
      91           0 :       if (nread)
      92             :         {
      93           0 :           any = 1;
      94           0 :           gcry_md_write (md, buffer, nread);
      95           0 :           err = ksba_writer_write_octet_string (writer, buffer, nread, 0);
      96           0 :           if (err)
      97             :             {
      98           0 :               log_error ("write failed: %s\n", gpg_strerror (err));
      99           0 :               rc = err;
     100             :             }
     101             :         }
     102             :     }
     103           0 :   while (nread && !rc);
     104           0 :   if (es_ferror (fp))
     105             :     {
     106           0 :       rc = gpg_error_from_syserror ();
     107           0 :       log_error ("read error on fd %d: %s\n", fd, strerror (errno));
     108             :     }
     109           0 :   es_fclose (fp);
     110           0 :   if (!any)
     111             :     {
     112             :       /* We can't allow to sign an empty message because it does not
     113             :          make much sense and more seriously, ksba_cms_build has
     114             :          already written the tag for data and now expects an octet
     115             :          string and an octet string of size 0 is illegal.  */
     116           0 :       log_error ("cannot sign an empty message\n");
     117           0 :       rc = gpg_error (GPG_ERR_NO_DATA);
     118             :     }
     119           0 :   if (!rc)
     120             :     {
     121           0 :       err = ksba_writer_write_octet_string (writer, NULL, 0, 1);
     122           0 :       if (err)
     123             :         {
     124           0 :           log_error ("write failed: %s\n", gpg_strerror (err));
     125           0 :           rc = err;
     126             :         }
     127             :     }
     128             : 
     129           0 :   return rc;
     130             : }
     131             : 
     132             : 
     133             : /* Get the default certificate which is defined as the first
     134             :    certificate capable of signing returned by the keyDB and has a
     135             :    secret key available. */
     136             : int
     137           0 : gpgsm_get_default_cert (ctrl_t ctrl, ksba_cert_t *r_cert)
     138             : {
     139             :   KEYDB_HANDLE hd;
     140           0 :   ksba_cert_t cert = NULL;
     141             :   int rc;
     142             :   char *p;
     143             : 
     144           0 :   hd = keydb_new (0);
     145           0 :   if (!hd)
     146           0 :     return gpg_error (GPG_ERR_GENERAL);
     147           0 :   rc = keydb_search_first (hd);
     148           0 :   if (rc)
     149             :     {
     150           0 :       keydb_release (hd);
     151           0 :       return rc;
     152             :     }
     153             : 
     154             :   do
     155             :     {
     156           0 :       rc = keydb_get_cert (hd, &cert);
     157           0 :       if (rc)
     158             :         {
     159           0 :           log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc));
     160           0 :           keydb_release (hd);
     161           0 :           return rc;
     162             :         }
     163             : 
     164           0 :       if (!gpgsm_cert_use_sign_p (cert))
     165             :         {
     166           0 :           p = gpgsm_get_keygrip_hexstring (cert);
     167           0 :           if (p)
     168             :             {
     169           0 :               if (!gpgsm_agent_havekey (ctrl, p))
     170             :                 {
     171           0 :                   xfree (p);
     172           0 :                   keydb_release (hd);
     173           0 :                   *r_cert = cert;
     174           0 :                   return 0; /* got it */
     175             :                 }
     176           0 :               xfree (p);
     177             :             }
     178             :         }
     179             : 
     180           0 :       ksba_cert_release (cert);
     181           0 :       cert = NULL;
     182             :     }
     183           0 :   while (!(rc = keydb_search_next (hd)));
     184           0 :   if (rc && rc != -1)
     185           0 :     log_error ("keydb_search_next failed: %s\n", gpg_strerror (rc));
     186             : 
     187           0 :   ksba_cert_release (cert);
     188           0 :   keydb_release (hd);
     189           0 :   return rc;
     190             : }
     191             : 
     192             : 
     193             : static ksba_cert_t
     194           0 : get_default_signer (ctrl_t ctrl)
     195             : {
     196             :   KEYDB_SEARCH_DESC desc;
     197           0 :   ksba_cert_t cert = NULL;
     198           0 :   KEYDB_HANDLE kh = NULL;
     199             :   int rc;
     200             : 
     201           0 :   if (!opt.local_user)
     202             :     {
     203           0 :       rc = gpgsm_get_default_cert (ctrl, &cert);
     204           0 :       if (rc)
     205             :         {
     206           0 :           if (rc != -1)
     207           0 :             log_debug ("failed to find default certificate: %s\n",
     208             :                        gpg_strerror (rc));
     209           0 :           return NULL;
     210             :         }
     211           0 :       return cert;
     212             :     }
     213             : 
     214           0 :   rc = classify_user_id (opt.local_user, &desc, 0);
     215           0 :   if (rc)
     216             :     {
     217           0 :       log_error ("failed to find default signer: %s\n", gpg_strerror (rc));
     218           0 :       return NULL;
     219             :     }
     220             : 
     221           0 :   kh = keydb_new (0);
     222           0 :   if (!kh)
     223           0 :     return NULL;
     224             : 
     225           0 :   rc = keydb_search (kh, &desc, 1);
     226           0 :   if (rc)
     227             :     {
     228           0 :       log_debug ("failed to find default certificate: rc=%d\n", rc);
     229             :     }
     230             :   else
     231             :     {
     232           0 :       rc = keydb_get_cert (kh, &cert);
     233           0 :       if (rc)
     234             :         {
     235           0 :           log_debug ("failed to get cert: rc=%d\n", rc);
     236             :         }
     237             :     }
     238             : 
     239           0 :   keydb_release (kh);
     240           0 :   return cert;
     241             : }
     242             : 
     243             : /* Depending on the options in CTRL add the certificate CERT as well as
     244             :    other certificate up in the chain to the Root-CA to the CMS
     245             :    object. */
     246             : static int
     247           0 : add_certificate_list (ctrl_t ctrl, ksba_cms_t cms, ksba_cert_t cert)
     248             : {
     249             :   gpg_error_t err;
     250           0 :   int rc = 0;
     251           0 :   ksba_cert_t next = NULL;
     252             :   int n;
     253           0 :   int not_root = 0;
     254             : 
     255           0 :   ksba_cert_ref (cert);
     256             : 
     257           0 :   n = ctrl->include_certs;
     258           0 :   log_debug ("adding certificates at level %d\n", n);
     259           0 :   if (n == -2)
     260             :     {
     261           0 :       not_root = 1;
     262           0 :       n = -1;
     263             :     }
     264           0 :   if (n < 0 || n > 50)
     265           0 :     n = 50; /* We better apply an upper bound */
     266             : 
     267             :   /* First add my own certificate unless we don't want any certificate
     268             :      included at all. */
     269           0 :   if (n)
     270             :     {
     271           0 :       if (not_root && gpgsm_is_root_cert (cert))
     272           0 :         err = 0;
     273             :       else
     274           0 :         err = ksba_cms_add_cert (cms, cert);
     275           0 :       if (err)
     276           0 :         goto ksba_failure;
     277           0 :       if (n>0)
     278           0 :         n--;
     279             :     }
     280             :   /* Walk the chain to include all other certificates.  Note that a -1
     281             :      used for N makes sure that there is no limit and all certs get
     282             :      included. */
     283           0 :   while ( n-- && !(rc = gpgsm_walk_cert_chain (ctrl, cert, &next)) )
     284             :     {
     285           0 :       if (not_root && gpgsm_is_root_cert (next))
     286           0 :         err = 0;
     287             :       else
     288           0 :         err = ksba_cms_add_cert (cms, next);
     289           0 :       ksba_cert_release (cert);
     290           0 :       cert = next; next = NULL;
     291           0 :       if (err)
     292           0 :         goto ksba_failure;
     293             :     }
     294           0 :   ksba_cert_release (cert);
     295             : 
     296           0 :   return rc == -1? 0: rc;
     297             : 
     298             :  ksba_failure:
     299           0 :   ksba_cert_release (cert);
     300           0 :   log_error ("ksba_cms_add_cert failed: %s\n", gpg_strerror (err));
     301           0 :   return err;
     302             : }
     303             : 
     304             : 
     305             : 
     306             : 
     307             : /* Perform a sign operation.
     308             : 
     309             :    Sign the data received on DATA-FD in embedded mode or in detached
     310             :    mode when DETACHED is true.  Write the signature to OUT_FP.  The
     311             :    keys used to sign are taken from SIGNERLIST or the default one will
     312             :    be used if the value of this argument is NULL. */
     313             : int
     314           0 : gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
     315             :             int data_fd, int detached, estream_t out_fp)
     316             : {
     317             :   int i, rc;
     318             :   gpg_error_t err;
     319           0 :   Base64Context b64writer = NULL;
     320             :   ksba_writer_t writer;
     321           0 :   ksba_cms_t cms = NULL;
     322             :   ksba_stop_reason_t stopreason;
     323           0 :   KEYDB_HANDLE kh = NULL;
     324           0 :   gcry_md_hd_t data_md = NULL;
     325             :   int signer;
     326             :   const char *algoid;
     327             :   int algo;
     328             :   ksba_isotime_t signed_at;
     329             :   certlist_t cl;
     330           0 :   int release_signerlist = 0;
     331             : 
     332           0 :   audit_set_type (ctrl->audit, AUDIT_TYPE_SIGN);
     333             : 
     334           0 :   kh = keydb_new (0);
     335           0 :   if (!kh)
     336             :     {
     337           0 :       log_error (_("failed to allocate keyDB handle\n"));
     338           0 :       rc = gpg_error (GPG_ERR_GENERAL);
     339           0 :       goto leave;
     340             :     }
     341             : 
     342           0 :   ctrl->pem_name = "SIGNED MESSAGE";
     343           0 :   rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
     344           0 :   if (rc)
     345             :     {
     346           0 :       log_error ("can't create writer: %s\n", gpg_strerror (rc));
     347           0 :       goto leave;
     348             :     }
     349             : 
     350           0 :   err = ksba_cms_new (&cms);
     351           0 :   if (err)
     352             :     {
     353           0 :       rc = err;
     354           0 :       goto leave;
     355             :     }
     356             : 
     357           0 :   err = ksba_cms_set_reader_writer (cms, NULL, writer);
     358           0 :   if (err)
     359             :     {
     360           0 :       log_debug ("ksba_cms_set_reader_writer failed: %s\n",
     361             :                  gpg_strerror (err));
     362           0 :       rc = err;
     363           0 :       goto leave;
     364             :     }
     365             : 
     366             :   /* We are going to create signed data with data as encap. content */
     367           0 :   err = ksba_cms_set_content_type (cms, 0, KSBA_CT_SIGNED_DATA);
     368           0 :   if (!err)
     369           0 :     err = ksba_cms_set_content_type (cms, 1, KSBA_CT_DATA);
     370           0 :   if (err)
     371             :     {
     372           0 :       log_debug ("ksba_cms_set_content_type failed: %s\n",
     373             :                  gpg_strerror (err));
     374           0 :       rc = err;
     375           0 :       goto leave;
     376             :     }
     377             : 
     378             :   /* If no list of signers is given, use the default certificate. */
     379           0 :   if (!signerlist)
     380             :     {
     381           0 :       ksba_cert_t cert = get_default_signer (ctrl);
     382           0 :       if (!cert)
     383             :         {
     384           0 :           log_error ("no default signer found\n");
     385           0 :           gpgsm_status2 (ctrl, STATUS_INV_SGNR,
     386             :                          get_inv_recpsgnr_code (GPG_ERR_NO_SECKEY), NULL);
     387           0 :           rc = gpg_error (GPG_ERR_GENERAL);
     388           0 :           goto leave;
     389             :         }
     390             : 
     391             :       /* Although we don't check for ambigious specification we will
     392             :          check that the signer's certificate is usable and valid.  */
     393           0 :       rc = gpgsm_cert_use_sign_p (cert);
     394           0 :       if (!rc)
     395           0 :         rc = gpgsm_validate_chain (ctrl, cert, "", NULL, 0, NULL, 0, NULL);
     396           0 :       if (rc)
     397             :         {
     398             :           char *tmpfpr;
     399             : 
     400           0 :           tmpfpr = gpgsm_get_fingerprint_hexstring (cert, 0);
     401           0 :           gpgsm_status2 (ctrl, STATUS_INV_SGNR,
     402             :                          get_inv_recpsgnr_code (rc), tmpfpr, NULL);
     403           0 :           xfree (tmpfpr);
     404           0 :           goto leave;
     405             :         }
     406             : 
     407             :       /* That one is fine - create signerlist. */
     408           0 :       signerlist = xtrycalloc (1, sizeof *signerlist);
     409           0 :       if (!signerlist)
     410             :         {
     411           0 :           rc = out_of_core ();
     412           0 :           ksba_cert_release (cert);
     413           0 :           goto leave;
     414             :         }
     415           0 :       signerlist->cert = cert;
     416           0 :       release_signerlist = 1;
     417             :     }
     418             : 
     419             :   /* Figure out the hash algorithm to use. We do not want to use the
     420             :      one for the certificate but if possible an OID for the plain
     421             :      algorithm.  */
     422           0 :   if (opt.forced_digest_algo && opt.verbose)
     423           0 :     log_info ("user requested hash algorithm %d\n", opt.forced_digest_algo);
     424           0 :   for (i=0, cl=signerlist; cl; cl = cl->next, i++)
     425             :     {
     426             :       const char *oid;
     427             : 
     428           0 :       if (opt.forced_digest_algo)
     429             :         {
     430           0 :           oid = NULL;
     431           0 :           cl->hash_algo = opt.forced_digest_algo;
     432             :         }
     433             :       else
     434             :         {
     435           0 :           oid = ksba_cert_get_digest_algo (cl->cert);
     436           0 :           cl->hash_algo = oid ? gcry_md_map_name (oid) : 0;
     437             :         }
     438           0 :       switch (cl->hash_algo)
     439             :         {
     440           0 :         case GCRY_MD_SHA1:   oid = "1.3.14.3.2.26"; break;
     441           0 :         case GCRY_MD_RMD160: oid = "1.3.36.3.2.1"; break;
     442           0 :         case GCRY_MD_SHA224: oid = "2.16.840.1.101.3.4.2.4"; break;
     443           0 :         case GCRY_MD_SHA256: oid = "2.16.840.1.101.3.4.2.1"; break;
     444           0 :         case GCRY_MD_SHA384: oid = "2.16.840.1.101.3.4.2.2"; break;
     445           0 :         case GCRY_MD_SHA512: oid = "2.16.840.1.101.3.4.2.3"; break;
     446             : /*         case GCRY_MD_WHIRLPOOL: oid = "No OID yet"; break; */
     447             : 
     448             :         case GCRY_MD_MD5:  /* We don't want to use MD5.  */
     449             :         case 0:            /* No algorithm found in cert.  */
     450             :         default:           /* Other algorithms.  */
     451           0 :           log_info (_("hash algorithm %d (%s) for signer %d not supported;"
     452             :                       " using %s\n"),
     453             :                     cl->hash_algo, oid? oid: "?", i,
     454             :                     gcry_md_algo_name (GCRY_MD_SHA1));
     455           0 :           cl->hash_algo = GCRY_MD_SHA1;
     456           0 :           oid = "1.3.14.3.2.26";
     457           0 :           break;
     458             :         }
     459           0 :       cl->hash_algo_oid = oid;
     460             :     }
     461             : 
     462           0 :   if (opt.verbose)
     463             :     {
     464           0 :       for (i=0, cl=signerlist; cl; cl = cl->next, i++)
     465           0 :         log_info (_("hash algorithm used for signer %d: %s (%s)\n"),
     466             :                   i, gcry_md_algo_name (cl->hash_algo), cl->hash_algo_oid);
     467             :     }
     468             : 
     469             : 
     470             :   /* Gather certificates of signers and store them in the CMS object. */
     471           0 :   for (cl=signerlist; cl; cl = cl->next)
     472             :     {
     473           0 :       rc = gpgsm_cert_use_sign_p (cl->cert);
     474           0 :       if (rc)
     475           0 :         goto leave;
     476             : 
     477           0 :       err = ksba_cms_add_signer (cms, cl->cert);
     478           0 :       if (err)
     479             :         {
     480           0 :           log_error ("ksba_cms_add_signer failed: %s\n", gpg_strerror (err));
     481           0 :           rc = err;
     482           0 :           goto leave;
     483             :         }
     484           0 :       rc = add_certificate_list (ctrl, cms, cl->cert);
     485           0 :       if (rc)
     486             :         {
     487           0 :           log_error ("failed to store list of certificates: %s\n",
     488             :                      gpg_strerror(rc));
     489           0 :           goto leave;
     490             :         }
     491             :       /* Set the hash algorithm we are going to use */
     492           0 :       err = ksba_cms_add_digest_algo (cms, cl->hash_algo_oid);
     493           0 :       if (err)
     494             :         {
     495           0 :           log_debug ("ksba_cms_add_digest_algo failed: %s\n",
     496             :                      gpg_strerror (err));
     497           0 :           rc = err;
     498           0 :           goto leave;
     499             :         }
     500             :     }
     501             : 
     502             : 
     503             :   /* Check whether one of the certificates is qualified.  Note that we
     504             :      already validated the certificate and thus the user data stored
     505             :      flag must be available. */
     506           0 :   if (!opt.no_chain_validation)
     507             :     {
     508           0 :       for (cl=signerlist; cl; cl = cl->next)
     509             :         {
     510             :           size_t buflen;
     511             :           char buffer[1];
     512             : 
     513           0 :           err = ksba_cert_get_user_data (cl->cert, "is_qualified",
     514             :                                          &buffer, sizeof (buffer), &buflen);
     515           0 :           if (err || !buflen)
     516             :             {
     517           0 :               log_error (_("checking for qualified certificate failed: %s\n"),
     518             :                          gpg_strerror (err));
     519           0 :               rc = err;
     520           0 :               goto leave;
     521             :             }
     522           0 :           if (*buffer)
     523           0 :             err = gpgsm_qualified_consent (ctrl, cl->cert);
     524             :           else
     525           0 :             err = gpgsm_not_qualified_warning (ctrl, cl->cert);
     526           0 :           if (err)
     527             :             {
     528           0 :               rc = err;
     529           0 :               goto leave;
     530             :             }
     531             :         }
     532             :     }
     533             : 
     534             :   /* Prepare hashing (actually we are figuring out what we have set
     535             :      above). */
     536           0 :   rc = gcry_md_open (&data_md, 0, 0);
     537           0 :   if (rc)
     538             :     {
     539           0 :       log_error ("md_open failed: %s\n", gpg_strerror (rc));
     540           0 :       goto leave;
     541             :     }
     542           0 :   if (DBG_HASHING)
     543           0 :     gcry_md_debug (data_md, "sign.data");
     544             : 
     545           0 :   for (i=0; (algoid=ksba_cms_get_digest_algo_list (cms, i)); i++)
     546             :     {
     547           0 :       algo = gcry_md_map_name (algoid);
     548           0 :       if (!algo)
     549             :         {
     550           0 :           log_error ("unknown hash algorithm '%s'\n", algoid? algoid:"?");
     551           0 :           rc = gpg_error (GPG_ERR_BUG);
     552           0 :           goto leave;
     553             :         }
     554           0 :       gcry_md_enable (data_md, algo);
     555           0 :       audit_log_i (ctrl->audit, AUDIT_DATA_HASH_ALGO, algo);
     556             :     }
     557             : 
     558           0 :   audit_log (ctrl->audit, AUDIT_SETUP_READY);
     559             : 
     560           0 :   if (detached)
     561             :     { /* We hash the data right now so that we can store the message
     562             :          digest.  ksba_cms_build() takes this as an flag that detached
     563             :          data is expected. */
     564             :       unsigned char *digest;
     565             :       size_t digest_len;
     566             : 
     567           0 :       if (!hash_data (data_fd, data_md))
     568           0 :         audit_log (ctrl->audit, AUDIT_GOT_DATA);
     569           0 :       for (cl=signerlist,signer=0; cl; cl = cl->next, signer++)
     570             :         {
     571           0 :           digest = gcry_md_read (data_md, cl->hash_algo);
     572           0 :           digest_len = gcry_md_get_algo_dlen (cl->hash_algo);
     573           0 :           if ( !digest || !digest_len )
     574             :             {
     575           0 :               log_error ("problem getting the hash of the data\n");
     576           0 :               rc = gpg_error (GPG_ERR_BUG);
     577           0 :               goto leave;
     578             :             }
     579           0 :           err = ksba_cms_set_message_digest (cms, signer, digest, digest_len);
     580           0 :           if (err)
     581             :             {
     582           0 :               log_error ("ksba_cms_set_message_digest failed: %s\n",
     583             :                          gpg_strerror (err));
     584           0 :               rc = err;
     585           0 :               goto leave;
     586             :             }
     587             :         }
     588             :     }
     589             : 
     590           0 :   gnupg_get_isotime (signed_at);
     591           0 :   for (cl=signerlist,signer=0; cl; cl = cl->next, signer++)
     592             :     {
     593           0 :       err = ksba_cms_set_signing_time (cms, signer, signed_at);
     594           0 :       if (err)
     595             :         {
     596           0 :           log_error ("ksba_cms_set_signing_time failed: %s\n",
     597             :                      gpg_strerror (err));
     598           0 :           rc = err;
     599           0 :           goto leave;
     600             :         }
     601             :     }
     602             : 
     603             :   /* We need to write at least a minimal list of our capabilities to
     604             :      try to convince some MUAs to use 3DES and not the crippled
     605             :      RC2. Our list is:
     606             : 
     607             :         aes128-CBC
     608             :         des-EDE3-CBC
     609             :   */
     610           0 :   err = ksba_cms_add_smime_capability (cms, "2.16.840.1.101.3.4.1.2", NULL, 0);
     611           0 :   if (!err)
     612           0 :     err = ksba_cms_add_smime_capability (cms, "1.2.840.113549.3.7", NULL, 0);
     613           0 :   if (err)
     614             :     {
     615           0 :       log_error ("ksba_cms_add_smime_capability failed: %s\n",
     616             :                  gpg_strerror (err));
     617           0 :       goto leave;
     618             :     }
     619             : 
     620             : 
     621             :   /* Main building loop. */
     622             :   do
     623             :     {
     624           0 :       err = ksba_cms_build (cms, &stopreason);
     625           0 :       if (err)
     626             :         {
     627           0 :           log_debug ("ksba_cms_build failed: %s\n", gpg_strerror (err));
     628           0 :           rc = err;
     629           0 :           goto leave;
     630             :         }
     631             : 
     632           0 :       if (stopreason == KSBA_SR_BEGIN_DATA)
     633             :         {
     634             :           /* Hash the data and store the message digest. */
     635             :           unsigned char *digest;
     636             :           size_t digest_len;
     637             : 
     638           0 :           assert (!detached);
     639             : 
     640           0 :           rc = hash_and_copy_data (data_fd, data_md, writer);
     641           0 :           if (rc)
     642           0 :             goto leave;
     643           0 :           audit_log (ctrl->audit, AUDIT_GOT_DATA);
     644           0 :           for (cl=signerlist,signer=0; cl; cl = cl->next, signer++)
     645             :             {
     646           0 :               digest = gcry_md_read (data_md, cl->hash_algo);
     647           0 :               digest_len = gcry_md_get_algo_dlen (cl->hash_algo);
     648           0 :               if ( !digest || !digest_len )
     649             :                 {
     650           0 :                   log_error ("problem getting the hash of the data\n");
     651           0 :                   rc = gpg_error (GPG_ERR_BUG);
     652           0 :                   goto leave;
     653             :                 }
     654           0 :               err = ksba_cms_set_message_digest (cms, signer,
     655             :                                                  digest, digest_len);
     656           0 :               if (err)
     657             :                 {
     658           0 :                   log_error ("ksba_cms_set_message_digest failed: %s\n",
     659             :                              gpg_strerror (err));
     660           0 :                   rc = err;
     661           0 :                   goto leave;
     662             :                 }
     663             :             }
     664             :         }
     665           0 :       else if (stopreason == KSBA_SR_NEED_SIG)
     666             :         {
     667             :           /* Compute the signature for all signers.  */
     668             :           gcry_md_hd_t md;
     669             : 
     670           0 :           rc = gcry_md_open (&md, 0, 0);
     671           0 :           if (rc)
     672             :             {
     673           0 :               log_error ("md_open failed: %s\n", gpg_strerror (rc));
     674           0 :               goto leave;
     675             :             }
     676           0 :           if (DBG_HASHING)
     677           0 :             gcry_md_debug (md, "sign.attr");
     678           0 :           ksba_cms_set_hash_function (cms, HASH_FNC, md);
     679           0 :           for (cl=signerlist,signer=0; cl; cl = cl->next, signer++)
     680             :             {
     681           0 :               unsigned char *sigval = NULL;
     682             :               char *buf, *fpr;
     683             : 
     684           0 :               audit_log_i (ctrl->audit, AUDIT_NEW_SIG, signer);
     685           0 :               if (signer)
     686           0 :                 gcry_md_reset (md);
     687             :               {
     688             :                 certlist_t cl_tmp;
     689             : 
     690           0 :                 for (cl_tmp=signerlist; cl_tmp; cl_tmp = cl_tmp->next)
     691             :                   {
     692           0 :                     gcry_md_enable (md, cl_tmp->hash_algo);
     693           0 :                     audit_log_i (ctrl->audit, AUDIT_ATTR_HASH_ALGO,
     694             :                                  cl_tmp->hash_algo);
     695             :                   }
     696             :               }
     697             : 
     698           0 :               rc = ksba_cms_hash_signed_attrs (cms, signer);
     699           0 :               if (rc)
     700             :                 {
     701           0 :                   log_debug ("hashing signed attrs failed: %s\n",
     702             :                              gpg_strerror (rc));
     703           0 :                   gcry_md_close (md);
     704           0 :                   goto leave;
     705             :                 }
     706             : 
     707           0 :               rc = gpgsm_create_cms_signature (ctrl, cl->cert,
     708             :                                                md, cl->hash_algo, &sigval);
     709           0 :               if (rc)
     710             :                 {
     711           0 :                   audit_log_cert (ctrl->audit, AUDIT_SIGNED_BY, cl->cert, rc);
     712           0 :                   gcry_md_close (md);
     713           0 :                   goto leave;
     714             :                 }
     715             : 
     716           0 :               err = ksba_cms_set_sig_val (cms, signer, sigval);
     717           0 :               xfree (sigval);
     718           0 :               if (err)
     719             :                 {
     720           0 :                   audit_log_cert (ctrl->audit, AUDIT_SIGNED_BY, cl->cert, err);
     721           0 :                   log_error ("failed to store the signature: %s\n",
     722             :                              gpg_strerror (err));
     723           0 :                   rc = err;
     724           0 :                   gcry_md_close (md);
     725           0 :                   goto leave;
     726             :                 }
     727             : 
     728             :               /* write a status message */
     729           0 :               fpr = gpgsm_get_fingerprint_hexstring (cl->cert, GCRY_MD_SHA1);
     730           0 :               if (!fpr)
     731             :                 {
     732           0 :                   rc = gpg_error (GPG_ERR_ENOMEM);
     733           0 :                   gcry_md_close (md);
     734           0 :                   goto leave;
     735             :                 }
     736           0 :               rc = 0;
     737             :               {
     738           0 :                 int pkalgo = gpgsm_get_key_algo_info (cl->cert, NULL);
     739           0 :                 buf = xtryasprintf ("%c %d %d 00 %s %s",
     740             :                                     detached? 'D':'S',
     741             :                                     pkalgo,
     742             :                                     cl->hash_algo,
     743             :                                     signed_at,
     744             :                                     fpr);
     745           0 :                 if (!buf)
     746           0 :                   rc = gpg_error_from_syserror ();
     747             :               }
     748           0 :               xfree (fpr);
     749           0 :               if (rc)
     750             :                 {
     751           0 :                   gcry_md_close (md);
     752           0 :                   goto leave;
     753             :                 }
     754           0 :               gpgsm_status (ctrl, STATUS_SIG_CREATED, buf);
     755           0 :               xfree (buf);
     756           0 :               audit_log_cert (ctrl->audit, AUDIT_SIGNED_BY, cl->cert, 0);
     757             :             }
     758           0 :           gcry_md_close (md);
     759             :         }
     760             :     }
     761           0 :   while (stopreason != KSBA_SR_READY);
     762             : 
     763           0 :   rc = gpgsm_finish_writer (b64writer);
     764           0 :   if (rc)
     765             :     {
     766           0 :       log_error ("write failed: %s\n", gpg_strerror (rc));
     767           0 :       goto leave;
     768             :     }
     769             : 
     770           0 :   audit_log (ctrl->audit, AUDIT_SIGNING_DONE);
     771           0 :   log_info ("signature created\n");
     772             : 
     773             : 
     774             :  leave:
     775           0 :   if (rc)
     776           0 :     log_error ("error creating signature: %s <%s>\n",
     777             :                gpg_strerror (rc), gpg_strsource (rc) );
     778           0 :   if (release_signerlist)
     779           0 :     gpgsm_release_certlist (signerlist);
     780           0 :   ksba_cms_release (cms);
     781           0 :   gpgsm_destroy_writer (b64writer);
     782           0 :   keydb_release (kh);
     783           0 :   gcry_md_close (data_md);
     784           0 :   return rc;
     785             : }

Generated by: LCOV version 1.11