gpg: Consider that gcry_mpi_get_opaque may return NULL.
[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'
244           || dfx->defer[1] != '\x14'
245           || datalen != 20
246           || memcmp (gcry_md_read (dfx->mdc_hash, 0), dfx->defer+2, datalen))
247         rc = gpg_error (GPG_ERR_BAD_SIGNATURE);
248       /* log_printhex("MDC message:", dfx->defer, 22); */
249       /* log_printhex("MDC calc:", gcry_md_read (dfx->mdc_hash,0), datalen); */
250     }
251
252
253  leave:
254   release_dfx_context (dfx);
255   return rc;
256 }
257
258
259
260 /* I think we should merge this with cipher_filter */
261 static int
262 mdc_decode_filter (void *opaque, int control, IOBUF a,
263                    byte *buf, size_t *ret_len)
264 {
265   decode_filter_ctx_t dfx = opaque;
266   size_t n, size = *ret_len;
267   int rc = 0;
268   int c;
269
270   if ( control == IOBUFCTRL_UNDERFLOW && dfx->eof_seen )
271     {
272       *ret_len = 0;
273       rc = -1;
274     }
275   else if( control == IOBUFCTRL_UNDERFLOW )
276     {
277       assert (a);
278       assert ( size > 44 );
279
280       /* Get at least 22 bytes and put it somewhere ahead in the buffer. */
281       for (n=22; n < 44 ; n++ )
282         {
283           if( (c = iobuf_get(a)) == -1 )
284             break;
285           buf[n] = c;
286         }
287       if ( n == 44 )
288         {
289           /* We have enough stuff - flush the deferred stuff.  */
290           /* (we asserted that the buffer is large enough) */
291           if ( !dfx->defer_filled )  /* First time. */
292             {
293               memcpy (buf, buf+22, 22 );
294               n = 22;
295             }
296           else
297             {
298               memcpy (buf, dfx->defer, 22 );
299             }
300           /* Now fill up. */
301           for (; n < size; n++ )
302             {
303               if ( (c = iobuf_get(a)) == -1 )
304                 break;
305               buf[n] = c;
306             }
307           /* Move the last 22 bytes back to the defer buffer. */
308           /* (right, we are wasting 22 bytes of the supplied buffer.) */
309           n -= 22;
310           memcpy (dfx->defer, buf+n, 22 );
311           dfx->defer_filled = 1;
312         }
313       else if ( !dfx->defer_filled )  /* EOF seen but empty defer buffer. */
314         {
315           /* This is bad because it means an incomplete hash. */
316           n -= 22;
317           memcpy (buf, buf+22, n );
318           dfx->eof_seen = 2; /* EOF with incomplete hash.  */
319         }
320       else  /* EOF seen (i.e. read less than 22 bytes). */
321         {
322           memcpy (buf, dfx->defer, 22 );
323           n -= 22;
324           memcpy (dfx->defer, buf+n, 22 );
325           dfx->eof_seen = 1; /* Normal EOF. */
326         }
327
328       if ( n )
329         {
330           if ( dfx->cipher_hd )
331             gcry_cipher_decrypt (dfx->cipher_hd, buf, n, NULL, 0);
332           if ( dfx->mdc_hash )
333             gcry_md_write (dfx->mdc_hash, buf, n);
334         }
335       else
336         {
337           assert ( dfx->eof_seen );
338           rc = -1; /* eof */
339         }
340       *ret_len = n;
341     }
342   else if ( control == IOBUFCTRL_FREE )
343     {
344       release_dfx_context (dfx);
345     }
346   else if ( control == IOBUFCTRL_DESC )
347     {
348       *(char**)buf = "mdc_decode_filter";
349     }
350   return rc;
351 }
352
353
354 static int
355 decode_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len)
356 {
357   decode_filter_ctx_t fc = opaque;
358   size_t n, size = *ret_len;
359   int rc = 0;
360
361   if ( control == IOBUFCTRL_UNDERFLOW )
362     {
363       assert(a);
364       n = iobuf_read ( a, buf, size );
365       if ( n == -1 )
366         n = 0;
367       if ( n )
368         {
369           if (fc->cipher_hd)
370             gcry_cipher_decrypt (fc->cipher_hd, buf, n, NULL, 0);
371         }
372       else
373         rc = -1; /* EOF */
374       *ret_len = n;
375     }
376   else if ( control == IOBUFCTRL_FREE )
377     {
378       release_dfx_context (fc);
379     }
380   else if ( control == IOBUFCTRL_DESC )
381     {
382       *(char**)buf = "decode_filter";
383     }
384   return rc;
385 }
386