Line data Source code
1 : /* decrypt-data.c - Decrypt an encrypted data packet
2 : * Copyright (C) 1998, 1999, 2000, 2001, 2005,
3 : * 2006, 2009 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 :
26 : #include "gpg.h"
27 : #include "util.h"
28 : #include "packet.h"
29 : #include "options.h"
30 : #include "i18n.h"
31 : #include "status.h"
32 :
33 :
34 : static int mdc_decode_filter ( void *opaque, int control, IOBUF a,
35 : byte *buf, size_t *ret_len);
36 : static int decode_filter ( void *opaque, int control, IOBUF a,
37 : byte *buf, size_t *ret_len);
38 :
39 : typedef struct decode_filter_context_s
40 : {
41 : gcry_cipher_hd_t cipher_hd;
42 : gcry_md_hd_t mdc_hash;
43 : char defer[22];
44 : int defer_filled;
45 : int eof_seen;
46 : int refcount;
47 : int partial; /* Working on a partial length packet. */
48 : size_t length; /* If !partial: Remaining bytes in the packet. */
49 : } *decode_filter_ctx_t;
50 :
51 :
52 : /* Helper to release the decode context. */
53 : static void
54 962 : release_dfx_context (decode_filter_ctx_t dfx)
55 : {
56 962 : if (!dfx)
57 962 : return;
58 :
59 962 : log_assert (dfx->refcount);
60 962 : if ( !--dfx->refcount )
61 : {
62 481 : gcry_cipher_close (dfx->cipher_hd);
63 481 : dfx->cipher_hd = NULL;
64 481 : gcry_md_close (dfx->mdc_hash);
65 481 : dfx->mdc_hash = NULL;
66 481 : xfree (dfx);
67 : }
68 : }
69 :
70 :
71 :
72 : /****************
73 : * Decrypt the data, specified by ED with the key DEK.
74 : */
75 : int
76 481 : decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek)
77 : {
78 : decode_filter_ctx_t dfx;
79 : byte *p;
80 481 : int rc=0, c, i;
81 : byte temp[32];
82 : unsigned blocksize;
83 : unsigned nprefix;
84 :
85 481 : dfx = xtrycalloc (1, sizeof *dfx);
86 481 : if (!dfx)
87 0 : return gpg_error_from_syserror ();
88 481 : dfx->refcount = 1;
89 :
90 481 : if ( opt.verbose && !dek->algo_info_printed )
91 : {
92 0 : if (!openpgp_cipher_test_algo (dek->algo))
93 0 : log_info (_("%s encrypted data\n"),
94 0 : openpgp_cipher_algo_name (dek->algo));
95 : else
96 0 : log_info (_("encrypted with unknown algorithm %d\n"), dek->algo );
97 0 : dek->algo_info_printed = 1;
98 : }
99 :
100 : {
101 : char buf[20];
102 :
103 481 : snprintf (buf, sizeof buf, "%d %d", ed->mdc_method, dek->algo);
104 481 : write_status_text (STATUS_DECRYPTION_INFO, buf);
105 : }
106 :
107 481 : if (opt.show_session_key)
108 : {
109 : char numbuf[25];
110 : char *hexbuf;
111 :
112 0 : snprintf (numbuf, sizeof numbuf, "%d:", dek->algo);
113 0 : hexbuf = bin2hex (dek->key, dek->keylen, NULL);
114 0 : if (!hexbuf)
115 : {
116 0 : rc = gpg_error_from_syserror ();
117 0 : goto leave;
118 : }
119 0 : log_info ("session key: '%s%s'\n", numbuf, hexbuf);
120 0 : write_status_strings (STATUS_SESSION_KEY, numbuf, hexbuf, NULL);
121 0 : xfree (hexbuf);
122 : }
123 :
124 481 : rc = openpgp_cipher_test_algo (dek->algo);
125 481 : if (rc)
126 0 : goto leave;
127 481 : blocksize = openpgp_cipher_get_algo_blklen (dek->algo);
128 481 : if ( !blocksize || blocksize > 16 )
129 0 : log_fatal ("unsupported blocksize %u\n", blocksize );
130 481 : nprefix = blocksize;
131 481 : if ( ed->len && ed->len < (nprefix+2) )
132 : {
133 : /* An invalid message. We can't check that during parsing
134 : because we may not know the used cipher then. */
135 0 : rc = gpg_error (GPG_ERR_INV_PACKET);
136 0 : goto leave;
137 : }
138 :
139 481 : if ( ed->mdc_method )
140 : {
141 421 : if (gcry_md_open (&dfx->mdc_hash, ed->mdc_method, 0 ))
142 0 : BUG ();
143 421 : if ( DBG_HASHING )
144 0 : gcry_md_debug (dfx->mdc_hash, "checkmdc");
145 : }
146 :
147 481 : rc = openpgp_cipher_open (&dfx->cipher_hd, dek->algo,
148 : GCRY_CIPHER_MODE_CFB,
149 : (GCRY_CIPHER_SECURE
150 : | ((ed->mdc_method || dek->algo >= 100)?
151 : 0 : GCRY_CIPHER_ENABLE_SYNC)));
152 481 : if (rc)
153 : {
154 : /* We should never get an error here cause we already checked
155 : * that the algorithm is available. */
156 0 : BUG();
157 : }
158 :
159 :
160 : /* log_hexdump( "thekey", dek->key, dek->keylen );*/
161 481 : rc = gcry_cipher_setkey (dfx->cipher_hd, dek->key, dek->keylen);
162 481 : if ( gpg_err_code (rc) == GPG_ERR_WEAK_KEY )
163 : {
164 0 : log_info(_("WARNING: message was encrypted with"
165 : " a weak key in the symmetric cipher.\n"));
166 0 : rc=0;
167 : }
168 481 : else if( rc )
169 : {
170 0 : log_error("key setup failed: %s\n", gpg_strerror (rc) );
171 0 : goto leave;
172 : }
173 :
174 481 : if (!ed->buf)
175 : {
176 0 : log_error(_("problem handling encrypted packet\n"));
177 0 : goto leave;
178 : }
179 :
180 481 : gcry_cipher_setiv (dfx->cipher_hd, NULL, 0);
181 :
182 481 : if ( ed->len )
183 : {
184 3382 : for (i=0; i < (nprefix+2) && ed->len; i++, ed->len-- )
185 : {
186 3172 : if ( (c=iobuf_get(ed->buf)) == -1 )
187 0 : break;
188 : else
189 3172 : temp[i] = c;
190 : }
191 : }
192 : else
193 : {
194 4477 : for (i=0; i < (nprefix+2); i++ )
195 4206 : if ( (c=iobuf_get(ed->buf)) == -1 )
196 0 : break;
197 : else
198 4206 : temp[i] = c;
199 : }
200 :
201 481 : gcry_cipher_decrypt (dfx->cipher_hd, temp, nprefix+2, NULL, 0);
202 481 : gcry_cipher_sync (dfx->cipher_hd);
203 481 : p = temp;
204 : /* log_hexdump( "prefix", temp, nprefix+2 ); */
205 481 : if (dek->symmetric
206 222 : && (p[nprefix-2] != p[nprefix] || p[nprefix-1] != p[nprefix+1]) )
207 : {
208 0 : rc = gpg_error (GPG_ERR_BAD_KEY);
209 0 : goto leave;
210 : }
211 :
212 481 : if ( dfx->mdc_hash )
213 421 : gcry_md_write (dfx->mdc_hash, temp, nprefix+2);
214 :
215 481 : dfx->refcount++;
216 481 : dfx->partial = ed->is_partial;
217 481 : dfx->length = ed->len;
218 481 : if ( ed->mdc_method )
219 421 : iobuf_push_filter ( ed->buf, mdc_decode_filter, dfx );
220 : else
221 60 : iobuf_push_filter ( ed->buf, decode_filter, dfx );
222 :
223 481 : if (opt.unwrap_encryption)
224 : {
225 : char *filename;
226 : estream_t fp;
227 0 : rc = get_output_file ("", 0, ed->buf, &filename, &fp);
228 0 : if (! rc)
229 : {
230 0 : iobuf_t output = iobuf_esopen (fp, "w", 0);
231 0 : armor_filter_context_t *afx = NULL;
232 :
233 0 : if (opt.armor)
234 : {
235 0 : afx = new_armor_context ();
236 0 : push_armor_filter (afx, output);
237 : }
238 :
239 0 : iobuf_copy (output, ed->buf);
240 0 : if ((rc = iobuf_error (ed->buf)))
241 0 : log_error (_("error reading '%s': %s\n"),
242 : filename, gpg_strerror (rc));
243 0 : else if ((rc = iobuf_error (output)))
244 0 : log_error (_("error writing '%s': %s\n"),
245 : filename, gpg_strerror (rc));
246 :
247 0 : iobuf_close (output);
248 0 : if (afx)
249 0 : release_armor_context (afx);
250 : }
251 : }
252 : else
253 481 : proc_packets (ctrl, procctx, ed->buf );
254 :
255 481 : ed->buf = NULL;
256 481 : if (dfx->eof_seen > 1 )
257 0 : rc = gpg_error (GPG_ERR_INV_PACKET);
258 481 : else if ( ed->mdc_method )
259 : {
260 : /* We used to let parse-packet.c handle the MDC packet but this
261 : turned out to be a problem with compressed packets: With old
262 : style packets there is no length information available and
263 : the decompressor uses an implicit end. However we can't know
264 : this implicit end beforehand (:-) and thus may feed the
265 : decompressor with more bytes than actually needed. It would
266 : be possible to unread the extra bytes but due to our weird
267 : iobuf system any unread is non reliable due to filters
268 : already popped off. The easy and sane solution is to care
269 : about the MDC packet only here and never pass it to the
270 : packet parser. Fortunatley the OpenPGP spec requires a
271 : strict format for the MDC packet so that we know that 22
272 : bytes are appended. */
273 421 : int datalen = gcry_md_get_algo_dlen (ed->mdc_method);
274 :
275 421 : log_assert (dfx->cipher_hd);
276 421 : log_assert (dfx->mdc_hash);
277 421 : gcry_cipher_decrypt (dfx->cipher_hd, dfx->defer, 22, NULL, 0);
278 421 : gcry_md_write (dfx->mdc_hash, dfx->defer, 2);
279 421 : gcry_md_final (dfx->mdc_hash);
280 :
281 421 : if ( dfx->defer[0] != '\xd3'
282 421 : || dfx->defer[1] != '\x14'
283 421 : || datalen != 20
284 421 : || memcmp (gcry_md_read (dfx->mdc_hash, 0), dfx->defer+2, datalen))
285 0 : rc = gpg_error (GPG_ERR_BAD_SIGNATURE);
286 : /* log_printhex("MDC message:", dfx->defer, 22); */
287 : /* log_printhex("MDC calc:", gcry_md_read (dfx->mdc_hash,0), datalen); */
288 : }
289 :
290 :
291 : leave:
292 481 : release_dfx_context (dfx);
293 481 : return rc;
294 : }
295 :
296 :
297 :
298 : static int
299 2285 : mdc_decode_filter (void *opaque, int control, IOBUF a,
300 : byte *buf, size_t *ret_len)
301 : {
302 2285 : decode_filter_ctx_t dfx = opaque;
303 2285 : size_t n, size = *ret_len;
304 2285 : int rc = 0;
305 : int c;
306 :
307 : /* Note: We need to distinguish between a partial and a fixed length
308 : packet. The first is the usual case as created by GPG. However
309 : for short messages the format degrades to a fixed length packet
310 : and other implementations might use fixed length as well. Only
311 : looking for the EOF on fixed data works only if the encrypted
312 : packet is not followed by other data. This used to be a long
313 : standing bug which was fixed on 2009-10-02. */
314 :
315 2285 : if ( control == IOBUFCTRL_UNDERFLOW && dfx->eof_seen )
316 : {
317 421 : *ret_len = 0;
318 421 : rc = -1;
319 : }
320 1864 : else if( control == IOBUFCTRL_UNDERFLOW )
321 : {
322 1022 : log_assert (a);
323 1022 : log_assert (size > 44); /* Our code requires at least this size. */
324 :
325 : /* Get at least 22 bytes and put it ahead in the buffer. */
326 1022 : if (dfx->partial)
327 : {
328 18929 : for (n=22; n < 44; n++)
329 : {
330 18106 : if ( (c = iobuf_get(a)) == -1 )
331 0 : break;
332 18106 : buf[n] = c;
333 : }
334 : }
335 : else
336 : {
337 4577 : for (n=22; n < 44 && dfx->length; n++, dfx->length--)
338 : {
339 4378 : c = iobuf_get (a);
340 4378 : if (c == -1)
341 0 : break; /* Premature EOF. */
342 4378 : buf[n] = c;
343 : }
344 : }
345 1022 : if (n == 44)
346 : {
347 : /* We have enough stuff - flush the deferred stuff. */
348 1022 : if ( !dfx->defer_filled ) /* First time. */
349 : {
350 421 : memcpy (buf, buf+22, 22);
351 421 : n = 22;
352 : }
353 : else
354 : {
355 601 : memcpy (buf, dfx->defer, 22);
356 : }
357 : /* Fill up the buffer. */
358 1022 : if (dfx->partial)
359 : {
360 5551239 : for (; n < size; n++ )
361 : {
362 5550638 : if ( (c = iobuf_get(a)) == -1 )
363 : {
364 222 : dfx->eof_seen = 1; /* Normal EOF. */
365 222 : break;
366 : }
367 5550416 : buf[n] = c;
368 : }
369 : }
370 : else
371 : {
372 9568 : for (; n < size && dfx->length; n++, dfx->length--)
373 : {
374 9369 : c = iobuf_get(a);
375 9369 : if (c == -1)
376 : {
377 0 : dfx->eof_seen = 3; /* Premature EOF. */
378 0 : break;
379 : }
380 9369 : buf[n] = c;
381 : }
382 199 : if (!dfx->length)
383 199 : dfx->eof_seen = 1; /* Normal EOF. */
384 : }
385 :
386 : /* Move the trailing 22 bytes back to the defer buffer. We
387 : have at least 44 bytes thus a memmove is not needed. */
388 1022 : n -= 22;
389 1022 : memcpy (dfx->defer, buf+n, 22 );
390 1022 : dfx->defer_filled = 1;
391 : }
392 0 : else if ( !dfx->defer_filled ) /* EOF seen but empty defer buffer. */
393 : {
394 : /* This is bad because it means an incomplete hash. */
395 0 : n -= 22;
396 0 : memcpy (buf, buf+22, n );
397 0 : dfx->eof_seen = 2; /* EOF with incomplete hash. */
398 : }
399 : else /* EOF seen (i.e. read less than 22 bytes). */
400 : {
401 0 : memcpy (buf, dfx->defer, 22 );
402 0 : n -= 22;
403 0 : memcpy (dfx->defer, buf+n, 22 );
404 0 : dfx->eof_seen = 1; /* Normal EOF. */
405 : }
406 :
407 1022 : if ( n )
408 : {
409 1022 : if ( dfx->cipher_hd )
410 1022 : gcry_cipher_decrypt (dfx->cipher_hd, buf, n, NULL, 0);
411 1022 : if ( dfx->mdc_hash )
412 1022 : gcry_md_write (dfx->mdc_hash, buf, n);
413 : }
414 : else
415 : {
416 0 : log_assert ( dfx->eof_seen );
417 0 : rc = -1; /* Return EOF. */
418 : }
419 1022 : *ret_len = n;
420 : }
421 842 : else if ( control == IOBUFCTRL_FREE )
422 : {
423 421 : release_dfx_context (dfx);
424 : }
425 421 : else if ( control == IOBUFCTRL_DESC )
426 : {
427 0 : mem2str (buf, "mdc_decode_filter", *ret_len);
428 : }
429 2285 : return rc;
430 : }
431 :
432 :
433 : static int
434 384 : decode_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len)
435 : {
436 384 : decode_filter_ctx_t fc = opaque;
437 384 : size_t size = *ret_len;
438 : size_t n;
439 384 : int c, rc = 0;
440 :
441 :
442 384 : if ( control == IOBUFCTRL_UNDERFLOW && fc->eof_seen )
443 : {
444 60 : *ret_len = 0;
445 60 : rc = -1;
446 : }
447 324 : else if ( control == IOBUFCTRL_UNDERFLOW )
448 : {
449 204 : log_assert (a);
450 :
451 204 : if (fc->partial)
452 : {
453 1315288 : for (n=0; n < size; n++ )
454 : {
455 1315144 : c = iobuf_get(a);
456 1315144 : if (c == -1)
457 : {
458 49 : fc->eof_seen = 1; /* Normal EOF. */
459 49 : break;
460 : }
461 1315095 : buf[n] = c;
462 : }
463 : }
464 : else
465 : {
466 534 : for (n=0; n < size && fc->length; n++, fc->length--)
467 : {
468 523 : c = iobuf_get(a);
469 523 : if (c == -1)
470 : {
471 0 : fc->eof_seen = 3; /* Premature EOF. */
472 0 : break;
473 : }
474 523 : buf[n] = c;
475 : }
476 11 : if (!fc->length)
477 11 : fc->eof_seen = 1; /* Normal EOF. */
478 : }
479 204 : if (n)
480 : {
481 204 : if (fc->cipher_hd)
482 204 : gcry_cipher_decrypt (fc->cipher_hd, buf, n, NULL, 0);
483 : }
484 : else
485 : {
486 0 : if (!fc->eof_seen)
487 0 : fc->eof_seen = 1;
488 0 : rc = -1; /* Return EOF. */
489 : }
490 204 : *ret_len = n;
491 : }
492 120 : else if ( control == IOBUFCTRL_FREE )
493 : {
494 60 : release_dfx_context (fc);
495 : }
496 60 : else if ( control == IOBUFCTRL_DESC )
497 : {
498 0 : mem2str (buf, "decode_filter", *ret_len);
499 : }
500 384 : return rc;
501 : }
|