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

Generated by: LCOV version 1.11