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