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, see <https://gnu.org/licenses/>.
19 * SPDX-License-Identifier: LGPL-2.1-or-later
20 */
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 #include "data.h"
36
37
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 than 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 /* The error code from the first ERROR line. This is in some cases
65 * used to return a better matching error code to the caller. */
66 gpg_error_t first_status_error;
67
68 /* A pointer to the next pointer of the last recipient in the list.
69 This makes appending new invalid signers painless while
70 preserving the order. */
71 gpgme_recipient_t *last_recipient_p;
72
73 /* The data object serial number of the plaintext. */
74 uint64_t plaintext_dserial;
75 } *op_data_t;
76
77
78 static void
release_op_data(void * hook)79 release_op_data (void *hook)
80 {
81 op_data_t opd = (op_data_t) hook;
82 gpgme_recipient_t recipient = opd->result.recipients;
83
84 free (opd->result.unsupported_algorithm);
85 free (opd->result.file_name);
86 free (opd->result.session_key);
87 free (opd->result.symkey_algo);
88
89 while (recipient)
90 {
91 gpgme_recipient_t next = recipient->next;
92 free (recipient);
93 recipient = next;
94 }
95 }
96
97
98 gpgme_decrypt_result_t
gpgme_op_decrypt_result(gpgme_ctx_t ctx)99 gpgme_op_decrypt_result (gpgme_ctx_t ctx)
100 {
101 void *hook;
102 op_data_t opd;
103 gpgme_error_t err;
104
105 TRACE_BEG (DEBUG_CTX, "gpgme_op_decrypt_result", ctx, "");
106
107 ctx->ignore_mdc_error = 0; /* Always reset this flag. */
108
109 err = _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, &hook, -1, NULL);
110 opd = hook;
111 if (err || !opd)
112 {
113 TRACE_SUC ("result=(null)");
114 return NULL;
115 }
116
117 /* Make sure that SYMKEY_ALGO has a value. */
118 if (!opd->result.symkey_algo)
119 {
120 opd->result.symkey_algo = strdup ("?.?");
121 if (!opd->result.symkey_algo)
122 {
123 TRACE_SUC ("result=(null)");
124 return NULL;
125 }
126 }
127
128 if (_gpgme_debug_trace ())
129 {
130 gpgme_recipient_t rcp;
131
132 if (opd->result.unsupported_algorithm)
133 {
134 TRACE_LOG ("result: unsupported_algorithm: %s",
135 opd->result.unsupported_algorithm);
136 }
137 if (opd->result.wrong_key_usage)
138 {
139 TRACE_LOG ("result: wrong key usage");
140 }
141 rcp = opd->result.recipients;
142 while (rcp)
143 {
144 TRACE_LOG ("result: recipient: keyid=%s, pubkey_algo=%i, "
145 "status=%s", rcp->keyid, rcp->pubkey_algo,
146 gpg_strerror (rcp->status));
147 rcp = rcp->next;
148 }
149 if (opd->result.file_name)
150 {
151 TRACE_LOG ("result: original file name: %s", opd->result.file_name);
152 }
153 }
154
155 TRACE_SUC ("result=%p", &opd->result);
156 return &opd->result;
157 }
158
159
160
161 /* Parse the ARGS of an error status line and record some error
162 * conditions at OPD. Returns 0 on success. */
163 static gpgme_error_t
parse_status_error(char * args,op_data_t opd)164 parse_status_error (char *args, op_data_t opd)
165 {
166 gpgme_error_t err;
167 char *field[3];
168 int nfields;
169 char *args2;
170
171 if (!args)
172 return trace_gpg_error (GPG_ERR_INV_ENGINE);
173
174 args2 = strdup (args); /* Split modifies the input string. */
175 nfields = _gpgme_split_fields (args2, field, DIM (field));
176 if (nfields < 1)
177 {
178 free (args2);
179 return trace_gpg_error (GPG_ERR_INV_ENGINE); /* Required arg missing. */
180 }
181 err = nfields < 2 ? 0 : atoi (field[1]);
182
183 if (!strcmp (field[0], "decrypt.algorithm"))
184 {
185 if (gpg_err_code (err) == GPG_ERR_UNSUPPORTED_ALGORITHM
186 && nfields > 2
187 && strcmp (field[2], "?"))
188 {
189 opd->result.unsupported_algorithm = strdup (field[2]);
190 if (!opd->result.unsupported_algorithm)
191 {
192 free (args2);
193 return gpg_error_from_syserror ();
194 }
195 }
196 }
197 else if (!strcmp (field[0], "decrypt.keyusage"))
198 {
199 if (gpg_err_code (err) == GPG_ERR_WRONG_KEY_USAGE)
200 opd->result.wrong_key_usage = 1;
201 }
202 else if (!strcmp (field[0], "pkdecrypt_failed"))
203 {
204 switch (gpg_err_code (err))
205 {
206 case GPG_ERR_CANCELED:
207 case GPG_ERR_FULLY_CANCELED:
208 /* It is better to return with a cancel error code than the
209 * general decryption failed error code. */
210 opd->pkdecrypt_failed = gpg_err_make (gpg_err_source (err),
211 GPG_ERR_CANCELED);
212 break;
213
214 case GPG_ERR_BAD_PASSPHRASE:
215 /* A bad passphrase is severe enough that we return this
216 * error code. */
217 opd->pkdecrypt_failed = err;
218 break;
219
220 default:
221 /* For now all other error codes are ignored and the
222 * standard DECRYPT_FAILED is returned. */
223 break;
224 }
225 }
226 else if (!strcmp (field[0], "nomdc_with_legacy_cipher"))
227 {
228 opd->result.legacy_cipher_nomdc = 1;
229 opd->not_integrity_protected = 1;
230 }
231
232 /* Record the first error code. */
233 if (err && !opd->first_status_error)
234 opd->first_status_error = err;
235
236
237 free (args2);
238 return 0;
239 }
240
241
242 static gpgme_error_t
parse_enc_to(char * args,gpgme_recipient_t * recp,gpgme_protocol_t protocol)243 parse_enc_to (char *args, gpgme_recipient_t *recp, gpgme_protocol_t protocol)
244 {
245 gpgme_recipient_t rec;
246 char *tail;
247 int i;
248
249 rec = malloc (sizeof (*rec));
250 if (!rec)
251 return gpg_error_from_syserror ();
252
253 rec->next = NULL;
254 rec->keyid = rec->_keyid;
255 rec->status = 0;
256
257 for (i = 0; i < sizeof (rec->_keyid) - 1; i++)
258 {
259 if (args[i] == '\0' || args[i] == ' ')
260 break;
261
262 rec->_keyid[i] = args[i];
263 }
264 rec->_keyid[i] = '\0';
265
266 args = &args[i];
267 if (*args != '\0' && *args != ' ')
268 {
269 free (rec);
270 return trace_gpg_error (GPG_ERR_INV_ENGINE);
271 }
272
273 while (*args == ' ')
274 args++;
275
276 if (*args)
277 {
278 gpg_err_set_errno (0);
279 rec->pubkey_algo = _gpgme_map_pk_algo (strtol (args, &tail, 0), protocol);
280 if (errno || args == tail || *tail != ' ')
281 {
282 /* The crypto backend does not behave. */
283 free (rec);
284 return trace_gpg_error (GPG_ERR_INV_ENGINE);
285 }
286 }
287
288 /* FIXME: The key length is always 0 right now, so no need to parse
289 it. */
290
291 *recp = rec;
292 return 0;
293 }
294
295
296 /* Parse the ARGS of a
297 * DECRYPTION_INFO <mdc_method> <sym_algo> [<aead_algo>]
298 * status. Returns 0 on success and updates the OPD.
299 */
300 static gpgme_error_t
parse_decryption_info(char * args,op_data_t opd,gpgme_protocol_t protocol)301 parse_decryption_info (char *args, op_data_t opd, gpgme_protocol_t protocol)
302 {
303 char *field[3];
304 int nfields;
305 char *args2;
306 int mdc, aead_algo;
307 const char *algostr, *modestr;
308
309 if (!args)
310 return trace_gpg_error (GPG_ERR_INV_ENGINE);
311
312 args2 = strdup (args); /* Split modifies the input string. */
313 nfields = _gpgme_split_fields (args2, field, DIM (field));
314 if (nfields < 2)
315 {
316 free (args2);
317 return trace_gpg_error (GPG_ERR_INV_ENGINE); /* Required arg missing. */
318 }
319
320 mdc = atoi (field[0]);
321 algostr = _gpgme_cipher_algo_name (atoi (field[1]), protocol);
322 aead_algo = nfields < 3? 0 : atoi (field[2]);
323 modestr = _gpgme_cipher_mode_name (aead_algo, protocol);
324
325 free (args2);
326
327 free (opd->result.symkey_algo);
328 if (!aead_algo && mdc != 2)
329 opd->result.symkey_algo = _gpgme_strconcat (algostr, ".PGPCFB", NULL);
330 else
331 opd->result.symkey_algo = _gpgme_strconcat (algostr, ".", modestr, NULL);
332 if (!opd->result.symkey_algo)
333 return gpg_error_from_syserror ();
334
335 if (!mdc && !aead_algo)
336 opd->not_integrity_protected = 1;
337
338 return 0;
339 }
340
341
342 gpgme_error_t
_gpgme_decrypt_status_handler(void * priv,gpgme_status_code_t code,char * args)343 _gpgme_decrypt_status_handler (void *priv, gpgme_status_code_t code,
344 char *args)
345 {
346 gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
347 gpgme_error_t err;
348 void *hook;
349 op_data_t opd;
350
351 err = _gpgme_passphrase_status_handler (priv, code, args);
352 if (err)
353 return err;
354
355 err = _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, &hook, -1, NULL);
356 opd = hook;
357 if (err)
358 return err;
359
360 switch (code)
361 {
362 case GPGME_STATUS_FAILURE:
363 opd->failure_code = _gpgme_parse_failure (args);
364 break;
365
366 case GPGME_STATUS_EOF:
367 /* We force an encryption failure if we know that integrity
368 * protection is missing. For modern version of gpg using
369 * modern cipher algorithms this is not required because gpg
370 * will issue a failure anyway. However older gpg versions emit
371 * only a warning.
372 * Fixme: These error values should probably be attributed to
373 * the underlying crypto engine (as error source). */
374 if (opd->failed)
375 {
376 /* This comes from a specialized ERROR status line. */
377 if (opd->pkdecrypt_failed)
378 return opd->pkdecrypt_failed;
379
380 /* For an integrity failure return just DECRYPTION_FAILED;
381 * the actual cause can be taken from an already set
382 * decryption result flag. */
383 if ((opd->not_integrity_protected && !ctx->ignore_mdc_error))
384 return gpg_error (GPG_ERR_DECRYPT_FAILED);
385
386 /* If we have any other ERROR code we prefer that over
387 * NO_SECKEY because it is probably the better matching
388 * code. For example a garbled message with multiple
389 * plaintext will return BAD_DATA here but may also have
390 * indicated a NO_SECKEY. */
391 if (opd->first_status_error)
392 return opd->first_status_error;
393
394 /* No secret key is pretty common reason. */
395 if (opd->any_no_seckey)
396 return gpg_error (GPG_ERR_NO_SECKEY);
397
398 /* Generic decryption failed error code. */
399 return gpg_error (GPG_ERR_DECRYPT_FAILED);
400 }
401 else if (!opd->okay)
402 {
403 /* No data was found. */
404 return gpg_error (GPG_ERR_NO_DATA);
405 }
406 else if (opd->failure_code)
407 {
408 /* The engine returned failure code at program exit. */
409 return opd->failure_code;
410 }
411 break;
412
413 case GPGME_STATUS_DECRYPTION_INFO:
414 err = parse_decryption_info (args, opd, ctx->protocol);
415 if (err)
416 return err;
417 break;
418
419 case GPGME_STATUS_DECRYPTION_OKAY:
420 opd->okay = 1;
421 break;
422
423 case GPGME_STATUS_DECRYPTION_FAILED:
424 opd->failed = 1;
425 /* Tell the data object that it shall not return any data. We
426 * use the serial number because the data object may be owned by
427 * another thread. We also don't check for an error because it
428 * is possible that the data object has already been destroyed
429 * and we are then not interested in returning an error. */
430 if (!ctx->ignore_mdc_error)
431 _gpgme_data_set_prop (NULL, opd->plaintext_dserial,
432 DATA_PROP_BLANKOUT, 1);
433 break;
434
435 case GPGME_STATUS_ERROR:
436 /* Note that this is an informational status code which should
437 * not lead to an error return unless it is something not
438 * related to the backend. However, it is used to return a
439 * better matching final error code. */
440 err = parse_status_error (args, opd);
441 if (err)
442 return err;
443 break;
444
445 case GPGME_STATUS_ENC_TO:
446 err = parse_enc_to (args, opd->last_recipient_p, ctx->protocol);
447 if (err)
448 return err;
449
450 opd->last_recipient_p = &(*opd->last_recipient_p)->next;
451 break;
452
453 case GPGME_STATUS_SESSION_KEY:
454 if (opd->result.session_key)
455 free (opd->result.session_key);
456 opd->result.session_key = strdup(args);
457 break;
458
459 case GPGME_STATUS_NO_SECKEY:
460 {
461 gpgme_recipient_t rec = opd->result.recipients;
462 while (rec)
463 {
464 if (!strcmp (rec->keyid, args))
465 {
466 rec->status = gpg_error (GPG_ERR_NO_SECKEY);
467 break;
468 }
469 rec = rec->next;
470 }
471 /* FIXME: Is this ok? */
472 if (!rec)
473 return trace_gpg_error (GPG_ERR_INV_ENGINE);
474 opd->any_no_seckey = 1;
475 }
476 break;
477
478 case GPGME_STATUS_PLAINTEXT:
479 {
480 int mime = 0;
481 err = _gpgme_parse_plaintext (args, &opd->result.file_name, &mime);
482 if (err)
483 return err;
484 opd->result.is_mime = !!mime;
485 }
486 break;
487
488 case GPGME_STATUS_INQUIRE_MAXLEN:
489 if (ctx->status_cb && !ctx->full_status)
490 {
491 err = ctx->status_cb (ctx->status_cb_value, "INQUIRE_MAXLEN", args);
492 if (err)
493 return err;
494 }
495 break;
496
497 case GPGME_STATUS_DECRYPTION_COMPLIANCE_MODE:
498 PARSE_COMPLIANCE_FLAGS (args, &opd->result);
499 break;
500
501 default:
502 break;
503 }
504
505 return 0;
506 }
507
508
509 static gpgme_error_t
decrypt_status_handler(void * priv,gpgme_status_code_t code,char * args)510 decrypt_status_handler (void *priv, gpgme_status_code_t code, char *args)
511 {
512 gpgme_error_t err;
513
514 err = _gpgme_progress_status_handler (priv, code, args);
515 if (!err)
516 err = _gpgme_decrypt_status_handler (priv, code, args);
517 return err;
518 }
519
520
521 gpgme_error_t
_gpgme_op_decrypt_init_result(gpgme_ctx_t ctx,gpgme_data_t plaintext)522 _gpgme_op_decrypt_init_result (gpgme_ctx_t ctx, gpgme_data_t plaintext)
523 {
524 gpgme_error_t err;
525 void *hook;
526 op_data_t opd;
527
528 err = _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, &hook,
529 sizeof (*opd), release_op_data);
530 opd = hook;
531 if (err)
532 return err;
533
534 opd->last_recipient_p = &opd->result.recipients;
535 opd->plaintext_dserial = _gpgme_data_get_dserial (plaintext);
536 return 0;
537 }
538
539
540 gpgme_error_t
_gpgme_decrypt_start(gpgme_ctx_t ctx,int synchronous,gpgme_decrypt_flags_t flags,gpgme_data_t cipher,gpgme_data_t plain)541 _gpgme_decrypt_start (gpgme_ctx_t ctx, int synchronous,
542 gpgme_decrypt_flags_t flags,
543 gpgme_data_t cipher, gpgme_data_t plain)
544 {
545 gpgme_error_t err;
546
547 assert (!(flags & GPGME_DECRYPT_VERIFY));
548
549 err = _gpgme_op_reset (ctx, synchronous);
550 if (err)
551 return err;
552
553 err = _gpgme_op_decrypt_init_result (ctx, plain);
554 if (err)
555 return err;
556
557 if (!cipher)
558 return gpg_error (GPG_ERR_NO_DATA);
559 if (!plain)
560 return gpg_error (GPG_ERR_INV_VALUE);
561
562 if (err)
563 return err;
564
565 if (ctx->passphrase_cb)
566 {
567 err = _gpgme_engine_set_command_handler
568 (ctx->engine, _gpgme_passphrase_command_handler, ctx);
569 if (err)
570 return err;
571 }
572
573 _gpgme_engine_set_status_handler (ctx->engine, decrypt_status_handler, ctx);
574
575 return _gpgme_engine_op_decrypt (ctx->engine,
576 flags,
577 cipher, plain,
578 ctx->export_session_keys,
579 ctx->override_session_key,
580 ctx->auto_key_retrieve);
581 }
582
583
584 gpgme_error_t
gpgme_op_decrypt_start(gpgme_ctx_t ctx,gpgme_data_t cipher,gpgme_data_t plain)585 gpgme_op_decrypt_start (gpgme_ctx_t ctx, gpgme_data_t cipher,
586 gpgme_data_t plain)
587 {
588 gpgme_error_t err;
589
590 TRACE_BEG (DEBUG_CTX, "gpgme_op_decrypt_start", ctx,
591 "cipher=%p, plain=%p", cipher, plain);
592
593 if (!ctx)
594 return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
595
596 err = _gpgme_decrypt_start (ctx, 0, 0, cipher, plain);
597 return TRACE_ERR (err);
598 }
599
600
601 /* Decrypt ciphertext CIPHER within CTX and store the resulting
602 plaintext in PLAIN. */
603 gpgme_error_t
gpgme_op_decrypt(gpgme_ctx_t ctx,gpgme_data_t cipher,gpgme_data_t plain)604 gpgme_op_decrypt (gpgme_ctx_t ctx, gpgme_data_t cipher, gpgme_data_t plain)
605 {
606 gpgme_error_t err;
607
608 TRACE_BEG (DEBUG_CTX, "gpgme_op_decrypt", ctx,
609 "cipher=%p, plain=%p", cipher, plain);
610
611 if (!ctx)
612 return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
613
614 err = _gpgme_decrypt_start (ctx, 1, 0, cipher, plain);
615 if (!err)
616 err = _gpgme_wait_one (ctx);
617 ctx->ignore_mdc_error = 0; /* Always reset. */
618 return TRACE_ERR (err);
619 }
620