示例#1
0
/* Created a detached signature for INDATA and write it to OUTDATA.
   On termination of the signing command engine_private_finished() is
   called with FILTER as the first argument.  */
int
op_gpgme_sign (protocol_t protocol, 
               gpgme_data_t indata, gpgme_data_t outdata,
               engine_filter_t filter, void *hwnd)
{
  gpg_error_t err;
  closure_data_t cld;
  gpgme_ctx_t ctx = NULL;
  gpgme_key_t sign_key = NULL;

  (void)hwnd;

  if (signer_dialog_box (&sign_key, NULL, 0) == -1)
    {
      log_debug ("%s:%s: leave (dialog failed)\n", SRCNAME, __func__);
      return gpg_error (GPG_ERR_CANCELED);  
    }

  cld = xcalloc (1, sizeof *cld);
  cld->closure = sign_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;

  gpgme_set_armor (ctx, 1);
  gpgme_set_passphrase_cb (ctx, passphrase_callback_box, &cld->pw_cb);
  cld->pw_cb.ctx = ctx;
  cld->pw_cb.ttl = opt.passwd_ttl;
  err = gpgme_signers_add (ctx, sign_key);
  if (!err)
    err = gpgme_op_sign_start (ctx, indata, outdata, GPGME_SIG_MODE_DETACH);

 leave:
  if (err)
    {
      xfree (cld);
      gpgme_release (ctx);
    }
  else
    engine_private_set_cancel (filter, ctx);
  gpgme_key_unref (sign_key);
  return err;
}
/**
 * seahorse_service_crypto_sign_text:
 * @crypto: SeahorseServiceCrypto
 * @signer: the signer keyid
 * @flags: 0 (ignored)
 * @cleartext: the text to sign
 * @crypttext: the clear text signature (out) (GPGME_SIG_MODE_CLEAR)
 * @error: an error to return
 *
 * DBus: SignText
 *
 * Signs the @cleartext and returns the signature in @crypttext
 *
 * Returns: TRUE on success
 */
gboolean
seahorse_service_crypto_sign_text (SeahorseServiceCrypto *crypto, const char *signer, 
                                   int flags, const char *cleartext, char **crypttext,
                                   GError **error)
{
    SeahorseObject *signkey = NULL;
    gpgme_error_t gerr;
    SeahorseGpgmeOperation *pop; 
    gpgme_data_t plain, cipher;
    gboolean ret = TRUE;
    
    /* 
     * TODO: Once we support different kinds of keys that support encryption
     * then all this logic will need to change. 
     */
    
    /* The signer */
    if (!signer || !signer[0]) 
        g_set_error (error, SEAHORSE_DBUS_ERROR, SEAHORSE_DBUS_ERROR_INVALID,
                     _("No signer specified"));
    
    signkey = seahorse_context_object_from_dbus (SCTX_APP (), signer);
    if (!signkey) {
        g_set_error (error, SEAHORSE_DBUS_ERROR, SEAHORSE_DBUS_ERROR_INVALID, 
                     _("Invalid or unrecognized signer: %s"), signer);
        return FALSE;
    }
        
    if (!SEAHORSE_IS_GPGME_KEY (signkey) || 
        !(seahorse_object_get_flags (signkey) & SEAHORSE_FLAG_CAN_SIGN)) {
        g_set_error (error, SEAHORSE_DBUS_ERROR, SEAHORSE_DBUS_ERROR_INVALID,
                     _("Key is not valid for signing: %s"), signer);
        return FALSE;
    }
    
    pop = seahorse_gpgme_operation_new (NULL);
    
    /* new data from text */
    gerr = gpgme_data_new_from_mem (&plain, cleartext, strlen (cleartext), FALSE);
    g_return_val_if_fail (GPG_IS_OK (gerr), FALSE);
    gerr = gpgme_data_new (&cipher);
    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 signage */
    gpgme_signers_add (pop->gctx, seahorse_gpgme_key_get_private (SEAHORSE_GPGME_KEY (signkey)));
    gerr = gpgme_op_sign_start (pop->gctx, plain, cipher, GPGME_SIG_MODE_CLEAR);

    /* Frees cipher */
    ret = process_crypto_result (pop, gerr, cipher, crypttext, NULL, error);
    
    g_object_unref (pop);
    gpgme_data_release (plain);
    return ret;
}
static gboolean
sign_start (SeahorseToolMode *mode, const gchar *uri, gpgme_data_t uridata,
            SeahorsePGPOperation *pop, GError **err)
{
    gpgme_data_t cipher;
    gpgme_error_t gerr;
    gchar *touri;

    g_assert (mode->signer);

    /* File to encrypt to */
    touri = seahorse_util_add_suffix (uri, SEAHORSE_SIG_SUFFIX,
                                      _("Choose Signature File Name for '%s'"));
    if (!touri)
        return FALSE;

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

    gpgme_set_armor (pop->gctx, seahorse_gconf_get_boolean (ARMOR_KEY));
    gpgme_set_textmode (pop->gctx, FALSE);

    /* Start actual signage */
    gpgme_signers_clear (pop->gctx);
    gpgme_signers_add (pop->gctx, mode->signer);
    gerr = gpgme_op_sign_start (pop->gctx, uridata, cipher, GPGME_SIG_MODE_DETACH);
    if (gerr != 0) {
        seahorse_util_gpgme_to_error (gerr, err);
        return FALSE;
    }

    return TRUE;
}
示例#4
0
文件: gpafilesignop.c 项目: gpg/gpa
static gpg_error_t
gpa_file_sign_operation_start (GpaFileSignOperation *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->plain, file_item->direct_in,
                                       file_item->direct_in_len, 0);
        if (err)
        {
            gpa_gpgme_warning (err);
            return err;
        }

        err = gpgme_data_new (&op->sig);
        if (err)
        {
            gpa_gpgme_warning (err);
            gpgme_data_release (op->plain);
            op->plain = NULL;
            return err;
        }
    }
    else
    {
        gchar *plain_filename = file_item->filename_in;
        char *filename_used;

        file_item->filename_out = destination_filename
                                  (plain_filename, gpgme_get_armor (GPA_OPERATION (op)->context->ctx),
                                   gpgme_get_protocol (GPA_OPERATION (op)->context->ctx), op->sign_type);

        /* Open the files */
        op->plain_fd = gpa_open_input (plain_filename, &op->plain,
                                       GPA_OPERATION (op)->window);
        if (op->plain_fd == -1)
            /* FIXME: Error value.  */
            return gpg_error (GPG_ERR_GENERAL);

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

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

    /* Start the operation */
    err = gpgme_op_sign_start (GPA_OPERATION (op)->context->ctx, op->plain,
                               op->sig, op->sign_type);
    if (err)
    {
        gpa_gpgme_warning (err);
        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;
}