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

          Line data    Source code
       1             : /* verify.c - Verify a messages signature
       2             :  * Copyright (C) 2001, 2002, 2003, 2007,
       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             : static char *
      38           0 : strtimestamp_r (ksba_isotime_t atime)
      39             : {
      40           0 :   char *buffer = xmalloc (15);
      41             : 
      42           0 :   if (!atime || !*atime)
      43           0 :     strcpy (buffer, "none");
      44             :   else
      45           0 :     sprintf (buffer, "%.4s-%.2s-%.2s", atime, atime+4, atime+6);
      46           0 :   return buffer;
      47             : }
      48             : 
      49             : 
      50             : 
      51             : /* Hash the data for a detached signature.  Returns 0 on success.  */
      52             : static gpg_error_t
      53           0 : hash_data (int fd, gcry_md_hd_t md)
      54             : {
      55           0 :   gpg_error_t err = 0;
      56             :   estream_t fp;
      57             :   char buffer[4096];
      58             :   int nread;
      59             : 
      60           0 :   fp = es_fdopen_nc (fd, "rb");
      61           0 :   if (!fp)
      62             :     {
      63           0 :       err = gpg_error_from_syserror ();
      64           0 :       log_error ("fdopen(%d) failed: %s\n", fd, gpg_strerror (err));
      65           0 :       return err;
      66             :     }
      67             : 
      68             :   do
      69             :     {
      70           0 :       nread = es_fread (buffer, 1, DIM(buffer), fp);
      71           0 :       gcry_md_write (md, buffer, nread);
      72             :     }
      73           0 :   while (nread);
      74           0 :   if (es_ferror (fp))
      75             :     {
      76           0 :       err = gpg_error_from_syserror ();
      77           0 :       log_error ("read error on fd %d: %s\n", fd, gpg_strerror (err));
      78             :     }
      79           0 :   es_fclose (fp);
      80           0 :   return err;
      81             : }
      82             : 
      83             : 
      84             : 
      85             : 
      86             : /* Perform a verify operation.  To verify detached signatures, DATA_FD
      87             :    must be different than -1.  With OUT_FP given and a non-detached
      88             :    signature, the signed material is written to that stream.  */
      89             : int
      90           0 : gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp)
      91             : {
      92             :   int i, rc;
      93           0 :   Base64Context b64reader = NULL;
      94           0 :   Base64Context b64writer = NULL;
      95             :   ksba_reader_t reader;
      96           0 :   ksba_writer_t writer = NULL;
      97           0 :   ksba_cms_t cms = NULL;
      98             :   ksba_stop_reason_t stopreason;
      99             :   ksba_cert_t cert;
     100             :   KEYDB_HANDLE kh;
     101           0 :   gcry_md_hd_t data_md = NULL;
     102             :   int signer;
     103             :   const char *algoid;
     104             :   int algo;
     105             :   int is_detached;
     106           0 :   estream_t in_fp = NULL;
     107             :   char *p;
     108             : 
     109           0 :   audit_set_type (ctrl->audit, AUDIT_TYPE_VERIFY);
     110             : 
     111           0 :   kh = keydb_new (0);
     112           0 :   if (!kh)
     113             :     {
     114           0 :       log_error (_("failed to allocate keyDB handle\n"));
     115           0 :       rc = gpg_error (GPG_ERR_GENERAL);
     116           0 :       goto leave;
     117             :     }
     118             : 
     119             : 
     120           0 :   in_fp = es_fdopen_nc (in_fd, "rb");
     121           0 :   if (!in_fp)
     122             :     {
     123           0 :       rc = gpg_error_from_syserror ();
     124           0 :       log_error ("fdopen() failed: %s\n", strerror (errno));
     125           0 :       goto leave;
     126             :     }
     127             : 
     128           0 :   rc = gpgsm_create_reader (&b64reader, ctrl, in_fp, 0, &reader);
     129           0 :   if (rc)
     130             :     {
     131           0 :       log_error ("can't create reader: %s\n", gpg_strerror (rc));
     132           0 :       goto leave;
     133             :     }
     134             : 
     135           0 :   if (out_fp)
     136             :     {
     137           0 :       rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
     138           0 :       if (rc)
     139             :         {
     140           0 :           log_error ("can't create writer: %s\n", gpg_strerror (rc));
     141           0 :           goto leave;
     142             :         }
     143             :     }
     144             : 
     145           0 :   rc = ksba_cms_new (&cms);
     146           0 :   if (rc)
     147           0 :     goto leave;
     148             : 
     149           0 :   rc = ksba_cms_set_reader_writer (cms, reader, writer);
     150           0 :   if (rc)
     151             :     {
     152           0 :       log_error ("ksba_cms_set_reader_writer failed: %s\n",
     153             :                  gpg_strerror (rc));
     154           0 :       goto leave;
     155             :     }
     156             : 
     157           0 :   rc = gcry_md_open (&data_md, 0, 0);
     158           0 :   if (rc)
     159             :     {
     160           0 :       log_error ("md_open failed: %s\n", gpg_strerror (rc));
     161           0 :       goto leave;
     162             :     }
     163           0 :   if (DBG_HASHING)
     164           0 :     gcry_md_debug (data_md, "vrfy.data");
     165             : 
     166           0 :   audit_log (ctrl->audit, AUDIT_SETUP_READY);
     167             : 
     168           0 :   is_detached = 0;
     169             :   do
     170             :     {
     171           0 :       rc = ksba_cms_parse (cms, &stopreason);
     172           0 :       if (rc)
     173             :         {
     174           0 :           log_error ("ksba_cms_parse failed: %s\n", gpg_strerror (rc));
     175           0 :           goto leave;
     176             :         }
     177             : 
     178           0 :       if (stopreason == KSBA_SR_NEED_HASH)
     179             :         {
     180           0 :           is_detached = 1;
     181           0 :           audit_log (ctrl->audit, AUDIT_DETACHED_SIGNATURE);
     182           0 :           if (opt.verbose)
     183           0 :             log_info ("detached signature\n");
     184             :         }
     185             : 
     186           0 :       if (stopreason == KSBA_SR_NEED_HASH
     187           0 :           || stopreason == KSBA_SR_BEGIN_DATA)
     188             :         {
     189           0 :           audit_log (ctrl->audit, AUDIT_GOT_DATA);
     190             : 
     191             :           /* We are now able to enable the hash algorithms */
     192           0 :           for (i=0; (algoid=ksba_cms_get_digest_algo_list (cms, i)); i++)
     193             :             {
     194           0 :               algo = gcry_md_map_name (algoid);
     195           0 :               if (!algo)
     196             :                 {
     197           0 :                   log_error ("unknown hash algorithm '%s'\n",
     198             :                              algoid? algoid:"?");
     199           0 :                   if (algoid
     200           0 :                       && (  !strcmp (algoid, "1.2.840.113549.1.1.2")
     201           0 :                           ||!strcmp (algoid, "1.2.840.113549.2.2")))
     202           0 :                     log_info (_("(this is the MD2 algorithm)\n"));
     203           0 :                   audit_log_s (ctrl->audit, AUDIT_BAD_DATA_HASH_ALGO, algoid);
     204             :                 }
     205             :               else
     206             :                 {
     207           0 :                   if (DBG_X509)
     208           0 :                     log_debug ("enabling hash algorithm %d (%s)\n",
     209             :                                algo, algoid? algoid:"");
     210           0 :                   gcry_md_enable (data_md, algo);
     211           0 :                   audit_log_i (ctrl->audit, AUDIT_DATA_HASH_ALGO, algo);
     212             :                 }
     213             :             }
     214           0 :           if (opt.extra_digest_algo)
     215             :             {
     216           0 :               if (DBG_X509)
     217           0 :                 log_debug ("enabling extra hash algorithm %d\n",
     218             :                            opt.extra_digest_algo);
     219           0 :               gcry_md_enable (data_md, opt.extra_digest_algo);
     220           0 :               audit_log_i (ctrl->audit, AUDIT_DATA_HASH_ALGO,
     221             :                            opt.extra_digest_algo);
     222             :             }
     223           0 :           if (is_detached)
     224             :             {
     225           0 :               if (data_fd == -1)
     226             :                 {
     227           0 :                   log_info ("detached signature w/o data "
     228             :                             "- assuming certs-only\n");
     229           0 :                   audit_log (ctrl->audit, AUDIT_CERT_ONLY_SIG);
     230             :                 }
     231             :               else
     232           0 :                 audit_log_ok (ctrl->audit, AUDIT_DATA_HASHING,
     233             :                               hash_data (data_fd, data_md));
     234             :             }
     235             :           else
     236             :             {
     237           0 :               ksba_cms_set_hash_function (cms, HASH_FNC, data_md);
     238             :             }
     239             :         }
     240           0 :       else if (stopreason == KSBA_SR_END_DATA)
     241             :         { /* The data bas been hashed */
     242           0 :           audit_log_ok (ctrl->audit, AUDIT_DATA_HASHING, 0);
     243             :         }
     244             :     }
     245           0 :   while (stopreason != KSBA_SR_READY);
     246             : 
     247           0 :   if (b64writer)
     248             :     {
     249           0 :       rc = gpgsm_finish_writer (b64writer);
     250           0 :       if (rc)
     251             :         {
     252           0 :           log_error ("write failed: %s\n", gpg_strerror (rc));
     253           0 :           audit_log_ok (ctrl->audit, AUDIT_WRITE_ERROR, rc);
     254           0 :           goto leave;
     255             :         }
     256             :     }
     257             : 
     258           0 :   if (data_fd != -1 && !is_detached)
     259             :     {
     260           0 :       log_error ("data given for a non-detached signature\n");
     261           0 :       rc = gpg_error (GPG_ERR_CONFLICT);
     262           0 :       audit_log (ctrl->audit, AUDIT_USAGE_ERROR);
     263           0 :       goto leave;
     264             :     }
     265             : 
     266           0 :   for (i=0; (cert=ksba_cms_get_cert (cms, i)); i++)
     267             :     {
     268             :       /* Fixme: it might be better to check the validity of the
     269             :          certificate first before entering it into the DB.  This way
     270             :          we would avoid cluttering the DB with invalid
     271             :          certificates. */
     272           0 :       audit_log_cert (ctrl->audit, AUDIT_SAVE_CERT, cert,
     273           0 :                       keydb_store_cert (cert, 0, NULL));
     274           0 :       ksba_cert_release (cert);
     275             :     }
     276             : 
     277           0 :   cert = NULL;
     278           0 :   for (signer=0; ; signer++)
     279             :     {
     280           0 :       char *issuer = NULL;
     281           0 :       ksba_sexp_t sigval = NULL;
     282             :       ksba_isotime_t sigtime, keyexptime;
     283             :       ksba_sexp_t serial;
     284           0 :       char *msgdigest = NULL;
     285             :       size_t msgdigestlen;
     286             :       char *ctattr;
     287             :       int sigval_hash_algo;
     288             :       int info_pkalgo;
     289             :       unsigned int verifyflags;
     290             : 
     291           0 :       rc = ksba_cms_get_issuer_serial (cms, signer, &issuer, &serial);
     292           0 :       if (!signer && gpg_err_code (rc) == GPG_ERR_NO_DATA
     293           0 :           && data_fd == -1 && is_detached)
     294             :         {
     295           0 :           log_info ("certs-only message accepted\n");
     296           0 :           rc = 0;
     297           0 :           break;
     298             :         }
     299           0 :       if (rc)
     300             :         {
     301           0 :           if (signer && rc == -1)
     302           0 :             rc = 0;
     303           0 :           break;
     304             :         }
     305             : 
     306           0 :       gpgsm_status (ctrl, STATUS_NEWSIG, NULL);
     307           0 :       audit_log_i (ctrl->audit, AUDIT_NEW_SIG, signer);
     308             : 
     309           0 :       if (DBG_X509)
     310             :         {
     311           0 :           log_debug ("signer %d - issuer: '%s'\n",
     312           0 :                      signer, issuer? issuer:"[NONE]");
     313           0 :           log_debug ("signer %d - serial: ", signer);
     314           0 :           gpgsm_dump_serial (serial);
     315           0 :           log_printf ("\n");
     316             :         }
     317           0 :       if (ctrl->audit)
     318             :         {
     319           0 :           char *tmpstr = gpgsm_format_sn_issuer (serial, issuer);
     320           0 :           audit_log_s (ctrl->audit, AUDIT_SIG_NAME, tmpstr);
     321           0 :           xfree (tmpstr);
     322             :         }
     323             : 
     324           0 :       rc = ksba_cms_get_signing_time (cms, signer, sigtime);
     325           0 :       if (gpg_err_code (rc) == GPG_ERR_NO_DATA)
     326           0 :         *sigtime = 0;
     327           0 :       else if (rc)
     328             :         {
     329           0 :           log_error ("error getting signing time: %s\n", gpg_strerror (rc));
     330           0 :           *sigtime = 0; /* (we can't encode an error in the time string.) */
     331             :         }
     332             : 
     333           0 :       rc = ksba_cms_get_message_digest (cms, signer,
     334             :                                         &msgdigest, &msgdigestlen);
     335           0 :       if (!rc)
     336             :         {
     337             :           size_t is_enabled;
     338             : 
     339           0 :           algoid = ksba_cms_get_digest_algo (cms, signer);
     340           0 :           algo = gcry_md_map_name (algoid);
     341           0 :           if (DBG_X509)
     342           0 :             log_debug ("signer %d - digest algo: %d\n", signer, algo);
     343           0 :           is_enabled = sizeof algo;
     344           0 :           if ( gcry_md_info (data_md, GCRYCTL_IS_ALGO_ENABLED,
     345             :                              &algo, &is_enabled)
     346           0 :                || !is_enabled)
     347             :             {
     348           0 :               log_error ("digest algo %d (%s) has not been enabled\n",
     349             :                          algo, algoid?algoid:"");
     350           0 :               audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "unsupported");
     351           0 :               goto next_signer;
     352             :             }
     353             :         }
     354           0 :       else if (gpg_err_code (rc) == GPG_ERR_NO_DATA)
     355             :         {
     356           0 :           assert (!msgdigest);
     357           0 :           rc = 0;
     358           0 :           algoid = NULL;
     359           0 :           algo = 0;
     360             :         }
     361             :       else /* real error */
     362             :         {
     363           0 :           audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "error");
     364           0 :           break;
     365             :         }
     366             : 
     367           0 :       rc = ksba_cms_get_sigattr_oids (cms, signer,
     368             :                                       "1.2.840.113549.1.9.3", &ctattr);
     369           0 :       if (!rc)
     370             :         {
     371             :           const char *s;
     372             : 
     373           0 :           if (DBG_X509)
     374           0 :             log_debug ("signer %d - content-type attribute: %s",
     375             :                        signer, ctattr);
     376             : 
     377           0 :           s = ksba_cms_get_content_oid (cms, 1);
     378           0 :           if (!s || strcmp (ctattr, s))
     379             :             {
     380           0 :               log_error ("content-type attribute does not match "
     381             :                          "actual content-type\n");
     382           0 :               ksba_free (ctattr);
     383           0 :               ctattr = NULL;
     384           0 :               audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "bad");
     385           0 :               goto next_signer;
     386             :             }
     387           0 :           ksba_free (ctattr);
     388           0 :           ctattr = NULL;
     389             :         }
     390           0 :       else if (rc != -1)
     391             :         {
     392           0 :           log_error ("error getting content-type attribute: %s\n",
     393             :                      gpg_strerror (rc));
     394           0 :           audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "bad");
     395           0 :           goto next_signer;
     396             :         }
     397           0 :       rc = 0;
     398             : 
     399             : 
     400           0 :       sigval = ksba_cms_get_sig_val (cms, signer);
     401           0 :       if (!sigval)
     402             :         {
     403           0 :           log_error ("no signature value available\n");
     404           0 :           audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "bad");
     405           0 :           goto next_signer;
     406             :         }
     407           0 :       sigval_hash_algo = hash_algo_from_sigval (sigval);
     408           0 :       if (DBG_X509)
     409             :         {
     410           0 :           log_debug ("signer %d - signature available (sigval hash=%d)",
     411             :                      signer, sigval_hash_algo);
     412             : /*           log_printhex ("sigval    ", sigval, */
     413             : /*                         gcry_sexp_canon_len (sigval, 0, NULL, NULL)); */
     414             :         }
     415           0 :       if (!sigval_hash_algo)
     416           0 :         sigval_hash_algo = algo; /* Fallback used e.g. with old libksba. */
     417             : 
     418             :       /* Find the certificate of the signer */
     419           0 :       keydb_search_reset (kh);
     420           0 :       rc = keydb_search_issuer_sn (kh, issuer, serial);
     421           0 :       if (rc)
     422             :         {
     423           0 :           if (rc == -1)
     424             :             {
     425           0 :               log_error ("certificate not found\n");
     426           0 :               rc = gpg_error (GPG_ERR_NO_PUBKEY);
     427             :             }
     428             :           else
     429           0 :             log_error ("failed to find the certificate: %s\n",
     430             :                        gpg_strerror(rc));
     431             :           {
     432             :             char numbuf[50];
     433           0 :             sprintf (numbuf, "%d", rc);
     434             : 
     435           0 :             gpgsm_status2 (ctrl, STATUS_ERROR, "verify.findkey",
     436             :                            numbuf, NULL);
     437             :           }
     438           0 :           audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "no-cert");
     439           0 :           goto next_signer;
     440             :         }
     441             : 
     442           0 :       rc = keydb_get_cert (kh, &cert);
     443           0 :       if (rc)
     444             :         {
     445           0 :           log_error ("failed to get cert: %s\n", gpg_strerror (rc));
     446           0 :           audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "error");
     447           0 :           goto next_signer;
     448             :         }
     449             : 
     450           0 :       log_info (_("Signature made "));
     451           0 :       if (*sigtime)
     452           0 :         dump_isotime (sigtime);
     453             :       else
     454           0 :         log_printf (_("[date not given]"));
     455           0 :       log_printf (_(" using certificate ID 0x%08lX\n"),
     456             :                   gpgsm_get_short_fingerprint (cert, NULL));
     457             : 
     458           0 :       audit_log_i (ctrl->audit, AUDIT_DATA_HASH_ALGO, algo);
     459             : 
     460           0 :       if (msgdigest)
     461             :         { /* Signed attributes are available. */
     462             :           gcry_md_hd_t md;
     463             :           unsigned char *s;
     464             : 
     465             :           /* Check that the message digest in the signed attributes
     466             :              matches the one we calculated on the data.  */
     467           0 :           s = gcry_md_read (data_md, algo);
     468           0 :           if ( !s || !msgdigestlen
     469           0 :                || gcry_md_get_algo_dlen (algo) != msgdigestlen
     470           0 :                || memcmp (s, msgdigest, msgdigestlen) )
     471             :             {
     472             :               char *fpr;
     473             : 
     474           0 :               log_error (_("invalid signature: message digest attribute "
     475             :                            "does not match computed one\n"));
     476           0 :               if (DBG_X509)
     477             :                 {
     478           0 :                   if (msgdigest)
     479           0 :                     log_printhex ("message:  ", msgdigest, msgdigestlen);
     480           0 :                   if (s)
     481           0 :                     log_printhex ("computed: ",
     482           0 :                                   s, gcry_md_get_algo_dlen (algo));
     483             :                 }
     484           0 :               fpr = gpgsm_fpr_and_name_for_status (cert);
     485           0 :               gpgsm_status (ctrl, STATUS_BADSIG, fpr);
     486           0 :               xfree (fpr);
     487           0 :               audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "bad");
     488           0 :               goto next_signer;
     489             :             }
     490             : 
     491           0 :           audit_log_i (ctrl->audit, AUDIT_ATTR_HASH_ALGO, sigval_hash_algo);
     492           0 :           rc = gcry_md_open (&md, sigval_hash_algo, 0);
     493           0 :           if (rc)
     494             :             {
     495           0 :               log_error ("md_open failed: %s\n", gpg_strerror (rc));
     496           0 :               audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "error");
     497           0 :               goto next_signer;
     498             :             }
     499           0 :           if (DBG_HASHING)
     500           0 :             gcry_md_debug (md, "vrfy.attr");
     501             : 
     502           0 :           ksba_cms_set_hash_function (cms, HASH_FNC, md);
     503           0 :           rc = ksba_cms_hash_signed_attrs (cms, signer);
     504           0 :           if (rc)
     505             :             {
     506           0 :               log_error ("hashing signed attrs failed: %s\n",
     507             :                          gpg_strerror (rc));
     508           0 :               gcry_md_close (md);
     509           0 :               audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "error");
     510           0 :               goto next_signer;
     511             :             }
     512           0 :           rc = gpgsm_check_cms_signature (cert, sigval, md,
     513             :                                           sigval_hash_algo, &info_pkalgo);
     514           0 :           gcry_md_close (md);
     515             :         }
     516             :       else
     517             :         {
     518           0 :           rc = gpgsm_check_cms_signature (cert, sigval, data_md,
     519             :                                           algo, &info_pkalgo);
     520             :         }
     521             : 
     522           0 :       if (rc)
     523             :         {
     524             :           char *fpr;
     525             : 
     526           0 :           log_error ("invalid signature: %s\n", gpg_strerror (rc));
     527           0 :           fpr = gpgsm_fpr_and_name_for_status (cert);
     528           0 :           gpgsm_status (ctrl, STATUS_BADSIG, fpr);
     529           0 :           xfree (fpr);
     530           0 :           audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "bad");
     531           0 :           goto next_signer;
     532             :         }
     533           0 :       rc = gpgsm_cert_use_verify_p (cert); /*(this displays an info message)*/
     534           0 :       if (rc)
     535             :         {
     536           0 :           gpgsm_status_with_err_code (ctrl, STATUS_ERROR, "verify.keyusage",
     537             :                                       gpg_err_code (rc));
     538           0 :           rc = 0;
     539             :         }
     540             : 
     541           0 :       if (DBG_X509)
     542           0 :         log_debug ("signature okay - checking certs\n");
     543           0 :       audit_log (ctrl->audit, AUDIT_VALIDATE_CHAIN);
     544           0 :       rc = gpgsm_validate_chain (ctrl, cert,
     545           0 :                                  *sigtime? sigtime : "19700101T000000",
     546             :                                  keyexptime, 0,
     547             :                                  NULL, 0, &verifyflags);
     548             :       {
     549             :         char *fpr, *buf, *tstr;
     550             : 
     551           0 :         fpr = gpgsm_fpr_and_name_for_status (cert);
     552           0 :         if (gpg_err_code (rc) == GPG_ERR_CERT_EXPIRED)
     553             :           {
     554           0 :             gpgsm_status (ctrl, STATUS_EXPKEYSIG, fpr);
     555           0 :             rc = 0;
     556             :           }
     557             :         else
     558           0 :           gpgsm_status (ctrl, STATUS_GOODSIG, fpr);
     559             : 
     560           0 :         xfree (fpr);
     561             : 
     562           0 :         fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
     563           0 :         tstr = strtimestamp_r (sigtime);
     564           0 :         buf = xasprintf ("%s %s %s %s 0 0 %d %d 00", fpr, tstr,
     565           0 :                          *sigtime? sigtime : "0",
     566           0 :                          *keyexptime? keyexptime : "0",
     567             :                          info_pkalgo, algo);
     568           0 :         xfree (tstr);
     569           0 :         xfree (fpr);
     570           0 :         gpgsm_status (ctrl, STATUS_VALIDSIG, buf);
     571           0 :         xfree (buf);
     572             :       }
     573             : 
     574           0 :       audit_log_ok (ctrl->audit, AUDIT_CHAIN_STATUS, rc);
     575           0 :       if (rc) /* of validate_chain */
     576             :         {
     577           0 :           log_error ("invalid certification chain: %s\n", gpg_strerror (rc));
     578           0 :           if (gpg_err_code (rc) == GPG_ERR_BAD_CERT_CHAIN
     579           0 :               || gpg_err_code (rc) == GPG_ERR_BAD_CERT
     580           0 :               || gpg_err_code (rc) == GPG_ERR_BAD_CA_CERT
     581           0 :               || gpg_err_code (rc) == GPG_ERR_CERT_REVOKED)
     582           0 :             gpgsm_status_with_err_code (ctrl, STATUS_TRUST_NEVER, NULL,
     583             :                                         gpg_err_code (rc));
     584             :           else
     585           0 :             gpgsm_status_with_err_code (ctrl, STATUS_TRUST_UNDEFINED, NULL,
     586             :                                         gpg_err_code (rc));
     587           0 :           audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "bad");
     588           0 :           goto next_signer;
     589             :         }
     590             : 
     591           0 :       audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "good");
     592             : 
     593           0 :       for (i=0; (p = ksba_cert_get_subject (cert, i)); i++)
     594             :         {
     595           0 :           log_info (!i? _("Good signature from")
     596             :                       : _("                aka"));
     597           0 :           log_printf (" \"");
     598           0 :           gpgsm_es_print_name (log_get_stream (), p);
     599           0 :           log_printf ("\"\n");
     600           0 :           ksba_free (p);
     601             :         }
     602             : 
     603             :       /* Print a note if this is a qualified signature.  */
     604             :       {
     605             :         size_t qualbuflen;
     606             :         char qualbuffer[1];
     607             : 
     608           0 :         rc = ksba_cert_get_user_data (cert, "is_qualified", &qualbuffer,
     609             :                                       sizeof (qualbuffer), &qualbuflen);
     610           0 :         if (!rc && qualbuflen)
     611             :           {
     612           0 :             if (*qualbuffer)
     613             :               {
     614           0 :                 log_info (_("This is a qualified signature\n"));
     615           0 :                 if (!opt.qualsig_approval)
     616           0 :                   log_info
     617           0 :                     (_("Note, that this software is not officially approved "
     618             :                        "to create or verify such signatures.\n"));
     619             :               }
     620             :           }
     621           0 :         else if (gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
     622           0 :           log_error ("get_user_data(is_qualified) failed: %s\n",
     623             :                      gpg_strerror (rc));
     624             :       }
     625             : 
     626           0 :       gpgsm_status (ctrl, STATUS_TRUST_FULLY,
     627           0 :                     (verifyflags & VALIDATE_FLAG_STEED)?
     628             :                     "0 steed":
     629           0 :                     (verifyflags & VALIDATE_FLAG_CHAIN_MODEL)?
     630             :                     "0 chain": "0 shell");
     631             : 
     632             : 
     633             :     next_signer:
     634           0 :       rc = 0;
     635           0 :       xfree (issuer);
     636           0 :       xfree (serial);
     637           0 :       xfree (sigval);
     638           0 :       xfree (msgdigest);
     639           0 :       ksba_cert_release (cert);
     640           0 :       cert = NULL;
     641           0 :     }
     642           0 :   rc = 0;
     643             : 
     644             :  leave:
     645           0 :   ksba_cms_release (cms);
     646           0 :   gpgsm_destroy_reader (b64reader);
     647           0 :   gpgsm_destroy_writer (b64writer);
     648           0 :   keydb_release (kh);
     649           0 :   gcry_md_close (data_md);
     650           0 :   es_fclose (in_fp);
     651             : 
     652           0 :   if (rc)
     653             :     {
     654             :       char numbuf[50];
     655           0 :       sprintf (numbuf, "%d", rc );
     656           0 :       gpgsm_status2 (ctrl, STATUS_ERROR, "verify.leave",
     657             :                      numbuf, NULL);
     658             :     }
     659             : 
     660           0 :   return rc;
     661             : }

Generated by: LCOV version 1.11