static gboolean
decrypt_start (SeahorseToolMode *mode, const gchar *uri, gpgme_data_t uridata,
               SeahorsePGPOperation *pop, GError **err)
{
    gpgme_data_t plain;
    gpgme_error_t gerr;
    gchar *touri;

    /* File to decrypt to */
    touri = seahorse_util_remove_suffix (uri, _("Choose Decrypted File Name for '%s'"));
    if (!touri)
        return FALSE;

    /* Open necessary files, release these with the operation */
    plain = seahorse_vfs_data_create (touri, SEAHORSE_VFS_WRITE | SEAHORSE_VFS_DELAY, err);
    g_free (touri);
    if (!plain)
        return FALSE;
    g_object_set_data_full (G_OBJECT (pop), "plain-data", plain,
                            (GDestroyNotify)gpgme_data_release);

    /* Start actual decryption */
    gerr = gpgme_op_decrypt_verify_start (pop->gctx, uridata, plain);
    if (gerr != 0) {
        seahorse_util_gpgme_to_error (gerr, err);
        return FALSE;
    }

    return TRUE;
}
Beispiel #2
0
/* Decrypt data from INDATA to OUTDATE.  If WITH_VERIFY is set, a
   signature of PGP/MIME combined message is also verified the same
   way as with op_gpgme_verify.  */
int
op_gpgme_decrypt (protocol_t protocol,
                  gpgme_data_t indata, gpgme_data_t outdata, 
                  engine_filter_t filter, void *hwnd,
                  int with_verify)
{
  gpgme_error_t err;
  closure_data_t cld;
  gpgme_ctx_t ctx = NULL;
  
  (void)hwnd;

  cld = xcalloc (1, sizeof *cld);
  cld->closure = decrypt_closure;
  cld->filter = filter;
  cld->with_verify = with_verify;

  err = gpgme_new (&ctx);
  if (err)
    goto leave;
  gpgme_set_progress_cb (ctx, NULL, cld);
  switch (protocol)
    {
    case PROTOCOL_OPENPGP:  /* Gpgme's default.  */
      break;
    case PROTOCOL_SMIME:
      err = gpgme_set_protocol (ctx, GPGME_PROTOCOL_CMS);
      break;
    default:
      err = gpg_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
      break;
    }
  if (err)
    goto leave;

  /* Note: We do no error checking for the next call because some
     backends may not implement a command hanler at all.  */
  gpgme_set_passphrase_cb (ctx, passphrase_callback_box, &cld->pw_cb);
  cld->pw_cb.ctx = ctx;

  if (with_verify) 
    err = gpgme_op_decrypt_verify_start (ctx, indata, outdata);
  else
    err = gpgme_op_decrypt_start (ctx, indata, outdata);


 leave:
  if (err)
    {
      xfree (cld);
      gpgme_release (ctx);
    }
  else
    engine_private_set_cancel (filter, ctx);
  return err;
}
/**
* crypto: SeahorseServiceCrypto context
* ktype: "openpgp"
* flags: FLAG_QUIET for no notification
* crypttext: the text to decrypt
* cryptlength: the length of the crypto text
* cleartext: the decrypted text (out)
* clearlength: The length of the clear text (out)
* signer: the signer if the text is signed (out)
* textmode: TRUE to switch textmode on
* ascii_armor: TRUE to switch ascii armor on
* error: a potential error (out)
*
* Decrypts any buffer (text and data). Can be used by DBus API functions
*
* Returns TRUE on success
**/
static gboolean
crypto_decrypt_generic (SeahorseServiceCrypto *crypto,
                        const char *ktype, int flags,
                        const char *crypttext, gsize cryptlength,
                        char **cleartext, gsize *clearlength,
                        char **signer, gboolean textmode,
                        gboolean ascii_armor, GError **error)

{
    gpgme_verify_result_t status;
    gpgme_error_t gerr;
    SeahorseGpgmeOperation *pop;
    gpgme_data_t plain, cipher;
    gboolean ret = TRUE;
    GQuark keyid;

    if (!g_str_equal (ktype, g_quark_to_string (SEAHORSE_PGP))) {
        g_set_error (error, SEAHORSE_DBUS_ERROR, SEAHORSE_DBUS_ERROR_INVALID,
                     _("Invalid key type for decryption: %s"), ktype);
        return FALSE;
    }

    /*
     * TODO: Once we support different kinds of keys that support encryption
     * then all this logic will need to change.
     */

    pop = seahorse_gpgme_operation_new (NULL);

    /* new data from text */
    gerr = gpgme_data_new_from_mem (&cipher, crypttext, cryptlength, FALSE);
    g_return_val_if_fail (GPG_IS_OK (gerr), FALSE);
    gerr = gpgme_data_new (&plain);
    g_return_val_if_fail (GPG_IS_OK (gerr), FALSE);

    /* encrypt with armor */
    gpgme_set_textmode (pop->gctx, textmode);
    gpgme_set_armor (pop->gctx, ascii_armor);

    /* Do the decryption */
    gerr = gpgme_op_decrypt_verify_start (pop->gctx, cipher, plain);

    /* Frees plain */
    ret = process_crypto_result (pop, gerr, plain, cleartext, clearlength, error);

    if (ret) {
        *signer = NULL;
        status = gpgme_op_verify_result (pop->gctx);

        if (status->signatures) {
            if (!(flags & FLAG_QUIET))
                notify_signatures (NULL, status);
            if (status->signatures->summary & GPGME_SIGSUM_GREEN ||
                status->signatures->summary & GPGME_SIGSUM_VALID ||
                status->signatures->summary & GPGME_SIGSUM_KEY_MISSING) {
                keyid = seahorse_pgp_key_canonize_id (status->signatures->fpr);
                *signer = seahorse_context_id_to_dbus (SCTX_APP (), keyid);
            }
        }
    }

    g_object_unref (pop);
    gpgme_data_release (cipher);
    return ret;
}
Beispiel #4
0
static gpg_error_t
gpa_file_decrypt_operation_start (GpaFileDecryptOperation *op,
				  gpa_file_item_t file_item)
{
  gpg_error_t err;

  if (file_item->direct_in)
    {
      /* No copy is made.  */
      err = gpgme_data_new_from_mem (&op->cipher, file_item->direct_in,
				     file_item->direct_in_len, 0);
      if (err)
	{
	  gpa_gpgme_warning (err);
	  return err;
	}

      err = gpgme_data_new (&op->plain);
      if (err)
	{
	  gpa_gpgme_warning (err);
	  gpgme_data_release (op->cipher);
	  op->plain = NULL;
	  return err;
	}

      gpgme_set_protocol (GPA_OPERATION (op)->context->ctx,
                          is_cms_data (file_item->direct_in,
                                       file_item->direct_in_len) ?
                          GPGME_PROTOCOL_CMS : GPGME_PROTOCOL_OpenPGP);
    }
  else
    {
      gchar *cipher_filename = file_item->filename_in;
      char *filename_used;

      file_item->filename_out = destination_filename (cipher_filename);
      /* Open the files */
      op->cipher_fd = gpa_open_input (cipher_filename, &op->cipher,
				  GPA_OPERATION (op)->window);
      if (op->cipher_fd == -1)
	/* FIXME: Error value.  */
	return gpg_error (GPG_ERR_GENERAL);

      op->plain_fd = gpa_open_output (file_item->filename_out, &op->plain,
				      GPA_OPERATION (op)->window,
                                      &filename_used);
      if (op->plain_fd == -1)
	{
	  gpgme_data_release (op->cipher);
	  close (op->cipher_fd);
          xfree (filename_used);
	  /* FIXME: Error value.  */
	  return gpg_error (GPG_ERR_GENERAL);
	}

      xfree (file_item->filename_out);
      file_item->filename_out = filename_used;

      gpgme_set_protocol (GPA_OPERATION (op)->context->ctx,
                          is_cms_file (cipher_filename) ?
                          GPGME_PROTOCOL_CMS : GPGME_PROTOCOL_OpenPGP);
    }

  /* Start the operation.  */
  err = gpgme_op_decrypt_verify_start (GPA_OPERATION (op)->context->ctx,
				       op->cipher, op->plain);
  if (err)
    {
      gpa_gpgme_warning (err);

      gpgme_data_release (op->plain);
      op->plain = NULL;
      close (op->plain_fd);
      op->plain_fd = -1;
      gpgme_data_release (op->cipher);
      op->cipher = NULL;
      close (op->cipher_fd);
      op->cipher_fd = -1;

      return err;
    }

  /* Show and update the progress dialog.  */
  gtk_widget_show_all (GPA_FILE_OPERATION (op)->progress_dialog);
  gpa_progress_dialog_set_label (GPA_PROGRESS_DIALOG
				 (GPA_FILE_OPERATION (op)->progress_dialog),
				 file_item->direct_name
				 ? file_item->direct_name
				 : file_item->filename_in);
  return 0;
}