Actually show translators comments in PO files
[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   rc = openpgp_cipher_test_algo (dek->algo);
108   if (rc)
109     goto leave;
110   blocksize = openpgp_cipher_get_algo_blklen (dek->algo);
111   if ( !blocksize || blocksize > 16 )
112     log_fatal ("unsupported blocksize %u\n", blocksize );
113   nprefix = blocksize;
114   if ( ed->len && ed->len < (nprefix+2) )
115     BUG();
116
117   if ( ed->mdc_method )
118     {
119       if (gcry_md_open (&dfx->mdc_hash, ed->mdc_method, 0 ))
120         BUG ();
121       if ( DBG_HASHING )
122         gcry_md_debug (dfx->mdc_hash, "checkmdc");
123     }
124
125   rc = openpgp_cipher_open (&dfx->cipher_hd, dek->algo,
126                             GCRY_CIPHER_MODE_CFB,
127                             (GCRY_CIPHER_SECURE
128                              | ((ed->mdc_method || dek->algo >= 100)?
129                                 0 : GCRY_CIPHER_ENABLE_SYNC)));
130   if (rc)
131     {
132       /* We should never get an error here cause we already checked
133        * that the algorithm is available.  */
134       BUG();
135     }
136
137
138   /* log_hexdump( "thekey", dek->key, dek->keylen );*/
139   rc = gcry_cipher_setkey (dfx->cipher_hd, dek->key, dek->keylen);
140   if ( gpg_err_code (rc) == GPG_ERR_WEAK_KEY )
141     {
142       log_info(_("WARNING: message was encrypted with"
143                  " a weak key in the symmetric cipher.\n"));
144       rc=0;
145     }
146   else if( rc )
147     {
148       log_error("key setup failed: %s\n", g10_errstr(rc) );
149       goto leave;
150     }
151
152   if (!ed->buf)
153     {
154       log_error(_("problem handling encrypted packet\n"));
155       goto leave;
156     }
157
158   gcry_cipher_setiv (dfx->cipher_hd, NULL, 0);
159
160   if ( ed->len )
161     {
162       for (i=0; i < (nprefix+2) && ed->len; i++, ed->len-- )
163         {
164           if ( (c=iobuf_get(ed->buf)) == -1 )
165             break;
166           else
167             temp[i] = c;
168         }
169     }
170   else
171     {
172       for (i=0; i < (nprefix+2); i++ )
173         if ( (c=iobuf_get(ed->buf)) == -1 )
174           break;
175         else
176           temp[i] = c;
177     }
178
179   gcry_cipher_decrypt (dfx->cipher_hd, temp, nprefix+2, NULL, 0);
180   gcry_cipher_sync (dfx->cipher_hd);
181   p = temp;
182   /* log_hexdump( "prefix", temp, nprefix+2 ); */
183   if (dek->symmetric
184       && (p[nprefix-2] != p[nprefix] || p[nprefix-1] != p[nprefix+1]) )
185     {
186       rc = gpg_error (GPG_ERR_BAD_KEY);
187       goto leave;
188     }
189
190   if ( dfx->mdc_hash )
191     gcry_md_write (dfx->mdc_hash, temp, nprefix+2);
192
193   dfx->refcount++;
194   if ( ed->mdc_method )
195     iobuf_push_filter ( ed->buf, mdc_decode_filter, dfx );
196   else
197     iobuf_push_filter ( ed->buf, decode_filter, dfx );
198
199   proc_packets ( procctx, ed->buf );
200   ed->buf = NULL;
201   if ( ed->mdc_method && dfx->eof_seen == 2 )
202     rc = gpg_error (GPG_ERR_INV_PACKET);
203   else if ( ed->mdc_method )
204     {
205       /* We used to let parse-packet.c handle the MDC packet but this
206          turned out to be a problem with compressed packets: With old
207          style packets there is no length information available and
208          the decompressor uses an implicit end.  However we can't know
209          this implicit end beforehand (:-) and thus may feed the
210          decompressor with more bytes than actually needed.  It would
211          be possible to unread the extra bytes but due to our weird
212          iobuf system any unread is non reliable due to filters
213          already popped off.  The easy and sane solution is to care
214          about the MDC packet only here and never pass it to the
215          packet parser.  Fortunatley the OpenPGP spec requires a
216          strict format for the MDC packet so that we know that 22
217          bytes are appended.  */
218       int datalen = gcry_md_get_algo_dlen (ed->mdc_method);
219
220       assert (dfx->cipher_hd);
221       assert (dfx->mdc_hash);
222       gcry_cipher_decrypt (dfx->cipher_hd, dfx->defer, 22, NULL, 0);
223       gcry_md_write (dfx->mdc_hash, dfx->defer, 2);
224       gcry_md_final (dfx->mdc_hash);
225
226       if (dfx->defer[0] != '\xd3' || dfx->defer[1] != '\x14' )
227         {
228           log_error("mdc_packet with invalid encoding\n");
229           rc = gpg_error (GPG_ERR_INV_PACKET);
230         }
231       else if (datalen != 20
232                || memcmp (gcry_md_read (dfx->mdc_hash, 0),
233                           dfx->defer+2,datalen ))
234         rc = gpg_error (GPG_ERR_BAD_SIGNATURE);
235       /* log_printhex("MDC message:", dfx->defer, 22); */
236       /* log_printhex("MDC calc:", gcry_md_read (dfx->mdc_hash,0), datalen); */
237     }
238
239
240  leave:
241   release_dfx_context (dfx);
242   return rc;
243 }
244
245
246
247 /* I think we should merge this with cipher_filter */
248 static int
249 mdc_decode_filter (void *opaque, int control, IOBUF a,
250                    byte *buf, size_t *ret_len)
251 {
252   decode_filter_ctx_t dfx = opaque;
253   size_t n, size = *ret_len;
254   int rc = 0;
255   int c;
256
257   if ( control == IOBUFCTRL_UNDERFLOW && dfx->eof_seen )
258     {
259       *ret_len = 0;
260       rc = -1;
261     }
262   else if( control == IOBUFCTRL_UNDERFLOW )
263     {
264       assert (a);
265       assert ( size > 44 );
266
267       /* Get at least 22 bytes and put it somewhere ahead in the buffer. */
268       for (n=22; n < 44 ; n++ )
269         {
270           if( (c = iobuf_get(a)) == -1 )
271             break;
272           buf[n] = c;
273         }
274       if ( n == 44 )
275         {
276           /* We have enough stuff - flush the deferred stuff.  */
277           /* (we asserted that the buffer is large enough) */
278           if ( !dfx->defer_filled )  /* First time. */
279             {
280               memcpy (buf, buf+22, 22 );
281               n = 22;
282             }
283           else
284             {
285               memcpy (buf, dfx->defer, 22 );
286             }
287           /* Now fill up. */
288           for (; n < size; n++ )
289             {
290               if ( (c = iobuf_get(a)) == -1 )
291                 break;
292               buf[n] = c;
293             }
294           /* Move the last 22 bytes back to the defer buffer. */
295           /* (right, we are wasting 22 bytes of the supplied buffer.) */
296           n -= 22;
297           memcpy (dfx->defer, buf+n, 22 );
298           dfx->defer_filled = 1;
299         }
300       else if ( !dfx->defer_filled )  /* EOF seen but empty defer buffer. */
301         {
302           /* This is bad because it means an incomplete hash. */
303           n -= 22;
304           memcpy (buf, buf+22, n );
305           dfx->eof_seen = 2; /* EOF with incomplete hash.  */
306         }
307       else  /* EOF seen (i.e. read less than 22 bytes). */
308         {
309           memcpy (buf, dfx->defer, 22 );
310           n -= 22;
311           memcpy (dfx->defer, buf+n, 22 );
312           dfx->eof_seen = 1; /* Normal EOF. */
313         }
314
315       if ( n )
316         {
317           if ( dfx->cipher_hd )
318             gcry_cipher_decrypt (dfx->cipher_hd, buf, n, NULL, 0);
319           if ( dfx->mdc_hash )
320             gcry_md_write (dfx->mdc_hash, buf, n);
321         }
322       else
323         {
324           assert ( dfx->eof_seen );
325           rc = -1; /* eof */
326         }
327       *ret_len = n;
328     }
329   else if ( control == IOBUFCTRL_FREE )
330     {
331       release_dfx_context (dfx);
332     }
333   else if ( control == IOBUFCTRL_DESC )
334     {
335       *(char**)buf = "mdc_decode_filter";
336     }
337   return rc;
338 }
339
340
341 static int
342 decode_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len)
343 {
344   decode_filter_ctx_t fc = opaque;
345   size_t n, size = *ret_len;
346   int rc = 0;
347
348   if ( control == IOBUFCTRL_UNDERFLOW )
349     {
350       assert(a);
351       n = iobuf_read ( a, buf, size );
352       if ( n == -1 )
353         n = 0;
354       if ( n )
355         {
356           if (fc->cipher_hd)
357             gcry_cipher_decrypt (fc->cipher_hd, buf, n, NULL, 0);
358         }
359       else
360         rc = -1; /* EOF */
361       *ret_len = n;
362     }
363   else if ( control == IOBUFCTRL_FREE )
364     {
365       release_dfx_context (fc);
366     }
367   else if ( control == IOBUFCTRL_DESC )
368     {
369       *(char**)buf = "decode_filter";
370     }
371   return rc;
372 }
373