gmime r1332 - in trunk: . gmime mono tests
- From: fejj svn gnome org
- To: svn-commits-list gnome org
- Subject: gmime r1332 - in trunk: . gmime mono tests
- Date: Wed, 4 Jun 2008 03:44:35 +0000 (UTC)
Author: fejj
Date: Wed Jun 4 03:44:35 2008
New Revision: 1332
URL: http://svn.gnome.org/viewvc/gmime?rev=1332&view=rev
Log:
2008-06-03 Jeffrey Stedfast <fejj novell com>
* tests/test-pgpmime.c: Updated to test for
multipart/encrypted+sign
* gmime/gmime-multipart-encrypted.c (g_mime_multipart_encrypted_encrypt):
Changed to take 'sign' and 'userid' arguments so that it is
possible to both sign and encrypt the content.
(g_mime_multipart_encrypted_decrypt): Updated to save the
GMimeSignatureValidity from our call ot
g_mime_cipher_context_decrypt() so that callers can choose to get
the signer validity (in the case where the encrypted part was also
signed).
(g_mime_multipart_encrypted_get_signature_validity): New function.
* gmime/gmime-gpg-context.c (gpg_decrypt): Updated to return a
GMimeSignatureValidity.
(gpg_ctx_parse_signer_info): Split out from gpg_ctx_parse_status()
to parse signer info.
(gpg_ctx_parse_status): Updated VERIFY mode to call
gpg_ctx_parse_signer_info() and made DECRYPT also call it so that
we properly collect signer info when the encrypted stream was also
signed.
(gpg_encrypt): Respect the 'sign' argument.
* gmime/gmime-cipher-context.c (g_mime_cipher_context_decrypt):
Now returns a GMimeSignatureValidity in case the encrypted stream
was also signed.
Modified:
trunk/ChangeLog
trunk/gmime/gmime-cipher-context.c
trunk/gmime/gmime-cipher-context.h
trunk/gmime/gmime-gpg-context.c
trunk/gmime/gmime-multipart-encrypted.c
trunk/gmime/gmime-multipart-encrypted.h
trunk/mono/gmime-api.raw
trunk/tests/test-pgpmime.c
Modified: trunk/gmime/gmime-cipher-context.c
==============================================================================
--- trunk/gmime/gmime-cipher-context.c (original)
+++ trunk/gmime/gmime-cipher-context.c Wed Jun 4 03:44:35 2008
@@ -59,8 +59,8 @@
GMimeStream *istream, GMimeStream *ostream,
GError **err);
-static int cipher_decrypt (GMimeCipherContext *ctx, GMimeStream *istream,
- GMimeStream *ostream, GError **err);
+static GMimeSignatureValidity *cipher_decrypt (GMimeCipherContext *ctx, GMimeStream *istream,
+ GMimeStream *ostream, GError **err);
static int cipher_import_keys (GMimeCipherContext *ctx, GMimeStream *istream,
GError **err);
@@ -298,14 +298,14 @@
}
-static int
+static GMimeSignatureValidity *
cipher_decrypt (GMimeCipherContext *ctx, GMimeStream *istream,
GMimeStream *ostream, GError **err)
{
g_set_error (err, GMIME_ERROR_QUARK, GMIME_ERROR_NOT_SUPPORTED,
"Decryption is not supported by this cipher");
- return -1;
+ return NULL;
}
@@ -319,15 +319,24 @@
* Decrypts the ciphertext input stream and writes the resulting
* cleartext to the output stream.
*
- * Returns: %0 on success or %-1 for fail.
+ * If the encrypted input stream was also signed, the returned
+ * #GMimeSignatureValidity will have signer information included and
+ * the signature status will be one of #GMIME_SIGNATURE_STATUS_GOOD,
+ * #GMIME_SIGNATURE_STATUS_BAD, or #GMIME_SIGNATURE_STATUS_UNKNOWN.
+ *
+ * If the encrypted input text was not signed, then the signature
+ * status of the returned #GMimeSignatureValidity will be
+ * #GMIME_SIGNATURE_STATUS_NONE.
+ *
+ * Returns: a #GMimeSignatureValidity on success or %NULL on error.
**/
-int
+GMimeSignatureValidity *
g_mime_cipher_context_decrypt (GMimeCipherContext *ctx, GMimeStream *istream,
GMimeStream *ostream, GError **err)
{
- g_return_val_if_fail (GMIME_IS_CIPHER_CONTEXT (ctx), -1);
- g_return_val_if_fail (GMIME_IS_STREAM (istream), -1);
- g_return_val_if_fail (GMIME_IS_STREAM (ostream), -1);
+ g_return_val_if_fail (GMIME_IS_CIPHER_CONTEXT (ctx), NULL);
+ g_return_val_if_fail (GMIME_IS_STREAM (istream), NULL);
+ g_return_val_if_fail (GMIME_IS_STREAM (ostream), NULL);
return GMIME_CIPHER_CONTEXT_GET_CLASS (ctx)->decrypt (ctx, istream, ostream, err);
}
@@ -786,7 +795,7 @@
* Returns: a #GMimeSignatureStatus value.
**/
GMimeSignatureStatus
-g_mime_signature_validity_get_status (GMimeSignatureValidity *validity)
+g_mime_signature_validity_get_status (const GMimeSignatureValidity *validity)
{
g_return_val_if_fail (validity != NULL, GMIME_SIGNATURE_STATUS_NONE);
@@ -820,7 +829,7 @@
* Returns: a user-readable string containing any status information.
**/
const char *
-g_mime_signature_validity_get_details (GMimeSignatureValidity *validity)
+g_mime_signature_validity_get_details (const GMimeSignatureValidity *validity)
{
g_return_val_if_fail (validity != NULL, NULL);
@@ -855,7 +864,7 @@
* as trust and cipher keys.
**/
const GMimeSigner *
-g_mime_signature_validity_get_signers (GMimeSignatureValidity *validity)
+g_mime_signature_validity_get_signers (const GMimeSignatureValidity *validity)
{
g_return_val_if_fail (validity != NULL, NULL);
Modified: trunk/gmime/gmime-cipher-context.h
==============================================================================
--- trunk/gmime/gmime-cipher-context.h (original)
+++ trunk/gmime/gmime-cipher-context.h Wed Jun 4 03:44:35 2008
@@ -107,7 +107,7 @@
GMimeStream *istream, GMimeStream *ostream,
GError **err);
- int (* decrypt) (GMimeCipherContext *ctx, GMimeStream *istream,
+ GMimeSignatureValidity * (* decrypt) (GMimeCipherContext *ctx, GMimeStream *istream,
GMimeStream *ostream, GError **err);
int (* import_keys) (GMimeCipherContext *ctx, GMimeStream *istream,
@@ -139,8 +139,8 @@
GMimeStream *istream, GMimeStream *ostream,
GError **err);
-int g_mime_cipher_context_decrypt (GMimeCipherContext *ctx, GMimeStream *istream,
- GMimeStream *ostream, GError **err);
+GMimeSignatureValidity *g_mime_cipher_context_decrypt (GMimeCipherContext *ctx, GMimeStream *istream,
+ GMimeStream *ostream, GError **err);
/* key/certificate routines */
int g_mime_cipher_context_import_keys (GMimeCipherContext *ctx, GMimeStream *istream,
@@ -306,13 +306,13 @@
GMimeSignatureValidity *g_mime_signature_validity_new (void);
void g_mime_signature_validity_free (GMimeSignatureValidity *validity);
-GMimeSignatureStatus g_mime_signature_validity_get_status (GMimeSignatureValidity *validity);
+GMimeSignatureStatus g_mime_signature_validity_get_status (const GMimeSignatureValidity *validity);
void g_mime_signature_validity_set_status (GMimeSignatureValidity *validity, GMimeSignatureStatus status);
-const char *g_mime_signature_validity_get_details (GMimeSignatureValidity *validity);
+const char *g_mime_signature_validity_get_details (const GMimeSignatureValidity *validity);
void g_mime_signature_validity_set_details (GMimeSignatureValidity *validity, const char *details);
-const GMimeSigner *g_mime_signature_validity_get_signers (GMimeSignatureValidity *validity);
+const GMimeSigner *g_mime_signature_validity_get_signers (const GMimeSignatureValidity *validity);
void g_mime_signature_validity_add_signer (GMimeSignatureValidity *validity, GMimeSigner *signer);
G_END_DECLS
Modified: trunk/gmime/gmime-gpg-context.c
==============================================================================
--- trunk/gmime/gmime-gpg-context.c (original)
+++ trunk/gmime/gmime-gpg-context.c Wed Jun 4 03:44:35 2008
@@ -88,8 +88,8 @@
GMimeStream *istream, GMimeStream *ostream,
GError **err);
-static int gpg_decrypt (GMimeCipherContext *ctx, GMimeStream *istream,
- GMimeStream *ostream, GError **err);
+static GMimeSignatureValidity *gpg_decrypt (GMimeCipherContext *ctx, GMimeStream *istream,
+ GMimeStream *ostream, GError **err);
static int gpg_import_keys (GMimeCipherContext *ctx, GMimeStream *istream,
GError **err);
@@ -236,6 +236,7 @@
GPG_CTX_MODE_SIGN,
GPG_CTX_MODE_VERIFY,
GPG_CTX_MODE_ENCRYPT,
+ GPG_CTX_MODE_SIGN_ENCRYPT,
GPG_CTX_MODE_DECRYPT,
GPG_CTX_MODE_IMPORT,
GPG_CTX_MODE_EXPORT,
@@ -413,7 +414,9 @@
static void
gpg_ctx_add_recipient (struct _GpgCtx *gpg, const char *keyid)
{
- if (gpg->mode != GPG_CTX_MODE_ENCRYPT && gpg->mode != GPG_CTX_MODE_EXPORT)
+ if (gpg->mode != GPG_CTX_MODE_ENCRYPT &&
+ gpg->mode != GPG_CTX_MODE_SIGN_ENCRYPT &&
+ gpg->mode != GPG_CTX_MODE_EXPORT)
return;
if (!gpg->recipients)
@@ -613,10 +616,16 @@
g_ptr_array_add (argv, gpg->sigfile);
g_ptr_array_add (argv, "-");
break;
+ case GPG_CTX_MODE_SIGN_ENCRYPT:
+ g_ptr_array_add (argv, "--sign");
+
+ /* fall thru... */
case GPG_CTX_MODE_ENCRYPT:
g_ptr_array_add (argv, "--encrypt");
+
if (gpg->armor)
g_ptr_array_add (argv, "--armor");
+
if (gpg->always_trust)
g_ptr_array_add (argv, "--always-trust");
@@ -624,6 +633,7 @@
g_ptr_array_add (argv, "-u");
g_ptr_array_add (argv, (char *) gpg->userid);
}
+
if (gpg->recipients) {
for (i = 0; i < gpg->recipients->len; i++) {
g_ptr_array_add (argv, "-r");
@@ -784,12 +794,127 @@
return inptr;
}
+static void
+gpg_ctx_parse_signer_info (struct _GpgCtx *gpg, char *status)
+{
+ GMimeSigner *signer;
+
+ if (!strncmp (status, "SIG_ID ", 7)) {
+ /* not sure if this contains anything we care about... */
+ } else if (!strncmp (status, "GOODSIG ", 8)) {
+ gpg->goodsig = TRUE;
+ status += 8;
+
+ signer = g_mime_signer_new ();
+ signer->status = GMIME_SIGNER_STATUS_GOOD;
+ gpg->signer->next = signer;
+ gpg->signer = signer;
+
+ /* get the key id of the signer */
+ status = next_token (status, &signer->keyid);
+
+ /* the rest of the string is the signer's name */
+ signer->name = g_strdup (status);
+ } else if (!strncmp (status, "BADSIG ", 7)) {
+ gpg->badsig = TRUE;
+ status += 7;
+
+ signer = g_mime_signer_new ();
+ signer->status = GMIME_SIGNER_STATUS_BAD;
+ gpg->signer->next = signer;
+ gpg->signer = signer;
+
+ /* get the key id of the signer */
+ status = next_token (status, &signer->keyid);
+
+ /* the rest of the string is the signer's name */
+ signer->name = g_strdup (status);
+ } else if (!strncmp (status, "ERRSIG ", 7)) {
+ /* Note: NO_PUBKEY often comes after an ERRSIG */
+ gpg->errsig = TRUE;
+ status += 7;
+
+ signer = g_mime_signer_new ();
+ signer->status = GMIME_SIGNER_STATUS_ERROR;
+ gpg->signer->next = signer;
+ gpg->signer = signer;
+
+ /* get the key id of the signer */
+ status = next_token (status, &signer->keyid);
+
+ /* skip the pubkey_algo */
+ status = next_token (status, NULL);
+
+ /* skip the digest_algo */
+ status = next_token (status, NULL);
+
+ /* skip the class */
+ status = next_token (status, NULL);
+
+ /* get the signature expiration date (or 0 for never) */
+ signer->expires = strtoul (status, NULL, 10);
+ status = next_token (status, NULL);
+
+ /* the last token is the 'rc' which we don't care about */
+ } else if (!strncmp (status, "NO_PUBKEY ", 10)) {
+ /* the only token is the keyid, but we've already got it */
+ gpg->signer->errors |= GMIME_SIGNER_ERROR_NO_PUBKEY;
+ gpg->nopubkey = TRUE;
+ } else if (!strncmp (status, "EXPSIG", 6)) {
+ /* FIXME: see what else we can glean from this... */
+ gpg->signer->errors |= GMIME_SIGNER_ERROR_EXPSIG;
+ } else if (!strncmp (status, "EXPKEYSIG", 9)) {
+ gpg->signer->errors |= GMIME_SIGNER_ERROR_EXPKEYSIG;
+ } else if (!strncmp (status, "REVKEYSIG", 9)) {
+ gpg->signer->errors |= GMIME_SIGNER_ERROR_REVKEYSIG;
+ } else if (!strncmp (status, "VALIDSIG ", 9)) {
+ char *inend;
+
+ gpg->validsig = TRUE;
+ status += 9;
+
+ signer = gpg->signer;
+
+ /* the first token is the fingerprint */
+ status = next_token (status, &signer->fingerprint);
+
+ /* the second token is the date the stream was signed YYYY-MM-DD */
+ status = next_token (status, NULL);
+
+ /* the third token is the signature creation date (or 0 for unknown?) */
+ signer->created = strtoul (status, &inend, 10);
+ if (inend == status || *inend != ' ')
+ return;
+
+ status = inend + 1;
+
+ /* the fourth token is the signature expiration date (or 0 for never) */
+ signer->expires = strtoul (status, NULL, 10);
+
+ /* ignore the rest... */
+ } else if (!strncmp (status, "TRUST_", 6)) {
+ status += 6;
+
+ signer = gpg->signer;
+ if (!strncmp (status, "NEVER", 5)) {
+ signer->trust = GMIME_SIGNER_TRUST_NEVER;
+ } else if (!strncmp (status, "MARGINAL", 8)) {
+ signer->trust = GMIME_SIGNER_TRUST_MARGINAL;
+ } else if (!strncmp (status, "FULLY", 5)) {
+ signer->trust = GMIME_SIGNER_TRUST_FULLY;
+ } else if (!strncmp (status, "ULTIMATE", 8)) {
+ signer->trust = GMIME_SIGNER_TRUST_ULTIMATE;
+ } else if (!strncmp (status, "UNDEFINED", 9)) {
+ signer->trust = GMIME_SIGNER_TRUST_UNDEFINED;
+ }
+ }
+}
+
static int
gpg_ctx_parse_status (struct _GpgCtx *gpg, GError **err)
{
size_t nread, nwritten;
register char *inptr;
- GMimeSigner *signer;
char *status, *tmp;
int len;
@@ -982,116 +1107,9 @@
}
break;
case GPG_CTX_MODE_VERIFY:
- if (!strncmp (status, "SIG_ID ", 7)) {
- /* not sure if this contains anything we care about... */
- } else if (!strncmp (status, "GOODSIG ", 8)) {
- gpg->goodsig = TRUE;
- status += 8;
-
- signer = g_mime_signer_new ();
- signer->status = GMIME_SIGNER_STATUS_GOOD;
- gpg->signer->next = signer;
- gpg->signer = signer;
-
- /* get the key id of the signer */
- status = next_token (status, &signer->keyid);
-
- /* the rest of the string is the signer's name */
- signer->name = g_strdup (status);
- } else if (!strncmp (status, "BADSIG ", 7)) {
- gpg->badsig = TRUE;
- status += 7;
-
- signer = g_mime_signer_new ();
- signer->status = GMIME_SIGNER_STATUS_BAD;
- gpg->signer->next = signer;
- gpg->signer = signer;
-
- /* get the key id of the signer */
- status = next_token (status, &signer->keyid);
-
- /* the rest of the string is the signer's name */
- signer->name = g_strdup (status);
- } else if (!strncmp (status, "ERRSIG ", 7)) {
- /* Note: NO_PUBKEY often comes after an ERRSIG */
- gpg->errsig = TRUE;
- status += 7;
-
- signer = g_mime_signer_new ();
- signer->status = GMIME_SIGNER_STATUS_ERROR;
- gpg->signer->next = signer;
- gpg->signer = signer;
-
- /* get the key id of the signer */
- status = next_token (status, &signer->keyid);
-
- /* skip the pubkey_algo */
- status = next_token (status, NULL);
-
- /* skip the digest_algo */
- status = next_token (status, NULL);
-
- /* skip the class */
- status = next_token (status, NULL);
-
- /* get the signature expiration date (or 0 for never) */
- signer->expires = strtoul (status, NULL, 10);
- status = next_token (status, NULL);
-
- /* the last token is the 'rc' which we don't care about */
- } else if (!strncmp (status, "NO_PUBKEY ", 10)) {
- /* the only token is the keyid, but we've already got it */
- gpg->signer->errors |= GMIME_SIGNER_ERROR_NO_PUBKEY;
- gpg->nopubkey = TRUE;
- } else if (!strncmp (status, "EXPSIG", 6)) {
- /* FIXME: see what else we can glean from this... */
- gpg->signer->errors |= GMIME_SIGNER_ERROR_EXPSIG;
- } else if (!strncmp (status, "EXPKEYSIG", 9)) {
- gpg->signer->errors |= GMIME_SIGNER_ERROR_EXPKEYSIG;
- } else if (!strncmp (status, "REVKEYSIG", 9)) {
- gpg->signer->errors |= GMIME_SIGNER_ERROR_REVKEYSIG;
- } else if (!strncmp (status, "VALIDSIG ", 9)) {
- char *inend;
-
- gpg->validsig = TRUE;
- status += 9;
-
- signer = gpg->signer;
-
- /* the first token is the fingerprint */
- status = next_token (status, &signer->fingerprint);
-
- /* the second token is the date the stream was signed YYYY-MM-DD */
- status = next_token (status, NULL);
-
- /* the third token is the signature creation date (or 0 for unknown?) */
- signer->created = strtoul (status, &inend, 10);
- if (inend == status || *inend != ' ')
- break;
-
- status = inend + 1;
-
- /* the fourth token is the signature expiration date (or 0 for never) */
- signer->expires = strtoul (status, NULL, 10);
-
- /* ignore the rest... */
- } else if (!strncmp (status, "TRUST_", 6)) {
- status += 6;
-
- signer = gpg->signer;
- if (!strncmp (status, "NEVER", 5)) {
- signer->trust = GMIME_SIGNER_TRUST_NEVER;
- } else if (!strncmp (status, "MARGINAL", 8)) {
- signer->trust = GMIME_SIGNER_TRUST_MARGINAL;
- } else if (!strncmp (status, "FULLY", 5)) {
- signer->trust = GMIME_SIGNER_TRUST_FULLY;
- } else if (!strncmp (status, "ULTIMATE", 8)) {
- signer->trust = GMIME_SIGNER_TRUST_ULTIMATE;
- } else if (!strncmp (status, "UNDEFINED", 9)) {
- signer->trust = GMIME_SIGNER_TRUST_UNDEFINED;
- }
- }
+ gpg_ctx_parse_signer_info (gpg, status);
break;
+ case GPG_CTX_MODE_SIGN_ENCRYPT:
case GPG_CTX_MODE_ENCRYPT:
if (!strncmp (status, "BEGIN_ENCRYPTION", 16)) {
/* nothing to do... but we know to expect data on stdout soon */
@@ -1107,7 +1125,9 @@
if (!strncmp (status, "BEGIN_DECRYPTION", 16)) {
/* nothing to do... but we know to expect data on stdout soon */
} else if (!strncmp (status, "END_DECRYPTION", 14)) {
- /* nothing to do, but we know the end is near? */
+ /* nothing to do, but we know we're done */
+ } else {
+ gpg_ctx_parse_signer_info (gpg, status);
}
break;
case GPG_CTX_MODE_IMPORT:
@@ -1350,6 +1370,7 @@
case GPG_CTX_MODE_VERIFY:
mode = "verify";
break;
+ case GPG_CTX_MODE_SIGN_ENCRYPT:
case GPG_CTX_MODE_ENCRYPT:
mode = "encrypt";
break;
@@ -1650,7 +1671,10 @@
int i;
gpg = gpg_ctx_new (context->session, ctx->path);
- gpg_ctx_set_mode (gpg, GPG_CTX_MODE_ENCRYPT);
+ if (sign)
+ gpg_ctx_set_mode (gpg, GPG_CTX_MODE_SIGN_ENCRYPT);
+ else
+ gpg_ctx_set_mode (gpg, GPG_CTX_MODE_ENCRYPT);
gpg_ctx_set_armor (gpg, TRUE);
gpg_ctx_set_userid (gpg, userid);
gpg_ctx_set_istream (gpg, istream);
@@ -1698,12 +1722,15 @@
}
-static int
+static GMimeSignatureValidity *
gpg_decrypt (GMimeCipherContext *context, GMimeStream *istream,
GMimeStream *ostream, GError **err)
{
GMimeGpgContext *ctx = (GMimeGpgContext *) context;
+ GMimeSignatureValidity *validity;
+ const char *diagnostics;
struct _GpgCtx *gpg;
+ int save;
gpg = gpg_ctx_new (context->session, ctx->path);
gpg_ctx_set_mode (gpg, GPG_CTX_MODE_DECRYPT);
@@ -1716,7 +1743,7 @@
errno ? g_strerror (errno) : _("Unknown"));
gpg_ctx_free (gpg);
- return -1;
+ return NULL;
}
while (!gpg_ctx_op_complete (gpg)) {
@@ -1724,14 +1751,11 @@
gpg_ctx_op_cancel (gpg);
gpg_ctx_free (gpg);
- return -1;
+ return NULL;
}
}
if (gpg_ctx_op_wait (gpg) != 0) {
- const char *diagnostics;
- int save;
-
save = errno;
diagnostics = gpg_ctx_get_diagnostics (gpg);
errno = save;
@@ -1739,12 +1763,34 @@
g_set_error (err, GMIME_ERROR, errno, diagnostics);
gpg_ctx_free (gpg);
- return -1;
+ return NULL;
+ }
+
+ diagnostics = gpg_ctx_get_diagnostics (gpg);
+
+ validity = g_mime_signature_validity_new ();
+ g_mime_signature_validity_set_details (validity, diagnostics);
+
+ if (gpg->signers) {
+ if (gpg->goodsig && !(gpg->badsig || gpg->errsig || gpg->nodata)) {
+ /* all signatures were good */
+ validity->status = GMIME_SIGNATURE_STATUS_GOOD;
+ } else if (gpg->badsig && !(gpg->goodsig && !gpg->errsig)) {
+ /* all signatures were bad */
+ validity->status = GMIME_SIGNATURE_STATUS_BAD;
+ } else if (!gpg->nodata) {
+ validity->status = GMIME_SIGNATURE_STATUS_UNKNOWN;
+ } else {
+ validity->status = GMIME_SIGNATURE_STATUS_BAD;
+ }
+
+ validity->signers = gpg->signers;
+ gpg->signers = NULL;
}
gpg_ctx_free (gpg);
- return 0;
+ return validity;
}
static int
Modified: trunk/gmime/gmime-multipart-encrypted.c
==============================================================================
--- trunk/gmime/gmime-multipart-encrypted.c (original)
+++ trunk/gmime/gmime-multipart-encrypted.c Wed Jun 4 03:44:35 2008
@@ -23,6 +23,7 @@
#include <config.h>
#endif
+#include <stdio.h>
#include <string.h>
#include "gmime-multipart-encrypted.h"
@@ -122,6 +123,7 @@
{
mpe->protocol = NULL;
mpe->decrypted = NULL;
+ mpe->validity = NULL;
}
static void
@@ -134,6 +136,9 @@
if (mpe->decrypted)
g_object_unref (mpe->decrypted);
+ if (mpe->validity)
+ g_mime_signature_validity_free (mpe->validity);
+
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -228,13 +233,15 @@
* @mpe: multipart/encrypted object
* @content: MIME part to encrypt
* @ctx: encryption cipher context
+ * @sign: %TRUE if the content should also be signed or %FALSE otherwise
+ * @userid: user id to use for signing (only used if @sign is %TRUE)
* @recipients: an array of recipients to encrypt to
- * @err: exception
+ * @err: a #GError
*
- * Attempts to encrypt the @content MIME part to the public keys of
- * @recipients using the @ctx encryption context. If successful, the
- * encrypted #GMimeObject is set as the encrypted part of the
- * multipart/encrypted object @mpe.
+ * Attempts to encrypt (and conditionally sign) the @content MIME part
+ * to the public keys of @recipients using the @ctx encryption
+ * context. If successful, the encrypted #GMimeObject is set as the
+ * encrypted part of the multipart/encrypted object @mpe.
*
* Returns: %0 on success or %-1 on fail. If the encryption fails, an
* exception will be set on @err to provide information as to why the
@@ -242,7 +249,8 @@
**/
int
g_mime_multipart_encrypted_encrypt (GMimeMultipartEncrypted *mpe, GMimeObject *content,
- GMimeCipherContext *ctx, GPtrArray *recipients,
+ GMimeCipherContext *ctx, gboolean sign,
+ const char *userid, GPtrArray *recipients,
GError **err)
{
GMimeStream *filtered_stream, *ciphertext, *stream;
@@ -273,7 +281,7 @@
/* encrypt the content stream */
ciphertext = g_mime_stream_mem_new ();
- if (g_mime_cipher_context_encrypt (ctx, FALSE, NULL, recipients, stream, ciphertext, err) == -1) {
+ if (g_mime_cipher_context_encrypt (ctx, sign, userid, recipients, stream, ciphertext, err) == -1) {
g_object_unref (ciphertext);
g_object_unref (stream);
return -1;
@@ -324,11 +332,16 @@
* g_mime_multipart_encrypted_decrypt:
* @mpe: multipart/encrypted object
* @ctx: decryption cipher context
- * @err: exception
+ * @validity: a #GMimeSignatureValidity
+ * @err: a #GError
*
* Attempts to decrypt the encrypted MIME part contained within the
* multipart/encrypted object @mpe using the @ctx decryption context.
*
+ * If @validity is non-NULL, then on a successful decrypt operation,
+ * it will be updated to point to a newly-allocated
+ * #GMimeSignatureValidity with signature status information.
+ *
* Returns: the decrypted MIME part on success or %NULL on fail. If the
* decryption fails, an exception will be set on @err to provide
* information as to why the failure occured.
@@ -339,9 +352,10 @@
{
GMimeObject *decrypted, *version, *encrypted;
const GMimeContentType *mime_type;
- GMimeDataWrapper *wrapper;
GMimeStream *stream, *ciphertext;
GMimeStream *filtered_stream;
+ GMimeSignatureValidity *sv;
+ GMimeDataWrapper *wrapper;
GMimeFilter *crlf_filter;
GMimeParser *parser;
const char *protocol;
@@ -362,7 +376,7 @@
if (protocol) {
/* make sure the protocol matches the cipher encrypt protocol */
if (g_ascii_strcasecmp (ctx->encrypt_protocol, protocol) != 0) {
- g_set_error (err, GMIME_ERROR_QUARK, GMIME_ERROR_PROTOCOL_ERROR,
+ g_set_error (err, GMIME_ERROR, GMIME_ERROR_PROTOCOL_ERROR,
"Failed to decrypt MIME part: protocol error");
return NULL;
@@ -377,7 +391,7 @@
/* make sure the protocol matches the version part's content-type */
content_type = g_mime_content_type_to_string (version->content_type);
if (g_ascii_strcasecmp (content_type, protocol) != 0) {
- g_set_error (err, GMIME_ERROR_QUARK, GMIME_ERROR_PROTOCOL_ERROR,
+ g_set_error (err, GMIME_ERROR, GMIME_ERROR_PROTOCOL_ERROR,
"Failed to decrypt MIME part: protocol error");
g_object_unref (version);
@@ -409,7 +423,7 @@
g_object_unref (crlf_filter);
/* get the cleartext */
- if (g_mime_cipher_context_decrypt (ctx, ciphertext, filtered_stream, err) == -1) {
+ if (!(sv = g_mime_cipher_context_decrypt (ctx, ciphertext, filtered_stream, err))) {
g_object_unref (filtered_stream);
g_object_unref (ciphertext);
g_object_unref (stream);
@@ -429,14 +443,39 @@
decrypted = g_mime_parser_construct_part (parser);
g_object_unref (parser);
- if (decrypted) {
- /* cache the decrypted part */
- g_object_ref (decrypted);
- mpe->decrypted = decrypted;
- } else {
- g_set_error (err, GMIME_ERROR_QUARK, GMIME_ERROR_PARSE_ERROR,
+ if (!decrypted) {
+ g_set_error (err, GMIME_ERROR, GMIME_ERROR_PARSE_ERROR,
"Failed to decrypt MIME part: parse error");
+
+ g_mime_signature_validity_free (sv);
+
+ return NULL;
}
+ /* cache the decrypted part */
+ g_object_ref (decrypted);
+ mpe->decrypted = decrypted;
+ mpe->validity = sv;
+
return decrypted;
}
+
+
+/**
+ * g_mime_multipart_encrypted_get_signature_validity:
+ * @mpe: a #GMimeMultipartEncrypted
+ *
+ * Gets the signature validity of the encrypted MIME part.
+ *
+ * Note: This is only useful after calling
+ * g_mime_multipart_encrypted_decrypt().
+ *
+ * Returns: a #GMimeSignatureValidity.
+ **/
+const GMimeSignatureValidity *
+g_mime_multipart_encrypted_get_signature_validity (GMimeMultipartEncrypted *mpe)
+{
+ g_return_val_if_fail (GMIME_IS_MULTIPART_ENCRYPTED (mpe), NULL);
+
+ return mpe->validity;
+}
Modified: trunk/gmime/gmime-multipart-encrypted.h
==============================================================================
--- trunk/gmime/gmime-multipart-encrypted.h (original)
+++ trunk/gmime/gmime-multipart-encrypted.h Wed Jun 4 03:44:35 2008
@@ -45,9 +45,9 @@
struct _GMimeMultipartEncrypted {
GMimeMultipart parent_object;
- char *protocol;
-
+ GMimeSignatureValidity *validity;
GMimeObject *decrypted;
+ char *protocol;
};
struct _GMimeMultipartEncryptedClass {
@@ -61,13 +61,16 @@
GMimeMultipartEncrypted *g_mime_multipart_encrypted_new (void);
int g_mime_multipart_encrypted_encrypt (GMimeMultipartEncrypted *mpe, GMimeObject *content,
- GMimeCipherContext *ctx, GPtrArray *recipients,
+ GMimeCipherContext *ctx, gboolean sign,
+ const char *userid, GPtrArray *recipients,
GError **err);
GMimeObject *g_mime_multipart_encrypted_decrypt (GMimeMultipartEncrypted *mpe,
GMimeCipherContext *ctx,
GError **err);
+const GMimeSignatureValidity *g_mime_multipart_encrypted_get_signature_validity (GMimeMultipartEncrypted *mpe);
+
G_END_DECLS
#endif /* __GMIME_MULTIPART_ENCRYPTED_H__ */
Modified: trunk/mono/gmime-api.raw
==============================================================================
--- trunk/mono/gmime-api.raw (original)
+++ trunk/mono/gmime-api.raw Wed Jun 4 03:44:35 2008
@@ -184,7 +184,7 @@
</parameters>
</virtual_method>
<virtual_method name="Decrypt" cname="decrypt">
- <return-type type="int" />
+ <return-type type="GMimeSignatureValidity*" />
<parameters>
<parameter type="GMimeCipherContext*" name="ctx" />
<parameter type="GMimeStream*" name="istream" />
@@ -210,7 +210,7 @@
</parameters>
</virtual_method>
<method name="Decrypt" cname="g_mime_cipher_context_decrypt">
- <return-type type="int" />
+ <return-type type="GMimeSignatureValidity*" />
<parameters>
<parameter type="GMimeStream*" name="istream" />
<parameter type="GMimeStream*" name="ostream" />
@@ -968,8 +968,9 @@
</method>
</object>
<object name="MultipartEncrypted" cname="GMimeMultipartEncrypted" parent="GMimeMultipart">
- <field name="Protocol" cname="protocol" type="char*" />
+ <field name="Validity" cname="validity" type="GMimeSignatureValidity*" />
<field name="Decrypted" cname="decrypted" type="GMimeObject*" />
+ <field name="Protocol" cname="protocol" type="char*" />
<method name="Decrypt" cname="g_mime_multipart_encrypted_decrypt">
<return-type type="GMimeObject*" />
<parameters>
@@ -982,10 +983,15 @@
<parameters>
<parameter type="GMimeObject*" name="content" />
<parameter type="GMimeCipherContext*" name="ctx" />
+ <parameter type="gboolean" name="sign" />
+ <parameter type="const-char*" name="userid" />
<parameter type="GPtrArray*" name="recipients" />
<parameter type="GError**" name="err" />
</parameters>
</method>
+ <method name="GetSignatureValidity" cname="g_mime_multipart_encrypted_get_signature_validity">
+ <return-type type="const-GMimeSignatureValidity*" />
+ </method>
<method name="GetType" cname="g_mime_multipart_encrypted_get_type" shared="true">
<return-type type="GType" />
</method>
Modified: trunk/tests/test-pgpmime.c
==============================================================================
--- trunk/tests/test-pgpmime.c (original)
+++ trunk/tests/test-pgpmime.c Wed Jun 4 03:44:35 2008
@@ -107,13 +107,14 @@
static void
-print_verify_results (GMimeSignatureValidity *validity)
+print_verify_results (const GMimeSignatureValidity *validity)
{
GMimeSigner *signer;
switch (validity->status) {
case GMIME_SIGNATURE_STATUS_NONE:
- fputs ("Unset\n", stdout);
+ fputs ("NONE\n", stdout);
+ break;
case GMIME_SIGNATURE_STATUS_GOOD:
fputs ("GOOD\n", stdout);
break;
@@ -271,9 +272,8 @@
g_object_unref (mps);
stream = g_mime_stream_mem_new ();
- g_mime_object_write_to_stream (GMIME_OBJECT (message), stream);
+ g_mime_object_write_to_stream ((GMimeObject *) message, stream);
g_mime_stream_reset (stream);
-
g_object_unref (message);
parser = g_mime_parser_new ();
@@ -308,16 +308,18 @@
#define MULTIPART_ENCRYPTED_CONTENT "This is a test of multipart/encrypted.\n"
static void
-test_multipart_encrypted (GMimeCipherContext *ctx)
+test_multipart_encrypted (GMimeCipherContext *ctx, gboolean sign)
{
+ const GMimeSignatureValidity *sv;
GMimeStream *cleartext, *stream;
GMimeContentType *content_type;
GMimeMultipartEncrypted *mpe;
GMimeDataWrapper *content;
GMimeObject *decrypted;
- GMimeMessage *message;
GPtrArray *recipients;
+ GMimeMessage *message;
Exception *ex = NULL;
+ GMimeParser *parser;
GByteArray *buf[2];
GError *err = NULL;
GMimePart *part;
@@ -347,7 +349,8 @@
/* encrypt the part */
recipients = g_ptr_array_new ();
g_ptr_array_add (recipients, "no user no domain");
- g_mime_multipart_encrypted_encrypt (mpe, GMIME_OBJECT (part), ctx, recipients, &err);
+ g_mime_multipart_encrypted_encrypt (mpe, GMIME_OBJECT (part), ctx, sign,
+ "no user no domain", recipients, &err);
g_ptr_array_free (recipients, TRUE);
g_object_unref (part);
@@ -363,26 +366,65 @@
g_mime_message_set_sender (message, "\"Jeffrey Stedfast\" <fejj helixcode com>");
g_mime_message_set_reply_to (message, "fejj helixcode com");
g_mime_message_add_recipient (message, GMIME_RECIPIENT_TYPE_TO,
- "Federico Mena-Quintero", "federico helixcode com");
+ "Federico Mena-Quintero",
+ "federico helixcode com");
g_mime_message_set_subject (message, "This is a test message");
g_mime_object_set_header ((GMimeObject *) message, "X-Mailer", "main.c");
g_mime_message_set_mime_part (message, GMIME_OBJECT (mpe));
+ g_object_unref (mpe);
+
+ stream = g_mime_stream_mem_new ();
+ g_mime_object_write_to_stream ((GMimeObject *) message, stream);
+ g_mime_stream_reset (stream);
+ g_object_unref (message);
+
+ parser = g_mime_parser_new ();
+ g_mime_parser_init_with_stream (parser, stream);
+ g_object_unref (stream);
+
+ message = g_mime_parser_construct_message (parser);
+ g_object_unref (parser);
+
+ if (!GMIME_IS_MULTIPART_ENCRYPTED (message->mime_part)) {
+ ex = exception_new ("resultant top-level mime part not a multipart/encrypted?");
+ g_object_unref (message);
+ throw (ex);
+ }
+
+ mpe = (GMimeMultipartEncrypted *) message->mime_part;
/* okay, now to test our decrypt function... */
decrypted = g_mime_multipart_encrypted_decrypt (mpe, ctx, &err);
if (!decrypted || err != NULL) {
ex = exception_new ("decryption failed: %s", err->message);
+ g_object_unref (cleartext);
+ g_object_unref (mpe);
g_error_free (err);
throw (ex);
}
+ sv = g_mime_multipart_encrypted_get_signature_validity (mpe);
+ v(print_verify_results (sv));
+
+ if (sign) {
+ if (sv->status != GMIME_SIGNATURE_STATUS_GOOD)
+ ex = exception_new ("signature validity status expected to be GOOD");
+ } else {
+ if (sv->status != GMIME_SIGNATURE_STATUS_NONE)
+ ex = exception_new ("signature validity status expected to be NONE");
+ }
+
+ g_object_unref (mpe);
+
+ if (ex != NULL) {
+ g_object_unref (cleartext);
+ throw (ex);
+ }
+
stream = g_mime_stream_mem_new ();
g_mime_object_write_to_stream (decrypted, stream);
g_object_unref (decrypted);
- g_object_unref (message);
- g_object_unref (mpe);
-
buf[0] = GMIME_STREAM_MEM (cleartext)->buffer;
buf[1] = GMIME_STREAM_MEM (stream)->buffer;
@@ -480,12 +522,20 @@
testsuite_check ("multipart/encrypted");
try {
- test_multipart_encrypted (ctx);
+ test_multipart_encrypted (ctx, FALSE);
testsuite_check_passed ();
} catch (ex) {
testsuite_check_failed ("multipart/encrypted failed: %s", ex->message);
} finally;
+ testsuite_check ("multipart/encrypted+sign");
+ try {
+ test_multipart_encrypted (ctx, TRUE);
+ testsuite_check_passed ();
+ } catch (ex) {
+ testsuite_check_failed ("multipart/encrypted+sign failed: %s", ex->message);
+ } finally;
+
g_object_unref (session);
g_object_unref (ctx);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]