LCOV - code coverage report
Current view: top level - g10 - decrypt-data.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 150 219 68.5 %
Date: 2015-11-05 17:10:59 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /* decrypt-data.c - Decrypt an encrypted data packet
       2             :  * Copyright (C) 1998, 1999, 2000, 2001, 2005,
       3             :  *               2006, 2009 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 <assert.h>
      26             : 
      27             : #include "gpg.h"
      28             : #include "util.h"
      29             : #include "packet.h"
      30             : #include "options.h"
      31             : #include "i18n.h"
      32             : #include "status.h"
      33             : 
      34             : 
      35             : static int mdc_decode_filter ( void *opaque, int control, IOBUF a,
      36             :                                byte *buf, size_t *ret_len);
      37             : static int decode_filter ( void *opaque, int control, IOBUF a,
      38             :                                         byte *buf, size_t *ret_len);
      39             : 
      40             : typedef struct decode_filter_context_s
      41             : {
      42             :   gcry_cipher_hd_t cipher_hd;
      43             :   gcry_md_hd_t mdc_hash;
      44             :   char defer[22];
      45             :   int  defer_filled;
      46             :   int  eof_seen;
      47             :   int  refcount;
      48             :   int  partial;   /* Working on a partial length packet.  */
      49             :   size_t length;  /* If !partial: Remaining bytes in the packet.  */
      50             : } *decode_filter_ctx_t;
      51             : 
      52             : 
      53             : /* Helper to release the decode context.  */
      54             : static void
      55         940 : release_dfx_context (decode_filter_ctx_t dfx)
      56             : {
      57         940 :   if (!dfx)
      58         940 :     return;
      59             : 
      60         940 :   assert (dfx->refcount);
      61         940 :   if ( !--dfx->refcount )
      62             :     {
      63         470 :       gcry_cipher_close (dfx->cipher_hd);
      64         470 :       dfx->cipher_hd = NULL;
      65         470 :       gcry_md_close (dfx->mdc_hash);
      66         470 :       dfx->mdc_hash = NULL;
      67         470 :       xfree (dfx);
      68             :     }
      69             : }
      70             : 
      71             : 
      72             : 
      73             : /****************
      74             :  * Decrypt the data, specified by ED with the key DEK.
      75             :  */
      76             : int
      77         470 : decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek)
      78             : {
      79             :   decode_filter_ctx_t dfx;
      80             :   byte *p;
      81         470 :   int rc=0, c, i;
      82             :   byte temp[32];
      83             :   unsigned blocksize;
      84             :   unsigned nprefix;
      85             : 
      86         470 :   dfx = xtrycalloc (1, sizeof *dfx);
      87         470 :   if (!dfx)
      88           0 :     return gpg_error_from_syserror ();
      89         470 :   dfx->refcount = 1;
      90             : 
      91         470 :   if ( opt.verbose && !dek->algo_info_printed )
      92             :     {
      93           0 :       if (!openpgp_cipher_test_algo (dek->algo))
      94           0 :         log_info (_("%s encrypted data\n"),
      95           0 :                   openpgp_cipher_algo_name (dek->algo));
      96             :       else
      97           0 :         log_info (_("encrypted with unknown algorithm %d\n"), dek->algo );
      98           0 :       dek->algo_info_printed = 1;
      99             :     }
     100             : 
     101             :   {
     102             :     char buf[20];
     103             : 
     104         470 :     snprintf (buf, sizeof buf, "%d %d", ed->mdc_method, dek->algo);
     105         470 :     write_status_text (STATUS_DECRYPTION_INFO, buf);
     106             :   }
     107             : 
     108         470 :   if (opt.show_session_key)
     109             :     {
     110             :       char numbuf[25];
     111             :       char *hexbuf;
     112             : 
     113           0 :       snprintf (numbuf, sizeof numbuf, "%d:", dek->algo);
     114           0 :       hexbuf = bin2hex (dek->key, dek->keylen, NULL);
     115           0 :       if (!hexbuf)
     116             :         {
     117           0 :           rc = gpg_error_from_syserror ();
     118           0 :           goto leave;
     119             :         }
     120           0 :       log_info ("session key: '%s%s'\n", numbuf, hexbuf);
     121           0 :       write_status_strings (STATUS_SESSION_KEY, numbuf, hexbuf, NULL);
     122           0 :       xfree (hexbuf);
     123             :     }
     124             : 
     125         470 :   rc = openpgp_cipher_test_algo (dek->algo);
     126         470 :   if (rc)
     127           0 :     goto leave;
     128         470 :   blocksize = openpgp_cipher_get_algo_blklen (dek->algo);
     129         470 :   if ( !blocksize || blocksize > 16 )
     130           0 :     log_fatal ("unsupported blocksize %u\n", blocksize );
     131         470 :   nprefix = blocksize;
     132         470 :   if ( ed->len && ed->len < (nprefix+2) )
     133             :     {
     134             :        /* An invalid message.  We can't check that during parsing
     135             :           because we may not know the used cipher then.  */
     136           0 :       rc = gpg_error (GPG_ERR_INV_PACKET);
     137           0 :       goto leave;
     138             :     }
     139             : 
     140         470 :   if ( ed->mdc_method )
     141             :     {
     142         417 :       if (gcry_md_open (&dfx->mdc_hash, ed->mdc_method, 0 ))
     143           0 :         BUG ();
     144         417 :       if ( DBG_HASHING )
     145           0 :         gcry_md_debug (dfx->mdc_hash, "checkmdc");
     146             :     }
     147             : 
     148         470 :   rc = openpgp_cipher_open (&dfx->cipher_hd, dek->algo,
     149             :                             GCRY_CIPHER_MODE_CFB,
     150             :                             (GCRY_CIPHER_SECURE
     151             :                              | ((ed->mdc_method || dek->algo >= 100)?
     152             :                                 0 : GCRY_CIPHER_ENABLE_SYNC)));
     153         470 :   if (rc)
     154             :     {
     155             :       /* We should never get an error here cause we already checked
     156             :        * that the algorithm is available.  */
     157           0 :       BUG();
     158             :     }
     159             : 
     160             : 
     161             :   /* log_hexdump( "thekey", dek->key, dek->keylen );*/
     162         470 :   rc = gcry_cipher_setkey (dfx->cipher_hd, dek->key, dek->keylen);
     163         470 :   if ( gpg_err_code (rc) == GPG_ERR_WEAK_KEY )
     164             :     {
     165           0 :       log_info(_("WARNING: message was encrypted with"
     166             :                  " a weak key in the symmetric cipher.\n"));
     167           0 :       rc=0;
     168             :     }
     169         470 :   else if( rc )
     170             :     {
     171           0 :       log_error("key setup failed: %s\n", gpg_strerror (rc) );
     172           0 :       goto leave;
     173             :     }
     174             : 
     175         470 :   if (!ed->buf)
     176             :     {
     177           0 :       log_error(_("problem handling encrypted packet\n"));
     178           0 :       goto leave;
     179             :     }
     180             : 
     181         470 :   gcry_cipher_setiv (dfx->cipher_hd, NULL, 0);
     182             : 
     183         470 :   if ( ed->len )
     184             :     {
     185        3327 :       for (i=0; i < (nprefix+2) && ed->len; i++, ed->len-- )
     186             :         {
     187        3122 :           if ( (c=iobuf_get(ed->buf)) == -1 )
     188           0 :             break;
     189             :           else
     190        3122 :             temp[i] = c;
     191             :         }
     192             :     }
     193             :   else
     194             :     {
     195        4379 :       for (i=0; i < (nprefix+2); i++ )
     196        4114 :         if ( (c=iobuf_get(ed->buf)) == -1 )
     197           0 :           break;
     198             :         else
     199        4114 :           temp[i] = c;
     200             :     }
     201             : 
     202         470 :   gcry_cipher_decrypt (dfx->cipher_hd, temp, nprefix+2, NULL, 0);
     203         470 :   gcry_cipher_sync (dfx->cipher_hd);
     204         470 :   p = temp;
     205             :   /* log_hexdump( "prefix", temp, nprefix+2 ); */
     206         470 :   if (dek->symmetric
     207         218 :       && (p[nprefix-2] != p[nprefix] || p[nprefix-1] != p[nprefix+1]) )
     208             :     {
     209           0 :       rc = gpg_error (GPG_ERR_BAD_KEY);
     210           0 :       goto leave;
     211             :     }
     212             : 
     213         470 :   if ( dfx->mdc_hash )
     214         417 :     gcry_md_write (dfx->mdc_hash, temp, nprefix+2);
     215             : 
     216         470 :   dfx->refcount++;
     217         470 :   dfx->partial = ed->is_partial;
     218         470 :   dfx->length = ed->len;
     219         470 :   if ( ed->mdc_method )
     220         417 :     iobuf_push_filter ( ed->buf, mdc_decode_filter, dfx );
     221             :   else
     222          53 :     iobuf_push_filter ( ed->buf, decode_filter, dfx );
     223             : 
     224         470 :   if (opt.unwrap_encryption)
     225             :     {
     226             :       char *filename;
     227             :       estream_t fp;
     228           0 :       rc = get_output_file ("", 0, ed->buf, &filename, &fp);
     229           0 :       if (! rc)
     230             :         {
     231           0 :           iobuf_t output = iobuf_esopen (fp, "w", 0);
     232           0 :           armor_filter_context_t *afx = NULL;
     233             : 
     234           0 :           if (opt.armor)
     235             :             {
     236           0 :               afx = new_armor_context ();
     237           0 :               push_armor_filter (afx, output);
     238             :             }
     239             : 
     240           0 :           iobuf_copy (output, ed->buf);
     241           0 :           if ((rc = iobuf_error (ed->buf)))
     242           0 :             log_error (_("error reading: %s\n"),
     243             :                        filename, gpg_strerror (rc));
     244           0 :           else if ((rc = iobuf_error (output)))
     245           0 :             log_error (_("error writing output ('%s'): %s\n"),
     246             :                        filename, gpg_strerror (rc));
     247             : 
     248           0 :           iobuf_close (output);
     249           0 :           if (afx)
     250           0 :             release_armor_context (afx);
     251             :         }
     252             :     }
     253             :   else
     254         470 :     proc_packets (ctrl, procctx, ed->buf );
     255             : 
     256         470 :   ed->buf = NULL;
     257         470 :   if (dfx->eof_seen > 1 )
     258           0 :     rc = gpg_error (GPG_ERR_INV_PACKET);
     259         470 :   else if ( ed->mdc_method )
     260             :     {
     261             :       /* We used to let parse-packet.c handle the MDC packet but this
     262             :          turned out to be a problem with compressed packets: With old
     263             :          style packets there is no length information available and
     264             :          the decompressor uses an implicit end.  However we can't know
     265             :          this implicit end beforehand (:-) and thus may feed the
     266             :          decompressor with more bytes than actually needed.  It would
     267             :          be possible to unread the extra bytes but due to our weird
     268             :          iobuf system any unread is non reliable due to filters
     269             :          already popped off.  The easy and sane solution is to care
     270             :          about the MDC packet only here and never pass it to the
     271             :          packet parser.  Fortunatley the OpenPGP spec requires a
     272             :          strict format for the MDC packet so that we know that 22
     273             :          bytes are appended.  */
     274         417 :       int datalen = gcry_md_get_algo_dlen (ed->mdc_method);
     275             : 
     276         417 :       assert (dfx->cipher_hd);
     277         417 :       assert (dfx->mdc_hash);
     278         417 :       gcry_cipher_decrypt (dfx->cipher_hd, dfx->defer, 22, NULL, 0);
     279         417 :       gcry_md_write (dfx->mdc_hash, dfx->defer, 2);
     280         417 :       gcry_md_final (dfx->mdc_hash);
     281             : 
     282         417 :       if (   dfx->defer[0] != '\xd3'
     283         417 :           || dfx->defer[1] != '\x14'
     284         417 :           || datalen != 20
     285         417 :           || memcmp (gcry_md_read (dfx->mdc_hash, 0), dfx->defer+2, datalen))
     286           0 :         rc = gpg_error (GPG_ERR_BAD_SIGNATURE);
     287             :       /* log_printhex("MDC message:", dfx->defer, 22); */
     288             :       /* log_printhex("MDC calc:", gcry_md_read (dfx->mdc_hash,0), datalen); */
     289             :     }
     290             : 
     291             : 
     292             :  leave:
     293         470 :   release_dfx_context (dfx);
     294         470 :   return rc;
     295             : }
     296             : 
     297             : 
     298             : 
     299             : static int
     300        2162 : mdc_decode_filter (void *opaque, int control, IOBUF a,
     301             :                    byte *buf, size_t *ret_len)
     302             : {
     303        2162 :   decode_filter_ctx_t dfx = opaque;
     304        2162 :   size_t n, size = *ret_len;
     305        2162 :   int rc = 0;
     306             :   int c;
     307             : 
     308             :   /* Note: We need to distinguish between a partial and a fixed length
     309             :      packet.  The first is the usual case as created by GPG.  However
     310             :      for short messages the format degrades to a fixed length packet
     311             :      and other implementations might use fixed length as well.  Only
     312             :      looking for the EOF on fixed data works only if the encrypted
     313             :      packet is not followed by other data.  This used to be a long
     314             :      standing bug which was fixed on 2009-10-02.  */
     315             : 
     316        2162 :   if ( control == IOBUFCTRL_UNDERFLOW && dfx->eof_seen )
     317             :     {
     318         417 :       *ret_len = 0;
     319         417 :       rc = -1;
     320             :     }
     321        1745 :   else if( control == IOBUFCTRL_UNDERFLOW )
     322             :     {
     323         911 :       assert (a);
     324         911 :       assert (size > 44); /* Our code requires at least this size.  */
     325             : 
     326             :       /* Get at least 22 bytes and put it ahead in the buffer.  */
     327         911 :       if (dfx->partial)
     328             :         {
     329       16376 :           for (n=22; n < 44; n++)
     330             :             {
     331       15664 :               if ( (c = iobuf_get(a)) == -1 )
     332           0 :                 break;
     333       15664 :               buf[n] = c;
     334             :             }
     335             :         }
     336             :       else
     337             :         {
     338        4577 :           for (n=22; n < 44 && dfx->length; n++, dfx->length--)
     339             :             {
     340        4378 :               c = iobuf_get (a);
     341        4378 :               if (c == -1)
     342           0 :                 break; /* Premature EOF.  */
     343        4378 :               buf[n] = c;
     344             :             }
     345             :         }
     346         911 :       if (n == 44)
     347             :         {
     348             :           /* We have enough stuff - flush the deferred stuff.  */
     349         911 :           if ( !dfx->defer_filled )  /* First time. */
     350             :             {
     351         417 :               memcpy (buf, buf+22, 22);
     352         417 :               n = 22;
     353             :             }
     354             :           else
     355             :             {
     356         494 :               memcpy (buf, dfx->defer, 22);
     357             :             }
     358             :           /* Fill up the buffer. */
     359         911 :           if (dfx->partial)
     360             :             {
     361     4681707 :               for (; n < size; n++ )
     362             :                 {
     363     4681213 :                   if ( (c = iobuf_get(a)) == -1 )
     364             :                     {
     365         218 :                       dfx->eof_seen = 1; /* Normal EOF. */
     366         218 :                       break;
     367             :                     }
     368     4680995 :                   buf[n] = c;
     369             :                 }
     370             :             }
     371             :           else
     372             :             {
     373        7806 :               for (; n < size && dfx->length; n++, dfx->length--)
     374             :                 {
     375        7607 :                   c = iobuf_get(a);
     376        7607 :                   if (c == -1)
     377             :                     {
     378           0 :                       dfx->eof_seen = 3; /* Premature EOF. */
     379           0 :                       break;
     380             :                     }
     381        7607 :                   buf[n] = c;
     382             :                 }
     383         199 :               if (!dfx->length)
     384         199 :                 dfx->eof_seen = 1; /* Normal EOF.  */
     385             :             }
     386             : 
     387             :           /* Move the trailing 22 bytes back to the defer buffer.  We
     388             :              have at least 44 bytes thus a memmove is not needed.  */
     389         911 :           n -= 22;
     390         911 :           memcpy (dfx->defer, buf+n, 22 );
     391         911 :           dfx->defer_filled = 1;
     392             :         }
     393           0 :       else if ( !dfx->defer_filled )  /* EOF seen but empty defer buffer. */
     394             :         {
     395             :           /* This is bad because it means an incomplete hash. */
     396           0 :           n -= 22;
     397           0 :           memcpy (buf, buf+22, n );
     398           0 :           dfx->eof_seen = 2; /* EOF with incomplete hash.  */
     399             :         }
     400             :       else  /* EOF seen (i.e. read less than 22 bytes). */
     401             :         {
     402           0 :           memcpy (buf, dfx->defer, 22 );
     403           0 :           n -= 22;
     404           0 :           memcpy (dfx->defer, buf+n, 22 );
     405           0 :           dfx->eof_seen = 1; /* Normal EOF. */
     406             :         }
     407             : 
     408         911 :       if ( n )
     409             :         {
     410         911 :           if ( dfx->cipher_hd )
     411         911 :             gcry_cipher_decrypt (dfx->cipher_hd, buf, n, NULL, 0);
     412         911 :           if ( dfx->mdc_hash )
     413         911 :             gcry_md_write (dfx->mdc_hash, buf, n);
     414             :         }
     415             :       else
     416             :         {
     417           0 :           assert ( dfx->eof_seen );
     418           0 :           rc = -1; /* Return EOF.  */
     419             :         }
     420         911 :       *ret_len = n;
     421             :     }
     422         834 :   else if ( control == IOBUFCTRL_FREE )
     423             :     {
     424         417 :       release_dfx_context (dfx);
     425             :     }
     426         417 :   else if ( control == IOBUFCTRL_DESC )
     427             :     {
     428           0 :       *(char**)buf = "mdc_decode_filter";
     429             :     }
     430        2162 :   return rc;
     431             : }
     432             : 
     433             : 
     434             : static int
     435         326 : decode_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len)
     436             : {
     437         326 :   decode_filter_ctx_t fc = opaque;
     438         326 :   size_t size = *ret_len;
     439             :   size_t n;
     440         326 :   int c, rc = 0;
     441             : 
     442             : 
     443         326 :   if ( control == IOBUFCTRL_UNDERFLOW && fc->eof_seen )
     444             :     {
     445          53 :       *ret_len = 0;
     446          53 :       rc = -1;
     447             :     }
     448         273 :   else if ( control == IOBUFCTRL_UNDERFLOW )
     449             :     {
     450         167 :       assert(a);
     451             : 
     452         167 :       if (fc->partial)
     453             :         {
     454     1066850 :           for (n=0; n < size; n++ )
     455             :             {
     456     1066736 :               c = iobuf_get(a);
     457     1066736 :               if (c == -1)
     458             :                 {
     459          47 :                   fc->eof_seen = 1; /* Normal EOF. */
     460          47 :                   break;
     461             :                 }
     462     1066689 :               buf[n] = c;
     463             :             }
     464             :         }
     465             :       else
     466             :         {
     467         449 :           for (n=0; n < size && fc->length; n++, fc->length--)
     468             :             {
     469         443 :               c = iobuf_get(a);
     470         443 :               if (c == -1)
     471             :                 {
     472           0 :                   fc->eof_seen = 3; /* Premature EOF. */
     473           0 :                   break;
     474             :                 }
     475         443 :               buf[n] = c;
     476             :             }
     477           6 :           if (!fc->length)
     478           6 :             fc->eof_seen = 1; /* Normal EOF.  */
     479             :         }
     480         167 :       if (n)
     481             :         {
     482         167 :           if (fc->cipher_hd)
     483         167 :             gcry_cipher_decrypt (fc->cipher_hd, buf, n, NULL, 0);
     484             :         }
     485             :       else
     486             :         {
     487           0 :           if (!fc->eof_seen)
     488           0 :             fc->eof_seen = 1;
     489           0 :           rc = -1; /* Return EOF. */
     490             :         }
     491         167 :       *ret_len = n;
     492             :     }
     493         106 :   else if ( control == IOBUFCTRL_FREE )
     494             :     {
     495          53 :       release_dfx_context (fc);
     496             :     }
     497          53 :   else if ( control == IOBUFCTRL_DESC )
     498             :     {
     499           0 :       *(char**)buf = "decode_filter";
     500             :     }
     501         326 :   return rc;
     502             : }

Generated by: LCOV version 1.11