Imported Upstream version 2.1.0
[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 <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 {
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)
78     {
79       /* Smells like a 3-des key.  This might happen because a SC has
80          already done the unpacking. */
81     }
82   else
83     {
84       if (n + 7 > seskeylen )
85         {
86           rc = gpg_error (GPG_ERR_INV_SESSION_KEY);
87           goto leave;
88         }
89
90       /* FIXME: Actually the leading zero is required but due to the way
91          we encode the output in libgcrypt as an MPI we are not able to
92          encode that leading zero.  However, when using a Smartcard we are
93          doing it the right way and therefore we have to skip the zero.  This
94          should be fixed in gpg-agent of course. */
95       if (!seskey[n])
96         n++;
97
98       if (seskey[n] != 2 )  /* Wrong block type version. */
99         {
100           rc = gpg_error (GPG_ERR_INV_SESSION_KEY);
101           goto leave;
102         }
103
104       for (n++; n < seskeylen && seskey[n]; n++) /* Skip the random bytes. */
105         ;
106       n++; /* and the zero byte */
107       if (n >= seskeylen )
108         {
109           rc = gpg_error (GPG_ERR_INV_SESSION_KEY);
110           goto leave;
111         }
112     }
113
114   if (DBG_CRYPTO)
115     log_printhex ("session key:", seskey+n, seskeylen-n);
116
117   rc = gcry_cipher_open (&parm->hd, parm->algo, parm->mode, 0);
118   if (rc)
119     {
120       log_error ("error creating decryptor: %s\n", gpg_strerror (rc));
121       goto leave;
122     }
123
124   rc = gcry_cipher_setkey (parm->hd, seskey+n, seskeylen-n);
125   if (gpg_err_code (rc) == GPG_ERR_WEAK_KEY)
126     {
127       log_info (_("WARNING: message was encrypted with "
128                   "a weak key in the symmetric cipher.\n"));
129       rc = 0;
130     }
131   if (rc)
132     {
133       log_error("key setup failed: %s\n", gpg_strerror(rc) );
134       goto leave;
135     }
136
137   gcry_cipher_setiv (parm->hd, parm->iv, parm->ivlen);
138
139  leave:
140   xfree (seskey);
141   return rc;
142 }
143
144
145 /* This function is called by the KSBA writer just before the actual
146    write is done.  The function must take INLEN bytes from INBUF,
147    decrypt it and store it inoutbuf which has a maximum size of
148    maxoutlen.  The valid bytes in outbuf should be return in outlen.
149    Due to different buffer sizes or different length of input and
150    output, it may happen that fewer bytes are processed or fewer bytes
151    are written. */
152 static gpg_error_t
153 decrypt_filter (void *arg,
154                 const void *inbuf, size_t inlen, size_t *inused,
155                 void *outbuf, size_t maxoutlen, size_t *outlen)
156 {
157   struct decrypt_filter_parm_s *parm = arg;
158   int blklen = parm->blklen;
159   size_t orig_inlen = inlen;
160
161   /* fixme: Should we issue an error when we have not seen one full block? */
162   if (!inlen)
163     return gpg_error (GPG_ERR_BUG);
164
165   if (maxoutlen < 2*parm->blklen)
166     return gpg_error (GPG_ERR_BUG);
167   /* Make some space because we will later need an extra block at the end.  */
168   maxoutlen -= blklen;
169
170   if (parm->helpblocklen)
171     {
172       int i, j;
173
174       for (i=parm->helpblocklen,j=0; i < blklen && j < inlen; i++, j++)
175         parm->helpblock[i] = ((const char*)inbuf)[j];
176       inlen -= j;
177       if (blklen > maxoutlen)
178         return gpg_error (GPG_ERR_BUG);
179       if (i < blklen)
180         {
181           parm->helpblocklen = i;
182           *outlen = 0;
183         }
184       else
185         {
186           parm->helpblocklen = 0;
187           if (parm->any_data)
188             {
189               memcpy (outbuf, parm->lastblock, blklen);
190               *outlen =blklen;
191             }
192           else
193             *outlen = 0;
194           gcry_cipher_decrypt (parm->hd, parm->lastblock, blklen,
195                                parm->helpblock, blklen);
196           parm->any_data = 1;
197         }
198       *inused = orig_inlen - inlen;
199       return 0;
200     }
201
202
203   if (inlen > maxoutlen)
204     inlen = maxoutlen;
205   if (inlen % blklen)
206     { /* store the remainder away */
207       parm->helpblocklen = inlen%blklen;
208       inlen = inlen/blklen*blklen;
209       memcpy (parm->helpblock, (const char*)inbuf+inlen, parm->helpblocklen);
210     }
211
212   *inused = inlen + parm->helpblocklen;
213   if (inlen)
214     {
215       assert (inlen >= blklen);
216       if (parm->any_data)
217         {
218           gcry_cipher_decrypt (parm->hd, (char*)outbuf+blklen, inlen,
219                                inbuf, inlen);
220           memcpy (outbuf, parm->lastblock, blklen);
221           memcpy (parm->lastblock,(char*)outbuf+inlen, blklen);
222           *outlen = inlen;
223         }
224       else
225         {
226           gcry_cipher_decrypt (parm->hd, outbuf, inlen, inbuf, inlen);
227           memcpy (parm->lastblock, (char*)outbuf+inlen-blklen, blklen);
228           *outlen = inlen - blklen;
229           parm->any_data = 1;
230         }
231     }
232   else
233     *outlen = 0;
234   return 0;
235 }
236
237
238 \f
239 /* Perform a decrypt operation.  */
240 int
241 gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp)
242 {
243   int rc;
244   Base64Context b64reader = NULL;
245   Base64Context b64writer = NULL;
246   ksba_reader_t reader;
247   ksba_writer_t writer;
248   ksba_cms_t cms = NULL;
249   ksba_stop_reason_t stopreason;
250   KEYDB_HANDLE kh;
251   int recp;
252   estream_t in_fp = NULL;
253   struct decrypt_filter_parm_s dfparm;
254
255   memset (&dfparm, 0, sizeof dfparm);
256
257   audit_set_type (ctrl->audit, AUDIT_TYPE_DECRYPT);
258
259   kh = keydb_new (0);
260   if (!kh)
261     {
262       log_error (_("failed to allocate keyDB handle\n"));
263       rc = gpg_error (GPG_ERR_GENERAL);
264       goto leave;
265     }
266
267   in_fp = es_fdopen_nc (in_fd, "rb");
268   if (!in_fp)
269     {
270       rc = gpg_error_from_syserror ();
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, &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   es_fclose (in_fp);
580   if (dfparm.hd)
581     gcry_cipher_close (dfparm.hd);
582   return rc;
583 }