Imported Upstream version 2.1.23
[platform/upstream/gpg2.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 (_("cipher algorithm '%s'"
365                            " may not be used 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,
485                                               PK_USE_DECRYPTION,
486                                               pk_algo, NULL, nbits, NULL))
487                       {
488                         char  kidstr[10+1];
489
490                         snprintf (kidstr, sizeof kidstr, "0x%08lX",
491                                   gpgsm_get_short_fingerprint (cert, NULL));
492                         log_info
493                           (_("key %s is not suitable for decryption"
494                              " in %s mode\n"),
495                            kidstr,
496                            gnupg_compliance_option_string (opt.compliance));
497                         rc = gpg_error (GPG_ERR_PUBKEY_ALGO);
498                         goto oops;
499                       }
500
501                     /* Check that all certs are compliant with CO_DE_VS.  */
502                     is_de_vs =
503                       (is_de_vs
504                        && gnupg_pk_is_compliant (CO_DE_VS, pk_algo, NULL,
505                                                  nbits, NULL));
506                   }
507
508                 oops:
509                   if (rc)
510                     {
511                       /* We cannot check compliance of certs that we
512                        * don't have.  */
513                       is_de_vs = 0;
514                     }
515                   xfree (issuer);
516                   xfree (serial);
517                   ksba_cert_release (cert);
518                 }
519
520               if (!hexkeygrip)
521                 ;
522               else if (!(enc_val = ksba_cms_get_enc_val (cms, recp)))
523                 log_error ("recp %d - error getting encrypted session key\n",
524                            recp);
525               else
526                 {
527                   rc = prepare_decryption (ctrl,
528                                            hexkeygrip, desc, enc_val, &dfparm);
529                   xfree (enc_val);
530                   if (rc)
531                     {
532                       log_info ("decrypting session key failed: %s\n",
533                                 gpg_strerror (rc));
534                       if (gpg_err_code (rc) == GPG_ERR_NO_SECKEY && *kidbuf)
535                         gpgsm_status2 (ctrl, STATUS_NO_SECKEY, kidbuf, NULL);
536                     }
537                   else
538                     { /* setup the bulk decrypter */
539                       any_key = 1;
540                       ksba_writer_set_filter (writer,
541                                               decrypt_filter,
542                                               &dfparm);
543
544                       if (is_de_vs)
545                         gpgsm_status (ctrl, STATUS_DECRYPTION_COMPLIANCE_MODE,
546                                       gnupg_status_compliance_flag (CO_DE_VS));
547
548                     }
549                   audit_log_ok (ctrl->audit, AUDIT_RECP_RESULT, rc);
550                 }
551               xfree (hexkeygrip);
552               xfree (desc);
553             }
554
555           /* If we write an audit log add the unused recipients to the
556              log as well.  */
557           if (ctrl->audit && any_key)
558             {
559               for (;; recp++)
560                 {
561                   char *issuer;
562                   ksba_sexp_t serial;
563                   int tmp_rc;
564
565                   tmp_rc = ksba_cms_get_issuer_serial (cms, recp,
566                                                        &issuer, &serial);
567                   if (tmp_rc == -1)
568                     break; /* no more recipients */
569                   audit_log_i (ctrl->audit, AUDIT_NEW_RECP, recp);
570                   if (tmp_rc)
571                     log_error ("recp %d - error getting info: %s\n",
572                                recp, gpg_strerror (rc));
573                   else
574                     {
575                       char *tmpstr = gpgsm_format_sn_issuer (serial, issuer);
576                       audit_log_s (ctrl->audit, AUDIT_RECP_NAME, tmpstr);
577                       xfree (tmpstr);
578                       xfree (issuer);
579                       xfree (serial);
580                     }
581                 }
582             }
583
584           if (!any_key)
585             {
586               rc = gpg_error (GPG_ERR_NO_SECKEY);
587               goto leave;
588             }
589         }
590       else if (stopreason == KSBA_SR_END_DATA)
591         {
592           ksba_writer_set_filter (writer, NULL, NULL);
593           if (dfparm.any_data)
594             { /* write the last block with padding removed */
595               int i, npadding = dfparm.lastblock[dfparm.blklen-1];
596               if (!npadding || npadding > dfparm.blklen)
597                 {
598                   log_error ("invalid padding with value %d\n", npadding);
599                   rc = gpg_error (GPG_ERR_INV_DATA);
600                   goto leave;
601                 }
602               rc = ksba_writer_write (writer,
603                                       dfparm.lastblock,
604                                       dfparm.blklen - npadding);
605               if (rc)
606                 goto leave;
607
608               for (i=dfparm.blklen - npadding; i < dfparm.blklen; i++)
609                 {
610                   if (dfparm.lastblock[i] != npadding)
611                     {
612                       log_error ("inconsistent padding\n");
613                       rc = gpg_error (GPG_ERR_INV_DATA);
614                       goto leave;
615                     }
616                 }
617             }
618         }
619
620     }
621   while (stopreason != KSBA_SR_READY);
622
623   rc = gnupg_ksba_finish_writer (b64writer);
624   if (rc)
625     {
626       log_error ("write failed: %s\n", gpg_strerror (rc));
627       goto leave;
628     }
629   gpgsm_status (ctrl, STATUS_DECRYPTION_OKAY, NULL);
630
631
632  leave:
633   audit_log_ok (ctrl->audit, AUDIT_DECRYPTION_RESULT, rc);
634   if (rc)
635     {
636       gpgsm_status (ctrl, STATUS_DECRYPTION_FAILED, NULL);
637       log_error ("message decryption failed: %s <%s>\n",
638                  gpg_strerror (rc), gpg_strsource (rc));
639     }
640   ksba_cms_release (cms);
641   gnupg_ksba_destroy_reader (b64reader);
642   gnupg_ksba_destroy_writer (b64writer);
643   keydb_release (kh);
644   es_fclose (in_fp);
645   if (dfparm.hd)
646     gcry_cipher_close (dfparm.hd);
647   return rc;
648 }