gpg: Graceful skip reading of corrupt MPIs.
[gnupg.git] / g10 / encr-data.c
index 851233c..105b105 100644 (file)
@@ -1,12 +1,12 @@
 /* encr-data.c -  process an encrypted data packet
  * Copyright (C) 1998, 1999, 2000, 2001, 2005,
- *               2006 Free Software Foundation, Inc.
+ *               2006, 2009, 2012 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
  * GnuPG is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 3 of the License, or
  * (at your option) any later version.
  *
  * GnuPG is distributed in the hope that it will be useful,
@@ -15,9 +15,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <config.h>
@@ -32,6 +30,7 @@
 #include "cipher.h"
 #include "options.h"
 #include "i18n.h"
+#include "status.h"
 
 
 static int mdc_decode_filter ( void *opaque, int control, IOBUF a,
@@ -82,7 +81,7 @@ decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek )
   byte temp[32];
   unsigned blocksize;
   unsigned nprefix;
-  
+
   dfx = xtrycalloc (1, sizeof *dfx);
   if (!dfx)
     return gpg_error_from_syserror ();
@@ -90,35 +89,61 @@ decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek )
 
   if ( opt.verbose && !dek->algo_info_printed )
     {
-      if (!gcry_cipher_test_algo (dek->algo))
-        log_info (_("%s encrypted data\n"), gcry_cipher_algo_name (dek->algo));
+      if (!openpgp_cipher_test_algo (dek->algo))
+        log_info (_("%s encrypted data\n"),
+                  openpgp_cipher_algo_name (dek->algo));
       else
         log_info (_("encrypted with unknown algorithm %d\n"), dek->algo );
       dek->algo_info_printed = 1;
     }
+
+  {
+    char buf[20];
+
+    snprintf (buf, sizeof buf, "%d %d", ed->mdc_method, dek->algo);
+    write_status_text (STATUS_DECRYPTION_INFO, buf);
+  }
+
+  if (opt.show_session_key)
+    {
+      char numbuf[25];
+      char *hexbuf;
+
+      snprintf (numbuf, sizeof numbuf, "%d:", dek->algo);
+      hexbuf = bin2hex (dek->key, dek->keylen, NULL);
+      if (!hexbuf)
+        {
+          rc = gpg_error_from_syserror ();
+          goto leave;
+        }
+      log_info ("session key: '%s%s'\n", numbuf, hexbuf);
+      write_status_strings (STATUS_SESSION_KEY, numbuf, hexbuf, NULL);
+      xfree (hexbuf);
+    }
+
   rc = openpgp_cipher_test_algo (dek->algo);
   if (rc)
     goto leave;
-  blocksize = gcry_cipher_get_algo_blklen (dek->algo);
+  blocksize = openpgp_cipher_get_algo_blklen (dek->algo);
   if ( !blocksize || blocksize > 16 )
     log_fatal ("unsupported blocksize %u\n", blocksize );
   nprefix = blocksize;
   if ( ed->len && ed->len < (nprefix+2) )
     BUG();
 
-  if ( ed->mdc_method ) 
+  if ( ed->mdc_method )
     {
       if (gcry_md_open (&dfx->mdc_hash, ed->mdc_method, 0 ))
         BUG ();
       if ( DBG_HASHING )
-        gcry_md_start_debug (dfx->mdc_hash, "checkmdc");
+        gcry_md_debug (dfx->mdc_hash, "checkmdc");
     }
 
-  rc = gcry_cipher_open (&dfx->cipher_hd, dek->algo,
-                         GCRY_CIPHER_MODE_CFB,
-                         (GCRY_CIPHER_SECURE
-                          | ((ed->mdc_method || dek->algo >= 100)?
-                             0 : GCRY_CIPHER_ENABLE_SYNC)));
+  rc = openpgp_cipher_open (&dfx->cipher_hd, dek->algo,
+                           GCRY_CIPHER_MODE_CFB,
+                           (GCRY_CIPHER_SECURE
+                            | ((ed->mdc_method || dek->algo >= 100)?
+                               0 : GCRY_CIPHER_ENABLE_SYNC)));
   if (rc)
     {
       /* We should never get an error here cause we already checked
@@ -141,7 +166,7 @@ decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek )
       goto leave;
     }
 
-  if (!ed->buf) 
+  if (!ed->buf)
     {
       log_error(_("problem handling encrypted packet\n"));
       goto leave;
@@ -151,7 +176,7 @@ decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek )
 
   if ( ed->len )
     {
-      for (i=0; i < (nprefix+2) && ed->len; i++, ed->len-- ) 
+      for (i=0; i < (nprefix+2) && ed->len; i++, ed->len-- )
         {
           if ( (c=iobuf_get(ed->buf)) == -1 )
             break;
@@ -159,7 +184,7 @@ decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek )
             temp[i] = c;
         }
     }
-  else 
+  else
     {
       for (i=0; i < (nprefix+2); i++ )
         if ( (c=iobuf_get(ed->buf)) == -1 )
@@ -167,7 +192,7 @@ decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek )
         else
           temp[i] = c;
     }
-  
+
   gcry_cipher_decrypt (dfx->cipher_hd, temp, nprefix+2, NULL, 0);
   gcry_cipher_sync (dfx->cipher_hd);
   p = temp;
@@ -178,7 +203,7 @@ decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek )
       rc = gpg_error (GPG_ERR_BAD_KEY);
       goto leave;
     }
-  
+
   if ( dfx->mdc_hash )
     gcry_md_write (dfx->mdc_hash, temp, nprefix+2);
 
@@ -193,7 +218,7 @@ decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek )
   if ( ed->mdc_method && dfx->eof_seen == 2 )
     rc = gpg_error (GPG_ERR_INV_PACKET);
   else if ( ed->mdc_method )
-    { 
+    {
       /* We used to let parse-packet.c handle the MDC packet but this
          turned out to be a problem with compressed packets: With old
          style packets there is no length information available and
@@ -227,8 +252,8 @@ decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek )
       /* log_printhex("MDC message:", dfx->defer, 22); */
       /* log_printhex("MDC calc:", gcry_md_read (dfx->mdc_hash,0), datalen); */
     }
-  
-  
+
+
  leave:
   release_dfx_context (dfx);
   return rc;
@@ -245,7 +270,7 @@ mdc_decode_filter (void *opaque, int control, IOBUF a,
   size_t n, size = *ret_len;
   int rc = 0;
   int c;
-  
+
   if ( control == IOBUFCTRL_UNDERFLOW && dfx->eof_seen )
     {
       *ret_len = 0;
@@ -255,7 +280,7 @@ mdc_decode_filter (void *opaque, int control, IOBUF a,
     {
       assert (a);
       assert ( size > 44 );
-      
+
       /* Get at least 22 bytes and put it somewhere ahead in the buffer. */
       for (n=22; n < 44 ; n++ )
         {
@@ -263,7 +288,7 @@ mdc_decode_filter (void *opaque, int control, IOBUF a,
             break;
           buf[n] = c;
        }
-      if ( n == 44 ) 
+      if ( n == 44 )
         {
           /* We have enough stuff - flush the deferred stuff.  */
           /* (we asserted that the buffer is large enough) */
@@ -277,7 +302,7 @@ mdc_decode_filter (void *opaque, int control, IOBUF a,
               memcpy (buf, dfx->defer, 22 );
            }
           /* Now fill up. */
-          for (; n < size; n++ ) 
+          for (; n < size; n++ )
             {
               if ( (c = iobuf_get(a)) == -1 )
                 break;
@@ -318,11 +343,11 @@ mdc_decode_filter (void *opaque, int control, IOBUF a,
        }
       *ret_len = n;
     }
-  else if ( control == IOBUFCTRL_FREE ) 
+  else if ( control == IOBUFCTRL_FREE )
     {
       release_dfx_context (dfx);
     }
-  else if ( control == IOBUFCTRL_DESC ) 
+  else if ( control == IOBUFCTRL_DESC )
     {
       *(char**)buf = "mdc_decode_filter";
     }
@@ -336,8 +361,8 @@ decode_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len)
   decode_filter_ctx_t fc = opaque;
   size_t n, size = *ret_len;
   int rc = 0;
-  
-  if ( control == IOBUFCTRL_UNDERFLOW ) 
+
+  if ( control == IOBUFCTRL_UNDERFLOW )
     {
       assert(a);
       n = iobuf_read ( a, buf, size );
@@ -352,7 +377,7 @@ decode_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len)
         rc = -1; /* EOF */
       *ret_len = n;
     }
-  else if ( control == IOBUFCTRL_FREE ) 
+  else if ( control == IOBUFCTRL_FREE )
     {
       release_dfx_context (fc);
     }