Example #1
0
/* 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;
}