core: New context flag "ignore-mdc-error".
[gpgme.git] / src / decrypt.c
1 /* decrypt.c - Decrypt function.
2    Copyright (C) 2000 Werner Koch (dd9jn)
3    Copyright (C) 2001, 2002, 2003, 2004, 2017 g10 Code GmbH
4
5    This file is part of GPGME.
6
7    GPGME is free software; you can redistribute it and/or modify it
8    under the terms of the GNU Lesser General Public License as
9    published by the Free Software Foundation; either version 2.1 of
10    the License, or (at your option) any later version.
11
12    GPGME is distributed in the hope that it will be useful, but
13    WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    Lesser General Public License for more details.
16
17    You should have received a copy of the GNU Lesser General Public
18    License along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20    02111-1307, USA.  */
21
22 #if HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25 #include <stdlib.h>
26 #include <string.h>
27 #include <errno.h>
28 #include <assert.h>
29
30 #include "debug.h"
31 #include "gpgme.h"
32 #include "util.h"
33 #include "context.h"
34 #include "ops.h"
35
36
37 \f
38 typedef struct
39 {
40   struct _gpgme_op_decrypt_result result;
41
42   /* The error code from a FAILURE status line or 0.  */
43   gpg_error_t failure_code;
44
45   int okay;
46
47   /* A flag telling that the a decryption failed and an optional error
48    * code to further specify the failure.  */
49   int failed;
50   gpg_error_t pkdecrypt_failed;
51
52   /* At least one secret key is not available.  gpg issues NO_SECKEY
53    * status lines for each key the message has been encrypted to but
54    * that secret key is not available.  This can't be done for hidden
55    * recipients, though.  We track it here to allow for a better error
56    * message that the general DECRYPTION_FAILED. */
57   int any_no_seckey;
58
59   /* If the engine emits a DECRYPTION_INFO status and that does not
60    * indicate that an integrity protection mode is active, this flag
61    * is set.  */
62   int not_integrity_protected;
63
64   /* A pointer to the next pointer of the last recipient in the list.
65      This makes appending new invalid signers painless while
66      preserving the order.  */
67   gpgme_recipient_t *last_recipient_p;
68 } *op_data_t;
69
70
71 static void
72 release_op_data (void *hook)
73 {
74   op_data_t opd = (op_data_t) hook;
75   gpgme_recipient_t recipient = opd->result.recipients;
76
77   free (opd->result.unsupported_algorithm);
78   free (opd->result.file_name);
79   free (opd->result.session_key);
80   free (opd->result.symkey_algo);
81
82   while (recipient)
83     {
84       gpgme_recipient_t next = recipient->next;
85       free (recipient);
86       recipient = next;
87     }
88 }
89
90
91 gpgme_decrypt_result_t
92 gpgme_op_decrypt_result (gpgme_ctx_t ctx)
93 {
94   void *hook;
95   op_data_t opd;
96   gpgme_error_t err;
97
98   TRACE_BEG (DEBUG_CTX, "gpgme_op_decrypt_result", ctx);
99
100   ctx->ignore_mdc_error = 0;  /* Always reset this flag.  */
101
102   err = _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, &hook, -1, NULL);
103   opd = hook;
104   if (err || !opd)
105     {
106       TRACE_SUC0 ("result=(null)");
107       return NULL;
108     }
109
110   /* Make sure that SYMKEY_ALGO has a value.  */
111   if (!opd->result.symkey_algo)
112     {
113       opd->result.symkey_algo = strdup ("?.?");
114       if (!opd->result.symkey_algo)
115         {
116           TRACE_SUC0 ("result=(null)");
117           return NULL;
118         }
119     }
120
121   if (_gpgme_debug_trace ())
122     {
123       gpgme_recipient_t rcp;
124
125       if (opd->result.unsupported_algorithm)
126         {
127           TRACE_LOG1 ("result: unsupported_algorithm: %s",
128                       opd->result.unsupported_algorithm);
129         }
130       if (opd->result.wrong_key_usage)
131         {
132           TRACE_LOG ("result: wrong key usage");
133         }
134       rcp = opd->result.recipients;
135       while (rcp)
136         {
137           TRACE_LOG3 ("result: recipient: keyid=%s, pubkey_algo=%i, "
138                       "status=%s", rcp->keyid, rcp->pubkey_algo,
139                       gpg_strerror (rcp->status));
140           rcp = rcp->next;
141         }
142       if (opd->result.file_name)
143         {
144           TRACE_LOG1 ("result: original file name: %s", opd->result.file_name);
145         }
146     }
147
148   TRACE_SUC1 ("result=%p", &opd->result);
149   return &opd->result;
150 }
151
152
153 \f
154 /* Parse the ARGS of an error status line and record some error
155  * conditions at OPD.  Returns 0 on success.  */
156 static gpgme_error_t
157 parse_status_error (char *args, op_data_t opd)
158 {
159   gpgme_error_t err;
160   char *field[3];
161   int nfields;
162   char *args2;
163
164   if (!args)
165     return trace_gpg_error (GPG_ERR_INV_ENGINE);
166
167   args2 = strdup (args); /* Split modifies the input string. */
168   nfields = _gpgme_split_fields (args2, field, DIM (field));
169   if (nfields < 1)
170     {
171       free (args2);
172       return trace_gpg_error (GPG_ERR_INV_ENGINE); /* Required arg missing.  */
173     }
174   err = nfields < 2 ? 0 : atoi (field[1]);
175
176   if (!strcmp (field[0], "decrypt.algorithm"))
177     {
178       if (gpg_err_code (err) == GPG_ERR_UNSUPPORTED_ALGORITHM
179           && nfields > 2
180           && strcmp (field[2], "?"))
181         {
182           opd->result.unsupported_algorithm = strdup (field[2]);
183           if (!opd->result.unsupported_algorithm)
184             {
185               free (args2);
186               return gpg_error_from_syserror ();
187             }
188         }
189     }
190   else if (!strcmp (field[0], "decrypt.keyusage"))
191     {
192       if (gpg_err_code (err) == GPG_ERR_WRONG_KEY_USAGE)
193         opd->result.wrong_key_usage = 1;
194     }
195   else if (!strcmp (field[0], "pkdecrypt_failed"))
196     {
197       switch (gpg_err_code (err))
198         {
199         case GPG_ERR_CANCELED:
200         case GPG_ERR_FULLY_CANCELED:
201           /* It is better to return with a cancel error code than the
202            * general decryption failed error code.  */
203           opd->pkdecrypt_failed = gpg_err_make (gpg_err_source (err),
204                                                 GPG_ERR_CANCELED);
205           break;
206
207         case GPG_ERR_BAD_PASSPHRASE:
208           /* A bad passphrase is severe enough that we return this
209            * error code.  */
210           opd->pkdecrypt_failed = err;
211           break;
212
213         default:
214           /* For now all other error codes are ignored and the
215            * standard DECRYPT_FAILED is returned.  */
216           break;
217         }
218     }
219   else if (!strcmp (field[0], "nomdc_with_legacy_cipher"))
220     {
221       opd->result.legacy_cipher_nomdc = 1;
222       opd->not_integrity_protected = 1;
223     }
224
225
226   free (args2);
227   return 0;
228 }
229
230
231 static gpgme_error_t
232 parse_enc_to (char *args, gpgme_recipient_t *recp, gpgme_protocol_t protocol)
233 {
234   gpgme_recipient_t rec;
235   char *tail;
236   int i;
237
238   rec = malloc (sizeof (*rec));
239   if (!rec)
240     return gpg_error_from_syserror ();
241
242   rec->next = NULL;
243   rec->keyid = rec->_keyid;
244   rec->status = 0;
245
246   for (i = 0; i < sizeof (rec->_keyid) - 1; i++)
247     {
248       if (args[i] == '\0' || args[i] == ' ')
249         break;
250
251       rec->_keyid[i] = args[i];
252     }
253   rec->_keyid[i] = '\0';
254
255   args = &args[i];
256   if (*args != '\0' && *args != ' ')
257     {
258       free (rec);
259       return trace_gpg_error (GPG_ERR_INV_ENGINE);
260     }
261
262   while (*args == ' ')
263     args++;
264
265   if (*args)
266     {
267       gpg_err_set_errno (0);
268       rec->pubkey_algo = _gpgme_map_pk_algo (strtol (args, &tail, 0), protocol);
269       if (errno || args == tail || *tail != ' ')
270         {
271           /* The crypto backend does not behave.  */
272           free (rec);
273           return trace_gpg_error (GPG_ERR_INV_ENGINE);
274         }
275     }
276
277   /* FIXME: The key length is always 0 right now, so no need to parse
278      it.  */
279
280   *recp = rec;
281   return 0;
282 }
283
284
285 /* Parse the ARGS of a
286  *   DECRYPTION_INFO <mdc_method> <sym_algo> [<aead_algo>]
287  * status.  Returns 0 on success and updates the OPD.
288  */
289 static gpgme_error_t
290 parse_decryption_info (char *args, op_data_t opd, gpgme_protocol_t protocol)
291 {
292   char *field[3];
293   int nfields;
294   char *args2;
295   int mdc, aead_algo;
296   const char *algostr, *modestr;
297
298   if (!args)
299     return trace_gpg_error (GPG_ERR_INV_ENGINE);
300
301   args2 = strdup (args); /* Split modifies the input string. */
302   nfields = _gpgme_split_fields (args2, field, DIM (field));
303   if (nfields < 2)
304     {
305       free (args2);
306       return trace_gpg_error (GPG_ERR_INV_ENGINE); /* Required arg missing.  */
307     }
308
309   mdc     = atoi (field[0]);
310   algostr = _gpgme_cipher_algo_name (atoi (field[1]), protocol);
311   aead_algo    = nfields < 3? 0 : atoi (field[2]);
312   modestr = _gpgme_cipher_mode_name (aead_algo, protocol);
313
314   free (args2);
315
316   free (opd->result.symkey_algo);
317   if (!aead_algo && mdc != 2)
318     opd->result.symkey_algo = _gpgme_strconcat (algostr, ".PGPCFB", NULL);
319   else
320     opd->result.symkey_algo = _gpgme_strconcat (algostr, ".", modestr, NULL);
321   if (!opd->result.symkey_algo)
322     return gpg_error_from_syserror ();
323
324   if (!mdc && !aead_algo)
325     opd->not_integrity_protected = 1;
326
327   return 0;
328 }
329
330
331 gpgme_error_t
332 _gpgme_decrypt_status_handler (void *priv, gpgme_status_code_t code,
333                                char *args)
334 {
335   gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
336   gpgme_error_t err;
337   void *hook;
338   op_data_t opd;
339
340   err = _gpgme_passphrase_status_handler (priv, code, args);
341   if (err)
342     return err;
343
344   err = _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, &hook, -1, NULL);
345   opd = hook;
346   if (err)
347     return err;
348
349   switch (code)
350     {
351     case GPGME_STATUS_FAILURE:
352       opd->failure_code = _gpgme_parse_failure (args);
353       break;
354
355     case GPGME_STATUS_EOF:
356       /* We force an encryption failure if we know that integrity
357        * protection is missing.  For modern version of gpg using
358        * modern cipher algorithms this is not required because gpg
359        * will issue a failure anyway.  However older gpg versions emit
360        * only a warning.
361        * Fixme: These error values should probably be attributed to
362        * the underlying crypto engine (as error source).  */
363       if (opd->failed && opd->pkdecrypt_failed)
364         return opd->pkdecrypt_failed;
365       else if (opd->failed && opd->any_no_seckey)
366         return gpg_error (GPG_ERR_NO_SECKEY);
367       else if (opd->failed || (opd->not_integrity_protected
368                                && !ctx->ignore_mdc_error))
369         return gpg_error (GPG_ERR_DECRYPT_FAILED);
370       else if (!opd->okay)
371         return gpg_error (GPG_ERR_NO_DATA);
372       else if (opd->failure_code)
373         return opd->failure_code;
374       break;
375
376     case GPGME_STATUS_DECRYPTION_INFO:
377       err = parse_decryption_info (args, opd, ctx->protocol);
378       if (err)
379         return err;
380       break;
381
382     case GPGME_STATUS_DECRYPTION_OKAY:
383       opd->okay = 1;
384       break;
385
386     case GPGME_STATUS_DECRYPTION_FAILED:
387       opd->failed = 1;
388       break;
389
390     case GPGME_STATUS_ERROR:
391       /* Note that this is an informational status code which should
392          not lead to an error return unless it is something not
393          related to the backend.  */
394       err = parse_status_error (args, opd);
395       if (err)
396         return err;
397       break;
398
399     case GPGME_STATUS_ENC_TO:
400       err = parse_enc_to (args, opd->last_recipient_p, ctx->protocol);
401       if (err)
402         return err;
403
404       opd->last_recipient_p = &(*opd->last_recipient_p)->next;
405       break;
406
407     case GPGME_STATUS_SESSION_KEY:
408       if (opd->result.session_key)
409         free (opd->result.session_key);
410       opd->result.session_key = strdup(args);
411       break;
412
413     case GPGME_STATUS_NO_SECKEY:
414       {
415         gpgme_recipient_t rec = opd->result.recipients;
416         while (rec)
417           {
418             if (!strcmp (rec->keyid, args))
419               {
420                 rec->status = gpg_error (GPG_ERR_NO_SECKEY);
421                 break;
422               }
423             rec = rec->next;
424           }
425         /* FIXME: Is this ok?  */
426         if (!rec)
427           return trace_gpg_error (GPG_ERR_INV_ENGINE);
428         opd->any_no_seckey = 1;
429       }
430       break;
431
432     case GPGME_STATUS_PLAINTEXT:
433       {
434         int mime = 0;
435         err = _gpgme_parse_plaintext (args, &opd->result.file_name, &mime);
436         if (err)
437           return err;
438         opd->result.is_mime = !!mime;
439       }
440       break;
441
442     case GPGME_STATUS_INQUIRE_MAXLEN:
443       if (ctx->status_cb && !ctx->full_status)
444         {
445           err = ctx->status_cb (ctx->status_cb_value, "INQUIRE_MAXLEN", args);
446           if (err)
447             return err;
448         }
449       break;
450
451     case GPGME_STATUS_DECRYPTION_COMPLIANCE_MODE:
452       PARSE_COMPLIANCE_FLAGS (args, &opd->result);
453       break;
454
455     default:
456       break;
457     }
458
459   return 0;
460 }
461
462
463 static gpgme_error_t
464 decrypt_status_handler (void *priv, gpgme_status_code_t code, char *args)
465 {
466   gpgme_error_t err;
467
468   err = _gpgme_progress_status_handler (priv, code, args);
469   if (!err)
470     err = _gpgme_decrypt_status_handler (priv, code, args);
471   return err;
472 }
473
474
475 gpgme_error_t
476 _gpgme_op_decrypt_init_result (gpgme_ctx_t ctx)
477 {
478   gpgme_error_t err;
479   void *hook;
480   op_data_t opd;
481
482   err = _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, &hook,
483                                sizeof (*opd), release_op_data);
484   opd = hook;
485   if (err)
486     return err;
487
488   opd->last_recipient_p = &opd->result.recipients;
489   return 0;
490 }
491
492
493 gpgme_error_t
494 _gpgme_decrypt_start (gpgme_ctx_t ctx, int synchronous,
495                       gpgme_decrypt_flags_t flags,
496                       gpgme_data_t cipher, gpgme_data_t plain)
497 {
498   gpgme_error_t err;
499
500   assert (!(flags & GPGME_DECRYPT_VERIFY));
501
502   err = _gpgme_op_reset (ctx, synchronous);
503   if (err)
504     return err;
505
506   err = _gpgme_op_decrypt_init_result (ctx);
507   if (err)
508     return err;
509
510   if (!cipher)
511     return gpg_error (GPG_ERR_NO_DATA);
512   if (!plain)
513     return gpg_error (GPG_ERR_INV_VALUE);
514
515   if (err)
516     return err;
517
518   if (ctx->passphrase_cb)
519     {
520       err = _gpgme_engine_set_command_handler
521         (ctx->engine, _gpgme_passphrase_command_handler, ctx);
522       if (err)
523         return err;
524     }
525
526   _gpgme_engine_set_status_handler (ctx->engine, decrypt_status_handler, ctx);
527
528   return _gpgme_engine_op_decrypt (ctx->engine,
529                                    flags,
530                                    cipher, plain,
531                                    ctx->export_session_keys,
532                                    ctx->override_session_key,
533                                    ctx->auto_key_retrieve);
534 }
535
536
537 gpgme_error_t
538 gpgme_op_decrypt_start (gpgme_ctx_t ctx, gpgme_data_t cipher,
539                         gpgme_data_t plain)
540 {
541   gpgme_error_t err;
542
543   TRACE_BEG2 (DEBUG_CTX, "gpgme_op_decrypt_start", ctx,
544               "cipher=%p, plain=%p", cipher, plain);
545
546   if (!ctx)
547     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
548
549   err = _gpgme_decrypt_start (ctx, 0, 0, cipher, plain);
550   return TRACE_ERR (err);
551 }
552
553
554 /* Decrypt ciphertext CIPHER within CTX and store the resulting
555    plaintext in PLAIN.  */
556 gpgme_error_t
557 gpgme_op_decrypt (gpgme_ctx_t ctx, gpgme_data_t cipher, gpgme_data_t plain)
558 {
559   gpgme_error_t err;
560
561   TRACE_BEG2 (DEBUG_CTX, "gpgme_op_decrypt", ctx,
562               "cipher=%p, plain=%p", cipher, plain);
563
564   if (!ctx)
565     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
566
567   err = _gpgme_decrypt_start (ctx, 1, 0, cipher, plain);
568   if (!err)
569     err = _gpgme_wait_one (ctx);
570   ctx->ignore_mdc_error = 0;  /* Always reset.  */
571   return TRACE_ERR (err);
572 }