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

          Line data    Source code
       1             : /* decrypt.c - Decrypt a message
       2             :  * Copyright (C) 2001, 2003, 2010 Free Software Foundation, Inc.
       3             :  *
       4             :  * This file is part of GnuPG.
       5             :  *
       6             :  * GnuPG is free software; you can redistribute it and/or modify
       7             :  * it under the terms of the GNU General Public License as published by
       8             :  * the Free Software Foundation; either version 3 of the License, or
       9             :  * (at your option) any later version.
      10             :  *
      11             :  * GnuPG is distributed in the hope that it will be useful,
      12             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :  * GNU General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU General Public License
      17             :  * along with this program; if not, see <http://www.gnu.org/licenses/>.
      18             :  */
      19             : 
      20             : #include <config.h>
      21             : #include <stdio.h>
      22             : #include <stdlib.h>
      23             : #include <string.h>
      24             : #include <errno.h>
      25             : #include <unistd.h>
      26             : #include <time.h>
      27             : #include <assert.h>
      28             : 
      29             : #include "gpgsm.h"
      30             : #include <gcrypt.h>
      31             : #include <ksba.h>
      32             : 
      33             : #include "keydb.h"
      34             : #include "i18n.h"
      35             : 
      36             : struct decrypt_filter_parm_s
      37             : {
      38             :   int algo;
      39             :   int mode;
      40             :   int blklen;
      41             :   gcry_cipher_hd_t hd;
      42             :   char iv[16];
      43             :   size_t ivlen;
      44             :   int any_data;  /* dod we push anything through the filter at all? */
      45             :   unsigned char lastblock[16];  /* to strip the padding we have to
      46             :                                    keep this one */
      47             :   char helpblock[16];  /* needed because there is no block buffering in
      48             :                           libgcrypt (yet) */
      49             :   int  helpblocklen;
      50             : };
      51             : 
      52             : 
      53             : 
      54             : /* Decrypt the session key and fill in the parm structure.  The
      55             :    algo and the IV is expected to be already in PARM. */
      56             : static int
      57           0 : prepare_decryption (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
      58             :                     ksba_const_sexp_t enc_val,
      59             :                     struct decrypt_filter_parm_s *parm)
      60             : {
      61           0 :   char *seskey = NULL;
      62             :   size_t n, seskeylen;
      63             :   int rc;
      64             : 
      65           0 :   rc = gpgsm_agent_pkdecrypt (ctrl, hexkeygrip, desc, enc_val,
      66             :                               &seskey, &seskeylen);
      67           0 :   if (rc)
      68             :     {
      69           0 :       log_error ("error decrypting session key: %s\n", gpg_strerror (rc));
      70           0 :       goto leave;
      71             :     }
      72             : 
      73           0 :   if (DBG_CRYPTO)
      74           0 :     log_printhex ("pkcs1 encoded session key:", seskey, seskeylen);
      75             : 
      76           0 :   n=0;
      77           0 :   if (seskeylen == 24)
      78             :     {
      79             :       /* Smells like a 3-des key.  This might happen because a SC has
      80             :          already done the unpacking. */
      81             :     }
      82             :   else
      83             :     {
      84           0 :       if (n + 7 > seskeylen )
      85             :         {
      86           0 :           rc = gpg_error (GPG_ERR_INV_SESSION_KEY);
      87           0 :           goto leave;
      88             :         }
      89             : 
      90             :       /* FIXME: Actually the leading zero is required but due to the way
      91             :          we encode the output in libgcrypt as an MPI we are not able to
      92             :          encode that leading zero.  However, when using a Smartcard we are
      93             :          doing it the right way and therefore we have to skip the zero.  This
      94             :          should be fixed in gpg-agent of course. */
      95           0 :       if (!seskey[n])
      96           0 :         n++;
      97             : 
      98           0 :       if (seskey[n] != 2 )  /* Wrong block type version. */
      99             :         {
     100           0 :           rc = gpg_error (GPG_ERR_INV_SESSION_KEY);
     101           0 :           goto leave;
     102             :         }
     103             : 
     104           0 :       for (n++; n < seskeylen && seskey[n]; n++) /* Skip the random bytes. */
     105             :         ;
     106           0 :       n++; /* and the zero byte */
     107           0 :       if (n >= seskeylen )
     108             :         {
     109           0 :           rc = gpg_error (GPG_ERR_INV_SESSION_KEY);
     110           0 :           goto leave;
     111             :         }
     112             :     }
     113             : 
     114           0 :   if (DBG_CRYPTO)
     115           0 :     log_printhex ("session key:", seskey+n, seskeylen-n);
     116             : 
     117           0 :   rc = gcry_cipher_open (&parm->hd, parm->algo, parm->mode, 0);
     118           0 :   if (rc)
     119             :     {
     120           0 :       log_error ("error creating decryptor: %s\n", gpg_strerror (rc));
     121           0 :       goto leave;
     122             :     }
     123             : 
     124           0 :   rc = gcry_cipher_setkey (parm->hd, seskey+n, seskeylen-n);
     125           0 :   if (gpg_err_code (rc) == GPG_ERR_WEAK_KEY)
     126             :     {
     127           0 :       log_info (_("WARNING: message was encrypted with "
     128             :                   "a weak key in the symmetric cipher.\n"));
     129           0 :       rc = 0;
     130             :     }
     131           0 :   if (rc)
     132             :     {
     133           0 :       log_error("key setup failed: %s\n", gpg_strerror(rc) );
     134           0 :       goto leave;
     135             :     }
     136             : 
     137           0 :   gcry_cipher_setiv (parm->hd, parm->iv, parm->ivlen);
     138             : 
     139             :  leave:
     140           0 :   xfree (seskey);
     141           0 :   return rc;
     142             : }
     143             : 
     144             : 
     145             : /* This function is called by the KSBA writer just before the actual
     146             :    write is done.  The function must take INLEN bytes from INBUF,
     147             :    decrypt it and store it inoutbuf which has a maximum size of
     148             :    maxoutlen.  The valid bytes in outbuf should be return in outlen.
     149             :    Due to different buffer sizes or different length of input and
     150             :    output, it may happen that fewer bytes are processed or fewer bytes
     151             :    are written. */
     152             : static gpg_error_t
     153           0 : decrypt_filter (void *arg,
     154             :                 const void *inbuf, size_t inlen, size_t *inused,
     155             :                 void *outbuf, size_t maxoutlen, size_t *outlen)
     156             : {
     157           0 :   struct decrypt_filter_parm_s *parm = arg;
     158           0 :   int blklen = parm->blklen;
     159           0 :   size_t orig_inlen = inlen;
     160             : 
     161             :   /* fixme: Should we issue an error when we have not seen one full block? */
     162           0 :   if (!inlen)
     163           0 :     return gpg_error (GPG_ERR_BUG);
     164             : 
     165           0 :   if (maxoutlen < 2*parm->blklen)
     166           0 :     return gpg_error (GPG_ERR_BUG);
     167             :   /* Make some space because we will later need an extra block at the end.  */
     168           0 :   maxoutlen -= blklen;
     169             : 
     170           0 :   if (parm->helpblocklen)
     171             :     {
     172             :       int i, j;
     173             : 
     174           0 :       for (i=parm->helpblocklen,j=0; i < blklen && j < inlen; i++, j++)
     175           0 :         parm->helpblock[i] = ((const char*)inbuf)[j];
     176           0 :       inlen -= j;
     177           0 :       if (blklen > maxoutlen)
     178           0 :         return gpg_error (GPG_ERR_BUG);
     179           0 :       if (i < blklen)
     180             :         {
     181           0 :           parm->helpblocklen = i;
     182           0 :           *outlen = 0;
     183             :         }
     184             :       else
     185             :         {
     186           0 :           parm->helpblocklen = 0;
     187           0 :           if (parm->any_data)
     188             :             {
     189           0 :               memcpy (outbuf, parm->lastblock, blklen);
     190           0 :               *outlen =blklen;
     191             :             }
     192             :           else
     193           0 :             *outlen = 0;
     194           0 :           gcry_cipher_decrypt (parm->hd, parm->lastblock, blklen,
     195           0 :                                parm->helpblock, blklen);
     196           0 :           parm->any_data = 1;
     197             :         }
     198           0 :       *inused = orig_inlen - inlen;
     199           0 :       return 0;
     200             :     }
     201             : 
     202             : 
     203           0 :   if (inlen > maxoutlen)
     204           0 :     inlen = maxoutlen;
     205           0 :   if (inlen % blklen)
     206             :     { /* store the remainder away */
     207           0 :       parm->helpblocklen = inlen%blklen;
     208           0 :       inlen = inlen/blklen*blklen;
     209           0 :       memcpy (parm->helpblock, (const char*)inbuf+inlen, parm->helpblocklen);
     210             :     }
     211             : 
     212           0 :   *inused = inlen + parm->helpblocklen;
     213           0 :   if (inlen)
     214             :     {
     215           0 :       assert (inlen >= blklen);
     216           0 :       if (parm->any_data)
     217             :         {
     218           0 :           gcry_cipher_decrypt (parm->hd, (char*)outbuf+blklen, inlen,
     219             :                                inbuf, inlen);
     220           0 :           memcpy (outbuf, parm->lastblock, blklen);
     221           0 :           memcpy (parm->lastblock,(char*)outbuf+inlen, blklen);
     222           0 :           *outlen = inlen;
     223             :         }
     224             :       else
     225             :         {
     226           0 :           gcry_cipher_decrypt (parm->hd, outbuf, inlen, inbuf, inlen);
     227           0 :           memcpy (parm->lastblock, (char*)outbuf+inlen-blklen, blklen);
     228           0 :           *outlen = inlen - blklen;
     229           0 :           parm->any_data = 1;
     230             :         }
     231             :     }
     232             :   else
     233           0 :     *outlen = 0;
     234           0 :   return 0;
     235             : }
     236             : 
     237             : 
     238             : 
     239             : /* Perform a decrypt operation.  */
     240             : int
     241           0 : gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp)
     242             : {
     243             :   int rc;
     244           0 :   Base64Context b64reader = NULL;
     245           0 :   Base64Context b64writer = NULL;
     246             :   ksba_reader_t reader;
     247             :   ksba_writer_t writer;
     248           0 :   ksba_cms_t cms = NULL;
     249             :   ksba_stop_reason_t stopreason;
     250             :   KEYDB_HANDLE kh;
     251             :   int recp;
     252           0 :   estream_t in_fp = NULL;
     253             :   struct decrypt_filter_parm_s dfparm;
     254             : 
     255           0 :   memset (&dfparm, 0, sizeof dfparm);
     256             : 
     257           0 :   audit_set_type (ctrl->audit, AUDIT_TYPE_DECRYPT);
     258             : 
     259           0 :   kh = keydb_new (0);
     260           0 :   if (!kh)
     261             :     {
     262           0 :       log_error (_("failed to allocate keyDB handle\n"));
     263           0 :       rc = gpg_error (GPG_ERR_GENERAL);
     264           0 :       goto leave;
     265             :     }
     266             : 
     267           0 :   in_fp = es_fdopen_nc (in_fd, "rb");
     268           0 :   if (!in_fp)
     269             :     {
     270           0 :       rc = gpg_error_from_syserror ();
     271           0 :       log_error ("fdopen() failed: %s\n", strerror (errno));
     272           0 :       goto leave;
     273             :     }
     274             : 
     275           0 :   rc = gpgsm_create_reader (&b64reader, ctrl, in_fp, 0, &reader);
     276           0 :   if (rc)
     277             :     {
     278           0 :       log_error ("can't create reader: %s\n", gpg_strerror (rc));
     279           0 :       goto leave;
     280             :     }
     281             : 
     282           0 :   rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
     283           0 :   if (rc)
     284             :     {
     285           0 :       log_error ("can't create writer: %s\n", gpg_strerror (rc));
     286           0 :       goto leave;
     287             :     }
     288             : 
     289           0 :   rc = ksba_cms_new (&cms);
     290           0 :   if (rc)
     291           0 :     goto leave;
     292             : 
     293           0 :   rc = ksba_cms_set_reader_writer (cms, reader, writer);
     294           0 :   if (rc)
     295             :     {
     296           0 :       log_debug ("ksba_cms_set_reader_writer failed: %s\n",
     297             :                  gpg_strerror (rc));
     298           0 :       goto leave;
     299             :     }
     300             : 
     301           0 :   audit_log (ctrl->audit, AUDIT_SETUP_READY);
     302             : 
     303             :   /* Parser loop. */
     304             :   do
     305             :     {
     306           0 :       rc = ksba_cms_parse (cms, &stopreason);
     307           0 :       if (rc)
     308             :         {
     309           0 :           log_debug ("ksba_cms_parse failed: %s\n", gpg_strerror (rc));
     310           0 :           goto leave;
     311             :         }
     312             : 
     313           0 :       if (stopreason == KSBA_SR_BEGIN_DATA
     314           0 :           || stopreason == KSBA_SR_DETACHED_DATA)
     315           0 :         {
     316             :           int algo, mode;
     317             :           const char *algoid;
     318           0 :           int any_key = 0;
     319             : 
     320           0 :           audit_log (ctrl->audit, AUDIT_GOT_DATA);
     321             : 
     322           0 :           algoid = ksba_cms_get_content_oid (cms, 2/* encryption algo*/);
     323           0 :           algo = gcry_cipher_map_name (algoid);
     324           0 :           mode = gcry_cipher_mode_from_oid (algoid);
     325           0 :           if (!algo || !mode)
     326             :             {
     327           0 :               rc = gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
     328           0 :               log_error ("unsupported algorithm '%s'\n", algoid? algoid:"?");
     329           0 :               if (algoid && !strcmp (algoid, "1.2.840.113549.3.2"))
     330           0 :                 log_info (_("(this is the RC2 algorithm)\n"));
     331           0 :               else if (!algoid)
     332           0 :                 log_info (_("(this does not seem to be an encrypted"
     333             :                             " message)\n"));
     334             :               {
     335             :                 char numbuf[50];
     336           0 :                 sprintf (numbuf, "%d", rc);
     337           0 :                 gpgsm_status2 (ctrl, STATUS_ERROR, "decrypt.algorithm",
     338             :                                numbuf, algoid?algoid:"?", NULL);
     339           0 :                 audit_log_s (ctrl->audit, AUDIT_BAD_DATA_CIPHER_ALGO, algoid);
     340             :               }
     341             : 
     342             :               /* If it seems that this is not an encrypted message we
     343             :                  return a more sensible error code. */
     344           0 :               if (!algoid)
     345           0 :                 rc = gpg_error (GPG_ERR_NO_DATA);
     346             : 
     347           0 :               goto leave;
     348             :             }
     349             : 
     350           0 :           audit_log_i (ctrl->audit, AUDIT_DATA_CIPHER_ALGO, algo);
     351           0 :           dfparm.algo = algo;
     352           0 :           dfparm.mode = mode;
     353           0 :           dfparm.blklen = gcry_cipher_get_algo_blklen (algo);
     354           0 :           if (dfparm.blklen > sizeof (dfparm.helpblock))
     355           0 :             return gpg_error (GPG_ERR_BUG);
     356             : 
     357           0 :           rc = ksba_cms_get_content_enc_iv (cms,
     358             :                                             dfparm.iv,
     359             :                                             sizeof (dfparm.iv),
     360             :                                             &dfparm.ivlen);
     361           0 :           if (rc)
     362             :             {
     363           0 :               log_error ("error getting IV: %s\n", gpg_strerror (rc));
     364           0 :               goto leave;
     365             :             }
     366             : 
     367           0 :           for (recp=0; !any_key; recp++)
     368             :             {
     369             :               char *issuer;
     370             :               ksba_sexp_t serial;
     371             :               ksba_sexp_t enc_val;
     372           0 :               char *hexkeygrip = NULL;
     373           0 :               char *desc = NULL;
     374             :               char kidbuf[16+1];
     375             : 
     376           0 :               *kidbuf = 0;
     377             : 
     378           0 :               rc = ksba_cms_get_issuer_serial (cms, recp, &issuer, &serial);
     379           0 :               if (rc == -1 && recp)
     380           0 :                 break; /* no more recipients */
     381           0 :               audit_log_i (ctrl->audit, AUDIT_NEW_RECP, recp);
     382           0 :               if (rc)
     383           0 :                 log_error ("recp %d - error getting info: %s\n",
     384             :                            recp, gpg_strerror (rc));
     385             :               else
     386             :                 {
     387           0 :                   ksba_cert_t cert = NULL;
     388             : 
     389           0 :                   log_debug ("recp %d - issuer: '%s'\n",
     390           0 :                              recp, issuer? issuer:"[NONE]");
     391           0 :                   log_debug ("recp %d - serial: ", recp);
     392           0 :                   gpgsm_dump_serial (serial);
     393           0 :                   log_printf ("\n");
     394             : 
     395           0 :                   if (ctrl->audit)
     396             :                     {
     397           0 :                       char *tmpstr = gpgsm_format_sn_issuer (serial, issuer);
     398           0 :                       audit_log_s (ctrl->audit, AUDIT_RECP_NAME, tmpstr);
     399           0 :                       xfree (tmpstr);
     400             :                     }
     401             : 
     402           0 :                   keydb_search_reset (kh);
     403           0 :                   rc = keydb_search_issuer_sn (kh, issuer, serial);
     404           0 :                   if (rc)
     405             :                     {
     406           0 :                       log_error ("failed to find the certificate: %s\n",
     407             :                                  gpg_strerror(rc));
     408           0 :                       goto oops;
     409             :                     }
     410             : 
     411           0 :                   rc = keydb_get_cert (kh, &cert);
     412           0 :                   if (rc)
     413             :                     {
     414           0 :                       log_error ("failed to get cert: %s\n", gpg_strerror (rc));
     415           0 :                       goto oops;
     416             :                     }
     417             : 
     418             :                   /* Print the ENC_TO status line.  Note that we can
     419             :                      do so only if we have the certificate.  This is
     420             :                      in contrast to gpg where the keyID is commonly
     421             :                      included in the encrypted messages. It is too
     422             :                      cumbersome to retrieve the used algorithm, thus
     423             :                      we don't print it for now.  We also record the
     424             :                      keyid for later use.  */
     425             :                   {
     426             :                     unsigned long kid[2];
     427             : 
     428           0 :                     kid[0] = gpgsm_get_short_fingerprint (cert, kid+1);
     429           0 :                     snprintf (kidbuf, sizeof kidbuf, "%08lX%08lX",
     430             :                               kid[1], kid[0]);
     431           0 :                     gpgsm_status2 (ctrl, STATUS_ENC_TO,
     432             :                                    kidbuf, "0", "0", NULL);
     433             :                   }
     434             : 
     435             :                   /* Put the certificate into the audit log.  */
     436           0 :                   audit_log_cert (ctrl->audit, AUDIT_SAVE_CERT, cert, 0);
     437             : 
     438             :                   /* Just in case there is a problem with the own
     439             :                      certificate we print this message - should never
     440             :                      happen of course */
     441           0 :                   rc = gpgsm_cert_use_decrypt_p (cert);
     442           0 :                   if (rc)
     443             :                     {
     444             :                       char numbuf[50];
     445           0 :                       sprintf (numbuf, "%d", rc);
     446           0 :                       gpgsm_status2 (ctrl, STATUS_ERROR, "decrypt.keyusage",
     447             :                                      numbuf, NULL);
     448           0 :                       rc = 0;
     449             :                     }
     450             : 
     451           0 :                   hexkeygrip = gpgsm_get_keygrip_hexstring (cert);
     452           0 :                   desc = gpgsm_format_keydesc (cert);
     453             : 
     454             :                 oops:
     455           0 :                   xfree (issuer);
     456           0 :                   xfree (serial);
     457           0 :                   ksba_cert_release (cert);
     458             :                 }
     459             : 
     460           0 :               if (!hexkeygrip)
     461             :                 ;
     462           0 :               else if (!(enc_val = ksba_cms_get_enc_val (cms, recp)))
     463           0 :                 log_error ("recp %d - error getting encrypted session key\n",
     464             :                            recp);
     465             :               else
     466             :                 {
     467           0 :                   rc = prepare_decryption (ctrl,
     468             :                                            hexkeygrip, desc, enc_val, &dfparm);
     469           0 :                   xfree (enc_val);
     470           0 :                   if (rc)
     471             :                     {
     472           0 :                       log_info ("decrypting session key failed: %s\n",
     473             :                                 gpg_strerror (rc));
     474           0 :                       if (gpg_err_code (rc) == GPG_ERR_NO_SECKEY && *kidbuf)
     475           0 :                         gpgsm_status2 (ctrl, STATUS_NO_SECKEY, kidbuf, NULL);
     476             :                     }
     477             :                   else
     478             :                     { /* setup the bulk decrypter */
     479           0 :                       any_key = 1;
     480           0 :                       ksba_writer_set_filter (writer,
     481             :                                               decrypt_filter,
     482             :                                               &dfparm);
     483             :                     }
     484           0 :                   audit_log_ok (ctrl->audit, AUDIT_RECP_RESULT, rc);
     485             :                 }
     486           0 :               xfree (hexkeygrip);
     487           0 :               xfree (desc);
     488             :             }
     489             : 
     490             :           /* If we write an audit log add the unused recipients to the
     491             :              log as well.  */
     492           0 :           if (ctrl->audit && any_key)
     493             :             {
     494           0 :               for (;; recp++)
     495             :                 {
     496             :                   char *issuer;
     497             :                   ksba_sexp_t serial;
     498             :                   int tmp_rc;
     499             : 
     500           0 :                   tmp_rc = ksba_cms_get_issuer_serial (cms, recp,
     501             :                                                        &issuer, &serial);
     502           0 :                   if (tmp_rc == -1)
     503           0 :                     break; /* no more recipients */
     504           0 :                   audit_log_i (ctrl->audit, AUDIT_NEW_RECP, recp);
     505           0 :                   if (tmp_rc)
     506           0 :                     log_error ("recp %d - error getting info: %s\n",
     507             :                                recp, gpg_strerror (rc));
     508             :                   else
     509             :                     {
     510           0 :                       char *tmpstr = gpgsm_format_sn_issuer (serial, issuer);
     511           0 :                       audit_log_s (ctrl->audit, AUDIT_RECP_NAME, tmpstr);
     512           0 :                       xfree (tmpstr);
     513           0 :                       xfree (issuer);
     514           0 :                       xfree (serial);
     515             :                     }
     516           0 :                 }
     517             :             }
     518             : 
     519           0 :           if (!any_key)
     520             :             {
     521           0 :               rc = gpg_error (GPG_ERR_NO_SECKEY);
     522           0 :               goto leave;
     523             :             }
     524             :         }
     525           0 :       else if (stopreason == KSBA_SR_END_DATA)
     526             :         {
     527           0 :           ksba_writer_set_filter (writer, NULL, NULL);
     528           0 :           if (dfparm.any_data)
     529             :             { /* write the last block with padding removed */
     530           0 :               int i, npadding = dfparm.lastblock[dfparm.blklen-1];
     531           0 :               if (!npadding || npadding > dfparm.blklen)
     532             :                 {
     533           0 :                   log_error ("invalid padding with value %d\n", npadding);
     534           0 :                   rc = gpg_error (GPG_ERR_INV_DATA);
     535           0 :                   goto leave;
     536             :                 }
     537           0 :               rc = ksba_writer_write (writer,
     538             :                                       dfparm.lastblock,
     539           0 :                                       dfparm.blklen - npadding);
     540           0 :               if (rc)
     541           0 :                 goto leave;
     542             : 
     543           0 :               for (i=dfparm.blklen - npadding; i < dfparm.blklen; i++)
     544             :                 {
     545           0 :                   if (dfparm.lastblock[i] != npadding)
     546             :                     {
     547           0 :                       log_error ("inconsistent padding\n");
     548           0 :                       rc = gpg_error (GPG_ERR_INV_DATA);
     549           0 :                       goto leave;
     550             :                     }
     551             :                 }
     552             :             }
     553             :         }
     554             : 
     555             :     }
     556           0 :   while (stopreason != KSBA_SR_READY);
     557             : 
     558           0 :   rc = gpgsm_finish_writer (b64writer);
     559           0 :   if (rc)
     560             :     {
     561           0 :       log_error ("write failed: %s\n", gpg_strerror (rc));
     562           0 :       goto leave;
     563             :     }
     564           0 :   gpgsm_status (ctrl, STATUS_DECRYPTION_OKAY, NULL);
     565             : 
     566             : 
     567             :  leave:
     568           0 :   audit_log_ok (ctrl->audit, AUDIT_DECRYPTION_RESULT, rc);
     569           0 :   if (rc)
     570             :     {
     571           0 :       gpgsm_status (ctrl, STATUS_DECRYPTION_FAILED, NULL);
     572           0 :       log_error ("message decryption failed: %s <%s>\n",
     573             :                  gpg_strerror (rc), gpg_strsource (rc));
     574             :     }
     575           0 :   ksba_cms_release (cms);
     576           0 :   gpgsm_destroy_reader (b64reader);
     577           0 :   gpgsm_destroy_writer (b64writer);
     578           0 :   keydb_release (kh);
     579           0 :   es_fclose (in_fp);
     580           0 :   if (dfparm.hd)
     581           0 :     gcry_cipher_close (dfparm.hd);
     582           0 :   return rc;
     583             : }

Generated by: LCOV version 1.11