/* Verify a detached message where the data is in the gpgme object DATA and the signature given as the string SIGNATUEE. */ int op_gpgme_verify (gpgme_protocol_t protocol, gpgme_data_t data, const char *signature, size_t sig_len, engine_filter_t filter, void *hwnd) { gpgme_error_t err; closure_data_t cld; gpgme_ctx_t ctx = NULL; gpgme_data_t sigobj = NULL; (void)hwnd; cld = xcalloc (1, sizeof *cld); cld->closure = verify_closure; cld->filter = filter; 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; err = gpgme_data_new_from_mem (&sigobj, signature, sig_len, 0); if (err) goto leave; cld->sigobj = sigobj; err = gpgme_op_verify_start (ctx, sigobj, data, NULL); leave: if (err) { gpgme_data_release (sigobj); xfree (cld); gpgme_release (ctx); } else engine_private_set_cancel (filter, ctx); return err; }
/** * seahorse_service_crypto_verify_text: * @crypto: #SeahorseServiceCrypto context * @ktype: "openpgp" * @flags: FLAG_QUIET for no notification * @crypttext: the text to decrypt * @cleartext: the plaintext after verification (out) * @signer: the signer if the text is signed (out) * @error: a potential error (out) * * DBus: VerifyText * * Decrypts the @crypttext and returns it in @cleartext. If the text * was signed, the signed is returned. * * Returns: TRUE on success */ gboolean seahorse_service_crypto_verify_text (SeahorseServiceCrypto *crypto, const gchar *ktype, int flags, const gchar *crypttext, gchar **cleartext, char **signer, 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 verifying: %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, strlen (crypttext), 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, TRUE); gpgme_set_armor (pop->gctx, TRUE); /* Do the decryption */ gerr = gpgme_op_verify_start (pop->gctx, cipher, NULL, plain); /* Frees plain */ ret = process_crypto_result (pop, gerr, plain, cleartext, NULL, 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 TRUE; }
static gboolean verify_start (SeahorseToolMode *mode, const gchar *uri, gpgme_data_t uridata, SeahorsePGPOperation *pop, GError **err) { gpgme_data_t plain; gpgme_error_t gerr; gchar *original, *unesc_uri; /* File to decrypt to */ original = seahorse_util_remove_suffix (uri, NULL); /* The original file doesn't exist, prompt for it */ if (!seahorse_util_uri_exists (original)) { GtkWidget *dialog; gchar *t; unesc_uri = g_uri_unescape_string (seahorse_util_uri_get_last (uri), NULL); t = g_strdup_printf (_("Choose Original File for '%s'"), unesc_uri); dialog = gtk_file_chooser_dialog_new (t, NULL, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); g_free (unesc_uri); g_free (t); gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (dialog), original); gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), FALSE); g_free (original); original = NULL; seahorse_tool_progress_block (TRUE); if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) original = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog)); seahorse_tool_progress_block (FALSE); gtk_widget_destroy (dialog); } if (!original) return FALSE; g_object_set_data_full (G_OBJECT (pop), "original-file", original, g_free); /* Open necessary files, release with operation */ plain = seahorse_vfs_data_create (original, SEAHORSE_VFS_READ, err); if (!plain) return FALSE; g_object_set_data_full (G_OBJECT (pop), "plain-data", plain, (GDestroyNotify)gpgme_data_release); /* Start actual verify */ gerr = gpgme_op_verify_start (pop->gctx, uridata, plain, NULL); if (gerr != 0) { seahorse_util_gpgme_to_error (gerr, err); return FALSE; } return TRUE; }