chiark / gitweb /
dirmngr: Fix for --disable-libdns usage.
[gnupg2.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 = gpgsm_create_reader (&b64reader, ctrl, in_fp, 0, &reader);
278   if (rc)
279     {
280       log_error ("can't create reader: %s\n", gpg_strerror (rc));
281       goto leave;
282     }
283
284   rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
285   if (rc)
286     {
287       log_error ("can't create writer: %s\n", gpg_strerror (rc));
288       goto leave;
289     }
290
291   rc = ksba_cms_new (&cms);
292   if (rc)
293     goto leave;
294
295   rc = ksba_cms_set_reader_writer (cms, reader, writer);
296   if (rc)
297     {
298       log_debug ("ksba_cms_set_reader_writer failed: %s\n",
299                  gpg_strerror (rc));
300       goto leave;
301     }
302
303   audit_log (ctrl->audit, AUDIT_SETUP_READY);
304
305   /* Parser loop. */
306   do
307     {
308       rc = ksba_cms_parse (cms, &stopreason);
309       if (rc)
310         {
311           log_debug ("ksba_cms_parse failed: %s\n", gpg_strerror (rc));
312           goto leave;
313         }
314
315       if (stopreason == KSBA_SR_BEGIN_DATA
316           || stopreason == KSBA_SR_DETACHED_DATA)
317         {
318           int algo, mode;
319           const char *algoid;
320           int any_key = 0;
321
322           audit_log (ctrl->audit, AUDIT_GOT_DATA);
323
324           algoid = ksba_cms_get_content_oid (cms, 2/* encryption algo*/);
325           algo = gcry_cipher_map_name (algoid);
326           mode = gcry_cipher_mode_from_oid (algoid);
327           if (!algo || !mode)
328             {
329               rc = gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
330               log_error ("unsupported algorithm '%s'\n", algoid? algoid:"?");
331               if (algoid && !strcmp (algoid, "1.2.840.113549.3.2"))
332                 log_info (_("(this is the RC2 algorithm)\n"));
333               else if (!algoid)
334                 log_info (_("(this does not seem to be an encrypted"
335                             " message)\n"));
336               {
337                 char numbuf[50];
338                 sprintf (numbuf, "%d", rc);
339                 gpgsm_status2 (ctrl, STATUS_ERROR, "decrypt.algorithm",
340                                numbuf, algoid?algoid:"?", NULL);
341                 audit_log_s (ctrl->audit, AUDIT_BAD_DATA_CIPHER_ALGO, algoid);
342               }
343
344               /* If it seems that this is not an encrypted message we
345                  return a more sensible error code. */
346               if (!algoid)
347                 rc = gpg_error (GPG_ERR_NO_DATA);
348
349               goto leave;
350             }
351
352           audit_log_i (ctrl->audit, AUDIT_DATA_CIPHER_ALGO, algo);
353           dfparm.algo = algo;
354           dfparm.mode = mode;
355           dfparm.blklen = gcry_cipher_get_algo_blklen (algo);
356           if (dfparm.blklen > sizeof (dfparm.helpblock))
357             return gpg_error (GPG_ERR_BUG);
358
359           rc = ksba_cms_get_content_enc_iv (cms,
360                                             dfparm.iv,
361                                             sizeof (dfparm.iv),
362                                             &dfparm.ivlen);
363           if (rc)
364             {
365               log_error ("error getting IV: %s\n", gpg_strerror (rc));
366               goto leave;
367             }
368
369           for (recp=0; !any_key; recp++)
370             {
371               char *issuer;
372               ksba_sexp_t serial;
373               ksba_sexp_t enc_val;
374               char *hexkeygrip = NULL;
375               char *desc = NULL;
376               char kidbuf[16+1];
377
378               *kidbuf = 0;
379
380               rc = ksba_cms_get_issuer_serial (cms, recp, &issuer, &serial);
381               if (rc == -1 && recp)
382                 break; /* no more recipients */
383               audit_log_i (ctrl->audit, AUDIT_NEW_RECP, recp);
384               if (rc)
385                 log_error ("recp %d - error getting info: %s\n",
386                            recp, gpg_strerror (rc));
387               else
388                 {
389                   ksba_cert_t cert = NULL;
390
391                   log_debug ("recp %d - issuer: '%s'\n",
392                              recp, issuer? issuer:"[NONE]");
393                   log_debug ("recp %d - serial: ", recp);
394                   gpgsm_dump_serial (serial);
395                   log_printf ("\n");
396
397                   if (ctrl->audit)
398                     {
399                       char *tmpstr = gpgsm_format_sn_issuer (serial, issuer);
400                       audit_log_s (ctrl->audit, AUDIT_RECP_NAME, tmpstr);
401                       xfree (tmpstr);
402                     }
403
404                   keydb_search_reset (kh);
405                   rc = keydb_search_issuer_sn (ctrl, kh, issuer, serial);
406                   if (rc)
407                     {
408                       log_error ("failed to find the certificate: %s\n",
409                                  gpg_strerror(rc));
410                       goto oops;
411                     }
412
413                   rc = keydb_get_cert (kh, &cert);
414                   if (rc)
415                     {
416                       log_error ("failed to get cert: %s\n", gpg_strerror (rc));
417                       goto oops;
418                     }
419
420                   /* Print the ENC_TO status line.  Note that we can
421                      do so only if we have the certificate.  This is
422                      in contrast to gpg where the keyID is commonly
423                      included in the encrypted messages. It is too
424                      cumbersome to retrieve the used algorithm, thus
425                      we don't print it for now.  We also record the
426                      keyid for later use.  */
427                   {
428                     unsigned long kid[2];
429
430                     kid[0] = gpgsm_get_short_fingerprint (cert, kid+1);
431                     snprintf (kidbuf, sizeof kidbuf, "%08lX%08lX",
432                               kid[1], kid[0]);
433                     gpgsm_status2 (ctrl, STATUS_ENC_TO,
434                                    kidbuf, "0", "0", NULL);
435                   }
436
437                   /* Put the certificate into the audit log.  */
438                   audit_log_cert (ctrl->audit, AUDIT_SAVE_CERT, cert, 0);
439
440                   /* Just in case there is a problem with the own
441                      certificate we print this message - should never
442                      happen of course */
443                   rc = gpgsm_cert_use_decrypt_p (cert);
444                   if (rc)
445                     {
446                       char numbuf[50];
447                       sprintf (numbuf, "%d", rc);
448                       gpgsm_status2 (ctrl, STATUS_ERROR, "decrypt.keyusage",
449                                      numbuf, NULL);
450                       rc = 0;
451                     }
452
453                   hexkeygrip = gpgsm_get_keygrip_hexstring (cert);
454                   desc = gpgsm_format_keydesc (cert);
455
456                 oops:
457                   xfree (issuer);
458                   xfree (serial);
459                   ksba_cert_release (cert);
460                 }
461
462               if (!hexkeygrip)
463                 ;
464               else if (!(enc_val = ksba_cms_get_enc_val (cms, recp)))
465                 log_error ("recp %d - error getting encrypted session key\n",
466                            recp);
467               else
468                 {
469                   rc = prepare_decryption (ctrl,
470                                            hexkeygrip, desc, enc_val, &dfparm);
471                   xfree (enc_val);
472                   if (rc)
473                     {
474                       log_info ("decrypting session key failed: %s\n",
475                                 gpg_strerror (rc));
476                       if (gpg_err_code (rc) == GPG_ERR_NO_SECKEY && *kidbuf)
477                         gpgsm_status2 (ctrl, STATUS_NO_SECKEY, kidbuf, NULL);
478                     }
479                   else
480                     { /* setup the bulk decrypter */
481                       any_key = 1;
482                       ksba_writer_set_filter (writer,
483                                               decrypt_filter,
484                                               &dfparm);
485                     }
486                   audit_log_ok (ctrl->audit, AUDIT_RECP_RESULT, rc);
487                 }
488               xfree (hexkeygrip);
489               xfree (desc);
490             }
491
492           /* If we write an audit log add the unused recipients to the
493              log as well.  */
494           if (ctrl->audit && any_key)
495             {
496               for (;; recp++)
497                 {
498                   char *issuer;
499                   ksba_sexp_t serial;
500                   int tmp_rc;
501
502                   tmp_rc = ksba_cms_get_issuer_serial (cms, recp,
503                                                        &issuer, &serial);
504                   if (tmp_rc == -1)
505                     break; /* no more recipients */
506                   audit_log_i (ctrl->audit, AUDIT_NEW_RECP, recp);
507                   if (tmp_rc)
508                     log_error ("recp %d - error getting info: %s\n",
509                                recp, gpg_strerror (rc));
510                   else
511                     {
512                       char *tmpstr = gpgsm_format_sn_issuer (serial, issuer);
513                       audit_log_s (ctrl->audit, AUDIT_RECP_NAME, tmpstr);
514                       xfree (tmpstr);
515                       xfree (issuer);
516                       xfree (serial);
517                     }
518                 }
519             }
520
521           if (!any_key)
522             {
523               rc = gpg_error (GPG_ERR_NO_SECKEY);
524               goto leave;
525             }
526         }
527       else if (stopreason == KSBA_SR_END_DATA)
528         {
529           ksba_writer_set_filter (writer, NULL, NULL);
530           if (dfparm.any_data)
531             { /* write the last block with padding removed */
532               int i, npadding = dfparm.lastblock[dfparm.blklen-1];
533               if (!npadding || npadding > dfparm.blklen)
534                 {
535                   log_error ("invalid padding with value %d\n", npadding);
536                   rc = gpg_error (GPG_ERR_INV_DATA);
537                   goto leave;
538                 }
539               rc = ksba_writer_write (writer,
540                                       dfparm.lastblock,
541                                       dfparm.blklen - npadding);
542               if (rc)
543                 goto leave;
544
545               for (i=dfparm.blklen - npadding; i < dfparm.blklen; i++)
546                 {
547                   if (dfparm.lastblock[i] != npadding)
548                     {
549                       log_error ("inconsistent padding\n");
550                       rc = gpg_error (GPG_ERR_INV_DATA);
551                       goto leave;
552                     }
553                 }
554             }
555         }
556
557     }
558   while (stopreason != KSBA_SR_READY);
559
560   rc = gpgsm_finish_writer (b64writer);
561   if (rc)
562     {
563       log_error ("write failed: %s\n", gpg_strerror (rc));
564       goto leave;
565     }
566   gpgsm_status (ctrl, STATUS_DECRYPTION_OKAY, NULL);
567
568
569  leave:
570   audit_log_ok (ctrl->audit, AUDIT_DECRYPTION_RESULT, rc);
571   if (rc)
572     {
573       gpgsm_status (ctrl, STATUS_DECRYPTION_FAILED, NULL);
574       log_error ("message decryption failed: %s <%s>\n",
575                  gpg_strerror (rc), gpg_strsource (rc));
576     }
577   ksba_cms_release (cms);
578   gpgsm_destroy_reader (b64reader);
579   gpgsm_destroy_writer (b64writer);
580   keydb_release (kh);
581   es_fclose (in_fp);
582   if (dfparm.hd)
583     gcry_cipher_close (dfparm.hd);
584   return rc;
585 }