Fixed backport of libassuan-2 changes.
[gnupg.git] / sm / decrypt.c
1 /* decrypt.c - Decrypt a message
2  *      Copyright (C) 2001, 2003 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <unistd.h> 
26 #include <time.h>
27 #include <assert.h>
28
29 #include "gpgsm.h"
30 #include <gcrypt.h>
31 #include <ksba.h>
32
33 #include "keydb.h"
34 #include "i18n.h"
35
36 struct decrypt_filter_parm_s {
37   int algo;
38   int mode;
39   int blklen;
40   gcry_cipher_hd_t hd;
41   char iv[16];
42   size_t ivlen;
43   int any_data;  /* dod we push anything through the filter at all? */
44   unsigned char lastblock[16];  /* to strip the padding we have to
45                                    keep this one */
46   char helpblock[16];  /* needed because there is no block buffering in
47                           libgcrypt (yet) */
48   int  helpblocklen;
49 };
50
51
52
53 /* Decrypt the session key and fill in the parm structure.  The
54    algo and the IV is expected to be already in PARM. */
55 static int 
56 prepare_decryption (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
57                     ksba_const_sexp_t enc_val,
58                     struct decrypt_filter_parm_s *parm)
59 {
60   char *seskey = NULL;
61   size_t n, seskeylen;
62   int rc;
63
64   rc = gpgsm_agent_pkdecrypt (ctrl, hexkeygrip, desc, enc_val,
65                               &seskey, &seskeylen);
66   if (rc)
67     {
68       log_error ("error decrypting session key: %s\n", gpg_strerror (rc));
69       goto leave;
70     }
71
72   if (DBG_CRYPTO)
73     log_printhex ("pkcs1 encoded session key:", seskey, seskeylen);
74
75   n=0;
76   if (seskeylen == 24)
77     {
78       /* Smells like a 3-des key.  This might happen because a SC has
79          already done the unpacking. */
80     }
81   else
82     {
83       if (n + 7 > seskeylen )
84         {
85           rc = gpg_error (GPG_ERR_INV_SESSION_KEY);
86           goto leave; 
87         }
88       
89       /* FIXME: Actually the leading zero is required but due to the way
90          we encode the output in libgcrypt as an MPI we are not able to
91          encode that leading zero.  However, when using a Smartcard we are
92          doing it the right way and therefore we have to skip the zero.  This
93          should be fixed in gpg-agent of course. */
94       if (!seskey[n])
95         n++;
96       
97       if (seskey[n] != 2 )  /* Wrong block type version. */
98         { 
99           rc = gpg_error (GPG_ERR_INV_SESSION_KEY);
100           goto leave; 
101         }
102       
103       for (n++; n < seskeylen && seskey[n]; n++) /* Skip the random bytes. */
104         ;
105       n++; /* and the zero byte */
106       if (n >= seskeylen )
107         { 
108           rc = gpg_error (GPG_ERR_INV_SESSION_KEY);
109           goto leave; 
110         }
111     }
112
113   if (DBG_CRYPTO)
114     log_printhex ("session key:", seskey+n, seskeylen-n);
115
116   rc = gcry_cipher_open (&parm->hd, parm->algo, parm->mode, 0);
117   if (rc)
118     {
119       log_error ("error creating decryptor: %s\n", gpg_strerror (rc));
120       goto leave;
121     }
122                         
123   rc = gcry_cipher_setkey (parm->hd, seskey+n, seskeylen-n);
124   if (gpg_err_code (rc) == GPG_ERR_WEAK_KEY)
125     {
126       log_info (_("WARNING: message was encrypted with "
127                   "a weak key in the symmetric cipher.\n"));
128       rc = 0;
129     }
130   if (rc)
131     {
132       log_error("key setup failed: %s\n", gpg_strerror(rc) );
133       goto leave;
134     }
135
136   gcry_cipher_setiv (parm->hd, parm->iv, parm->ivlen);
137
138  leave:
139   xfree (seskey);
140   return rc;
141 }
142
143
144 /* This function is called by the KSBA writer just before the actual
145    write is done.  The function must take INLEN bytes from INBUF,
146    decrypt it and store it inoutbuf which has a maximum size of
147    maxoutlen.  The valid bytes in outbuf should be return in outlen.
148    Due to different buffer sizes or different length of input and
149    output, it may happen that fewer bytes are processed or fewer bytes
150    are written. */
151 static gpg_error_t
152 decrypt_filter (void *arg,
153                 const void *inbuf, size_t inlen, size_t *inused,
154                 void *outbuf, size_t maxoutlen, size_t *outlen)
155 {
156   struct decrypt_filter_parm_s *parm = arg;
157   int blklen = parm->blklen;
158   size_t orig_inlen = inlen;
159
160   /* fixme: Should we issue an error when we have not seen one full block? */
161   if (!inlen)
162     return gpg_error (GPG_ERR_BUG);
163
164   if (maxoutlen < 2*parm->blklen)
165     return gpg_error (GPG_ERR_BUG);
166   /* Make some space because we will later need an extra block at the end.  */
167   maxoutlen -= blklen;
168
169   if (parm->helpblocklen)
170     {
171       int i, j;
172
173       for (i=parm->helpblocklen,j=0; i < blklen && j < inlen; i++, j++)
174         parm->helpblock[i] = ((const char*)inbuf)[j];
175       inlen -= j;
176       if (blklen > maxoutlen)
177         return gpg_error (GPG_ERR_BUG);
178       if (i < blklen)
179         {
180           parm->helpblocklen = i;
181           *outlen = 0;
182         }
183       else
184         {
185           parm->helpblocklen = 0;
186           if (parm->any_data)
187             {
188               memcpy (outbuf, parm->lastblock, blklen);
189               *outlen =blklen;
190             }
191           else
192             *outlen = 0;
193           gcry_cipher_decrypt (parm->hd, parm->lastblock, blklen,
194                                parm->helpblock, blklen);
195           parm->any_data = 1;
196         }
197       *inused = orig_inlen - inlen;
198       return 0;
199     }
200
201
202   if (inlen > maxoutlen)
203     inlen = maxoutlen;
204   if (inlen % blklen)
205     { /* store the remainder away */
206       parm->helpblocklen = inlen%blklen;
207       inlen = inlen/blklen*blklen;
208       memcpy (parm->helpblock, (const char*)inbuf+inlen, parm->helpblocklen);
209     }
210
211   *inused = inlen + parm->helpblocklen;
212   if (inlen)
213     {
214       assert (inlen >= blklen);
215       if (parm->any_data)
216         {
217           gcry_cipher_decrypt (parm->hd, (char*)outbuf+blklen, inlen,
218                                inbuf, inlen);
219           memcpy (outbuf, parm->lastblock, blklen);
220           memcpy (parm->lastblock,(char*)outbuf+inlen, blklen);
221           *outlen = inlen;
222         }
223       else
224         {
225           gcry_cipher_decrypt (parm->hd, outbuf, inlen, inbuf, inlen);
226           memcpy (parm->lastblock, (char*)outbuf+inlen-blklen, blklen);
227           *outlen = inlen - blklen;
228           parm->any_data = 1;
229         }
230     }
231   else
232     *outlen = 0;
233   return 0;
234 }
235
236
237 \f
238 /* Perform a decrypt operation.  */
239 int
240 gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp)
241 {
242   int rc;
243   Base64Context b64reader = NULL;
244   Base64Context b64writer = NULL;
245   ksba_reader_t reader;
246   ksba_writer_t writer;
247   ksba_cms_t cms = NULL;
248   ksba_stop_reason_t stopreason;
249   KEYDB_HANDLE kh;
250   int recp;
251   FILE *in_fp = NULL;
252   struct decrypt_filter_parm_s dfparm;
253
254   memset (&dfparm, 0, sizeof dfparm);
255
256   audit_set_type (ctrl->audit, AUDIT_TYPE_DECRYPT);
257
258   kh = keydb_new (0);
259   if (!kh)
260     {
261       log_error (_("failed to allocated keyDB handle\n"));
262       rc = gpg_error (GPG_ERR_GENERAL);
263       goto leave;
264     }
265
266
267   in_fp = fdopen ( dup (in_fd), "rb");
268   if (!in_fp)
269     {
270       rc = gpg_error (gpg_err_code_from_errno (errno));
271       log_error ("fdopen() failed: %s\n", strerror (errno));
272       goto leave;
273     }
274
275   rc = gpgsm_create_reader (&b64reader, ctrl, in_fp, 0, &reader);
276   if (rc)
277     {
278       log_error ("can't create reader: %s\n", gpg_strerror (rc));
279       goto leave;
280     }
281
282   rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, NULL, &writer);
283   if (rc)
284     {
285       log_error ("can't create writer: %s\n", gpg_strerror (rc));
286       goto leave;
287     }
288
289   rc = ksba_cms_new (&cms);
290   if (rc)
291     goto leave;
292
293   rc = ksba_cms_set_reader_writer (cms, reader, writer);
294   if (rc)
295     {
296       log_debug ("ksba_cms_set_reader_writer failed: %s\n",
297                  gpg_strerror (rc));
298       goto leave;
299     }
300
301   audit_log (ctrl->audit, AUDIT_SETUP_READY);
302
303   /* Parser loop. */
304   do 
305     {
306       rc = ksba_cms_parse (cms, &stopreason);
307       if (rc)
308         {
309           log_debug ("ksba_cms_parse failed: %s\n", gpg_strerror (rc));
310           goto leave;
311         }
312
313       if (stopreason == KSBA_SR_BEGIN_DATA
314           || stopreason == KSBA_SR_DETACHED_DATA)
315         {
316           int algo, mode;
317           const char *algoid;
318           int any_key = 0;
319           
320           audit_log (ctrl->audit, AUDIT_GOT_DATA);
321
322           algoid = ksba_cms_get_content_oid (cms, 2/* encryption algo*/);
323           algo = gcry_cipher_map_name (algoid);
324           mode = gcry_cipher_mode_from_oid (algoid);
325           if (!algo || !mode)
326             {
327               rc = gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
328               log_error ("unsupported algorithm `%s'\n", algoid? algoid:"?");
329               if (algoid && !strcmp (algoid, "1.2.840.113549.3.2"))
330                 log_info (_("(this is the RC2 algorithm)\n"));
331               else if (!algoid)
332                 log_info (_("(this does not seem to be an encrypted"
333                             " message)\n"));
334               {
335                 char numbuf[50];
336                 sprintf (numbuf, "%d", rc);
337                 gpgsm_status2 (ctrl, STATUS_ERROR, "decrypt.algorithm",
338                                numbuf, algoid?algoid:"?", NULL);
339                 audit_log_s (ctrl->audit, AUDIT_BAD_DATA_CIPHER_ALGO, algoid);
340               }
341
342               /* If it seems that this is not an encrypted message we
343                  return a more sensible error code. */
344               if (!algoid)
345                 rc = gpg_error (GPG_ERR_NO_DATA);
346
347               goto leave;
348             }
349
350           audit_log_i (ctrl->audit, AUDIT_DATA_CIPHER_ALGO, algo);
351           dfparm.algo = algo;
352           dfparm.mode = mode;
353           dfparm.blklen = gcry_cipher_get_algo_blklen (algo);
354           if (dfparm.blklen > sizeof (dfparm.helpblock))
355             return gpg_error (GPG_ERR_BUG);
356
357           rc = ksba_cms_get_content_enc_iv (cms,
358                                             dfparm.iv,
359                                             sizeof (dfparm.iv),
360                                             &dfparm.ivlen);
361           if (rc)
362             {
363               log_error ("error getting IV: %s\n", gpg_strerror (rc));
364               goto leave;
365             }
366           
367           for (recp=0; !any_key; recp++)
368             {
369               char *issuer;
370               ksba_sexp_t serial;
371               ksba_sexp_t enc_val;
372               char *hexkeygrip = NULL;
373               char *desc = NULL;
374               char kidbuf[16+1];
375
376               *kidbuf = 0;
377
378               rc = ksba_cms_get_issuer_serial (cms, recp, &issuer, &serial);
379               if (rc == -1 && recp)
380                 break; /* no more recipients */
381               audit_log_i (ctrl->audit, AUDIT_NEW_RECP, recp);
382               if (rc)
383                 log_error ("recp %d - error getting info: %s\n",
384                            recp, gpg_strerror (rc));
385               else
386                 {
387                   ksba_cert_t cert = NULL;
388
389                   log_debug ("recp %d - issuer: `%s'\n",
390                              recp, issuer? issuer:"[NONE]");
391                   log_debug ("recp %d - serial: ", recp);
392                   gpgsm_dump_serial (serial);
393                   log_printf ("\n");
394
395                   if (ctrl->audit)
396                     {
397                       char *tmpstr = gpgsm_format_sn_issuer (serial, issuer);
398                       audit_log_s (ctrl->audit, AUDIT_RECP_NAME, tmpstr);
399                       xfree (tmpstr);
400                     }
401
402                   keydb_search_reset (kh);
403                   rc = keydb_search_issuer_sn (kh, issuer, serial);
404                   if (rc)
405                     {
406                       log_error ("failed to find the certificate: %s\n",
407                                  gpg_strerror(rc));
408                       goto oops;
409                     }
410
411                   rc = keydb_get_cert (kh, &cert);
412                   if (rc)
413                     {
414                       log_error ("failed to get cert: %s\n", gpg_strerror (rc));
415                       goto oops;     
416                     }
417
418                   /* Print the ENC_TO status line.  Note that we can
419                      do so only if we have the certificate.  This is
420                      in contrast to gpg where the keyID is commonly
421                      included in the encrypted messages. It is too
422                      cumbersome to retrieve the used algorithm, thus
423                      we don't print it for now.  We also record the
424                      keyid for later use.  */
425                   {
426                     unsigned long kid[2];
427                     
428                     kid[0] = gpgsm_get_short_fingerprint (cert, kid+1);
429                     snprintf (kidbuf, sizeof kidbuf, "%08lX%08lX",
430                               kid[1], kid[0]);
431                     gpgsm_status2 (ctrl, STATUS_ENC_TO, 
432                                    kidbuf, "0", "0", NULL);
433                   }
434
435                   /* Put the certificate into the audit log.  */
436                   audit_log_cert (ctrl->audit, AUDIT_SAVE_CERT, cert, 0);
437
438                   /* Just in case there is a problem with the own
439                      certificate we print this message - should never
440                      happen of course */
441                   rc = gpgsm_cert_use_decrypt_p (cert);
442                   if (rc)
443                     {
444                       char numbuf[50];
445                       sprintf (numbuf, "%d", rc);
446                       gpgsm_status2 (ctrl, STATUS_ERROR, "decrypt.keyusage",
447                                      numbuf, NULL);
448                       rc = 0;
449                     }
450
451                   hexkeygrip = gpgsm_get_keygrip_hexstring (cert);
452                   desc = gpgsm_format_keydesc (cert);
453
454                 oops:
455                   xfree (issuer);
456                   xfree (serial);
457                   ksba_cert_release (cert);
458                 }
459
460               if (!hexkeygrip)
461                 ;
462               else if (!(enc_val = ksba_cms_get_enc_val (cms, recp)))
463                 log_error ("recp %d - error getting encrypted session key\n",
464                            recp);
465               else
466                 {
467                   rc = prepare_decryption (ctrl,
468                                            hexkeygrip, desc, enc_val, &dfparm);
469                   xfree (enc_val);
470                   if (rc)
471                     {
472                       log_info ("decrypting session key failed: %s\n",
473                                 gpg_strerror (rc));
474                       if (gpg_err_code (rc) == GPG_ERR_NO_SECKEY && *kidbuf)
475                         gpgsm_status2 (ctrl, STATUS_NO_SECKEY, kidbuf, NULL);
476                     }
477                   else
478                     { /* setup the bulk decrypter */
479                       any_key = 1;
480                       ksba_writer_set_filter (writer,
481                                               decrypt_filter,
482                                               &dfparm);
483                     }
484                   audit_log_ok (ctrl->audit, AUDIT_RECP_RESULT, rc);
485                 }
486               xfree (hexkeygrip);
487               xfree (desc);
488             }
489
490           /* If we write an audit log add the unused recipients to the
491              log as well.  */
492           if (ctrl->audit && any_key)
493             {
494               for (;; recp++)
495                 {
496                   char *issuer;
497                   ksba_sexp_t serial;
498                   int tmp_rc;
499
500                   tmp_rc = ksba_cms_get_issuer_serial (cms, recp,
501                                                        &issuer, &serial);
502                   if (tmp_rc == -1)
503                     break; /* no more recipients */
504                   audit_log_i (ctrl->audit, AUDIT_NEW_RECP, recp);
505                   if (tmp_rc)
506                     log_error ("recp %d - error getting info: %s\n",
507                                recp, gpg_strerror (rc));
508                   else
509                     {
510                       char *tmpstr = gpgsm_format_sn_issuer (serial, issuer);
511                       audit_log_s (ctrl->audit, AUDIT_RECP_NAME, tmpstr);
512                       xfree (tmpstr);
513                       xfree (issuer);
514                       xfree (serial);
515                     }
516                 }
517             }
518
519           if (!any_key)
520             {
521               rc = gpg_error (GPG_ERR_NO_SECKEY);
522               goto leave;
523             }
524         }
525       else if (stopreason == KSBA_SR_END_DATA)
526         {
527           ksba_writer_set_filter (writer, NULL, NULL);
528           if (dfparm.any_data)
529             { /* write the last block with padding removed */
530               int i, npadding = dfparm.lastblock[dfparm.blklen-1];
531               if (!npadding || npadding > dfparm.blklen)
532                 {
533                   log_error ("invalid padding with value %d\n", npadding);
534                   rc = gpg_error (GPG_ERR_INV_DATA);
535                   goto leave;
536                 }
537               rc = ksba_writer_write (writer,
538                                       dfparm.lastblock, 
539                                       dfparm.blklen - npadding);
540               if (rc)
541                 goto leave;
542
543               for (i=dfparm.blklen - npadding; i < dfparm.blklen; i++)
544                 {
545                   if (dfparm.lastblock[i] != npadding)
546                     {
547                       log_error ("inconsistent padding\n");
548                       rc = gpg_error (GPG_ERR_INV_DATA);
549                       goto leave;
550                     }
551                 }
552             }
553         }
554
555     }
556   while (stopreason != KSBA_SR_READY);   
557
558   rc = gpgsm_finish_writer (b64writer);
559   if (rc) 
560     {
561       log_error ("write failed: %s\n", gpg_strerror (rc));
562       goto leave;
563     }
564   gpgsm_status (ctrl, STATUS_DECRYPTION_OKAY, NULL);
565
566
567  leave:
568   audit_log_ok (ctrl->audit, AUDIT_DECRYPTION_RESULT, rc);
569   if (rc)
570     {
571       gpgsm_status (ctrl, STATUS_DECRYPTION_FAILED, NULL);
572       log_error ("message decryption failed: %s <%s>\n",
573                  gpg_strerror (rc), gpg_strsource (rc));
574     }
575   ksba_cms_release (cms);
576   gpgsm_destroy_reader (b64reader);
577   gpgsm_destroy_writer (b64writer);
578   keydb_release (kh); 
579   if (in_fp)
580     fclose (in_fp);
581   if (dfparm.hd)
582     gcry_cipher_close (dfparm.hd); 
583   return rc;
584 }
585
586