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