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