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