core: Make the status-fd monitor work for all gpgsm commands.
[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         opd->result.is_mime = !!mime;
418       }
419       break;
420
421     case GPGME_STATUS_INQUIRE_MAXLEN:
422       if (ctx->status_cb && !ctx->full_status)
423         {
424           err = ctx->status_cb (ctx->status_cb_value, "INQUIRE_MAXLEN", args);
425           if (err)
426             return err;
427         }
428       break;
429
430     case GPGME_STATUS_DECRYPTION_COMPLIANCE_MODE:
431       PARSE_COMPLIANCE_FLAGS (args, &opd->result);
432       break;
433
434     default:
435       break;
436     }
437
438   return 0;
439 }
440
441
442 static gpgme_error_t
443 decrypt_status_handler (void *priv, gpgme_status_code_t code, char *args)
444 {
445   gpgme_error_t err;
446
447   err = _gpgme_progress_status_handler (priv, code, args);
448   if (!err)
449     err = _gpgme_decrypt_status_handler (priv, code, args);
450   return err;
451 }
452
453
454 gpgme_error_t
455 _gpgme_op_decrypt_init_result (gpgme_ctx_t ctx)
456 {
457   gpgme_error_t err;
458   void *hook;
459   op_data_t opd;
460
461   err = _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, &hook,
462                                sizeof (*opd), release_op_data);
463   opd = hook;
464   if (err)
465     return err;
466
467   opd->last_recipient_p = &opd->result.recipients;
468   return 0;
469 }
470
471
472 gpgme_error_t
473 _gpgme_decrypt_start (gpgme_ctx_t ctx, int synchronous,
474                       gpgme_decrypt_flags_t flags,
475                       gpgme_data_t cipher, gpgme_data_t plain)
476 {
477   gpgme_error_t err;
478
479   assert (!(flags & GPGME_DECRYPT_VERIFY));
480
481   err = _gpgme_op_reset (ctx, synchronous);
482   if (err)
483     return err;
484
485   err = _gpgme_op_decrypt_init_result (ctx);
486   if (err)
487     return err;
488
489   if (!cipher)
490     return gpg_error (GPG_ERR_NO_DATA);
491   if (!plain)
492     return gpg_error (GPG_ERR_INV_VALUE);
493
494   if (err)
495     return err;
496
497   if (ctx->passphrase_cb)
498     {
499       err = _gpgme_engine_set_command_handler
500         (ctx->engine, _gpgme_passphrase_command_handler, ctx, NULL);
501       if (err)
502         return err;
503     }
504
505   _gpgme_engine_set_status_handler (ctx->engine, decrypt_status_handler, ctx);
506
507   return _gpgme_engine_op_decrypt (ctx->engine,
508                                    flags,
509                                    cipher, plain,
510                                    ctx->export_session_keys,
511                                    ctx->override_session_key,
512                                    ctx->auto_key_retrieve);
513 }
514
515
516 gpgme_error_t
517 gpgme_op_decrypt_start (gpgme_ctx_t ctx, gpgme_data_t cipher,
518                         gpgme_data_t plain)
519 {
520   gpgme_error_t err;
521
522   TRACE_BEG2 (DEBUG_CTX, "gpgme_op_decrypt_start", ctx,
523               "cipher=%p, plain=%p", cipher, plain);
524
525   if (!ctx)
526     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
527
528   err = _gpgme_decrypt_start (ctx, 0, 0, cipher, plain);
529   return TRACE_ERR (err);
530 }
531
532
533 /* Decrypt ciphertext CIPHER within CTX and store the resulting
534    plaintext in PLAIN.  */
535 gpgme_error_t
536 gpgme_op_decrypt (gpgme_ctx_t ctx, gpgme_data_t cipher, gpgme_data_t plain)
537 {
538   gpgme_error_t err;
539
540   TRACE_BEG2 (DEBUG_CTX, "gpgme_op_decrypt", ctx,
541               "cipher=%p, plain=%p", cipher, plain);
542
543   if (!ctx)
544     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
545
546   err = _gpgme_decrypt_start (ctx, 1, 0, cipher, plain);
547   if (!err)
548     err = _gpgme_wait_one (ctx);
549   return TRACE_ERR (err);
550 }