[gmime] Share code between gpg and pkcs7 contexts
- From: Jeffrey Stedfast <fejj src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gmime] Share code between gpg and pkcs7 contexts
- Date: Fri, 10 Mar 2017 23:27:00 +0000 (UTC)
commit e5a8f5c16a824b9b8d5760c98697f2dcc9929f75
Author: Jeffrey Stedfast <jestedfa microsoft com>
Date: Fri Mar 10 13:11:38 2017 -0500
Share code between gpg and pkcs7 contexts
gmime/gmime-gpg-context.c | 275 +--------------------------------
gmime/gmime-gpgme-utils.c | 316 ++++++++++++++++++++++++++++++++++++-
gmime/gmime-gpgme-utils.h | 18 ++-
gmime/gmime-pkcs7-context.c | 363 +------------------------------------------
tests/test-pgpmime.c | 13 ++-
5 files changed, 345 insertions(+), 640 deletions(-)
---
diff --git a/gmime/gmime-gpg-context.c b/gmime/gmime-gpg-context.c
index 29de2e4..0f453f2 100644
--- a/gmime/gmime-gpg-context.c
+++ b/gmime/gmime-gpg-context.c
@@ -266,49 +266,6 @@ gpg_get_key_exchange_protocol (GMimeCryptoContext *ctx)
return "application/pgp-keys";
}
-#ifdef ENABLE_CRYPTO
-static ssize_t
-gpg_stream_read (void *stream, void *buffer, size_t size)
-{
- return g_mime_stream_read ((GMimeStream *) stream, (char *) buffer, size);
-}
-
-static ssize_t
-gpg_stream_write (void *stream, const void *buffer, size_t size)
-{
- return g_mime_stream_write ((GMimeStream *) stream, (const char *) buffer, size);
-}
-
-static off_t
-gpg_stream_seek (void *stream, off_t offset, int whence)
-{
- switch (whence) {
- case SEEK_SET:
- return (off_t) g_mime_stream_seek ((GMimeStream *) stream, (gint64) offset,
GMIME_STREAM_SEEK_SET);
- case SEEK_CUR:
- return (off_t) g_mime_stream_seek ((GMimeStream *) stream, (gint64) offset,
GMIME_STREAM_SEEK_CUR);
- case SEEK_END:
- return (off_t) g_mime_stream_seek ((GMimeStream *) stream, (gint64) offset,
GMIME_STREAM_SEEK_END);
- default:
- return -1;
- }
-}
-
-static void
-gpg_stream_free (void *stream)
-{
- /* no-op */
-}
-
-static struct gpgme_data_cbs gpg_stream_funcs = {
- gpg_stream_read,
- gpg_stream_write,
- gpg_stream_seek,
- gpg_stream_free
-};
-
-#endif /* ENABLE_CRYPTO */
-
static int
gpg_sign (GMimeCryptoContext *context, gboolean detach, const char *userid, GMimeDigestAlgo digest,
GMimeStream *istream, GMimeStream *ostream, GError **err)
@@ -316,45 +273,10 @@ gpg_sign (GMimeCryptoContext *context, gboolean detach, const char *userid, GMim
#ifdef ENABLE_CRYPTO
gpgme_sig_mode_t mode = detach ? GPGME_SIG_MODE_DETACH : GPGME_SIG_MODE_CLEAR;
GMimeGpgContext *gpg = (GMimeGpgContext *) context;
- gpgme_sign_result_t result;
- gpgme_data_t input, output;
- gpgme_error_t error;
-
- if (!g_mime_gpgme_add_signer (gpg->ctx, userid, err))
- return -1;
-
- if ((error = gpgme_data_new_from_cbs (&input, &gpg_stream_funcs, istream)) != GPG_ERR_NO_ERROR) {
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open input stream: %s"),
gpgme_strerror (error));
- gpgme_signers_clear (gpg->ctx);
- return -1;
- }
-
- if ((error = gpgme_data_new_from_cbs (&output, &gpg_stream_funcs, ostream)) != GPG_ERR_NO_ERROR) {
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open output stream: %s"),
gpgme_strerror (error));
- gpgme_signers_clear (gpg->ctx);
- gpgme_data_release (input);
- return -1;
- }
gpgme_set_textmode (gpg->ctx, !detach);
- /* sign the input stream */
- if ((error = gpgme_op_sign (gpg->ctx, input, output, mode)) != GPG_ERR_NO_ERROR) {
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Signing failed: %s"), gpgme_strerror (error));
- gpgme_signers_clear (gpg->ctx);
- gpgme_data_release (output);
- gpgme_data_release (input);
- return -1;
- }
-
- gpgme_signers_clear (gpg->ctx);
- gpgme_data_release (output);
- gpgme_data_release (input);
-
- /* return the digest algorithm used for signing */
- result = gpgme_op_sign_result (gpg->ctx);
-
- return (GMimeDigestAlgo) result->signatures->hash_algo;
+ return g_mime_gpgme_sign (gpg->ctx, mode, userid, digest, istream, ostream, err);
#else
g_set_error_literal (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED, _("PGP support is not enabled in
this build"));
@@ -368,56 +290,8 @@ gpg_verify (GMimeCryptoContext *context, GMimeVerifyFlags flags, GMimeStream *is
{
#ifdef ENABLE_CRYPTO
GMimeGpgContext *gpg = (GMimeGpgContext *) context;
- gpgme_data_t sig, signed_text, plain;
- gpgme_error_t error;
-
- if (sigstream != NULL) {
- /* if @sigstream is non-NULL, then it is a detached signature */
- if ((error = gpgme_data_new_from_cbs (&signed_text, &gpg_stream_funcs, istream)) !=
GPG_ERR_NO_ERROR) {
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open input stream: %s"),
gpgme_strerror (error));
- return NULL;
- }
-
- if ((error = gpgme_data_new_from_cbs (&sig, &gpg_stream_funcs, sigstream)) !=
GPG_ERR_NO_ERROR) {
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open signature stream: %s"),
gpgme_strerror (error));
- gpgme_data_release (signed_text);
- return NULL;
- }
-
- plain = NULL;
- } else if (ostream != NULL) {
- /* if @ostream is non-NULL, then we are expected to write the extracted plaintext to it */
- if ((error = gpgme_data_new_from_cbs (&sig, &gpg_stream_funcs, istream)) != GPG_ERR_NO_ERROR)
{
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open input stream: %s"),
gpgme_strerror (error));
- return NULL;
- }
-
- if ((error = gpgme_data_new_from_cbs (&plain, &gpg_stream_funcs, ostream)) !=
GPG_ERR_NO_ERROR) {
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open output stream: %s"),
gpgme_strerror (error));
- gpgme_data_release (sig);
- return NULL;
- }
-
- signed_text = NULL;
- } else {
- g_set_error_literal (err, GMIME_GPGME_ERROR, error, _("Missing signature stream or output
stream"));
- return NULL;
- }
- error = gpgme_op_verify (gpg->ctx, sig, signed_text, plain);
- if (signed_text)
- gpgme_data_release (signed_text);
- if (plain)
- gpgme_data_release (plain);
- gpgme_data_release (sig);
-
- if (error != GPG_ERR_NO_ERROR) {
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not verify gpg signature: %s"),
gpgme_strerror (error));
- return NULL;
- }
-
- /* get/return the gpg signatures */
- return g_mime_gpgme_get_signatures (gpg->ctx, TRUE);
+ return g_mime_gpgme_verify (gpg->ctx, flags, istream, sigstream, ostream, err);
#else
g_set_error_literal (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED, _("PGP support is not enabled in
this build"));
@@ -432,66 +306,8 @@ gpg_encrypt (GMimeCryptoContext *context, gboolean sign, const char *userid, GMi
{
#ifdef ENABLE_CRYPTO
GMimeGpgContext *gpg = (GMimeGpgContext *) context;
- gpgme_encrypt_flags_t encrypt_flags = 0;
- gpgme_data_t input, output;
- gpgme_error_t error;
- gpgme_key_t *rcpts;
- gpgme_key_t key;
- guint i;
-
- if (flags & GMIME_ENCRYPT_FLAGS_ALWAYS_TRUST)
- encrypt_flags |= GPGME_ENCRYPT_ALWAYS_TRUST;
- /* create an array of recipient keys for GpgMe */
- rcpts = g_new0 (gpgme_key_t, recipients->len + 1);
- for (i = 0; i < recipients->len; i++) {
- if (!(key = g_mime_gpgme_get_key_by_name (gpg->ctx, recipients->pdata[i], FALSE, err))) {
- g_mime_gpgme_keylist_free (rcpts);
- return -1;
- }
-
- rcpts[i] = key;
- }
-
- if ((error = gpgme_data_new_from_cbs (&input, &gpg_stream_funcs, istream)) != GPG_ERR_NO_ERROR) {
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open input stream: %s"),
gpgme_strerror (error));
- g_mime_gpgme_keylist_free (rcpts);
- return -1;
- }
-
- if ((error = gpgme_data_new_from_cbs (&output, &gpg_stream_funcs, ostream)) != GPG_ERR_NO_ERROR) {
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open output stream: %s"),
gpgme_strerror (error));
- g_mime_gpgme_keylist_free (rcpts);
- gpgme_data_release (input);
- return -1;
- }
-
- /* encrypt the input stream */
- if (sign) {
- if (!g_mime_gpgme_add_signer (gpg->ctx, userid, err)) {
- g_mime_gpgme_keylist_free (rcpts);
- gpgme_data_release (output);
- gpgme_data_release (input);
- return -1;
- }
-
- error = gpgme_op_encrypt_sign (gpg->ctx, rcpts, encrypt_flags, input, output);
-
- gpgme_signers_clear (gpg->ctx);
- } else {
- error = gpgme_op_encrypt (gpg->ctx, rcpts, encrypt_flags, input, output);
- }
-
- g_mime_gpgme_keylist_free (rcpts);
- gpgme_data_release (output);
- gpgme_data_release (input);
-
- if (error != GPG_ERR_NO_ERROR) {
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Encryption failed: %s"), gpgme_strerror
(error));
- return -1;
- }
-
- return 0;
+ return g_mime_gpgme_encrypt (gpg->ctx, sign, userid, digest, flags, recipients, istream, ostream,
err);
#else
g_set_error_literal (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED, _("PGP support is not enabled in
this build"));
@@ -505,53 +321,8 @@ gpg_decrypt (GMimeCryptoContext *context, GMimeDecryptFlags flags, const char *s
{
#ifdef ENABLE_CRYPTO
GMimeGpgContext *gpg = (GMimeGpgContext *) context;
- GMimeDecryptResult *result;
- gpgme_decrypt_result_t res;
- gpgme_data_t input, output;
- gpgme_error_t error;
-
- if ((error = gpgme_data_new_from_cbs (&input, &gpg_stream_funcs, istream)) != GPG_ERR_NO_ERROR) {
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open input stream: %s"),
gpgme_strerror (error));
- return NULL;
- }
-
- if ((error = gpgme_data_new_from_cbs (&output, &gpg_stream_funcs, ostream)) != GPG_ERR_NO_ERROR) {
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open output stream: %s"),
gpgme_strerror (error));
- gpgme_data_release (input);
- return NULL;
- }
-
- if (flags & GMIME_DECRYPT_FLAGS_EXPORT_SESSION_KEY)
- gpgme_set_ctx_flag (gpg->ctx, "export-session-key", "1");
- if (session_key)
- gpgme_set_ctx_flag (gpg->ctx, "override-session-key", session_key);
-
- /* decrypt the input stream */
- if ((error = gpgme_op_decrypt_verify (gpg->ctx, input, output)) != GPG_ERR_NO_ERROR) {
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Decryption failed: %s"), gpgme_strerror
(error));
-
- if (flags & GMIME_DECRYPT_FLAGS_EXPORT_SESSION_KEY)
- gpgme_set_ctx_flag (gpg->ctx, "export-session-key", "0");
-
- if (session_key)
- gpgme_set_ctx_flag (gpg->ctx, "override-session-key", NULL);
-
- gpgme_data_release (output);
- gpgme_data_release (input);
- return NULL;
- }
-
- if (flags & GMIME_DECRYPT_FLAGS_EXPORT_SESSION_KEY)
- gpgme_set_ctx_flag (gpg->ctx, "export-session-key", "0");
-
- if (session_key)
- gpgme_set_ctx_flag (gpg->ctx, "override-session-key", NULL);
-
- gpgme_data_release (output);
- gpgme_data_release (input);
-
- return g_mime_gpgme_get_decrypt_result (gpg->ctx);
+ return g_mime_gpgme_decrypt (gpg->ctx, flags, session_key, istream, ostream, err);
#else
g_set_error_literal (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED, _("PGP support is not enabled in
this build"));
@@ -564,25 +335,8 @@ gpg_import_keys (GMimeCryptoContext *context, GMimeStream *istream, GError **err
{
#ifdef ENABLE_CRYPTO
GMimeGpgContext *gpg = (GMimeGpgContext *) context;
- gpgme_data_t keydata;
- gpgme_error_t error;
- if ((error = gpgme_data_new_from_cbs (&keydata, &gpg_stream_funcs, istream)) != GPG_ERR_NO_ERROR) {
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open input stream: %s"),
gpgme_strerror (error));
- return -1;
- }
-
- /* import the key(s) */
- if ((error = gpgme_op_import (gpg->ctx, keydata)) != GPG_ERR_NO_ERROR) {
- //printf ("import error (%d): %s\n", error & GPG_ERR_CODE_MASK, gpg_strerror (error));
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not import key data: %s"),
gpgme_strerror (error));
- gpgme_data_release (keydata);
- return -1;
- }
-
- gpgme_data_release (keydata);
-
- return 0;
+ return g_mime_gpgme_import (gpg->ctx, istream, err);
#else
g_set_error_literal (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED, _("PGP support is not enabled in
this build"));
@@ -595,25 +349,8 @@ gpg_export_keys (GMimeCryptoContext *context, const char *keys[], GMimeStream *o
{
#ifdef ENABLE_CRYPTO
GMimeGpgContext *gpg = (GMimeGpgContext *) context;
- gpgme_data_t keydata;
- gpgme_error_t error;
- guint i;
-
- if ((error = gpgme_data_new_from_cbs (&keydata, &gpg_stream_funcs, ostream)) != GPG_ERR_NO_ERROR) {
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open output stream: %s"),
gpgme_strerror (error));
- return -1;
- }
-
- /* export the key(s) */
- if ((error = gpgme_op_export_ext (gpg->ctx, keys, 0, keydata)) != GPG_ERR_NO_ERROR) {
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not export key data: %s"),
gpgme_strerror (error));
- gpgme_data_release (keydata);
- return -1;
- }
-
- gpgme_data_release (keydata);
- return 0;
+ return g_mime_gpgme_export (gpg->ctx, keys, ostream, err);
#else
g_set_error_literal (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED, _("PGP support is not enabled in
this build"));
diff --git a/gmime/gmime-gpgme-utils.c b/gmime/gmime-gpgme-utils.c
index 9a7c208..964aea3 100644
--- a/gmime/gmime-gpgme-utils.c
+++ b/gmime/gmime-gpgme-utils.c
@@ -32,6 +32,46 @@
#define _(x) x
+static ssize_t
+g_mime_gpgme_stream_read (void *stream, void *buffer, size_t size)
+{
+ return g_mime_stream_read ((GMimeStream *) stream, (char *) buffer, size);
+}
+
+static ssize_t
+g_mime_gpgme_stream_write (void *stream, const void *buffer, size_t size)
+{
+ return g_mime_stream_write ((GMimeStream *) stream, (const char *) buffer, size);
+}
+
+static off_t
+g_mime_gpgme_stream_seek (void *stream, off_t offset, int whence)
+{
+ switch (whence) {
+ case SEEK_SET:
+ return (off_t) g_mime_stream_seek ((GMimeStream *) stream, (gint64) offset,
GMIME_STREAM_SEEK_SET);
+ case SEEK_CUR:
+ return (off_t) g_mime_stream_seek ((GMimeStream *) stream, (gint64) offset,
GMIME_STREAM_SEEK_CUR);
+ case SEEK_END:
+ return (off_t) g_mime_stream_seek ((GMimeStream *) stream, (gint64) offset,
GMIME_STREAM_SEEK_END);
+ default:
+ return -1;
+ }
+}
+
+static void
+g_mime_gpgme_stream_free (void *stream)
+{
+ /* no-op */
+}
+
+static struct gpgme_data_cbs gpg_stream_funcs = {
+ g_mime_gpgme_stream_read,
+ g_mime_gpgme_stream_write,
+ g_mime_gpgme_stream_seek,
+ g_mime_gpgme_stream_free
+};
+
gpgme_error_t
g_mime_gpgme_passphrase_callback (void *hook, const char *uid_hint, const char *passphrase_info, int
prev_was_bad, int fd)
{
@@ -63,7 +103,7 @@ g_mime_gpgme_passphrase_callback (void *hook, const char *uid_hint, const char *
#define KEY_IS_OK(k) (!((k)->expired || (k)->revoked || \
(k)->disabled || (k)->invalid))
-gpgme_key_t
+static gpgme_key_t
g_mime_gpgme_get_key_by_name (gpgme_ctx_t ctx, const char *name, gboolean secret, GError **err)
{
time_t now = time (NULL);
@@ -146,7 +186,7 @@ g_mime_gpgme_get_key_by_name (gpgme_ctx_t ctx, const char *name, gboolean secret
return key;
}
-gboolean
+static gboolean
g_mime_gpgme_add_signer (gpgme_ctx_t ctx, const char *signer, GError **err)
{
gpgme_key_t key = NULL;
@@ -166,6 +206,47 @@ g_mime_gpgme_add_signer (gpgme_ctx_t ctx, const char *signer, GError **err)
return TRUE;
}
+int
+g_mime_gpgme_sign (gpgme_ctx_t ctx, gpgme_sig_mode_t mode, const char *userid, GMimeDigestAlgo digest,
+ GMimeStream *istream, GMimeStream *ostream, GError **err)
+{
+ gpgme_sign_result_t result;
+ gpgme_data_t input, output;
+ gpgme_error_t error;
+
+ if (!g_mime_gpgme_add_signer (ctx, userid, err))
+ return -1;
+
+ if ((error = gpgme_data_new_from_cbs (&input, &gpg_stream_funcs, istream)) != GPG_ERR_NO_ERROR) {
+ g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open input stream: %s"),
gpgme_strerror (error));
+ gpgme_signers_clear (ctx);
+ return -1;
+ }
+
+ if ((error = gpgme_data_new_from_cbs (&output, &gpg_stream_funcs, ostream)) != GPG_ERR_NO_ERROR) {
+ g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open output stream: %s"),
gpgme_strerror (error));
+ gpgme_data_release (input);
+ gpgme_signers_clear (ctx);
+ return -1;
+ }
+
+ /* sign the input stream */
+ error = gpgme_op_sign (ctx, input, output, mode);
+ gpgme_data_release (output);
+ gpgme_data_release (input);
+ gpgme_signers_clear (ctx);
+
+ if (error != GPG_ERR_NO_ERROR) {
+ g_set_error (err, GMIME_GPGME_ERROR, error, _("Signing failed: %s"), gpgme_strerror (error));
+ return -1;
+ }
+
+ /* return the digest algorithm used for signing */
+ result = gpgme_op_sign_result (ctx);
+
+ return (GMimeDigestAlgo) result->signatures->hash_algo;
+}
+
static GMimeCertificateTrust
get_trust (gpgme_validity_t trust)
{
@@ -186,7 +267,7 @@ get_trust (gpgme_validity_t trust)
}
}
-GMimeSignatureList *
+static GMimeSignatureList *
g_mime_gpgme_get_signatures (gpgme_ctx_t ctx, gboolean verify)
{
GMimeSignatureList *signatures;
@@ -265,7 +346,63 @@ g_mime_gpgme_get_signatures (gpgme_ctx_t ctx, gboolean verify)
return signatures;
}
-void
+GMimeSignatureList *
+g_mime_gpgme_verify (gpgme_ctx_t ctx, GMimeVerifyFlags flags, GMimeStream *istream, GMimeStream *sigstream,
+ GMimeStream *ostream, GError **err)
+{
+ gpgme_data_t sig, signed_text, plain;
+ gpgme_error_t error;
+
+ if (sigstream != NULL) {
+ /* if @sigstream is non-NULL, then it is a detached signature */
+ if ((error = gpgme_data_new_from_cbs (&signed_text, &gpg_stream_funcs, istream)) !=
GPG_ERR_NO_ERROR) {
+ g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open input stream: %s"),
gpgme_strerror (error));
+ return NULL;
+ }
+
+ if ((error = gpgme_data_new_from_cbs (&sig, &gpg_stream_funcs, sigstream)) !=
GPG_ERR_NO_ERROR) {
+ g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open signature stream: %s"),
gpgme_strerror (error));
+ gpgme_data_release (signed_text);
+ return NULL;
+ }
+
+ plain = NULL;
+ } else if (ostream != NULL) {
+ /* if @ostream is non-NULL, then we are expected to write the extracted plaintext to it */
+ if ((error = gpgme_data_new_from_cbs (&sig, &gpg_stream_funcs, istream)) != GPG_ERR_NO_ERROR)
{
+ g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open input stream: %s"),
gpgme_strerror (error));
+ return NULL;
+ }
+
+ if ((error = gpgme_data_new_from_cbs (&plain, &gpg_stream_funcs, ostream)) !=
GPG_ERR_NO_ERROR) {
+ g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open output stream: %s"),
gpgme_strerror (error));
+ gpgme_data_release (sig);
+ return NULL;
+ }
+
+ signed_text = NULL;
+ } else {
+ g_set_error_literal (err, GMIME_GPGME_ERROR, error, _("Missing signature stream or output
stream"));
+ return NULL;
+ }
+
+ error = gpgme_op_verify (ctx, sig, signed_text, plain);
+ if (signed_text)
+ gpgme_data_release (signed_text);
+ if (plain)
+ gpgme_data_release (plain);
+ gpgme_data_release (sig);
+
+ if (error != GPG_ERR_NO_ERROR) {
+ g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not verify signature: %s"),
gpgme_strerror (error));
+ return NULL;
+ }
+
+ /* get/return the signatures */
+ return g_mime_gpgme_get_signatures (ctx, TRUE);
+}
+
+static void
g_mime_gpgme_keylist_free (gpgme_key_t *keys)
{
gpgme_key_t *key = keys;
@@ -278,7 +415,74 @@ g_mime_gpgme_keylist_free (gpgme_key_t *keys)
g_free (keys);
}
-GMimeDecryptResult *
+int
+g_mime_gpgme_encrypt (gpgme_ctx_t ctx, gboolean sign, const char *userid, GMimeDigestAlgo digest,
+ GMimeEncryptFlags flags, GPtrArray *recipients, GMimeStream *istream, GMimeStream
*ostream,
+ GError **err)
+{
+ gpgme_encrypt_flags_t encrypt_flags = 0;
+ gpgme_data_t input, output;
+ gpgme_error_t error;
+ gpgme_key_t *rcpts;
+ gpgme_key_t key;
+ guint i;
+
+ if (flags & GMIME_ENCRYPT_FLAGS_ALWAYS_TRUST)
+ encrypt_flags |= GPGME_ENCRYPT_ALWAYS_TRUST;
+
+ /* create an array of recipient keys for GpgMe */
+ rcpts = g_new0 (gpgme_key_t, recipients->len + 1);
+ for (i = 0; i < recipients->len; i++) {
+ if (!(key = g_mime_gpgme_get_key_by_name (ctx, recipients->pdata[i], FALSE, err))) {
+ g_mime_gpgme_keylist_free (rcpts);
+ return -1;
+ }
+
+ rcpts[i] = key;
+ }
+
+ if ((error = gpgme_data_new_from_cbs (&input, &gpg_stream_funcs, istream)) != GPG_ERR_NO_ERROR) {
+ g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open input stream: %s"),
gpgme_strerror (error));
+ g_mime_gpgme_keylist_free (rcpts);
+ return -1;
+ }
+
+ if ((error = gpgme_data_new_from_cbs (&output, &gpg_stream_funcs, ostream)) != GPG_ERR_NO_ERROR) {
+ g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open output stream: %s"),
gpgme_strerror (error));
+ g_mime_gpgme_keylist_free (rcpts);
+ gpgme_data_release (input);
+ return -1;
+ }
+
+ /* encrypt the input stream */
+ if (sign) {
+ if (!g_mime_gpgme_add_signer (ctx, userid, err)) {
+ g_mime_gpgme_keylist_free (rcpts);
+ gpgme_data_release (output);
+ gpgme_data_release (input);
+ return -1;
+ }
+
+ error = gpgme_op_encrypt_sign (ctx, rcpts, encrypt_flags, input, output);
+
+ gpgme_signers_clear (ctx);
+ } else {
+ error = gpgme_op_encrypt (ctx, rcpts, encrypt_flags, input, output);
+ }
+
+ g_mime_gpgme_keylist_free (rcpts);
+ gpgme_data_release (output);
+ gpgme_data_release (input);
+
+ if (error != GPG_ERR_NO_ERROR) {
+ g_set_error (err, GMIME_GPGME_ERROR, error, _("Encryption failed: %s"), gpgme_strerror
(error));
+ return -1;
+ }
+
+ return 0;
+}
+
+static GMimeDecryptResult *
g_mime_gpgme_get_decrypt_result (gpgme_ctx_t ctx)
{
GMimeDecryptResult *result;
@@ -295,8 +499,10 @@ g_mime_gpgme_get_decrypt_result (gpgme_ctx_t ctx)
if (!(res = gpgme_op_decrypt_result (ctx)) || !res->recipients)
return result;
+#if GPGME_VERSION_NUMBER >= 0x010800
if (res->session_key)
result->session_key = g_strdup (res->session_key);
+#endif
recipient = res->recipients;
while (recipient != NULL) {
@@ -312,4 +518,104 @@ g_mime_gpgme_get_decrypt_result (gpgme_ctx_t ctx)
return result;
}
+GMimeDecryptResult *
+g_mime_gpgme_decrypt (gpgme_ctx_t ctx, GMimeDecryptFlags flags, const char *session_key,
+ GMimeStream *istream, GMimeStream *ostream, GError **err)
+{
+ GMimeDecryptResult *result;
+ gpgme_decrypt_result_t res;
+ gpgme_data_t input, output;
+ gpgme_error_t error;
+
+ if ((error = gpgme_data_new_from_cbs (&input, &gpg_stream_funcs, istream)) != GPG_ERR_NO_ERROR) {
+ g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open input stream: %s"),
gpgme_strerror (error));
+ return NULL;
+ }
+
+ if ((error = gpgme_data_new_from_cbs (&output, &gpg_stream_funcs, ostream)) != GPG_ERR_NO_ERROR) {
+ g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open output stream: %s"),
gpgme_strerror (error));
+ gpgme_data_release (input);
+ return NULL;
+ }
+
+#if GPGME_VERSION_NUMBER >= 0x010800
+ if (flags & GMIME_DECRYPT_FLAGS_EXPORT_SESSION_KEY)
+ gpgme_set_ctx_flag (ctx, "export-session-key", "1");
+
+ if (session_key)
+ gpgme_set_ctx_flag (ctx, "override-session-key", session_key);
+#endif
+
+ /* decrypt the input stream */
+ if (gpgme_get_protocol (ctx) == GPGME_PROTOCOL_OpenPGP)
+ error = gpgme_op_decrypt_verify (ctx, input, output);
+ else
+ error = gpgme_op_decrypt (ctx, input, output);
+
+#if GPGME_VERSION_NUMBER >= 0x010800
+ if (flags & GMIME_DECRYPT_FLAGS_EXPORT_SESSION_KEY)
+ gpgme_set_ctx_flag (ctx, "export-session-key", "0");
+
+ if (session_key)
+ gpgme_set_ctx_flag (ctx, "override-session-key", NULL);
+#endif
+
+ gpgme_data_release (output);
+ gpgme_data_release (input);
+
+ if (error != GPG_ERR_NO_ERROR) {
+ g_set_error (err, GMIME_GPGME_ERROR, error, _("Decryption failed: %s"), gpgme_strerror
(error));
+ return NULL;
+ }
+
+ return g_mime_gpgme_get_decrypt_result (ctx);
+}
+
+int
+g_mime_gpgme_import (gpgme_ctx_t ctx, GMimeStream *istream, GError **err)
+{
+ gpgme_data_t keydata;
+ gpgme_error_t error;
+
+ if ((error = gpgme_data_new_from_cbs (&keydata, &gpg_stream_funcs, istream)) != GPG_ERR_NO_ERROR) {
+ g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open input stream: %s"),
gpgme_strerror (error));
+ return -1;
+ }
+
+ /* import the key(s) */
+ error = gpgme_op_import (ctx, keydata);
+ gpgme_data_release (keydata);
+
+ if (error != GPG_ERR_NO_ERROR) {
+ g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not import key data: %s"),
gpgme_strerror (error));
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+g_mime_gpgme_export (gpgme_ctx_t ctx, const char *keys[], GMimeStream *ostream, GError **err)
+{
+ gpgme_data_t keydata;
+ gpgme_error_t error;
+ guint i;
+
+ if ((error = gpgme_data_new_from_cbs (&keydata, &gpg_stream_funcs, ostream)) != GPG_ERR_NO_ERROR) {
+ g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open output stream: %s"),
gpgme_strerror (error));
+ return -1;
+ }
+
+ /* export the key(s) */
+ error = gpgme_op_export_ext (ctx, keys, 0, keydata);
+ gpgme_data_release (keydata);
+
+ if (error != GPG_ERR_NO_ERROR) {
+ g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not export key data: %s"),
gpgme_strerror (error));
+ return -1;
+ }
+
+ return 0;
+}
+
#endif /* ENABLE_CRYPTO */
diff --git a/gmime/gmime-gpgme-utils.h b/gmime/gmime-gpgme-utils.h
index 4933be0..601b5a0 100644
--- a/gmime/gmime-gpgme-utils.h
+++ b/gmime/gmime-gpgme-utils.h
@@ -34,16 +34,22 @@ G_GNUC_INTERNAL gpgme_error_t g_mime_gpgme_passphrase_callback (void *hook, cons
const char *passphrase_info,
int prev_was_bad, int fd);
-G_GNUC_INTERNAL gpgme_key_t g_mime_gpgme_get_key_by_name (gpgme_ctx_t ctx, const char *name,
- gboolean secret, GError **err);
+G_GNUC_INTERNAL int g_mime_gpgme_sign (gpgme_ctx_t ctx, gpgme_sig_mode_t mode, const char *userid,
GMimeDigestAlgo digest,
+ GMimeStream *istream, GMimeStream *ostream, GError **err);
-G_GNUC_INTERNAL gboolean g_mime_gpgme_add_signer (gpgme_ctx_t ctx, const char *signer, GError **err);
+G_GNUC_INTERNAL GMimeSignatureList *g_mime_gpgme_verify (gpgme_ctx_t ctx, GMimeVerifyFlags flags,
GMimeStream *istream,
+ GMimeStream *sigstream, GMimeStream *ostream, GError
**err);
-G_GNUC_INTERNAL GMimeSignatureList *g_mime_gpgme_get_signatures (gpgme_ctx_t ctx, gboolean verify);
+G_GNUC_INTERNAL int g_mime_gpgme_encrypt (gpgme_ctx_t ctx, gboolean sign, const char *userid,
GMimeDigestAlgo digest,
+ GMimeEncryptFlags flags, GPtrArray *recipients, GMimeStream
*istream, GMimeStream *ostream,
+ GError **err);
-G_GNUC_INTERNAL void g_mime_gpgme_keylist_free (gpgme_key_t *keys);
+G_GNUC_INTERNAL GMimeDecryptResult *g_mime_gpgme_decrypt (gpgme_ctx_t ctx, GMimeDecryptFlags flags, const
char *session_key,
+ GMimeStream *istream, GMimeStream *ostream, GError
**err);
-G_GNUC_INTERNAL GMimeDecryptResult *g_mime_gpgme_get_decrypt_result (gpgme_ctx_t ctx);
+G_GNUC_INTERNAL int g_mime_gpgme_import (gpgme_ctx_t ctx, GMimeStream *istream, GError **err);
+
+G_GNUC_INTERNAL int g_mime_gpgme_export (gpgme_ctx_t ctx, const char *keys[], GMimeStream *ostream, GError
**err);
G_END_DECLS
diff --git a/gmime/gmime-pkcs7-context.c b/gmime/gmime-pkcs7-context.c
index f7fbf1a..ba4a75b 100644
--- a/gmime/gmime-pkcs7-context.c
+++ b/gmime/gmime-pkcs7-context.c
@@ -262,137 +262,6 @@ pkcs7_get_key_exchange_protocol (GMimeCryptoContext *ctx)
return "application/pkcs7-keys";
}
-#ifdef ENABLE_CRYPTO
-static ssize_t
-pkcs7_stream_read (void *stream, void *buffer, size_t size)
-{
- return g_mime_stream_read ((GMimeStream *) stream, (char *) buffer, size);
-}
-
-static ssize_t
-pkcs7_stream_write (void *stream, const void *buffer, size_t size)
-{
- return g_mime_stream_write ((GMimeStream *) stream, (const char *) buffer, size);
-}
-
-static off_t
-pkcs7_stream_seek (void *stream, off_t offset, int whence)
-{
- switch (whence) {
- case SEEK_SET:
- return (off_t) g_mime_stream_seek ((GMimeStream *) stream, (gint64) offset,
GMIME_STREAM_SEEK_SET);
- case SEEK_CUR:
- return (off_t) g_mime_stream_seek ((GMimeStream *) stream, (gint64) offset,
GMIME_STREAM_SEEK_CUR);
- case SEEK_END:
- return (off_t) g_mime_stream_seek ((GMimeStream *) stream, (gint64) offset,
GMIME_STREAM_SEEK_END);
- default:
- return -1;
- }
-}
-
-static void
-pkcs7_stream_free (void *stream)
-{
- /* no-op */
-}
-
-static struct gpgme_data_cbs pkcs7_stream_funcs = {
- pkcs7_stream_read,
- pkcs7_stream_write,
- pkcs7_stream_seek,
- pkcs7_stream_free
-};
-
-
-
-#define KEY_IS_OK(k) (!((k)->expired || (k)->revoked || \
- (k)->disabled || (k)->invalid))
-
-static gpgme_key_t
-pkcs7_get_key_by_name (GMimePkcs7Context *pkcs7, const char *name, gboolean secret, GError **err)
-{
- time_t now = time (NULL);
- gpgme_key_t key = NULL;
- gpgme_subkey_t subkey;
- gboolean bad = FALSE;
- gpgme_error_t error;
- int errval = 0;
-
- if ((error = gpgme_op_keylist_start (pkcs7->ctx, name, secret)) != GPG_ERR_NO_ERROR) {
- if (secret)
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not list secret keys for \"%s\":
%s"), name, gpgme_strerror (error));
- else
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not list keys for \"%s\": %s"),
name, gpgme_strerror (error));
- return NULL;
- }
-
- while ((error = gpgme_op_keylist_next (pkcs7->ctx, &key)) == GPG_ERR_NO_ERROR) {
- /* check if this key and the relevant subkey are usable */
- if (KEY_IS_OK (key)) {
- subkey = key->subkeys;
-
- while (subkey && ((secret && !subkey->can_sign) ||
- (!secret && !subkey->can_encrypt)))
- subkey = subkey->next;
-
- if (subkey && KEY_IS_OK (subkey) &&
- (subkey->expires == 0 || subkey->expires > now))
- break;
-
- if (subkey->expired)
- errval = GPG_ERR_KEY_EXPIRED;
- else
- errval = GPG_ERR_BAD_KEY;
- } else {
- if (key->expired)
- errval = GPG_ERR_KEY_EXPIRED;
- else
- errval = GPG_ERR_BAD_KEY;
- }
-
- gpgme_key_unref (key);
- bad = TRUE;
- key = NULL;
- }
-
- gpgme_op_keylist_end (pkcs7->ctx);
-
- if (error != GPG_ERR_NO_ERROR && error != GPG_ERR_EOF) {
- if (secret)
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not list secret keys for \"%s\":
%s"), name, gpgme_strerror (error));
- else
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not list keys for \"%s\": %s"),
name, gpgme_strerror (error));
-
- return NULL;
- }
-
- if (!key) {
- if (strchr (name, '@')) {
- if (bad)
- g_set_error (err, GMIME_GPGME_ERROR, errval,
- _("A key for %s is present, but it is expired, disabled, revoked
or invalid"),
- name);
- else
- g_set_error (err, GMIME_GPGME_ERROR, GPG_ERR_NOT_FOUND,
- _("Could not find a key for %s"), name);
- } else {
- if (bad)
- g_set_error (err, GMIME_GPGME_ERROR, errval,
- _("A key with id %s is present, but it is expired, disabled,
revoked or invalid"),
- name);
- else
- g_set_error (err, GMIME_GPGME_ERROR, GPG_ERR_NOT_FOUND,
- _("Could not find a key with id %s"), name);
- }
-
- return NULL;
- }
-
- return key;
-}
-
-#endif /* ENABLE_CRYPTO */
-
static int
pkcs7_sign (GMimeCryptoContext *context, gboolean detach, const char *userid, GMimeDigestAlgo digest,
GMimeStream *istream, GMimeStream *ostream, GError **err)
@@ -400,43 +269,8 @@ pkcs7_sign (GMimeCryptoContext *context, gboolean detach, const char *userid, GM
#ifdef ENABLE_CRYPTO
gpgme_sig_mode_t mode = detach ? GPGME_SIG_MODE_DETACH : GPGME_SIG_MODE_NORMAL;
GMimePkcs7Context *pkcs7 = (GMimePkcs7Context *) context;
- gpgme_sign_result_t result;
- gpgme_data_t input, output;
- gpgme_error_t error;
-
- if (!g_mime_gpgme_add_signer (pkcs7->ctx, userid, err))
- return -1;
-
- if ((error = gpgme_data_new_from_cbs (&input, &pkcs7_stream_funcs, istream)) != GPG_ERR_NO_ERROR) {
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open input stream: %s"),
gpgme_strerror (error));
- gpgme_signers_clear (pkcs7->ctx);
- return -1;
- }
-
- if ((error = gpgme_data_new_from_cbs (&output, &pkcs7_stream_funcs, ostream)) != GPG_ERR_NO_ERROR) {
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open output stream: %s"),
gpgme_strerror (error));
- gpgme_signers_clear (pkcs7->ctx);
- gpgme_data_release (input);
- return -1;
- }
-
- /* sign the input stream */
- if ((error = gpgme_op_sign (pkcs7->ctx, input, output, mode)) != GPG_ERR_NO_ERROR) {
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Signing failed: %s"), gpgme_strerror (error));
- gpgme_signers_clear (pkcs7->ctx);
- gpgme_data_release (output);
- gpgme_data_release (input);
- return -1;
- }
- gpgme_signers_clear (pkcs7->ctx);
- gpgme_data_release (output);
- gpgme_data_release (input);
-
- /* return the digest algorithm used for signing */
- result = gpgme_op_sign_result (pkcs7->ctx);
-
- return (GMimeDigestAlgo) result->signatures->hash_algo;
+ return g_mime_gpgme_sign (pkcs7->ctx, mode, userid, digest, istream, ostream, err);
#else
g_set_error_literal (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED, _("S/MIME support is not enabled in
this build"));
@@ -450,56 +284,8 @@ pkcs7_verify (GMimeCryptoContext *context, GMimeVerifyFlags flags, GMimeStream *
{
#ifdef ENABLE_CRYPTO
GMimePkcs7Context *pkcs7 = (GMimePkcs7Context *) context;
- gpgme_data_t sig, signed_text, plain;
- gpgme_error_t error;
- if (sigstream != NULL) {
- /* if @sigstream is non-NULL, then it is a detached signature */
- if ((error = gpgme_data_new_from_cbs (&signed_text, &pkcs7_stream_funcs, istream)) !=
GPG_ERR_NO_ERROR) {
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open input stream: %s"),
gpgme_strerror (error));
- return NULL;
- }
-
- if ((error = gpgme_data_new_from_cbs (&sig, &pkcs7_stream_funcs, sigstream)) !=
GPG_ERR_NO_ERROR) {
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open signature stream: %s"),
gpgme_strerror (error));
- gpgme_data_release (signed_text);
- return NULL;
- }
-
- plain = NULL;
- } else if (ostream != NULL) {
- /* if @ostream is non-NULL, then we are expected to write the extracted plaintext to it */
- if ((error = gpgme_data_new_from_cbs (&sig, &pkcs7_stream_funcs, istream)) !=
GPG_ERR_NO_ERROR) {
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open input stream: %s"),
gpgme_strerror (error));
- return NULL;
- }
-
- if ((error = gpgme_data_new_from_cbs (&plain, &pkcs7_stream_funcs, ostream)) !=
GPG_ERR_NO_ERROR) {
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open output stream: %s"),
gpgme_strerror (error));
- gpgme_data_release (sig);
- return NULL;
- }
-
- signed_text = NULL;
- } else {
- g_set_error_literal (err, GMIME_GPGME_ERROR, error, _("Missing signature stream or output
stream"));
- return NULL;
- }
-
- error = gpgme_op_verify (pkcs7->ctx, sig, signed_text, plain);
- if (signed_text)
- gpgme_data_release (signed_text);
- if (plain)
- gpgme_data_release (plain);
- gpgme_data_release (sig);
-
- if (error != GPG_ERR_NO_ERROR) {
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not verify pkcs7 signature: %s"),
gpgme_strerror (error));
- return NULL;
- }
-
- /* get/return the pkcs7 signatures */
- return g_mime_gpgme_get_signatures (pkcs7->ctx, TRUE);
+ return g_mime_gpgme_verify (pkcs7->ctx, flags, istream, sigstream, ostream, err);
#else
g_set_error_literal (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED, _("S/MIME support is not enabled in
this build"));
@@ -507,21 +293,6 @@ pkcs7_verify (GMimeCryptoContext *context, GMimeVerifyFlags flags, GMimeStream *
#endif /* ENABLE_CRYPTO */
}
-#ifdef ENABLE_CRYPTO
-static void
-key_list_free (gpgme_key_t *keys)
-{
- gpgme_key_t *key = keys;
-
- while (*key != NULL) {
- gpgme_key_unref (*key);
- key++;
- }
-
- g_free (keys);
-}
-#endif /* ENABLE_CRYPTO */
-
static int
pkcs7_encrypt (GMimeCryptoContext *context, gboolean sign, const char *userid, GMimeDigestAlgo digest,
GMimeEncryptFlags flags, GPtrArray *recipients, GMimeStream *istream, GMimeStream *ostream,
@@ -529,12 +300,6 @@ pkcs7_encrypt (GMimeCryptoContext *context, gboolean sign, const char *userid, G
{
#ifdef ENABLE_CRYPTO
GMimePkcs7Context *pkcs7 = (GMimePkcs7Context *) context;
- gpgme_encrypt_flags_t encrypt_flags = 0;
- gpgme_data_t input, output;
- gpgme_error_t error;
- gpgme_key_t *rcpts;
- gpgme_key_t key;
- guint i;
if (sign) {
g_set_error_literal (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED,
@@ -542,45 +307,7 @@ pkcs7_encrypt (GMimeCryptoContext *context, gboolean sign, const char *userid, G
return -1;
}
- if (flags & GMIME_ENCRYPT_FLAGS_ALWAYS_TRUST)
- encrypt_flags |= GPGME_ENCRYPT_ALWAYS_TRUST;
-
- /* create an array of recipient keys for GpgMe */
- rcpts = g_new0 (gpgme_key_t, recipients->len + 1);
- for (i = 0; i < recipients->len; i++) {
- if (!(key = pkcs7_get_key_by_name (pkcs7, recipients->pdata[i], FALSE, err))) {
- g_mime_gpgme_keylist_free (rcpts);
- return -1;
- }
-
- rcpts[i] = key;
- }
-
- if ((error = gpgme_data_new_from_cbs (&input, &pkcs7_stream_funcs, istream)) != GPG_ERR_NO_ERROR) {
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open input stream: %s"),
gpgme_strerror (error));
- g_mime_gpgme_keylist_free (rcpts);
- return -1;
- }
-
- if ((error = gpgme_data_new_from_cbs (&output, &pkcs7_stream_funcs, ostream)) != GPG_ERR_NO_ERROR) {
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open output stream: %s"),
gpgme_strerror (error));
- g_mime_gpgme_keylist_free (rcpts);
- gpgme_data_release (input);
- return -1;
- }
-
- /* encrypt the input stream */
- error = gpgme_op_encrypt (pkcs7->ctx, rcpts, encrypt_flags, input, output);
- g_mime_gpgme_keylist_free (rcpts);
- gpgme_data_release (output);
- gpgme_data_release (input);
-
- if (error != GPG_ERR_NO_ERROR) {
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Encryption failed: %s"), gpgme_strerror
(error));
- return -1;
- }
-
- return 0;
+ return g_mime_gpgme_encrypt (pkcs7->ctx, sign, userid, digest, flags, recipients, istream, ostream,
err);
#else
g_set_error_literal (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED, _("S/MIME support is not enabled in
this build"));
@@ -594,53 +321,8 @@ pkcs7_decrypt (GMimeCryptoContext *context, GMimeDecryptFlags flags, const char
{
#ifdef ENABLE_CRYPTO
GMimePkcs7Context *pkcs7 = (GMimePkcs7Context *) context;
- GMimeDecryptResult *result;
- gpgme_decrypt_result_t res;
- gpgme_data_t input, output;
- gpgme_error_t error;
-
- if ((error = gpgme_data_new_from_cbs (&input, &pkcs7_stream_funcs, istream)) != GPG_ERR_NO_ERROR) {
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open input stream: %s"),
gpgme_strerror (error));
- return NULL;
- }
-
- if ((error = gpgme_data_new_from_cbs (&output, &pkcs7_stream_funcs, ostream)) != GPG_ERR_NO_ERROR) {
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open output stream: %s"),
gpgme_strerror (error));
- gpgme_data_release (input);
- return NULL;
- }
-
- if (flags & GMIME_DECRYPT_FLAGS_EXPORT_SESSION_KEY)
- gpgme_set_ctx_flag (pkcs7->ctx, "export-session-key", "1");
-
- if (session_key)
- gpgme_set_ctx_flag (pkcs7->ctx, "override-session-key", session_key);
-
- /* decrypt the input stream */
- if ((error = gpgme_op_decrypt (pkcs7->ctx, input, output)) != GPG_ERR_NO_ERROR) {
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Decryption failed: %s"), gpgme_strerror
(error));
-
- if (flags & GMIME_DECRYPT_FLAGS_EXPORT_SESSION_KEY)
- gpgme_set_ctx_flag (pkcs7->ctx, "export-session-key", "0");
-
- if (session_key)
- gpgme_set_ctx_flag (pkcs7->ctx, "override-session-key", NULL);
-
- gpgme_data_release (output);
- gpgme_data_release (input);
- return NULL;
- }
-
- if (flags & GMIME_DECRYPT_FLAGS_EXPORT_SESSION_KEY)
- gpgme_set_ctx_flag (pkcs7->ctx, "export-session-key", "0");
-
- if (session_key)
- gpgme_set_ctx_flag (pkcs7->ctx, "override-session-key", NULL);
- gpgme_data_release (output);
- gpgme_data_release (input);
-
- return g_mime_gpgme_get_decrypt_result (pkcs7->ctx);
+ return g_mime_gpgme_decrypt (pkcs7->ctx, flags, session_key, istream, ostream, err);
#else
g_set_error_literal (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED, _("S/MIME support is not enabled in
this build"));
@@ -653,24 +335,8 @@ pkcs7_import_keys (GMimeCryptoContext *context, GMimeStream *istream, GError **e
{
#ifdef ENABLE_CRYPTO
GMimePkcs7Context *pkcs7 = (GMimePkcs7Context *) context;
- gpgme_data_t keydata;
- gpgme_error_t error;
-
- if ((error = gpgme_data_new_from_cbs (&keydata, &pkcs7_stream_funcs, istream)) != GPG_ERR_NO_ERROR) {
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open input stream: %s"),
gpgme_strerror (error));
- return -1;
- }
-
- /* import the key(s) */
- if ((error = gpgme_op_import (pkcs7->ctx, keydata)) != GPG_ERR_NO_ERROR) {
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not import key data: %s"),
gpgme_strerror (error));
- gpgme_data_release (keydata);
- return -1;
- }
-
- gpgme_data_release (keydata);
- return 0;
+ return g_mime_gpgme_import (pkcs7->ctx, istream, err);
#else
g_set_error_literal (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED, _("S/MIME support is not enabled in
this build"));
@@ -683,25 +349,8 @@ pkcs7_export_keys (GMimeCryptoContext *context, const char *keys[], GMimeStream
{
#ifdef ENABLE_CRYPTO
GMimePkcs7Context *pkcs7 = (GMimePkcs7Context *) context;
- gpgme_data_t keydata;
- gpgme_error_t error;
- guint i;
-
- if ((error = gpgme_data_new_from_cbs (&keydata, &pkcs7_stream_funcs, ostream)) != GPG_ERR_NO_ERROR) {
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open output stream: %s"),
gpgme_strerror (error));
- return -1;
- }
-
- /* export the key(s) */
- if ((error = gpgme_op_export_ext (pkcs7->ctx, keys, 0, keydata)) != GPG_ERR_NO_ERROR) {
- g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not export key data: %s"),
gpgme_strerror (error));
- gpgme_data_release (keydata);
- return -1;
- }
-
- gpgme_data_release (keydata);
- return 0;
+ return g_mime_gpgme_export (pkcs7->ctx, keys, ostream, err);
#else
g_set_error_literal (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED, _("S/MIME support is not enabled in
this build"));
diff --git a/tests/test-pgpmime.c b/tests/test-pgpmime.c
index 31c4247..1c5f247 100644
--- a/tests/test-pgpmime.c
+++ b/tests/test-pgpmime.c
@@ -354,15 +354,17 @@ test_multipart_encrypted (GMimeCryptoContext *ctx, gboolean sign,
throw (ex);
}
+#if GPGME_VERSION_NUMBER >= 0x010800
if (!result->session_key) {
ex = exception_new ("No session key returned!");
throw (ex);
}
ret = g_strdup (result->session_key);
+#endif
if (result->signatures)
v(print_verify_results (result->signatures));
-
+
if (sign) {
status = get_sig_status (result->signatures);
@@ -377,7 +379,7 @@ test_multipart_encrypted (GMimeCryptoContext *ctx, gboolean sign,
if (ex != NULL) {
g_free (ret);
- ret = 0;
+ ret = NULL;
throw (ex);
}
@@ -394,9 +396,10 @@ test_multipart_encrypted (GMimeCryptoContext *ctx, gboolean sign,
if (ex != NULL) {
g_free (ret);
- ret = 0;
+ ret = NULL;
throw (ex);
}
+
return ret;
}
@@ -493,11 +496,15 @@ int main (int argc, char *argv[])
} catch (ex) {
testsuite_check_failed ("multipart/encrypted failed: %s", ex->message);
} finally;
+
if (cleartext)
g_object_unref (cleartext);
+
if (stream)
g_object_unref (stream);
+
cleartext = stream = NULL;
+
if (session_key) {
memset (session_key, 0, strlen (session_key));
g_free (session_key);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]