gpg: Graceful skip reading of corrupt MPIs.
[gnupg.git] / g10 / encr-data.c
1 /* encr-data.c -  process an encrypted data packet
2  * Copyright (C) 1998, 1999, 2000, 2001, 2005,
3  *               2006, 2009, 2012 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 "cipher.h"
31 #include "options.h"
32 #include "i18n.h"
33 #include "status.h"
34
35
36 static int mdc_decode_filter ( void *opaque, int control, IOBUF a,
37                                byte *buf, size_t *ret_len);
38 static int decode_filter ( void *opaque, int control, IOBUF a,
39                                         byte *buf, size_t *ret_len);
40
41 typedef struct decode_filter_context_s
42 {
43   gcry_cipher_hd_t cipher_hd;
44   gcry_md_hd_t mdc_hash;
45   char defer[22];
46   int  defer_filled;
47   int  eof_seen;
48   int  refcount;
49 } *decode_filter_ctx_t;
50
51
52 /* Helper to release the decode context.  */
53 static void
54 release_dfx_context (decode_filter_ctx_t dfx)
55 {
56   if (!dfx)
57     return;
58
59   assert (dfx->refcount);
60   if ( !--dfx->refcount )
61     {
62       gcry_cipher_close (dfx->cipher_hd);
63       dfx->cipher_hd = NULL;
64       gcry_md_close (dfx->mdc_hash);
65       dfx->mdc_hash = NULL;
66       xfree (dfx);
67     }
68 }
69
70
71
72 /****************
73  * Decrypt the data, specified by ED with the key DEK.
74  */
75 int
76 decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek )
77 {
78   decode_filter_ctx_t dfx;
79   byte *p;
80   int rc=0, c, i;
81   byte temp[32];
82   unsigned blocksize;
83   unsigned nprefix;
84
85   dfx = xtrycalloc (1, sizeof *dfx);
86   if (!dfx)
87     return gpg_error_from_syserror ();
88   dfx->refcount = 1;
89
90   if ( opt.verbose && !dek->algo_info_printed )
91     {
92       if (!openpgp_cipher_test_algo (dek->algo))
93         log_info (_("%s encrypted data\n"),
94                   openpgp_cipher_algo_name (dek->algo));
95       else
96         log_info (_("encrypted with unknown algorithm %d\n"), dek->algo );
97       dek->algo_info_printed = 1;
98     }
99
100   {
101     char buf[20];
102
103     snprintf (buf, sizeof buf, "%d %d", ed->mdc_method, dek->algo);
104     write_status_text (STATUS_DECRYPTION_INFO, buf);
105   }
106
107   if (opt.show_session_key)
108     {
109       char numbuf[25];
110       char *hexbuf;
111
112       snprintf (numbuf, sizeof numbuf, "%d:", dek->algo);
113       hexbuf = bin2hex (dek->key, dek->keylen, NULL);
114       if (!hexbuf)
115         {
116           rc = gpg_error_from_syserror ();
117           goto leave;
118         }
119       log_info ("session key: '%s%s'\n", numbuf, hexbuf);
120       write_status_strings (STATUS_SESSION_KEY, numbuf, hexbuf, NULL);
121       xfree (hexbuf);
122     }
123
124   rc = openpgp_cipher_test_algo (dek->algo);
125   if (rc)
126     goto leave;
127   blocksize = openpgp_cipher_get_algo_blklen (dek->algo);
128   if ( !blocksize || blocksize > 16 )
129     log_fatal ("unsupported blocksize %u\n", blocksize );
130   nprefix = blocksize;
131   if ( ed->len && ed->len < (nprefix+2) )
132     BUG();
133
134   if ( ed->mdc_method )
135     {
136       if (gcry_md_open (&dfx->mdc_hash, ed->mdc_method, 0 ))
137         BUG ();
138       if ( DBG_HASHING )
139         gcry_md_debug (dfx->mdc_hash, "checkmdc");
140     }
141
142   rc = openpgp_cipher_open (&dfx->cipher_hd, dek->algo,
143                             GCRY_CIPHER_MODE_CFB,
144                             (GCRY_CIPHER_SECURE
145                              | ((ed->mdc_method || dek->algo >= 100)?
146                                 0 : GCRY_CIPHER_ENABLE_SYNC)));
147   if (rc)
148     {
149       /* We should never get an error here cause we already checked
150        * that the algorithm is available.  */
151       BUG();
152     }
153
154
155   /* log_hexdump( "thekey", dek->key, dek->keylen );*/
156   rc = gcry_cipher_setkey (dfx->cipher_hd, dek->key, dek->keylen);
157   if ( gpg_err_code (rc) == GPG_ERR_WEAK_KEY )
158     {
159       log_info(_("WARNING: message was encrypted with"
160                  " a weak key in the symmetric cipher.\n"));
161       rc=0;
162     }
163   else if( rc )
164     {
165       log_error("key setup failed: %s\n", g10_errstr(rc) );
166       goto leave;
167     }
168
169   if (!ed->buf)
170     {
171       log_error(_("problem handling encrypted packet\n"));
172       goto leave;
173     }
174
175   gcry_cipher_setiv (dfx->cipher_hd, NULL, 0);
176
177   if ( ed->len )
178     {
179       for (i=0; i < (nprefix+2) && ed->len; i++, ed->len-- )
180         {
181           if ( (c=iobuf_get(ed->buf)) == -1 )
182             break;
183           else
184             temp[i] = c;
185         }
186     }
187   else
188     {
189       for (i=0; i < (nprefix+2); i++ )
190         if ( (c=iobuf_get(ed->buf)) == -1 )
191           break;
192         else
193           temp[i] = c;
194     }
195
196   gcry_cipher_decrypt (dfx->cipher_hd, temp, nprefix+2, NULL, 0);
197   gcry_cipher_sync (dfx->cipher_hd);
198   p = temp;
199   /* log_hexdump( "prefix", temp, nprefix+2 ); */
200   if (dek->symmetric
201       && (p[nprefix-2] != p[nprefix] || p[nprefix-1] != p[nprefix+1]) )
202     {
203       rc = gpg_error (GPG_ERR_BAD_KEY);
204       goto leave;
205     }
206
207   if ( dfx->mdc_hash )
208     gcry_md_write (dfx->mdc_hash, temp, nprefix+2);
209
210   dfx->refcount++;
211   if ( ed->mdc_method )
212     iobuf_push_filter ( ed->buf, mdc_decode_filter, dfx );
213   else
214     iobuf_push_filter ( ed->buf, decode_filter, dfx );
215
216   proc_packets ( procctx, ed->buf );
217   ed->buf = NULL;
218   if ( ed->mdc_method && dfx->eof_seen == 2 )
219     rc = gpg_error (GPG_ERR_INV_PACKET);
220   else if ( ed->mdc_method )
221     {
222       /* We used to let parse-packet.c handle the MDC packet but this
223          turned out to be a problem with compressed packets: With old
224          style packets there is no length information available and
225          the decompressor uses an implicit end.  However we can't know
226          this implicit end beforehand (:-) and thus may feed the
227          decompressor with more bytes than actually needed.  It would
228          be possible to unread the extra bytes but due to our weird
229          iobuf system any unread is non reliable due to filters
230          already popped off.  The easy and sane solution is to care
231          about the MDC packet only here and never pass it to the
232          packet parser.  Fortunatley the OpenPGP spec requires a
233          strict format for the MDC packet so that we know that 22
234          bytes are appended.  */
235       int datalen = gcry_md_get_algo_dlen (ed->mdc_method);
236
237       assert (dfx->cipher_hd);
238       assert (dfx->mdc_hash);
239       gcry_cipher_decrypt (dfx->cipher_hd, dfx->defer, 22, NULL, 0);
240       gcry_md_write (dfx->mdc_hash, dfx->defer, 2);
241       gcry_md_final (dfx->mdc_hash);
242
243       if (dfx->defer[0] != '\xd3' || dfx->defer[1] != '\x14' )
244         {
245           log_error("mdc_packet with invalid encoding\n");
246           rc = gpg_error (GPG_ERR_INV_PACKET);
247         }
248       else if (datalen != 20
249                || memcmp (gcry_md_read (dfx->mdc_hash, 0),
250                           dfx->defer+2,datalen ))
251         rc = gpg_error (GPG_ERR_BAD_SIGNATURE);
252       /* log_printhex("MDC message:", dfx->defer, 22); */
253       /* log_printhex("MDC calc:", gcry_md_read (dfx->mdc_hash,0), datalen); */
254     }
255
256
257  leave:
258   release_dfx_context (dfx);
259   return rc;
260 }
261
262
263
264 /* I think we should merge this with cipher_filter */
265 static int
266 mdc_decode_filter (void *opaque, int control, IOBUF a,
267                    byte *buf, size_t *ret_len)
268 {
269   decode_filter_ctx_t dfx = opaque;
270   size_t n, size = *ret_len;
271   int rc = 0;
272   int c;
273
274   if ( control == IOBUFCTRL_UNDERFLOW && dfx->eof_seen )
275     {
276       *ret_len = 0;
277       rc = -1;
278     }
279   else if( control == IOBUFCTRL_UNDERFLOW )
280     {
281       assert (a);
282       assert ( size > 44 );
283
284       /* Get at least 22 bytes and put it somewhere ahead in the buffer. */
285       for (n=22; n < 44 ; n++ )
286         {
287           if( (c = iobuf_get(a)) == -1 )
288             break;
289           buf[n] = c;
290         }
291       if ( n == 44 )
292         {
293           /* We have enough stuff - flush the deferred stuff.  */
294           /* (we asserted that the buffer is large enough) */
295           if ( !dfx->defer_filled )  /* First time. */
296             {
297               memcpy (buf, buf+22, 22 );
298               n = 22;
299             }
300           else
301             {
302               memcpy (buf, dfx->defer, 22 );
303             }
304           /* Now fill up. */
305           for (; n < size; n++ )
306             {
307               if ( (c = iobuf_get(a)) == -1 )
308                 break;
309               buf[n] = c;
310             }
311           /* Move the last 22 bytes back to the defer buffer. */
312           /* (right, we are wasting 22 bytes of the supplied buffer.) */
313           n -= 22;
314           memcpy (dfx->defer, buf+n, 22 );
315           dfx->defer_filled = 1;
316         }
317       else if ( !dfx->defer_filled )  /* EOF seen but empty defer buffer. */
318         {
319           /* This is bad because it means an incomplete hash. */
320           n -= 22;
321           memcpy (buf, buf+22, n );
322           dfx->eof_seen = 2; /* EOF with incomplete hash.  */
323         }
324       else  /* EOF seen (i.e. read less than 22 bytes). */
325         {
326           memcpy (buf, dfx->defer, 22 );
327           n -= 22;
328           memcpy (dfx->defer, buf+n, 22 );
329           dfx->eof_seen = 1; /* Normal EOF. */
330         }
331
332       if ( n )
333         {
334           if ( dfx->cipher_hd )
335             gcry_cipher_decrypt (dfx->cipher_hd, buf, n, NULL, 0);
336           if ( dfx->mdc_hash )
337             gcry_md_write (dfx->mdc_hash, buf, n);
338         }
339       else
340         {
341           assert ( dfx->eof_seen );
342           rc = -1; /* eof */
343         }
344       *ret_len = n;
345     }
346   else if ( control == IOBUFCTRL_FREE )
347     {
348       release_dfx_context (dfx);
349     }
350   else if ( control == IOBUFCTRL_DESC )
351     {
352       *(char**)buf = "mdc_decode_filter";
353     }
354   return rc;
355 }
356
357
358 static int
359 decode_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len)
360 {
361   decode_filter_ctx_t fc = opaque;
362   size_t n, size = *ret_len;
363   int rc = 0;
364
365   if ( control == IOBUFCTRL_UNDERFLOW )
366     {
367       assert(a);
368       n = iobuf_read ( a, buf, size );
369       if ( n == -1 )
370         n = 0;
371       if ( n )
372         {
373           if (fc->cipher_hd)
374             gcry_cipher_decrypt (fc->cipher_hd, buf, n, NULL, 0);
375         }
376       else
377         rc = -1; /* EOF */
378       *ret_len = n;
379     }
380   else if ( control == IOBUFCTRL_FREE )
381     {
382       release_dfx_context (fc);
383     }
384   else if ( control == IOBUFCTRL_DESC )
385     {
386       *(char**)buf = "decode_filter";
387     }
388   return rc;
389 }
390