Line data Source code
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 : #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
79 51 : release_op_data (void *hook)
80 : {
81 51 : op_data_t opd = (op_data_t) hook;
82 51 : gpgme_recipient_t recipient = opd->result.recipients;
83 :
84 51 : free (opd->result.unsupported_algorithm);
85 51 : free (opd->result.file_name);
86 51 : free (opd->result.session_key);
87 51 : free (opd->result.symkey_algo);
88 :
89 143 : while (recipient)
90 : {
91 41 : gpgme_recipient_t next = recipient->next;
92 41 : free (recipient);
93 41 : recipient = next;
94 : }
95 51 : }
96 :
97 :
98 : gpgme_decrypt_result_t
99 46 : gpgme_op_decrypt_result (gpgme_ctx_t ctx)
100 : {
101 : void *hook;
102 : op_data_t opd;
103 : gpgme_error_t err;
104 :
105 46 : TRACE_BEG (DEBUG_CTX, "gpgme_op_decrypt_result", ctx);
106 :
107 46 : ctx->ignore_mdc_error = 0; /* Always reset this flag. */
108 :
109 46 : err = _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, &hook, -1, NULL);
110 46 : opd = hook;
111 46 : if (err || !opd)
112 : {
113 0 : TRACE_SUC0 ("result=(null)");
114 0 : return NULL;
115 : }
116 :
117 : /* Make sure that SYMKEY_ALGO has a value. */
118 46 : if (!opd->result.symkey_algo)
119 : {
120 1 : opd->result.symkey_algo = strdup ("?.?");
121 1 : if (!opd->result.symkey_algo)
122 : {
123 0 : TRACE_SUC0 ("result=(null)");
124 0 : return NULL;
125 : }
126 : }
127 :
128 : if (_gpgme_debug_trace ())
129 : {
130 : gpgme_recipient_t rcp;
131 :
132 46 : if (opd->result.unsupported_algorithm)
133 : {
134 0 : TRACE_LOG1 ("result: unsupported_algorithm: %s",
135 : opd->result.unsupported_algorithm);
136 : }
137 46 : if (opd->result.wrong_key_usage)
138 : {
139 0 : TRACE_LOG ("result: wrong key usage");
140 : }
141 46 : rcp = opd->result.recipients;
142 133 : while (rcp)
143 : {
144 41 : TRACE_LOG3 ("result: recipient: keyid=%s, pubkey_algo=%i, "
145 : "status=%s", rcp->keyid, rcp->pubkey_algo,
146 : gpg_strerror (rcp->status));
147 41 : rcp = rcp->next;
148 : }
149 46 : if (opd->result.file_name)
150 : {
151 33 : TRACE_LOG1 ("result: original file name: %s", opd->result.file_name);
152 : }
153 : }
154 :
155 46 : TRACE_SUC1 ("result=%p", &opd->result);
156 46 : 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
164 0 : 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 0 : if (!args)
172 0 : return trace_gpg_error (GPG_ERR_INV_ENGINE);
173 :
174 0 : args2 = strdup (args); /* Split modifies the input string. */
175 0 : nfields = _gpgme_split_fields (args2, field, DIM (field));
176 0 : if (nfields < 1)
177 : {
178 0 : free (args2);
179 0 : return trace_gpg_error (GPG_ERR_INV_ENGINE); /* Required arg missing. */
180 : }
181 0 : err = nfields < 2 ? 0 : atoi (field[1]);
182 :
183 0 : if (!strcmp (field[0], "decrypt.algorithm"))
184 : {
185 0 : if (gpg_err_code (err) == GPG_ERR_UNSUPPORTED_ALGORITHM
186 0 : && nfields > 2
187 0 : && strcmp (field[2], "?"))
188 : {
189 0 : opd->result.unsupported_algorithm = strdup (field[2]);
190 0 : if (!opd->result.unsupported_algorithm)
191 : {
192 0 : free (args2);
193 0 : return gpg_error_from_syserror ();
194 : }
195 : }
196 : }
197 0 : else if (!strcmp (field[0], "decrypt.keyusage"))
198 : {
199 0 : if (gpg_err_code (err) == GPG_ERR_WRONG_KEY_USAGE)
200 0 : opd->result.wrong_key_usage = 1;
201 : }
202 0 : else if (!strcmp (field[0], "pkdecrypt_failed"))
203 : {
204 0 : 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 0 : opd->pkdecrypt_failed = gpg_err_make (gpg_err_source (err),
211 : GPG_ERR_CANCELED);
212 0 : break;
213 :
214 : case GPG_ERR_BAD_PASSPHRASE:
215 : /* A bad passphrase is severe enough that we return this
216 : * error code. */
217 0 : opd->pkdecrypt_failed = err;
218 0 : break;
219 :
220 : default:
221 : /* For now all other error codes are ignored and the
222 : * standard DECRYPT_FAILED is returned. */
223 0 : break;
224 : }
225 : }
226 0 : else if (!strcmp (field[0], "nomdc_with_legacy_cipher"))
227 : {
228 0 : opd->result.legacy_cipher_nomdc = 1;
229 0 : opd->not_integrity_protected = 1;
230 : }
231 :
232 : /* Record the first error code. */
233 0 : if (err && !opd->first_status_error)
234 0 : opd->first_status_error = err;
235 :
236 :
237 0 : free (args2);
238 0 : return 0;
239 : }
240 :
241 :
242 : static gpgme_error_t
243 41 : 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 41 : rec = malloc (sizeof (*rec));
250 41 : if (!rec)
251 0 : return gpg_error_from_syserror ();
252 :
253 41 : rec->next = NULL;
254 41 : rec->keyid = rec->_keyid;
255 41 : rec->status = 0;
256 :
257 697 : for (i = 0; i < sizeof (rec->_keyid) - 1; i++)
258 : {
259 656 : if (args[i] == '\0' || args[i] == ' ')
260 : break;
261 :
262 656 : rec->_keyid[i] = args[i];
263 : }
264 41 : rec->_keyid[i] = '\0';
265 :
266 41 : args = &args[i];
267 41 : if (*args != '\0' && *args != ' ')
268 : {
269 0 : free (rec);
270 0 : return trace_gpg_error (GPG_ERR_INV_ENGINE);
271 : }
272 :
273 123 : while (*args == ' ')
274 41 : args++;
275 :
276 41 : if (*args)
277 : {
278 41 : gpg_err_set_errno (0);
279 41 : rec->pubkey_algo = _gpgme_map_pk_algo (strtol (args, &tail, 0), protocol);
280 41 : if (errno || args == tail || *tail != ' ')
281 : {
282 : /* The crypto backend does not behave. */
283 0 : free (rec);
284 0 : 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 41 : *recp = rec;
292 41 : 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
301 52 : 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 52 : if (!args)
310 0 : return trace_gpg_error (GPG_ERR_INV_ENGINE);
311 :
312 52 : args2 = strdup (args); /* Split modifies the input string. */
313 52 : nfields = _gpgme_split_fields (args2, field, DIM (field));
314 52 : if (nfields < 2)
315 : {
316 0 : free (args2);
317 0 : return trace_gpg_error (GPG_ERR_INV_ENGINE); /* Required arg missing. */
318 : }
319 :
320 52 : mdc = atoi (field[0]);
321 52 : algostr = _gpgme_cipher_algo_name (atoi (field[1]), protocol);
322 52 : aead_algo = nfields < 3? 0 : atoi (field[2]);
323 52 : modestr = _gpgme_cipher_mode_name (aead_algo, protocol);
324 :
325 52 : free (args2);
326 :
327 52 : free (opd->result.symkey_algo);
328 52 : if (!aead_algo && mdc != 2)
329 0 : opd->result.symkey_algo = _gpgme_strconcat (algostr, ".PGPCFB", NULL);
330 : else
331 52 : opd->result.symkey_algo = _gpgme_strconcat (algostr, ".", modestr, NULL);
332 52 : if (!opd->result.symkey_algo)
333 0 : return gpg_error_from_syserror ();
334 :
335 52 : if (!mdc && !aead_algo)
336 0 : opd->not_integrity_protected = 1;
337 :
338 52 : return 0;
339 : }
340 :
341 :
342 : gpgme_error_t
343 868 : _gpgme_decrypt_status_handler (void *priv, gpgme_status_code_t code,
344 : char *args)
345 : {
346 868 : gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
347 : gpgme_error_t err;
348 : void *hook;
349 : op_data_t opd;
350 :
351 868 : err = _gpgme_passphrase_status_handler (priv, code, args);
352 868 : if (err)
353 0 : return err;
354 :
355 868 : err = _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, &hook, -1, NULL);
356 868 : opd = hook;
357 868 : if (err)
358 0 : return err;
359 :
360 868 : switch (code)
361 : {
362 : case GPGME_STATUS_FAILURE:
363 0 : opd->failure_code = _gpgme_parse_failure (args);
364 0 : 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 52 : if (opd->failed)
375 : {
376 : /* This comes from a specialized ERROR status line. */
377 0 : if (opd->pkdecrypt_failed)
378 0 : 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 0 : if ((opd->not_integrity_protected && !ctx->ignore_mdc_error))
384 0 : 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 0 : if (opd->first_status_error)
392 0 : return opd->first_status_error;
393 :
394 : /* No secret key is pretty common reason. */
395 0 : if (opd->any_no_seckey)
396 0 : return gpg_error (GPG_ERR_NO_SECKEY);
397 :
398 : /* Generic decryption failed error code. */
399 0 : return gpg_error (GPG_ERR_DECRYPT_FAILED);
400 : }
401 52 : else if (!opd->okay)
402 : {
403 : /* No data was found. */
404 0 : return gpg_error (GPG_ERR_NO_DATA);
405 : }
406 52 : else if (opd->failure_code)
407 : {
408 : /* The engine returned failure code at program exit. */
409 0 : return opd->failure_code;
410 : }
411 52 : break;
412 :
413 : case GPGME_STATUS_DECRYPTION_INFO:
414 52 : err = parse_decryption_info (args, opd, ctx->protocol);
415 52 : if (err)
416 0 : return err;
417 52 : break;
418 :
419 : case GPGME_STATUS_DECRYPTION_OKAY:
420 52 : opd->okay = 1;
421 52 : break;
422 :
423 : case GPGME_STATUS_DECRYPTION_FAILED:
424 0 : 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 0 : if (!ctx->ignore_mdc_error)
431 0 : _gpgme_data_set_prop (NULL, opd->plaintext_dserial,
432 : DATA_PROP_BLANKOUT, 1);
433 0 : 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 0 : err = parse_status_error (args, opd);
441 0 : if (err)
442 0 : return err;
443 0 : break;
444 :
445 : case GPGME_STATUS_ENC_TO:
446 41 : err = parse_enc_to (args, opd->last_recipient_p, ctx->protocol);
447 41 : if (err)
448 0 : return err;
449 :
450 41 : opd->last_recipient_p = &(*opd->last_recipient_p)->next;
451 41 : break;
452 :
453 : case GPGME_STATUS_SESSION_KEY:
454 0 : if (opd->result.session_key)
455 0 : free (opd->result.session_key);
456 0 : opd->result.session_key = strdup(args);
457 0 : break;
458 :
459 : case GPGME_STATUS_NO_SECKEY:
460 : {
461 1 : gpgme_recipient_t rec = opd->result.recipients;
462 2 : while (rec)
463 : {
464 1 : if (!strcmp (rec->keyid, args))
465 : {
466 1 : rec->status = gpg_error (GPG_ERR_NO_SECKEY);
467 1 : break;
468 : }
469 0 : rec = rec->next;
470 : }
471 : /* FIXME: Is this ok? */
472 1 : if (!rec)
473 0 : return trace_gpg_error (GPG_ERR_INV_ENGINE);
474 1 : opd->any_no_seckey = 1;
475 : }
476 1 : break;
477 :
478 : case GPGME_STATUS_PLAINTEXT:
479 : {
480 50 : int mime = 0;
481 50 : err = _gpgme_parse_plaintext (args, &opd->result.file_name, &mime);
482 50 : if (err)
483 0 : return err;
484 50 : opd->result.is_mime = !!mime;
485 : }
486 50 : break;
487 :
488 : case GPGME_STATUS_INQUIRE_MAXLEN:
489 15 : if (ctx->status_cb && !ctx->full_status)
490 : {
491 0 : err = ctx->status_cb (ctx->status_cb_value, "INQUIRE_MAXLEN", args);
492 0 : if (err)
493 0 : return err;
494 : }
495 15 : break;
496 :
497 : case GPGME_STATUS_DECRYPTION_COMPLIANCE_MODE:
498 14 : PARSE_COMPLIANCE_FLAGS (args, &opd->result);
499 14 : break;
500 :
501 : default:
502 591 : break;
503 : }
504 :
505 868 : return 0;
506 : }
507 :
508 :
509 : static gpgme_error_t
510 507 : decrypt_status_handler (void *priv, gpgme_status_code_t code, char *args)
511 : {
512 : gpgme_error_t err;
513 :
514 507 : err = _gpgme_progress_status_handler (priv, code, args);
515 507 : if (!err)
516 507 : err = _gpgme_decrypt_status_handler (priv, code, args);
517 507 : return err;
518 : }
519 :
520 :
521 : gpgme_error_t
522 51 : _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 51 : err = _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, &hook,
529 : sizeof (*opd), release_op_data);
530 51 : opd = hook;
531 51 : if (err)
532 0 : return err;
533 :
534 51 : opd->last_recipient_p = &opd->result.recipients;
535 51 : opd->plaintext_dserial = _gpgme_data_get_dserial (plaintext);
536 51 : return 0;
537 : }
538 :
539 :
540 : gpgme_error_t
541 35 : _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 35 : assert (!(flags & GPGME_DECRYPT_VERIFY));
548 :
549 35 : err = _gpgme_op_reset (ctx, synchronous);
550 34 : if (err)
551 0 : return err;
552 :
553 34 : err = _gpgme_op_decrypt_init_result (ctx, plain);
554 34 : if (err)
555 0 : return err;
556 :
557 34 : if (!cipher)
558 0 : return gpg_error (GPG_ERR_NO_DATA);
559 34 : if (!plain)
560 0 : return gpg_error (GPG_ERR_INV_VALUE);
561 :
562 34 : if (err)
563 0 : return err;
564 :
565 34 : if (ctx->passphrase_cb)
566 : {
567 29 : err = _gpgme_engine_set_command_handler
568 : (ctx->engine, _gpgme_passphrase_command_handler, ctx);
569 29 : if (err)
570 0 : return err;
571 : }
572 :
573 34 : _gpgme_engine_set_status_handler (ctx->engine, decrypt_status_handler, ctx);
574 :
575 68 : return _gpgme_engine_op_decrypt (ctx->engine,
576 : flags,
577 : cipher, plain,
578 34 : ctx->export_session_keys,
579 34 : ctx->override_session_key,
580 34 : ctx->auto_key_retrieve);
581 : }
582 :
583 :
584 : gpgme_error_t
585 0 : 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 0 : TRACE_BEG2 (DEBUG_CTX, "gpgme_op_decrypt_start", ctx,
591 : "cipher=%p, plain=%p", cipher, plain);
592 :
593 0 : if (!ctx)
594 0 : return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
595 :
596 0 : err = _gpgme_decrypt_start (ctx, 0, 0, cipher, plain);
597 0 : 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
604 32 : gpgme_op_decrypt (gpgme_ctx_t ctx, gpgme_data_t cipher, gpgme_data_t plain)
605 : {
606 : gpgme_error_t err;
607 :
608 32 : TRACE_BEG2 (DEBUG_CTX, "gpgme_op_decrypt", ctx,
609 : "cipher=%p, plain=%p", cipher, plain);
610 :
611 32 : if (!ctx)
612 0 : return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
613 :
614 32 : err = _gpgme_decrypt_start (ctx, 1, 0, cipher, plain);
615 32 : if (!err)
616 32 : err = _gpgme_wait_one (ctx);
617 32 : ctx->ignore_mdc_error = 0; /* Always reset. */
618 32 : return TRACE_ERR (err);
619 : }
|