Blame src/decrypt.c

Packit Service 672cf4
/* decrypt.c - Decrypt function.
Packit Service 6c01f9
   Copyright (C) 2000 Werner Koch (dd9jn)
Packit Service 6c01f9
   Copyright (C) 2001, 2002, 2003, 2004, 2017 g10 Code GmbH
Packit Service 6c01f9
Packit Service 6c01f9
   This file is part of GPGME.
Packit Service 6c01f9
Packit Service 6c01f9
   GPGME is free software; you can redistribute it and/or modify it
Packit Service 6c01f9
   under the terms of the GNU Lesser General Public License as
Packit Service 6c01f9
   published by the Free Software Foundation; either version 2.1 of
Packit Service 6c01f9
   the License, or (at your option) any later version.
Packit Service 6c01f9
Packit Service 6c01f9
   GPGME is distributed in the hope that it will be useful, but
Packit Service 6c01f9
   WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 6c01f9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 6c01f9
   Lesser General Public License for more details.
Packit Service 6c01f9
Packit Service 6c01f9
   You should have received a copy of the GNU Lesser General Public
Packit Service 6c01f9
   License along with this program; if not, write to the Free Software
Packit Service 6c01f9
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
Packit Service 6c01f9
   02111-1307, USA.  */
Packit Service 672cf4
Packit Service 672cf4
#if HAVE_CONFIG_H
Packit Service 672cf4
#include <config.h>
Packit Service 672cf4
#endif
Packit Service 672cf4
#include <stdlib.h>
Packit Service 672cf4
#include <string.h>
Packit Service 672cf4
#include <errno.h>
Packit Service 672cf4
#include <assert.h>
Packit Service 672cf4
Packit Service 672cf4
#include "debug.h"
Packit Service 672cf4
#include "gpgme.h"
Packit Service 672cf4
#include "util.h"
Packit Service 672cf4
#include "context.h"
Packit Service 672cf4
#include "ops.h"
Packit Service 6c01f9
Packit Service 672cf4
Packit Service 672cf4

Packit Service 672cf4
typedef struct
Packit Service 672cf4
{
Packit Service 672cf4
  struct _gpgme_op_decrypt_result result;
Packit Service 672cf4
Packit Service 672cf4
  /* The error code from a FAILURE status line or 0.  */
Packit Service 672cf4
  gpg_error_t failure_code;
Packit Service 672cf4
Packit Service 672cf4
  int okay;
Packit Service 672cf4
Packit Service 672cf4
  /* A flag telling that the a decryption failed and an optional error
Packit Service 672cf4
   * code to further specify the failure.  */
Packit Service 672cf4
  int failed;
Packit Service 672cf4
  gpg_error_t pkdecrypt_failed;
Packit Service 672cf4
Packit Service 672cf4
  /* At least one secret key is not available.  gpg issues NO_SECKEY
Packit Service 672cf4
   * status lines for each key the message has been encrypted to but
Packit Service 672cf4
   * that secret key is not available.  This can't be done for hidden
Packit Service 672cf4
   * recipients, though.  We track it here to allow for a better error
Packit Service 6c01f9
   * message that the general DECRYPTION_FAILED. */
Packit Service 672cf4
  int any_no_seckey;
Packit Service 672cf4
Packit Service 672cf4
  /* A pointer to the next pointer of the last recipient in the list.
Packit Service 672cf4
     This makes appending new invalid signers painless while
Packit Service 672cf4
     preserving the order.  */
Packit Service 672cf4
  gpgme_recipient_t *last_recipient_p;
Packit Service 672cf4
} *op_data_t;
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
static void
Packit Service 672cf4
release_op_data (void *hook)
Packit Service 672cf4
{
Packit Service 672cf4
  op_data_t opd = (op_data_t) hook;
Packit Service 672cf4
  gpgme_recipient_t recipient = opd->result.recipients;
Packit Service 672cf4
Packit Service 6c01f9
  if (opd->result.unsupported_algorithm)
Packit Service 6c01f9
    free (opd->result.unsupported_algorithm);
Packit Service 6c01f9
Packit Service 6c01f9
  if (opd->result.file_name)
Packit Service 6c01f9
    free (opd->result.file_name);
Packit Service 6c01f9
Packit Service 6c01f9
  if (opd->result.session_key)
Packit Service 6c01f9
    free (opd->result.session_key);
Packit Service 672cf4
Packit Service 672cf4
  while (recipient)
Packit Service 672cf4
    {
Packit Service 672cf4
      gpgme_recipient_t next = recipient->next;
Packit Service 672cf4
      free (recipient);
Packit Service 672cf4
      recipient = next;
Packit Service 672cf4
    }
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
gpgme_decrypt_result_t
Packit Service 672cf4
gpgme_op_decrypt_result (gpgme_ctx_t ctx)
Packit Service 672cf4
{
Packit Service 672cf4
  void *hook;
Packit Service 672cf4
  op_data_t opd;
Packit Service 672cf4
  gpgme_error_t err;
Packit Service 672cf4
Packit Service 6c01f9
  TRACE_BEG (DEBUG_CTX, "gpgme_op_decrypt_result", ctx);
Packit Service 672cf4
Packit Service 672cf4
  err = _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, &hook, -1, NULL);
Packit Service 672cf4
  opd = hook;
Packit Service 672cf4
  if (err || !opd)
Packit Service 672cf4
    {
Packit Service 6c01f9
      TRACE_SUC0 ("result=(null)");
Packit Service 672cf4
      return NULL;
Packit Service 672cf4
    }
Packit Service 672cf4
Packit Service 672cf4
  if (_gpgme_debug_trace ())
Packit Service 672cf4
    {
Packit Service 672cf4
      gpgme_recipient_t rcp;
Packit Service 672cf4
Packit Service 672cf4
      if (opd->result.unsupported_algorithm)
Packit Service 672cf4
	{
Packit Service 6c01f9
	  TRACE_LOG1 ("result: unsupported_algorithm: %s",
Packit Service 672cf4
		      opd->result.unsupported_algorithm);
Packit Service 672cf4
	}
Packit Service 672cf4
      if (opd->result.wrong_key_usage)
Packit Service 672cf4
	{
Packit Service 672cf4
	  TRACE_LOG ("result: wrong key usage");
Packit Service 672cf4
	}
Packit Service 672cf4
      rcp = opd->result.recipients;
Packit Service 672cf4
      while (rcp)
Packit Service 672cf4
	{
Packit Service 6c01f9
	  TRACE_LOG3 ("result: recipient: keyid=%s, pubkey_algo=%i, "
Packit Service 672cf4
		      "status=%s", rcp->keyid, rcp->pubkey_algo,
Packit Service 672cf4
		      gpg_strerror (rcp->status));
Packit Service 672cf4
	  rcp = rcp->next;
Packit Service 672cf4
	}
Packit Service 672cf4
      if (opd->result.file_name)
Packit Service 672cf4
	{
Packit Service 6c01f9
	  TRACE_LOG1 ("result: original file name: %s", opd->result.file_name);
Packit Service 672cf4
	}
Packit Service 672cf4
    }
Packit Service 672cf4
Packit Service 6c01f9
  TRACE_SUC1 ("result=%p", &opd->result);
Packit Service 672cf4
  return &opd->result;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4

Packit Service 672cf4
/* Parse the ARGS of an error status line and record some error
Packit Service 672cf4
 * conditions at OPD.  Returns 0 on success.  */
Packit Service 672cf4
static gpgme_error_t
Packit Service 672cf4
parse_status_error (char *args, op_data_t opd)
Packit Service 672cf4
{
Packit Service 672cf4
  gpgme_error_t err;
Packit Service 672cf4
  char *field[3];
Packit Service 672cf4
  int nfields;
Packit Service 672cf4
  char *args2;
Packit Service 672cf4
Packit Service 672cf4
  if (!args)
Packit Service 672cf4
    return trace_gpg_error (GPG_ERR_INV_ENGINE);
Packit Service 672cf4
Packit Service 672cf4
  args2 = strdup (args); /* Split modifies the input string. */
Packit Service 672cf4
  nfields = _gpgme_split_fields (args2, field, DIM (field));
Packit Service 672cf4
  if (nfields < 1)
Packit Service 672cf4
    {
Packit Service 672cf4
      free (args2);
Packit Service 672cf4
      return trace_gpg_error (GPG_ERR_INV_ENGINE); /* Required arg missing.  */
Packit Service 672cf4
    }
Packit Service 672cf4
  err = nfields < 2 ? 0 : atoi (field[1]);
Packit Service 672cf4
Packit Service 672cf4
  if (!strcmp (field[0], "decrypt.algorithm"))
Packit Service 672cf4
    {
Packit Service 672cf4
      if (gpg_err_code (err) == GPG_ERR_UNSUPPORTED_ALGORITHM
Packit Service 672cf4
          && nfields > 2
Packit Service 672cf4
          && strcmp (field[2], "?"))
Packit Service 672cf4
        {
Packit Service 672cf4
          opd->result.unsupported_algorithm = strdup (field[2]);
Packit Service 672cf4
          if (!opd->result.unsupported_algorithm)
Packit Service 672cf4
            {
Packit Service 672cf4
              free (args2);
Packit Service 672cf4
              return gpg_error_from_syserror ();
Packit Service 672cf4
            }
Packit Service 672cf4
        }
Packit Service 672cf4
    }
Packit Service 672cf4
  else if (!strcmp (field[0], "decrypt.keyusage"))
Packit Service 672cf4
    {
Packit Service 672cf4
      if (gpg_err_code (err) == GPG_ERR_WRONG_KEY_USAGE)
Packit Service 672cf4
        opd->result.wrong_key_usage = 1;
Packit Service 672cf4
    }
Packit Service 672cf4
  else if (!strcmp (field[0], "pkdecrypt_failed"))
Packit Service 672cf4
    {
Packit Service 672cf4
      switch (gpg_err_code (err))
Packit Service 672cf4
        {
Packit Service 672cf4
        case GPG_ERR_CANCELED:
Packit Service 672cf4
        case GPG_ERR_FULLY_CANCELED:
Packit Service 672cf4
          /* It is better to return with a cancel error code than the
Packit Service 672cf4
           * general decryption failed error code.  */
Packit Service 672cf4
          opd->pkdecrypt_failed = gpg_err_make (gpg_err_source (err),
Packit Service 672cf4
                                                GPG_ERR_CANCELED);
Packit Service 672cf4
          break;
Packit Service 672cf4
Packit Service 672cf4
        case GPG_ERR_BAD_PASSPHRASE:
Packit Service 672cf4
          /* A bad passphrase is severe enough that we return this
Packit Service 672cf4
           * error code.  */
Packit Service 672cf4
          opd->pkdecrypt_failed = err;
Packit Service 672cf4
          break;
Packit Service 672cf4
Packit Service 672cf4
        default:
Packit Service 672cf4
          /* For now all other error codes are ignored and the
Packit Service 672cf4
           * standard DECRYPT_FAILED is returned.  */
Packit Service 672cf4
          break;
Packit Service 672cf4
        }
Packit Service 672cf4
    }
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
  free (args2);
Packit Service 672cf4
  return 0;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
static gpgme_error_t
Packit Service 672cf4
parse_enc_to (char *args, gpgme_recipient_t *recp, gpgme_protocol_t protocol)
Packit Service 672cf4
{
Packit Service 672cf4
  gpgme_recipient_t rec;
Packit Service 672cf4
  char *tail;
Packit Service 672cf4
  int i;
Packit Service 672cf4
Packit Service 672cf4
  rec = malloc (sizeof (*rec));
Packit Service 672cf4
  if (!rec)
Packit Service 672cf4
    return gpg_error_from_syserror ();
Packit Service 672cf4
Packit Service 672cf4
  rec->next = NULL;
Packit Service 672cf4
  rec->keyid = rec->_keyid;
Packit Service 672cf4
  rec->status = 0;
Packit Service 672cf4
Packit Service 672cf4
  for (i = 0; i < sizeof (rec->_keyid) - 1; i++)
Packit Service 672cf4
    {
Packit Service 672cf4
      if (args[i] == '\0' || args[i] == ' ')
Packit Service 672cf4
	break;
Packit Service 672cf4
Packit Service 672cf4
      rec->_keyid[i] = args[i];
Packit Service 672cf4
    }
Packit Service 672cf4
  rec->_keyid[i] = '\0';
Packit Service 672cf4
Packit Service 672cf4
  args = &args[i];
Packit Service 672cf4
  if (*args != '\0' && *args != ' ')
Packit Service 672cf4
    {
Packit Service 672cf4
      free (rec);
Packit Service 672cf4
      return trace_gpg_error (GPG_ERR_INV_ENGINE);
Packit Service 672cf4
    }
Packit Service 672cf4
Packit Service 672cf4
  while (*args == ' ')
Packit Service 672cf4
    args++;
Packit Service 672cf4
Packit Service 672cf4
  if (*args)
Packit Service 672cf4
    {
Packit Service 672cf4
      gpg_err_set_errno (0);
Packit Service 672cf4
      rec->pubkey_algo = _gpgme_map_pk_algo (strtol (args, &tail, 0), protocol);
Packit Service 672cf4
      if (errno || args == tail || *tail != ' ')
Packit Service 672cf4
	{
Packit Service 672cf4
	  /* The crypto backend does not behave.  */
Packit Service 672cf4
	  free (rec);
Packit Service 672cf4
	  return trace_gpg_error (GPG_ERR_INV_ENGINE);
Packit Service 672cf4
	}
Packit Service 672cf4
    }
Packit Service 672cf4
Packit Service 672cf4
  /* FIXME: The key length is always 0 right now, so no need to parse
Packit Service 672cf4
     it.  */
Packit Service 672cf4
Packit Service 672cf4
  *recp = rec;
Packit Service 672cf4
  return 0;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
gpgme_error_t
Packit Service 672cf4
_gpgme_decrypt_status_handler (void *priv, gpgme_status_code_t code,
Packit Service 672cf4
			       char *args)
Packit Service 672cf4
{
Packit Service 672cf4
  gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
Packit Service 672cf4
  gpgme_error_t err;
Packit Service 672cf4
  void *hook;
Packit Service 672cf4
  op_data_t opd;
Packit Service 672cf4
Packit Service 672cf4
  err = _gpgme_passphrase_status_handler (priv, code, args);
Packit Service 672cf4
  if (err)
Packit Service 672cf4
    return err;
Packit Service 672cf4
Packit Service 672cf4
  err = _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, &hook, -1, NULL);
Packit Service 672cf4
  opd = hook;
Packit Service 672cf4
  if (err)
Packit Service 672cf4
    return err;
Packit Service 672cf4
Packit Service 672cf4
  switch (code)
Packit Service 672cf4
    {
Packit Service 672cf4
    case GPGME_STATUS_FAILURE:
Packit Service 672cf4
      opd->failure_code = _gpgme_parse_failure (args);
Packit Service 672cf4
      break;
Packit Service 672cf4
Packit Service 672cf4
    case GPGME_STATUS_EOF:
Packit Service 6c01f9
      /* FIXME: These error values should probably be attributed to
Packit Service 6c01f9
	 the underlying crypto engine (as error source).  */
Packit Service 6c01f9
      if (opd->failed && opd->pkdecrypt_failed)
Packit Service 6c01f9
        return opd->pkdecrypt_failed;
Packit Service 6c01f9
      else if (opd->failed && opd->any_no_seckey)
Packit Service 6c01f9
	return gpg_error (GPG_ERR_NO_SECKEY);
Packit Service 6c01f9
      else if (opd->failed)
Packit Service 6c01f9
	return gpg_error (GPG_ERR_DECRYPT_FAILED);
Packit Service 672cf4
      else if (!opd->okay)
Packit Service 6c01f9
	return gpg_error (GPG_ERR_NO_DATA);
Packit Service 672cf4
      else if (opd->failure_code)
Packit Service 6c01f9
        return opd->failure_code;
Packit Service 672cf4
      break;
Packit Service 672cf4
Packit Service 672cf4
    case GPGME_STATUS_DECRYPTION_INFO:
Packit Service 6c01f9
      /* Fixme: Provide a way to return the used symmetric algorithm. */
Packit Service 672cf4
      break;
Packit Service 672cf4
Packit Service 672cf4
    case GPGME_STATUS_DECRYPTION_OKAY:
Packit Service 672cf4
      opd->okay = 1;
Packit Service 672cf4
      break;
Packit Service 672cf4
Packit Service 672cf4
    case GPGME_STATUS_DECRYPTION_FAILED:
Packit Service 672cf4
      opd->failed = 1;
Packit Service 672cf4
      break;
Packit Service 672cf4
Packit Service 672cf4
    case GPGME_STATUS_ERROR:
Packit Service 672cf4
      /* Note that this is an informational status code which should
Packit Service 6c01f9
         not lead to an error return unless it is something not
Packit Service 6c01f9
         related to the backend.  */
Packit Service 672cf4
      err = parse_status_error (args, opd);
Packit Service 672cf4
      if (err)
Packit Service 672cf4
        return err;
Packit Service 672cf4
      break;
Packit Service 672cf4
Packit Service 672cf4
    case GPGME_STATUS_ENC_TO:
Packit Service 672cf4
      err = parse_enc_to (args, opd->last_recipient_p, ctx->protocol);
Packit Service 672cf4
      if (err)
Packit Service 672cf4
	return err;
Packit Service 672cf4
Packit Service 672cf4
      opd->last_recipient_p = &(*opd->last_recipient_p)->next;
Packit Service 672cf4
      break;
Packit Service 672cf4
Packit Service 672cf4
    case GPGME_STATUS_SESSION_KEY:
Packit Service 672cf4
      if (opd->result.session_key)
Packit Service 672cf4
        free (opd->result.session_key);
Packit Service 672cf4
      opd->result.session_key = strdup(args);
Packit Service 672cf4
      break;
Packit Service 672cf4
Packit Service 672cf4
    case GPGME_STATUS_NO_SECKEY:
Packit Service 672cf4
      {
Packit Service 672cf4
	gpgme_recipient_t rec = opd->result.recipients;
Packit Service 672cf4
	while (rec)
Packit Service 672cf4
	  {
Packit Service 672cf4
	    if (!strcmp (rec->keyid, args))
Packit Service 672cf4
	      {
Packit Service 672cf4
		rec->status = gpg_error (GPG_ERR_NO_SECKEY);
Packit Service 672cf4
		break;
Packit Service 672cf4
	      }
Packit Service 672cf4
	    rec = rec->next;
Packit Service 672cf4
	  }
Packit Service 672cf4
	/* FIXME: Is this ok?  */
Packit Service 672cf4
	if (!rec)
Packit Service 672cf4
	  return trace_gpg_error (GPG_ERR_INV_ENGINE);
Packit Service 672cf4
        opd->any_no_seckey = 1;
Packit Service 672cf4
      }
Packit Service 672cf4
      break;
Packit Service 672cf4
Packit Service 672cf4
    case GPGME_STATUS_PLAINTEXT:
Packit Service 6c01f9
      err = _gpgme_parse_plaintext (args, &opd->result.file_name);
Packit Service 6c01f9
      if (err)
Packit Service 6c01f9
	return err;
Packit Service 672cf4
      break;
Packit Service 672cf4
Packit Service 672cf4
    case GPGME_STATUS_INQUIRE_MAXLEN:
Packit Service 672cf4
      if (ctx->status_cb && !ctx->full_status)
Packit Service 672cf4
        {
Packit Service 672cf4
          err = ctx->status_cb (ctx->status_cb_value, "INQUIRE_MAXLEN", args);
Packit Service 672cf4
          if (err)
Packit Service 672cf4
            return err;
Packit Service 672cf4
        }
Packit Service 672cf4
      break;
Packit Service 672cf4
Packit Service 672cf4
    case GPGME_STATUS_DECRYPTION_COMPLIANCE_MODE:
Packit Service 672cf4
      PARSE_COMPLIANCE_FLAGS (args, &opd->result);
Packit Service 672cf4
      break;
Packit Service 672cf4
Packit Service 672cf4
    default:
Packit Service 672cf4
      break;
Packit Service 672cf4
    }
Packit Service 672cf4
Packit Service 672cf4
  return 0;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
static gpgme_error_t
Packit Service 672cf4
decrypt_status_handler (void *priv, gpgme_status_code_t code, char *args)
Packit Service 672cf4
{
Packit Service 672cf4
  gpgme_error_t err;
Packit Service 672cf4
Packit Service 672cf4
  err = _gpgme_progress_status_handler (priv, code, args);
Packit Service 672cf4
  if (!err)
Packit Service 672cf4
    err = _gpgme_decrypt_status_handler (priv, code, args);
Packit Service 672cf4
  return err;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
gpgme_error_t
Packit Service 6c01f9
_gpgme_op_decrypt_init_result (gpgme_ctx_t ctx)
Packit Service 672cf4
{
Packit Service 672cf4
  gpgme_error_t err;
Packit Service 672cf4
  void *hook;
Packit Service 672cf4
  op_data_t opd;
Packit Service 672cf4
Packit Service 672cf4
  err = _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, &hook,
Packit Service 672cf4
			       sizeof (*opd), release_op_data);
Packit Service 672cf4
  opd = hook;
Packit Service 672cf4
  if (err)
Packit Service 672cf4
    return err;
Packit Service 672cf4
Packit Service 672cf4
  opd->last_recipient_p = &opd->result.recipients;
Packit Service 672cf4
  return 0;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
gpgme_error_t
Packit Service 672cf4
_gpgme_decrypt_start (gpgme_ctx_t ctx, int synchronous,
Packit Service 672cf4
                      gpgme_decrypt_flags_t flags,
Packit Service 672cf4
                      gpgme_data_t cipher, gpgme_data_t plain)
Packit Service 672cf4
{
Packit Service 672cf4
  gpgme_error_t err;
Packit Service 672cf4
Packit Service 672cf4
  assert (!(flags & GPGME_DECRYPT_VERIFY));
Packit Service 672cf4
Packit Service 672cf4
  err = _gpgme_op_reset (ctx, synchronous);
Packit Service 672cf4
  if (err)
Packit Service 672cf4
    return err;
Packit Service 672cf4
Packit Service 6c01f9
  err = _gpgme_op_decrypt_init_result (ctx);
Packit Service 672cf4
  if (err)
Packit Service 672cf4
    return err;
Packit Service 672cf4
Packit Service 672cf4
  if (!cipher)
Packit Service 672cf4
    return gpg_error (GPG_ERR_NO_DATA);
Packit Service 672cf4
  if (!plain)
Packit Service 672cf4
    return gpg_error (GPG_ERR_INV_VALUE);
Packit Service 672cf4
Packit Service 672cf4
  if (err)
Packit Service 672cf4
    return err;
Packit Service 672cf4
Packit Service 672cf4
  if (ctx->passphrase_cb)
Packit Service 672cf4
    {
Packit Service 672cf4
      err = _gpgme_engine_set_command_handler
Packit Service 6c01f9
	(ctx->engine, _gpgme_passphrase_command_handler, ctx, NULL);
Packit Service 672cf4
      if (err)
Packit Service 672cf4
	return err;
Packit Service 672cf4
    }
Packit Service 672cf4
Packit Service 672cf4
  _gpgme_engine_set_status_handler (ctx->engine, decrypt_status_handler, ctx);
Packit Service 672cf4
Packit Service 672cf4
  return _gpgme_engine_op_decrypt (ctx->engine,
Packit Service 672cf4
                                   flags,
Packit Service 672cf4
                                   cipher, plain,
Packit Service 672cf4
                                   ctx->export_session_keys,
Packit Service 672cf4
                                   ctx->override_session_key,
Packit Service 672cf4
                                   ctx->auto_key_retrieve);
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
gpgme_error_t
Packit Service 672cf4
gpgme_op_decrypt_start (gpgme_ctx_t ctx, gpgme_data_t cipher,
Packit Service 672cf4
			gpgme_data_t plain)
Packit Service 672cf4
{
Packit Service 672cf4
  gpgme_error_t err;
Packit Service 672cf4
Packit Service 6c01f9
  TRACE_BEG2 (DEBUG_CTX, "gpgme_op_decrypt_start", ctx,
Packit Service 672cf4
	      "cipher=%p, plain=%p", cipher, plain);
Packit Service 672cf4
Packit Service 672cf4
  if (!ctx)
Packit Service 672cf4
    return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
Packit Service 672cf4
Packit Service 672cf4
  err = _gpgme_decrypt_start (ctx, 0, 0, cipher, plain);
Packit Service 672cf4
  return TRACE_ERR (err);
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
/* Decrypt ciphertext CIPHER within CTX and store the resulting
Packit Service 672cf4
   plaintext in PLAIN.  */
Packit Service 672cf4
gpgme_error_t
Packit Service 672cf4
gpgme_op_decrypt (gpgme_ctx_t ctx, gpgme_data_t cipher, gpgme_data_t plain)
Packit Service 672cf4
{
Packit Service 672cf4
  gpgme_error_t err;
Packit Service 672cf4
Packit Service 6c01f9
  TRACE_BEG2 (DEBUG_CTX, "gpgme_op_decrypt", ctx,
Packit Service 672cf4
	      "cipher=%p, plain=%p", cipher, plain);
Packit Service 672cf4
Packit Service 672cf4
  if (!ctx)
Packit Service 672cf4
    return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
Packit Service 672cf4
Packit Service 672cf4
  err = _gpgme_decrypt_start (ctx, 1, 0, cipher, plain);
Packit Service 672cf4
  if (!err)
Packit Service 672cf4
    err = _gpgme_wait_one (ctx);
Packit Service 672cf4
  return TRACE_ERR (err);
Packit Service 672cf4
}