core: Add 'is_mime' flags to the verify and decrypt results.
[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   /* A pointer to the next pointer of the last recipient in the list.
60      This makes appending new invalid signers painless while
61      preserving the order.  */
62   gpgme_recipient_t *last_recipient_p;
63 } *op_data_t;
64
65
66 static void
67 release_op_data (void *hook)
68 {
69   op_data_t opd = (op_data_t) hook;
70   gpgme_recipient_t recipient = opd->result.recipients;
71
72   free (opd->result.unsupported_algorithm);
73   free (opd->result.file_name);
74   free (opd->result.session_key);
75   free (opd->result.symkey_algo);
76
77   while (recipient)
78     {
79       gpgme_recipient_t next = recipient->next;
80       free (recipient);
81       recipient = next;
82     }
83 }
84
85
86 gpgme_decrypt_result_t
87 gpgme_op_decrypt_result (gpgme_ctx_t ctx)
88 {
89   void *hook;
90   op_data_t opd;
91   gpgme_error_t err;
92
93   TRACE_BEG (DEBUG_CTX, "gpgme_op_decrypt_result", ctx);
94
95   err = _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, &hook, -1, NULL);
96   opd = hook;
97   if (err || !opd)
98     {
99       TRACE_SUC0 ("result=(null)");
100       return NULL;
101     }
102
103   /* Make sure that SYMKEY_ALGO has a value.  */
104   if (!opd->result.symkey_algo)
105     {
106       opd->result.symkey_algo = strdup ("?.?");
107       if (!opd->result.symkey_algo)
108         {
109           TRACE_SUC0 ("result=(null)");
110           return NULL;
111         }
112     }
113
114   if (_gpgme_debug_trace ())
115     {
116       gpgme_recipient_t rcp;
117
118       if (opd->result.unsupported_algorithm)
119         {
120           TRACE_LOG1 ("result: unsupported_algorithm: %s",
121                       opd->result.unsupported_algorithm);
122         }
123       if (opd->result.wrong_key_usage)
124         {
125           TRACE_LOG ("result: wrong key usage");
126         }
127       rcp = opd->result.recipients;
128       while (rcp)
129         {
130           TRACE_LOG3 ("result: recipient: keyid=%s, pubkey_algo=%i, "
131                       "status=%s", rcp->keyid, rcp->pubkey_algo,
132                       gpg_strerror (rcp->status));
133           rcp = rcp->next;
134         }
135       if (opd->result.file_name)
136         {
137           TRACE_LOG1 ("result: original file name: %s", opd->result.file_name);
138         }
139     }
140
141   TRACE_SUC1 ("result=%p", &opd->result);
142   return &opd->result;
143 }
144
145
146 \f
147 /* Parse the ARGS of an error status line and record some error
148  * conditions at OPD.  Returns 0 on success.  */
149 static gpgme_error_t
150 parse_status_error (char *args, op_data_t opd)
151 {
152   gpgme_error_t err;
153   char *field[3];
154   int nfields;
155   char *args2;
156
157   if (!args)
158     return trace_gpg_error (GPG_ERR_INV_ENGINE);
159
160   args2 = strdup (args); /* Split modifies the input string. */
161   nfields = _gpgme_split_fields (args2, field, DIM (field));
162   if (nfields < 1)
163     {
164       free (args2);
165       return trace_gpg_error (GPG_ERR_INV_ENGINE); /* Required arg missing.  */
166     }
167   err = nfields < 2 ? 0 : atoi (field[1]);
168
169   if (!strcmp (field[0], "decrypt.algorithm"))
170     {
171       if (gpg_err_code (err) == GPG_ERR_UNSUPPORTED_ALGORITHM
172           && nfields > 2
173           && strcmp (field[2], "?"))
174         {
175           opd->result.unsupported_algorithm = strdup (field[2]);
176           if (!opd->result.unsupported_algorithm)
177             {
178               free (args2);
179               return gpg_error_from_syserror ();
180             }
181         }
182     }
183   else if (!strcmp (field[0], "decrypt.keyusage"))
184     {
185       if (gpg_err_code (err) == GPG_ERR_WRONG_KEY_USAGE)
186         opd->result.wrong_key_usage = 1;
187     }
188   else if (!strcmp (field[0], "pkdecrypt_failed"))
189     {
190       switch (gpg_err_code (err))
191         {
192         case GPG_ERR_CANCELED:
193         case GPG_ERR_FULLY_CANCELED:
194           /* It is better to return with a cancel error code than the
195            * general decryption failed error code.  */
196           opd->pkdecrypt_failed = gpg_err_make (gpg_err_source (err),
197                                                 GPG_ERR_CANCELED);
198           break;
199
200         case GPG_ERR_BAD_PASSPHRASE:
201           /* A bad passphrase is severe enough that we return this
202            * error code.  */
203           opd->pkdecrypt_failed = err;
204           break;
205
206         default:
207           /* For now all other error codes are ignored and the
208            * standard DECRYPT_FAILED is returned.  */
209           break;
210         }
211     }
212
213
214   free (args2);
215   return 0;
216 }
217
218
219 static gpgme_error_t
220 parse_enc_to (char *args, gpgme_recipient_t *recp, gpgme_protocol_t protocol)
221 {
222   gpgme_recipient_t rec;
223   char *tail;
224   int i;
225
226   rec = malloc (sizeof (*rec));
227   if (!rec)
228     return gpg_error_from_syserror ();
229
230   rec->next = NULL;
231   rec->keyid = rec->_keyid;
232   rec->status = 0;
233
234   for (i = 0; i < sizeof (rec->_keyid) - 1; i++)
235     {
236       if (args[i] == '\0' || args[i] == ' ')
237         break;
238
239       rec->_keyid[i] = args[i];
240     }
241   rec->_keyid[i] = '\0';
242
243   args = &args[i];
244   if (*args != '\0' && *args != ' ')
245     {
246       free (rec);
247       return trace_gpg_error (GPG_ERR_INV_ENGINE);
248     }
249
250   while (*args == ' ')
251     args++;
252
253   if (*args)
254     {
255       gpg_err_set_errno (0);
256       rec->pubkey_algo = _gpgme_map_pk_algo (strtol (args, &tail, 0), protocol);
257       if (errno || args == tail || *tail != ' ')
258         {
259           /* The crypto backend does not behave.  */
260           free (rec);
261           return trace_gpg_error (GPG_ERR_INV_ENGINE);
262         }
263     }
264
265   /* FIXME: The key length is always 0 right now, so no need to parse
266      it.  */
267
268   *recp = rec;
269   return 0;
270 }
271
272
273 /* Parse the ARGS of a
274  *   DECRYPTION_INFO <mdc_method> <sym_algo> [<aead_algo>]
275  * status.  Returns 0 on success and updates the OPD.
276  */
277 static gpgme_error_t
278 parse_decryption_info (char *args, op_data_t opd, gpgme_protocol_t protocol)
279 {
280   char *field[3];
281   int nfields;
282   char *args2;
283   int mdc, mode;
284   const char *algostr, *modestr;
285
286   if (!args)
287     return trace_gpg_error (GPG_ERR_INV_ENGINE);
288
289   args2 = strdup (args); /* Split modifies the input string. */
290   nfields = _gpgme_split_fields (args2, field, DIM (field));
291   if (nfields < 2)
292     {
293       free (args2);
294       return trace_gpg_error (GPG_ERR_INV_ENGINE); /* Required arg missing.  */
295     }
296
297   mdc     = atoi (field[0]);
298   algostr = _gpgme_cipher_algo_name (atoi (field[1]), protocol);
299   mode    = nfields < 3? 0 : atoi (field[2]);
300   modestr = _gpgme_cipher_mode_name (mode, protocol);
301
302   free (args2);
303
304   free (opd->result.symkey_algo);
305   if (!mode && mdc != 2)
306     opd->result.symkey_algo = _gpgme_strconcat (algostr, ".PGPCFB", NULL);
307   else
308     opd->result.symkey_algo = _gpgme_strconcat (algostr, ".", modestr, NULL);
309   if (!opd->result.symkey_algo)
310     return gpg_error_from_syserror ();
311
312   return 0;
313 }
314
315
316 gpgme_error_t
317 _gpgme_decrypt_status_handler (void *priv, gpgme_status_code_t code,
318                                char *args)
319 {
320   gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
321   gpgme_error_t err;
322   void *hook;
323   op_data_t opd;
324
325   err = _gpgme_passphrase_status_handler (priv, code, args);
326   if (err)
327     return err;
328
329   err = _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, &hook, -1, NULL);
330   opd = hook;
331   if (err)
332     return err;
333
334   switch (code)
335     {
336     case GPGME_STATUS_FAILURE:
337       opd->failure_code = _gpgme_parse_failure (args);
338       break;
339
340     case GPGME_STATUS_EOF:
341       /* FIXME: These error values should probably be attributed to
342          the underlying crypto engine (as error source).  */
343       if (opd->failed && opd->pkdecrypt_failed)
344         return opd->pkdecrypt_failed;
345       else if (opd->failed && opd->any_no_seckey)
346         return gpg_error (GPG_ERR_NO_SECKEY);
347       else if (opd->failed)
348         return gpg_error (GPG_ERR_DECRYPT_FAILED);
349       else if (!opd->okay)
350         return gpg_error (GPG_ERR_NO_DATA);
351       else if (opd->failure_code)
352         return opd->failure_code;
353       break;
354
355     case GPGME_STATUS_DECRYPTION_INFO:
356       err = parse_decryption_info (args, opd, ctx->protocol);
357       if (err)
358         return err;
359       break;
360
361     case GPGME_STATUS_DECRYPTION_OKAY:
362       opd->okay = 1;
363       break;
364
365     case GPGME_STATUS_DECRYPTION_FAILED:
366       opd->failed = 1;
367       break;
368
369     case GPGME_STATUS_ERROR:
370       /* Note that this is an informational status code which should
371          not lead to an error return unless it is something not
372          related to the backend.  */
373       err = parse_status_error (args, opd);
374       if (err)
375         return err;
376       break;
377
378     case GPGME_STATUS_ENC_TO:
379       err = parse_enc_to (args, opd->last_recipient_p, ctx->protocol);
380       if (err)
381         return err;
382
383       opd->last_recipient_p = &(*opd->last_recipient_p)->next;
384       break;
385
386     case GPGME_STATUS_SESSION_KEY:
387       if (opd->result.session_key)
388         free (opd->result.session_key);
389       opd->result.session_key = strdup(args);
390       break;
391
392     case GPGME_STATUS_NO_SECKEY:
393       {
394         gpgme_recipient_t rec = opd->result.recipients;
395         while (rec)
396           {
397             if (!strcmp (rec->keyid, args))
398               {
399                 rec->status = gpg_error (GPG_ERR_NO_SECKEY);
400                 break;
401               }
402             rec = rec->next;
403           }
404         /* FIXME: Is this ok?  */
405         if (!rec)
406           return trace_gpg_error (GPG_ERR_INV_ENGINE);
407         opd->any_no_seckey = 1;
408       }
409       break;
410
411     case GPGME_STATUS_PLAINTEXT:
412       {
413         int mime = 0;
414         err = _gpgme_parse_plaintext (args, &opd->result.file_name, &mime);
415         if (err)
416           return err;
417         gpgrt_log_debug ("decrypt.c setting mime to %d\n", mime);
418         opd->result.is_mime = !!mime;
419       }
420       break;
421
422     case GPGME_STATUS_INQUIRE_MAXLEN:
423       if (ctx->status_cb && !ctx->full_status)
424         {
425           err = ctx->status_cb (ctx->status_cb_value, "INQUIRE_MAXLEN", args);
426           if (err)
427             return err;
428         }
429       break;
430
431     case GPGME_STATUS_DECRYPTION_COMPLIANCE_MODE:
432       PARSE_COMPLIANCE_FLAGS (args, &opd->result);
433       break;
434
435     default:
436       break;
437     }
438
439   return 0;
440 }
441
442
443 static gpgme_error_t
444 decrypt_status_handler (void *priv, gpgme_status_code_t code, char *args)
445 {
446   gpgme_error_t err;
447
448   err = _gpgme_progress_status_handler (priv, code, args);
449   if (!err)
450     err = _gpgme_decrypt_status_handler (priv, code, args);
451   return err;
452 }
453
454
455 gpgme_error_t
456 _gpgme_op_decrypt_init_result (gpgme_ctx_t ctx)
457 {
458   gpgme_error_t err;
459   void *hook;
460   op_data_t opd;
461
462   err = _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, &hook,
463                                sizeof (*opd), release_op_data);
464   opd = hook;
465   if (err)
466     return err;
467
468   opd->last_recipient_p = &opd->result.recipients;
469   return 0;
470 }
471
472
473 gpgme_error_t
474 _gpgme_decrypt_start (gpgme_ctx_t ctx, int synchronous,
475                       gpgme_decrypt_flags_t flags,
476                       gpgme_data_t cipher, gpgme_data_t plain)
477 {
478   gpgme_error_t err;
479
480   assert (!(flags & GPGME_DECRYPT_VERIFY));
481
482   err = _gpgme_op_reset (ctx, synchronous);
483   if (err)
484     return err;
485
486   err = _gpgme_op_decrypt_init_result (ctx);
487   if (err)
488     return err;
489
490   if (!cipher)
491     return gpg_error (GPG_ERR_NO_DATA);
492   if (!plain)
493     return gpg_error (GPG_ERR_INV_VALUE);
494
495   if (err)
496     return err;
497
498   if (ctx->passphrase_cb)
499     {
500       err = _gpgme_engine_set_command_handler
501         (ctx->engine, _gpgme_passphrase_command_handler, ctx, NULL);
502       if (err)
503         return err;
504     }
505
506   _gpgme_engine_set_status_handler (ctx->engine, decrypt_status_handler, ctx);
507
508   return _gpgme_engine_op_decrypt (ctx->engine,
509                                    flags,
510                                    cipher, plain,
511                                    ctx->export_session_keys,
512                                    ctx->override_session_key,
513                                    ctx->auto_key_retrieve);
514 }
515
516
517 gpgme_error_t
518 gpgme_op_decrypt_start (gpgme_ctx_t ctx, gpgme_data_t cipher,
519                         gpgme_data_t plain)
520 {
521   gpgme_error_t err;
522
523   TRACE_BEG2 (DEBUG_CTX, "gpgme_op_decrypt_start", ctx,
524               "cipher=%p, plain=%p", cipher, plain);
525
526   if (!ctx)
527     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
528
529   err = _gpgme_decrypt_start (ctx, 0, 0, cipher, plain);
530   return TRACE_ERR (err);
531 }
532
533
534 /* Decrypt ciphertext CIPHER within CTX and store the resulting
535    plaintext in PLAIN.  */
536 gpgme_error_t
537 gpgme_op_decrypt (gpgme_ctx_t ctx, gpgme_data_t cipher, gpgme_data_t plain)
538 {
539   gpgme_error_t err;
540
541   TRACE_BEG2 (DEBUG_CTX, "gpgme_op_decrypt", ctx,
542               "cipher=%p, plain=%p", cipher, plain);
543
544   if (!ctx)
545     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
546
547   err = _gpgme_decrypt_start (ctx, 1, 0, cipher, plain);
548   if (!err)
549     err = _gpgme_wait_one (ctx);
550   return TRACE_ERR (err);
551 }