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