[gmime] Implemented GMimeDecryptionResult (bug #641319)



commit db77dad1b2ca06329164e54e790cbbba82bb7dfd
Author: Jeffrey Stedfast <fejj gnome org>
Date:   Fri Mar 4 17:09:40 2011 -0500

    Implemented GMimeDecryptionResult (bug #641319)
    
    2011-03-04  Jeffrey Stedfast  <fejj novell com>
    
    	Implemented bug #641319.
    
    	* gmime/gmime-crypto-context.c (g_mime_crypto_recipient_*): New
    	set of functions for manipulating a GMimeCryptoRecipient.
    	(g_mime_decryption_result_*): New set of functions to manipulate a
    	GMimeDecryptionResult
    	(g_mime_crypto_context_decrypt): Now returns a
    	GMimeDecryptionResult.
    
    	* gmime/gmime-multipart-encrypted.c
    	(g_mime_multipart_encrypted_decrypt): Updated for API changes.
    
    	* gmime/gmime-pkcs7-context.c (pkcs7_decrypt): Updated for API
    	changes.
    
    	* gmime/gmime-gpg-context.c (gpg_decrypt): Updated for API
    	changes.

 ChangeLog                         |   20 +++
 docs/reference/gmime-sections.txt |   17 +++
 gmime/gmime-crypto-context.c      |  270 +++++++++++++++++++++++++++++++++++--
 gmime/gmime-crypto-context.h      |  147 ++++++++++++++-------
 gmime/gmime-gpg-context.c         |   62 +++++++--
 gmime/gmime-multipart-encrypted.c |   25 ++--
 gmime/gmime-multipart-encrypted.h |    2 +-
 gmime/gmime-pkcs7-context.c       |   50 ++++++--
 mono/gmime-api.raw                |   64 ++++++++-
 tests/test-pgp.c                  |   10 +-
 tests/test-pgpmime.c              |   15 +-
 tests/test-pkcs7.c                |   10 +-
 tests/test-smime.c                |   15 +-
 13 files changed, 588 insertions(+), 119 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index f1b2a29..f6c4ab6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,25 @@
 2011-03-04  Jeffrey Stedfast  <fejj novell com>
 
+	Implemented bug #641319.
+
+	* gmime/gmime-crypto-context.c (g_mime_crypto_recipient_*): New
+	set of functions for manipulating a GMimeCryptoRecipient.
+	(g_mime_decryption_result_*): New set of functions to manipulate a
+	GMimeDecryptionResult
+	(g_mime_crypto_context_decrypt): Now returns a
+	GMimeDecryptionResult.
+
+	* gmime/gmime-multipart-encrypted.c
+	(g_mime_multipart_encrypted_decrypt): Updated for API changes.
+
+	* gmime/gmime-pkcs7-context.c (pkcs7_decrypt): Updated for API
+	changes.
+
+	* gmime/gmime-gpg-context.c (gpg_decrypt): Updated for API
+	changes.
+
+2011-03-04  Jeffrey Stedfast  <fejj novell com>
+
 	API cleanup as well as preparing for the possibility of a
 	multi-protocol CryptoContext.
 
diff --git a/docs/reference/gmime-sections.txt b/docs/reference/gmime-sections.txt
index 7dde510..b1e3073 100644
--- a/docs/reference/gmime-sections.txt
+++ b/docs/reference/gmime-sections.txt
@@ -1202,6 +1202,23 @@ g_mime_signature_validity_set_details
 g_mime_signature_validity_get_details
 g_mime_signature_validity_add_signer
 g_mime_signature_validity_get_signers
+<SUBSECTION>
+GMimeCryptoRecipient
+g_mime_crypto_recipient_new
+g_mime_crypto_recipient_free
+g_mime_crypto_recipient_next
+g_mime_crypto_recipient_set_key_id
+g_mime_crypto_recipient_get_key_id
+g_mime_crypto_recipient_set_pubkey_algo
+g_mime_crypto_recipient_get_pubkey_algo
+<SUBSECTION>
+GMimeDecryptionResult
+g_mime_decryption_result_new
+g_mime_decryption_result_free
+g_mime_decryption_result_set_validity
+g_mime_decryption_result_get_validity
+g_mime_decryption_result_add_recipient
+g_mime_decryption_result_get_recipients
 <SUBSECTION Private>
 g_mime_crypto_context_get_type
 
diff --git a/gmime/gmime-crypto-context.c b/gmime/gmime-crypto-context.c
index 0d95dd5..8504ba0 100644
--- a/gmime/gmime-crypto-context.c
+++ b/gmime/gmime-crypto-context.c
@@ -65,8 +65,8 @@ static int crypto_encrypt (GMimeCryptoContext *ctx, gboolean sign,
 			   GPtrArray *recipients, GMimeStream *istream,
 			   GMimeStream *ostream, GError **err);
 
-static GMimeSignatureValidity *crypto_decrypt (GMimeCryptoContext *ctx, GMimeStream *istream,
-					       GMimeStream *ostream, GError **err);
+static GMimeDecryptionResult *crypto_decrypt (GMimeCryptoContext *ctx, GMimeStream *istream,
+					      GMimeStream *ostream, GError **err);
 
 static int crypto_import_keys (GMimeCryptoContext *ctx, GMimeStream *istream,
 			       GError **err);
@@ -413,7 +413,7 @@ g_mime_crypto_context_encrypt (GMimeCryptoContext *ctx, gboolean sign, const cha
 }
 
 
-static GMimeSignatureValidity *
+static GMimeDecryptionResult *
 crypto_decrypt (GMimeCryptoContext *ctx, GMimeStream *istream,
 		GMimeStream *ostream, GError **err)
 {
@@ -435,15 +435,16 @@ crypto_decrypt (GMimeCryptoContext *ctx, GMimeStream *istream,
  * cleartext to the output stream.
  *
  * If the encrypted input stream was also signed, the returned
- * #GMimeSignatureValidity will contain a list of signers, each with a
- * #GMimeSignerStatus (among other details).
+ * #GMimeDecryptionResult will have a non-%NULL #GMimeSignatureValidity which
+ * will contain a list of signers, each with a #GMimeSignerStatus (among other
+ * details about each signer).
  *
- * If the encrypted input text was not signed, then the
- * #GMimeSignatureValidity will not contain any signers.
+ * On success, the returned #GMimeDecryptionResult will contain a list of
+ * recipient keys that the original encrypted stream was encrypted to.
  *
- * Returns: a #GMimeSignatureValidity on success or %NULL on error.
+ * Returns: a #GMimeDecryptionResult on success or %NULL on error.
  **/
-GMimeSignatureValidity *
+GMimeDecryptionResult *
 g_mime_crypto_context_decrypt (GMimeCryptoContext *ctx, GMimeStream *istream,
 			       GMimeStream *ostream, GError **err)
 {
@@ -1293,3 +1294,254 @@ g_mime_signature_validity_add_signer (GMimeSignatureValidity *validity, GMimeSig
 		s->next = signer;
 	}
 }
+
+
+/**
+ * g_mime_crypto_recipient_new:
+ *
+ * Allocates an new #GMimeCryptoRecipient. This function is meant to be used
+ * in #GMimeCryptoContext subclasses when allocating recipients to add to a
+ * #GMimeDecryptionResult.
+ *
+ * Returns: a new #GMimeCryptoRecipient.
+ **/
+GMimeCryptoRecipient *
+g_mime_crypto_recipient_new (void)
+{
+	GMimeCryptoRecipient *recipient;
+	
+	recipient = g_slice_new (GMimeCryptoRecipient);
+	recipient->pubkey_algo = GMIME_CRYPTO_PUBKEY_ALGO_DEFAULT;
+	recipient->keyid = NULL;
+	recipient->next = NULL;
+	
+	return recipient;
+}
+
+
+/**
+ * g_mime_crypto_recipient_free:
+ * @recipient: a #GMimeCryptoRecipient
+ *
+ * Frees the singleton recipient. Should NOT be used to free recipients
+ * returned from g_mime_signature_validity_get_recipients().
+ **/
+void
+g_mime_crypto_recipient_free (GMimeCryptoRecipient *recipient)
+{
+	g_free (recipient->keyid);
+	
+	g_slice_free (GMimeCryptoRecipient, recipient);
+}
+
+
+/**
+ * g_mime_crypto_recipient_next:
+ * @recipient: a #GMimeCryptoRecipient
+ *
+ * Advance to the next recipient.
+ *
+ * Returns: the next #GMimeCryptoRecipient or %NULL when complete.
+ **/
+const GMimeCryptoRecipient *
+g_mime_crypto_recipient_next (const GMimeCryptoRecipient *recipient)
+{
+	g_return_val_if_fail (recipient != NULL, NULL);
+	
+	return recipient->next;
+}
+
+
+/**
+ * g_mime_crypto_recipient_set_pubkey_algo:
+ * @recipient: a #GMimeCryptoRecipient
+ * @pubkey_algo: a #GMimeCryptoPubKeyAlgo
+ *
+ * Set the public-key algorithm used by the recipient.
+ **/
+void
+g_mime_crypto_recipient_set_pubkey_algo (GMimeCryptoRecipient *recipient, GMimeCryptoPubKeyAlgo pubkey_algo)
+{
+	g_return_if_fail (recipient != NULL);
+	
+	recipient->pubkey_algo = pubkey_algo;
+}
+
+
+/**
+ * g_mime_crypto_recipient_get_pubkey_algo:
+ * @recipient: a #GMimeCryptoRecipient
+ *
+ * Get the public-key algorithm used by the recipient.
+ *
+ * Returns: the public-key algorithm used by the recipient.
+ **/
+GMimeCryptoPubKeyAlgo
+g_mime_crypto_recipient_get_pubkey_algo (const GMimeCryptoRecipient *recipient)
+{
+	g_return_val_if_fail (recipient != NULL, GMIME_CRYPTO_PUBKEY_ALGO_DEFAULT);
+	
+	return recipient->pubkey_algo;
+}
+
+
+/**
+ * g_mime_crypto_recipient_set_key_id:
+ * @recipient: a #GMimeCryptoRecipient
+ * @key_id: key id
+ *
+ * Set the recipient's key id.
+ **/
+void
+g_mime_crypto_recipient_set_key_id (GMimeCryptoRecipient *recipient, const char *key_id)
+{
+	g_return_if_fail (recipient != NULL);
+	
+	g_free (recipient->keyid);
+	recipient->keyid = g_strdup (key_id);
+}
+
+
+/**
+ * g_mime_crypto_recipient_get_key_id:
+ * @recipient: a #GMimeCryptoRecipient
+ *
+ * Get the recipient's key id.
+ *
+ * Returns: the recipient's key id.
+ **/
+const char *
+g_mime_crypto_recipient_get_key_id (const GMimeCryptoRecipient *recipient)
+{
+	g_return_val_if_fail (recipient != NULL, NULL);
+	
+	return recipient->keyid;
+}
+
+
+/**
+ * g_mime_decryption_result_new:
+ *
+ * Creates a new #GMimeDecryptionResult.
+ *
+ * Returns: a new #GMimeDecryptionResult.
+ **/
+GMimeDecryptionResult *
+g_mime_decryption_result_new (void)
+{
+	GMimeDecryptionResult *result;
+	
+	result = g_slice_new (GMimeDecryptionResult);
+	result->recipients = NULL;
+	result->validity = NULL;
+	
+	return result;
+}
+
+
+/**
+ * g_mime_decryption_result_free:
+ * @result: a #GMimeDecryptionResult
+ *
+ * Frees the memory used by @result back to the system.
+ **/
+void
+g_mime_decryption_result_free (GMimeDecryptionResult *result)
+{
+	GMimeCryptoRecipient *recipient, *next;
+	
+	if (result == NULL)
+		return;
+	
+	recipient = result->recipients;
+	while (recipient != NULL) {
+		next = recipient->next;
+		g_mime_crypto_recipient_free (recipient);
+		recipient = next;
+	}
+	
+	g_mime_signature_validity_free (result->validity);
+	
+	g_slice_free (GMimeDecryptionResult, result);
+}
+
+
+/**
+ * g_mime_decryption_result_get_validity:
+ * @result: a #GMimeDecryptionResult
+ *
+ * Gets the signature validity if the decrypted stream was also signed.
+ *
+ * Returns: a #GMimeSignatureValidity or %NULL if the stream was not signed.
+ **/
+const GMimeSignatureValidity *
+g_mime_decryption_result_get_validity (const GMimeDecryptionResult *result)
+{
+	g_return_val_if_fail (result != NULL, NULL);
+	
+	return result->validity;
+}
+
+
+/**
+ * g_mime_decryption_result_set_validity:
+ * @result: a #GMimeDecryptionResult
+ * @validity: a #GMimeSignatureValidity
+ *
+ * Sets @validity as the #GMimeDecryptionResult.
+ **/
+void
+g_mime_decryption_result_set_validity (GMimeDecryptionResult *result, GMimeSignatureValidity *validity)
+{
+	g_return_if_fail (result != NULL);
+	
+	g_mime_signature_validity_free (result->validity);
+	result->validity = validity;
+}
+
+
+/**
+ * g_mime_decryption_result_get_recipients:
+ * @result: signature result
+ *
+ * Gets the list of recipients.
+ *
+ * Returns: a #GMimeCryptoRecipient list which contain further information such
+ * as trust and crypto keys. These recipients are part of the
+ * #GMimeDecryptionResult and should NOT be freed individually.
+ **/
+const GMimeCryptoRecipient *
+g_mime_decryption_result_get_recipients (const GMimeDecryptionResult *result)
+{
+	g_return_val_if_fail (result != NULL, NULL);
+	
+	return result->recipients;
+}
+
+
+/**
+ * g_mime_decryption_result_add_recipient:
+ * @result: a #GMimeDecryptionResult
+ * @recipient: a #GMimeCryptoRecipient
+ *
+ * Adds @recipient to the list of recipients on @result. Once the recipient
+ * is added, it must NOT be freed.
+ **/
+void
+g_mime_decryption_result_add_recipient (GMimeDecryptionResult *result, GMimeCryptoRecipient *recipient)
+{
+	GMimeCryptoRecipient *r;
+	
+	g_return_if_fail (result != NULL);
+	g_return_if_fail (recipient != NULL);
+	
+	if (result->recipients == NULL) {
+		result->recipients = recipient;
+	} else {
+		r = result->recipients;
+		while (r->next != NULL)
+			r = r->next;
+		
+		r->next = recipient;
+	}
+}
diff --git a/gmime/gmime-crypto-context.h b/gmime/gmime-crypto-context.h
index f15e9a9..86342fa 100644
--- a/gmime/gmime-crypto-context.h
+++ b/gmime/gmime-crypto-context.h
@@ -42,6 +42,8 @@ typedef struct _GMimeCryptoContext GMimeCryptoContext;
 typedef struct _GMimeCryptoContextClass GMimeCryptoContextClass;
 
 typedef struct _GMimeSigner GMimeSigner;
+typedef struct _GMimeCryptoRecipient GMimeCryptoRecipient;
+typedef struct _GMimeDecryptionResult GMimeDecryptionResult;
 typedef struct _GMimeSignatureValidity GMimeSignatureValidity;
 
 
@@ -63,30 +65,6 @@ typedef gboolean (* GMimePasswordRequestFunc) (GMimeCryptoContext *ctx, const ch
 					       gboolean reprompt, GMimeStream *response, GError **err);
 
 
-
-/**
- * GMimeCryptoPubKeyAlgo:
- * @GMIME_CRYPTO_PUBKEY_ALGO_DEFAULT: The default public-key algorithm.
- * @GMIME_CRYPTO_PUBKEY_ALGO_RSA: The RSA algorithm.
- * @GMIME_CRYPTO_PUBKEY_ALGO_RSA_E: An encryption-only RSA algorithm.
- * @GMIME_CRYPTO_PUBKEY_ALGO_RSA_S: A signature-only RSA algorithm.
- * @GMIME_CRYPTO_PUBKEY_ALGO_ELG: The ElGamal algorithm.
- * @GMIME_CRYPTO_PUBKEY_ALGO_ELG_E: An encryption-only ElGamal algorithm.
- * @GMIME_CRYPTO_PUBKEY_ALGO_DSA: The DSA algorithm.
- *
- * A public-key algorithm.
- **/
-typedef enum {
-	GMIME_CRYPTO_PUBKEY_ALGO_DEFAULT,
-	GMIME_CRYPTO_PUBKEY_ALGO_RSA,
-	GMIME_CRYPTO_PUBKEY_ALGO_RSA_E,
-	GMIME_CRYPTO_PUBKEY_ALGO_RSA_S,
-	GMIME_CRYPTO_PUBKEY_ALGO_ELG,
-	GMIME_CRYPTO_PUBKEY_ALGO_ELG_E,
-	GMIME_CRYPTO_PUBKEY_ALGO_DSA
-} GMimeCryptoPubKeyAlgo;
-
-
 /**
  * GMimeCryptoHash:
  * @GMIME_CRYPTO_HASH_DEFAULT: The default hash algorithm.
@@ -159,7 +137,7 @@ struct _GMimeCryptoContextClass {
 						  GPtrArray *recipients, GMimeStream *istream,
 						  GMimeStream *ostream, GError **err);
 	
-	GMimeSignatureValidity * (* decrypt)     (GMimeCryptoContext *ctx, GMimeStream *istream,
+	GMimeDecryptionResult *  (* decrypt)     (GMimeCryptoContext *ctx, GMimeStream *istream,
 						  GMimeStream *ostream, GError **err);
 	
 	int                      (* import_keys) (GMimeCryptoContext *ctx, GMimeStream *istream,
@@ -175,45 +153,67 @@ GType g_mime_crypto_context_get_type (void);
 void g_mime_crypto_context_set_request_password (GMimeCryptoContext *ctx, GMimePasswordRequestFunc request_passwd);
 
 /* hash routines */
-GMimeCryptoHash      g_mime_crypto_context_hash_id (GMimeCryptoContext *ctx, const char *hash);
+GMimeCryptoHash g_mime_crypto_context_hash_id (GMimeCryptoContext *ctx, const char *hash);
 
-const char          *g_mime_crypto_context_hash_name (GMimeCryptoContext *ctx, GMimeCryptoHash hash);
+const char *g_mime_crypto_context_hash_name (GMimeCryptoContext *ctx, GMimeCryptoHash hash);
 
 /* protocol routines */
-const char          *g_mime_crypto_context_get_signature_protocol (GMimeCryptoContext *ctx);
+const char *g_mime_crypto_context_get_signature_protocol (GMimeCryptoContext *ctx);
 
-const char          *g_mime_crypto_context_get_encryption_protocol (GMimeCryptoContext *ctx);
+const char *g_mime_crypto_context_get_encryption_protocol (GMimeCryptoContext *ctx);
 
-const char          *g_mime_crypto_context_get_key_exchange_protocol (GMimeCryptoContext *ctx);
+const char *g_mime_crypto_context_get_key_exchange_protocol (GMimeCryptoContext *ctx);
 
 /* crypto routines */
-int                  g_mime_crypto_context_sign (GMimeCryptoContext *ctx, const char *userid,
-						 GMimeCryptoHash hash, GMimeStream *istream,
-						 GMimeStream *ostream, GError **err);
+int g_mime_crypto_context_sign (GMimeCryptoContext *ctx, const char *userid,
+				GMimeCryptoHash hash, GMimeStream *istream,
+				GMimeStream *ostream, GError **err);
 
 GMimeSignatureValidity *g_mime_crypto_context_verify (GMimeCryptoContext *ctx, GMimeCryptoHash hash,
 						      GMimeStream *istream, GMimeStream *sigstream,
 						      GError **err);
 
-int                  g_mime_crypto_context_encrypt (GMimeCryptoContext *ctx, gboolean sign,
-						    const char *userid, GMimeCryptoHash hash,
-						    GPtrArray *recipients, GMimeStream *istream,
-						    GMimeStream *ostream, GError **err);
+int g_mime_crypto_context_encrypt (GMimeCryptoContext *ctx, gboolean sign,
+				   const char *userid, GMimeCryptoHash hash,
+				   GPtrArray *recipients, GMimeStream *istream,
+				   GMimeStream *ostream, GError **err);
 
-GMimeSignatureValidity *g_mime_crypto_context_decrypt (GMimeCryptoContext *ctx, GMimeStream *istream,
-						       GMimeStream *ostream, GError **err);
+GMimeDecryptionResult *g_mime_crypto_context_decrypt (GMimeCryptoContext *ctx, GMimeStream *istream,
+						      GMimeStream *ostream, GError **err);
 
 /* key/certificate routines */
-int                  g_mime_crypto_context_import_keys (GMimeCryptoContext *ctx, GMimeStream *istream,
-							GError **err);
+int g_mime_crypto_context_import_keys (GMimeCryptoContext *ctx, GMimeStream *istream, GError **err);
 
-int                  g_mime_crypto_context_export_keys (GMimeCryptoContext *ctx, GPtrArray *keys,
-							GMimeStream *ostream, GError **err);
+int g_mime_crypto_context_export_keys (GMimeCryptoContext *ctx, GPtrArray *keys,
+				       GMimeStream *ostream, GError **err);
 
 
 /* signature status structures and functions */
 
 /**
+ * GMimeCryptoPubKeyAlgo:
+ * @GMIME_CRYPTO_PUBKEY_ALGO_DEFAULT: The default public-key algorithm.
+ * @GMIME_CRYPTO_PUBKEY_ALGO_RSA: The RSA algorithm.
+ * @GMIME_CRYPTO_PUBKEY_ALGO_RSA_E: An encryption-only RSA algorithm.
+ * @GMIME_CRYPTO_PUBKEY_ALGO_RSA_S: A signature-only RSA algorithm.
+ * @GMIME_CRYPTO_PUBKEY_ALGO_ELG: The ElGamal algorithm.
+ * @GMIME_CRYPTO_PUBKEY_ALGO_ELG_E: An encryption-only ElGamal algorithm.
+ * @GMIME_CRYPTO_PUBKEY_ALGO_DSA: The DSA algorithm.
+ *
+ * A public-key algorithm.
+ **/
+typedef enum {
+	GMIME_CRYPTO_PUBKEY_ALGO_DEFAULT,
+	GMIME_CRYPTO_PUBKEY_ALGO_RSA,
+	GMIME_CRYPTO_PUBKEY_ALGO_RSA_E,
+	GMIME_CRYPTO_PUBKEY_ALGO_RSA_S,
+	GMIME_CRYPTO_PUBKEY_ALGO_ELG,
+	GMIME_CRYPTO_PUBKEY_ALGO_ELG_E,
+	GMIME_CRYPTO_PUBKEY_ALGO_DSA
+} GMimeCryptoPubKeyAlgo;
+
+
+/**
  * GMimeSignerTrust:
  * @GMIME_SIGNER_TRUST_NONE: No trust assigned.
  * @GMIME_SIGNER_TRUST_NEVER: Never trust this signer.
@@ -390,13 +390,64 @@ struct _GMimeSignatureValidity {
 
 
 GMimeSignatureValidity *g_mime_signature_validity_new (void);
-void                    g_mime_signature_validity_free (GMimeSignatureValidity *validity);
+void g_mime_signature_validity_free (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 (const GMimeSignatureValidity *validity);
+void g_mime_signature_validity_add_signer (GMimeSignatureValidity *validity, GMimeSigner *signer);
+
+
+
+/**
+ * GMimeCryptoRecipient:
+ * @next: Pointer to the next #GMimeCryptoRecipient.
+ * @pubkey_algo: The public-key algorithm used by the recipient, if known.
+ * @keyid: The recipient's key id.
+ *
+ * A structure containing useful information about a recipient.
+ **/
+struct _GMimeCryptoRecipient {
+	GMimeCryptoRecipient *next;
+	GMimeCryptoPubKeyAlgo pubkey_algo;
+	char *keyid;
+};
+
+
+GMimeCryptoRecipient *g_mime_crypto_recipient_new (void);
+void g_mime_crypto_recipient_free (GMimeCryptoRecipient *recipient);
+
+const GMimeCryptoRecipient *g_mime_crypto_recipient_next (const GMimeCryptoRecipient *recipient);
+
+void g_mime_crypto_recipient_set_pubkey_algo (GMimeCryptoRecipient *recipient, GMimeCryptoPubKeyAlgo pubkey_algo);
+GMimeCryptoPubKeyAlgo g_mime_crypto_recipient_get_pubkey_algo (const GMimeCryptoRecipient *recipient);
+
+void g_mime_crypto_recipient_set_key_id (GMimeCryptoRecipient *recipient, const char *key_id);
+const char *g_mime_crypto_recipient_get_key_id (const GMimeCryptoRecipient *recipient);
+
+
+/**
+ * GMimeDecryptionResult:
+ * @validity: A #GMimeSignatureValidity if signed or %NULL otherwise.
+ * @recipients: A list of #GMimeCryptoRecipient structures.
+ *
+ * A structure containing the results from decrypting an encrypted stream.
+ **/
+struct _GMimeDecryptionResult {
+	GMimeSignatureValidity *validity;
+	GMimeCryptoRecipient *recipients;
+};
+
+
+GMimeDecryptionResult *g_mime_decryption_result_new (void);
+void g_mime_decryption_result_free (GMimeDecryptionResult *result);
 
-const char             *g_mime_signature_validity_get_details (const GMimeSignatureValidity *validity);
-void                    g_mime_signature_validity_set_details (GMimeSignatureValidity *validity, const char *details);
+const GMimeSignatureValidity *g_mime_decryption_result_get_validity (const GMimeDecryptionResult *result);
+void g_mime_decryption_result_set_validity (GMimeDecryptionResult *result, GMimeSignatureValidity *validity);
 
-const GMimeSigner      *g_mime_signature_validity_get_signers (const GMimeSignatureValidity *validity);
-void                    g_mime_signature_validity_add_signer  (GMimeSignatureValidity *validity, GMimeSigner *signer);
+const GMimeCryptoRecipient *g_mime_decryption_result_get_recipients (const GMimeDecryptionResult *result);
+void g_mime_decryption_result_add_recipient (GMimeDecryptionResult *result, GMimeCryptoRecipient *recipient);
 
 G_END_DECLS
 
diff --git a/gmime/gmime-gpg-context.c b/gmime/gmime-gpg-context.c
index 69efcad..6351603 100644
--- a/gmime/gmime-gpg-context.c
+++ b/gmime/gmime-gpg-context.c
@@ -96,8 +96,8 @@ static int gpg_encrypt (GMimeCryptoContext *ctx, gboolean sign, const char *user
 			GMimeCryptoHash hash, GPtrArray *recipients, GMimeStream *istream,
 			GMimeStream *ostream, GError **err);
 
-static GMimeSignatureValidity *gpg_decrypt (GMimeCryptoContext *ctx, GMimeStream *istream,
-					    GMimeStream *ostream, GError **err);
+static GMimeDecryptionResult *gpg_decrypt (GMimeCryptoContext *ctx, GMimeStream *istream,
+					   GMimeStream *ostream, GError **err);
 
 static int gpg_import_keys (GMimeCryptoContext *ctx, GMimeStream *istream,
 			    GError **err);
@@ -301,6 +301,9 @@ struct _GpgCtx {
 	GByteArray *diag;
 	GMimeStream *diagnostics;
 	
+	GMimeCryptoRecipient *encrypted_to;  /* full list of encrypted-to recipients */
+	GMimeCryptoRecipient *enc_to;        /* most recent recipient (tail pointer) */
+	
 	GMimeSigner *signers;
 	GMimeSigner *signer;
 	
@@ -359,6 +362,9 @@ gpg_ctx_new (GMimeGpgContext *ctx)
 	gpg->need_passwd = FALSE;
 	gpg->need_id = NULL;
 	
+	gpg->encrypted_to = NULL;
+	gpg->enc_to = (GMimeCryptoRecipient *) &gpg->encrypted_to;
+	
 	gpg->signers = NULL;
 	gpg->signer = (GMimeSigner *) &gpg->signers;
 	
@@ -481,7 +487,8 @@ gpg_ctx_get_diagnostics (struct _GpgCtx *gpg)
 static void
 gpg_ctx_free (struct _GpgCtx *gpg)
 {
-	GMimeSigner *signer, *next;
+	GMimeCryptoRecipient *recipient, *nr;
+	GMimeSigner *signer, *ns;
 	guint i;
 	
 	g_hash_table_destroy (gpg->userid_hint);
@@ -521,11 +528,18 @@ gpg_ctx_free (struct _GpgCtx *gpg)
 	
 	g_object_unref (gpg->diagnostics);
 	
+	recipient = gpg->encrypted_to;
+	while (recipient != NULL) {
+		nr = recipient->next;
+		g_mime_crypto_recipient_free (recipient);
+		recipient = nr;
+	}
+	
 	signer = gpg->signers;
 	while (signer != NULL) {
-		next = signer->next;
+		ns = signer->next;
 		g_mime_signer_free (signer);
-		signer = next;
+		signer = ns;
 	}
 	
 	g_slice_free (struct _GpgCtx, gpg);
@@ -1198,6 +1212,9 @@ gpg_ctx_parse_status (struct _GpgCtx *gpg, GError **err)
 		
 		return -1;
 	} else {
+		GMimeCryptoRecipient *recipient;
+		char *inend;
+		
 		switch (gpg->mode) {
 		case GPG_CTX_MODE_SIGN:
 			if (strncmp (status, "SIG_CREATED ", 12) != 0)
@@ -1234,6 +1251,25 @@ gpg_ctx_parse_status (struct _GpgCtx *gpg, GError **err)
 				/* 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 we're done */
+			} else if (!strncmp (status, "ENC_TO ", 7)) {
+				/* parse the recipient info */
+				recipient = g_mime_crypto_recipient_new ();
+				gpg->enc_to->next = recipient;
+				gpg->enc_to = recipient;
+				
+				status += 7;
+				
+				/* first token is the recipient's keyid */
+				status = next_token (status, &recipient->keyid);
+				
+				/* second token is the recipient's pubkey algo */
+				recipient->pubkey_algo = gpg_pubkey_algo (strtoul (status, &inend, 10));
+				if (inend == status || *inend != ' ')
+					return;
+				
+				status = inend + 1;
+				
+				/* third token is the status code, ignore for now */
 			} else {
 				gpg_ctx_parse_signer_info (gpg, status);
 			}
@@ -1883,12 +1919,12 @@ gpg_encrypt (GMimeCryptoContext *context, gboolean sign, const char *userid,
 }
 
 
-static GMimeSignatureValidity *
+static GMimeDecryptionResult *
 gpg_decrypt (GMimeCryptoContext *context, GMimeStream *istream,
 	     GMimeStream *ostream, GError **err)
 {
 	GMimeGpgContext *ctx = (GMimeGpgContext *) context;
-	GMimeSignatureValidity *validity;
+	GMimeDecryptionResult *result;
 	const char *diagnostics;
 	struct _GpgCtx *gpg;
 	int save;
@@ -1927,16 +1963,18 @@ gpg_decrypt (GMimeCryptoContext *context, GMimeStream *istream,
 		return NULL;
 	}
 	
+	result = g_mime_decryption_result_new ();
+	result->validity = g_mime_signature_validity_new ();
 	diagnostics = gpg_ctx_get_diagnostics (gpg);
-	
-	validity = g_mime_signature_validity_new ();
-	g_mime_signature_validity_set_details (validity, diagnostics);
-	validity->signers = gpg->signers;
+	g_mime_signature_validity_set_details (result->validity, diagnostics);
+	result->validity->signers = gpg->signers;
+	result->recipients = gpg->encrypted_to;
+	gpg->encrypted_to = NULL;
 	gpg->signers = NULL;
 	
 	gpg_ctx_free (gpg);
 	
-	return validity;
+	return result;
 }
 
 static int
diff --git a/gmime/gmime-multipart-encrypted.c b/gmime/gmime-multipart-encrypted.c
index c6ce660..cfc24f6 100644
--- a/gmime/gmime-multipart-encrypted.c
+++ b/gmime/gmime-multipart-encrypted.c
@@ -246,15 +246,16 @@ g_mime_multipart_encrypted_encrypt (GMimeMultipartEncrypted *mpe, GMimeObject *c
  * g_mime_multipart_encrypted_decrypt:
  * @mpe: multipart/encrypted object
  * @ctx: decryption context
- * @validity: a #GMimeSignatureValidity
+ * @result: a #GMimeDecryptionResult
  * @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.
+ * If @result is non-NULL, then on a successful decrypt operation, it will be
+ * updated to point to a newly-allocated #GMimeDecryptionResult with signature
+ * status information as well as a list of recipients that the part was
+ * encrypted to.
  *
  * Returns: the decrypted MIME part on success or %NULL on fail. If the
  * decryption fails, an exception will be set on @err to provide
@@ -262,14 +263,14 @@ g_mime_multipart_encrypted_encrypt (GMimeMultipartEncrypted *mpe, GMimeObject *c
  **/
 GMimeObject *
 g_mime_multipart_encrypted_decrypt (GMimeMultipartEncrypted *mpe, GMimeCryptoContext *ctx,
-				    GMimeSignatureValidity **validity, GError **err)
+				    GMimeDecryptionResult **result, GError **err)
 {
 	GMimeObject *decrypted, *version, *encrypted;
 	GMimeStream *stream, *ciphertext;
 	const char *protocol, *supported;
 	GMimeStream *filtered_stream;
 	GMimeContentType *mime_type;
-	GMimeSignatureValidity *sv;
+	GMimeDecryptionResult *res;
 	GMimeDataWrapper *wrapper;
 	GMimeFilter *crlf_filter;
 	GMimeParser *parser;
@@ -278,8 +279,8 @@ g_mime_multipart_encrypted_decrypt (GMimeMultipartEncrypted *mpe, GMimeCryptoCon
 	g_return_val_if_fail (GMIME_IS_MULTIPART_ENCRYPTED (mpe), NULL);
 	g_return_val_if_fail (GMIME_IS_CRYPTO_CONTEXT (ctx), NULL);
 	
-	if (validity)
-		*validity = NULL;
+	if (result)
+		*result = NULL;
 	
 	protocol = g_mime_object_get_content_type_parameter (GMIME_OBJECT (mpe), "protocol");
 	supported = g_mime_crypto_context_get_encryption_protocol (ctx);
@@ -339,7 +340,7 @@ g_mime_multipart_encrypted_decrypt (GMimeMultipartEncrypted *mpe, GMimeCryptoCon
 	g_object_unref (crlf_filter);
 	
 	/* get the cleartext */
-	if (!(sv = g_mime_crypto_context_decrypt (ctx, ciphertext, filtered_stream, err))) {
+	if (!(res = g_mime_crypto_context_decrypt (ctx, ciphertext, filtered_stream, err))) {
 		g_object_unref (filtered_stream);
 		g_object_unref (stream);
 		
@@ -361,13 +362,13 @@ g_mime_multipart_encrypted_decrypt (GMimeMultipartEncrypted *mpe, GMimeCryptoCon
 		g_set_error_literal (err, GMIME_ERROR, GMIME_ERROR_PARSE_ERROR,
 				     _("Cannot decrypt multipart/encrypted part: failed to parse decrypted content."));
 		
-		g_mime_signature_validity_free (sv);
+		g_mime_decryption_result_free (res);
 		
 		return NULL;
 	}
 	
-	if (validity)
-		*validity = sv;
+	if (result)
+		*result = res;
 	
 	return decrypted;
 }
diff --git a/gmime/gmime-multipart-encrypted.h b/gmime/gmime-multipart-encrypted.h
index 824b706..e20170c 100644
--- a/gmime/gmime-multipart-encrypted.h
+++ b/gmime/gmime-multipart-encrypted.h
@@ -73,7 +73,7 @@ int g_mime_multipart_encrypted_encrypt (GMimeMultipartEncrypted *mpe, GMimeObjec
 
 GMimeObject *g_mime_multipart_encrypted_decrypt (GMimeMultipartEncrypted *mpe,
 						 GMimeCryptoContext *ctx,
-						 GMimeSignatureValidity **validity,
+						 GMimeDecryptionResult **result,
 						 GError **err);
 
 G_END_DECLS
diff --git a/gmime/gmime-pkcs7-context.c b/gmime/gmime-pkcs7-context.c
index fb4afa2..c45dc0a 100644
--- a/gmime/gmime-pkcs7-context.c
+++ b/gmime/gmime-pkcs7-context.c
@@ -94,8 +94,8 @@ static int pkcs7_encrypt (GMimeCryptoContext *ctx, gboolean sign, const char *us
 			  GMimeCryptoHash hash, GPtrArray *recipients, GMimeStream *istream,
 			  GMimeStream *ostream, GError **err);
 
-static GMimeSignatureValidity *pkcs7_decrypt (GMimeCryptoContext *ctx, GMimeStream *istream,
-					      GMimeStream *ostream, GError **err);
+static GMimeDecryptionResult *pkcs7_decrypt (GMimeCryptoContext *ctx, GMimeStream *istream,
+					     GMimeStream *ostream, GError **err);
 
 static int pkcs7_import_keys (GMimeCryptoContext *ctx, GMimeStream *istream,
 			      GError **err);
@@ -547,12 +547,12 @@ pkcs7_get_validity (Pkcs7Ctx *pkcs7, gboolean verify)
 	gpgme_user_id_t uid;
 	gpgme_key_t key;
 	
-	/* create a new signature validity to return */
-	validity = g_mime_signature_validity_new ();
-	
 	/* get the signature verification results from GpgMe */
 	if (!(result = gpgme_op_verify_result (pkcs7->ctx)) || !result->signatures)
-		return validity;
+		return verify ? g_mime_signature_validity_new () : NULL;
+	
+	/* create a new signature validity to return */
+	validity = g_mime_signature_validity_new ();
 	
 	/* collect the signers for this signature */
 	signers = (GMimeSigner *) &validity->signers;
@@ -778,13 +778,46 @@ pkcs7_encrypt (GMimeCryptoContext *context, gboolean sign, const char *userid,
 }
 
 
-static GMimeSignatureValidity *
+static GMimeDecryptionResult *
+pkcs7_get_decrypt_result (Pkcs7Ctx *pkcs7)
+{
+	GMimeCryptoRecipient *recipient, *recipients;
+	GMimeDecryptionResult *result;
+	gpgme_decrypt_result_t res;
+	gpgme_recipient_t recip;
+	
+	result = g_mime_decryption_result_new ();
+	result->validity = pkcs7_get_validity (pkcs7, FALSE);
+	
+	if (!(res = gpgme_op_decrypt_result (pkcs7->ctx)) || !res->recipients)
+		return result;
+	
+	recipients = (GMimeCryptoRecipient *) &result->recipients;
+	
+	recip = res->recipients;
+	while (recip != NULL) {
+		recipient = g_mime_crypto_recipient_new ();
+		recipients->next = recipient;
+		recipients = recipient;
+		
+		g_mime_crypto_recipient_set_pubkey_algo (recipient, pkcs7_pubkey_algo (recip->pubkey_algo));
+		g_mime_crypto_recipient_set_key_id (recipient, recip->keyid);
+		
+		recip = recip->next;
+	}
+	
+	return result;
+}
+
+static GMimeDecryptionResult *
 pkcs7_decrypt (GMimeCryptoContext *context, GMimeStream *istream,
 	       GMimeStream *ostream, GError **err)
 {
 #ifdef ENABLE_SMIME
 	GMimePkcs7Context *ctx = (GMimePkcs7Context *) context;
+	GMimeDecryptionResult *result;
 	Pkcs7Ctx *pkcs7 = ctx->priv;
+	gpgme_decrypt_result_t res;
 	gpgme_data_t input, output;
 	gpgme_error_t error;
 	
@@ -810,8 +843,7 @@ pkcs7_decrypt (GMimeCryptoContext *context, GMimeStream *istream,
 	gpgme_data_release (output);
 	gpgme_data_release (input);
 	
-	/* get/return the pkcs7 signature validity */
-	return pkcs7_get_validity (pkcs7, FALSE);
+	return pkcs7_get_decrypt_result (pkcs7);
 #else
 	g_set_error (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED, _("S/MIME support is not enabled in this build"));
 	
diff --git a/mono/gmime-api.raw b/mono/gmime-api.raw
index 0ef0b8c..ef4e918 100644
--- a/mono/gmime-api.raw
+++ b/mono/gmime-api.raw
@@ -190,7 +190,7 @@
         </parameters>
       </virtual_method>
       <virtual_method name="Decrypt" cname="decrypt">
-        <return-type type="GMimeSignatureValidity*" />
+        <return-type type="GMimeDecryptionResult*" />
         <parameters>
           <parameter type="GMimeCryptoContext*" name="ctx" />
           <parameter type="GMimeStream*" name="istream" />
@@ -216,7 +216,7 @@
         </parameters>
       </virtual_method>
       <method name="Decrypt" cname="g_mime_crypto_context_decrypt">
-        <return-type type="GMimeSignatureValidity*" />
+        <return-type type="GMimeDecryptionResult*" />
         <parameters>
           <parameter type="GMimeStream*" name="istream" />
           <parameter type="GMimeStream*" name="ostream" />
@@ -1021,7 +1021,7 @@
         <return-type type="GMimeObject*" />
         <parameters>
           <parameter type="GMimeCryptoContext*" name="ctx" />
-          <parameter type="GMimeSignatureValidity**" name="validity" />
+          <parameter type="GMimeDecryptionResult**" name="result" />
           <parameter type="GError**" name="err" />
         </parameters>
       </method>
@@ -2238,6 +2238,62 @@
         </parameters>
       </method>
     </struct>
+    <struct name="CryptoRecipient" cname="GMimeCryptoRecipient" opaque="true">
+      <field name="Next" cname="next" type="GMimeCryptoRecipient*" access="public" writeable="true" />
+      <field name="PubkeyAlgo" cname="pubkey_algo" type="GMimeCryptoPubKeyAlgo" access="public" writeable="true" />
+      <field name="Keyid" cname="keyid" type="char*" access="public" writeable="true" />
+      <method name="Free" cname="g_mime_crypto_recipient_free">
+        <return-type type="void" />
+      </method>
+      <method name="GetKeyId" cname="g_mime_crypto_recipient_get_key_id">
+        <return-type type="const-char*" />
+      </method>
+      <method name="GetPubkeyAlgo" cname="g_mime_crypto_recipient_get_pubkey_algo">
+        <return-type type="GMimeCryptoPubKeyAlgo" />
+      </method>
+      <constructor cname="g_mime_crypto_recipient_new" />
+      <method name="Next" cname="g_mime_crypto_recipient_next">
+        <return-type type="const-GMimeCryptoRecipient*" />
+      </method>
+      <method name="SetKeyId" cname="g_mime_crypto_recipient_set_key_id">
+        <return-type type="void" />
+        <parameters>
+          <parameter type="const-char*" name="key_id" />
+        </parameters>
+      </method>
+      <method name="SetPubkeyAlgo" cname="g_mime_crypto_recipient_set_pubkey_algo">
+        <return-type type="void" />
+        <parameters>
+          <parameter type="GMimeCryptoPubKeyAlgo" name="pubkey_algo" />
+        </parameters>
+      </method>
+    </struct>
+    <struct name="DecryptionResult" cname="GMimeDecryptionResult" opaque="true">
+      <field name="Validity" cname="validity" type="GMimeSignatureValidity*" access="public" writeable="true" />
+      <field name="Recipients" cname="recipients" type="GMimeCryptoRecipient*" access="public" writeable="true" />
+      <method name="AddRecipient" cname="g_mime_decryption_result_add_recipient">
+        <return-type type="void" />
+        <parameters>
+          <parameter type="GMimeCryptoRecipient*" name="recipient" />
+        </parameters>
+      </method>
+      <method name="Free" cname="g_mime_decryption_result_free">
+        <return-type type="void" />
+      </method>
+      <method name="GetRecipients" cname="g_mime_decryption_result_get_recipients">
+        <return-type type="const-GMimeCryptoRecipient*" />
+      </method>
+      <method name="GetValidity" cname="g_mime_decryption_result_get_validity">
+        <return-type type="const-GMimeSignatureValidity*" />
+      </method>
+      <constructor cname="g_mime_decryption_result_new" />
+      <method name="SetValidity" cname="g_mime_decryption_result_set_validity">
+        <return-type type="void" />
+        <parameters>
+          <parameter type="GMimeSignatureValidity*" name="validity" />
+        </parameters>
+      </method>
+    </struct>
     <struct name="Encoding" cname="GMimeEncoding" opaque="true">
       <method name="Base64DecodeStep" cname="g_mime_encoding_base64_decode_step" shared="true">
         <return-type type="size_t" />
@@ -2684,7 +2740,7 @@
         </parameters>
       </constructor>
       <method name="Next" cname="g_mime_signer_next">
-        <return-type type="GMimeSigner*" />
+        <return-type type="const-GMimeSigner*" />
       </method>
       <method name="SetEmail" cname="g_mime_signer_set_email">
         <return-type type="void" />
diff --git a/tests/test-pgp.c b/tests/test-pgp.c
index f66fa99..9bde5f2 100644
--- a/tests/test-pgp.c
+++ b/tests/test-pgp.c
@@ -139,7 +139,7 @@ test_encrypt (GMimeCryptoContext *ctx, gboolean sign, GMimeStream *cleartext, GM
 static void
 test_decrypt (GMimeCryptoContext *ctx, gboolean sign, GMimeStream *cleartext, GMimeStream *ciphertext)
 {
-	GMimeSignatureValidity *sv;
+	GMimeDecryptionResult *result;
 	Exception *ex = NULL;
 	GMimeStream *stream;
 	GError *err = NULL;
@@ -147,7 +147,7 @@ test_decrypt (GMimeCryptoContext *ctx, gboolean sign, GMimeStream *cleartext, GM
 	
 	stream = g_mime_stream_mem_new ();
 	
-	if (!(sv = g_mime_crypto_context_decrypt (ctx, ciphertext, stream, &err))) {
+	if (!(result = g_mime_crypto_context_decrypt (ctx, ciphertext, stream, &err))) {
 		g_object_unref (stream);
 		ex = exception_new ("%s", err->message);
 		g_error_free (err);
@@ -155,14 +155,14 @@ test_decrypt (GMimeCryptoContext *ctx, gboolean sign, GMimeStream *cleartext, GM
 	}
 	
 	if (sign) {
-		if (get_sig_status (sv->signers) != GMIME_SIGNER_STATUS_GOOD)
+		if (!result->validity || get_sig_status (result->validity->signers) != GMIME_SIGNER_STATUS_GOOD)
 			ex = exception_new ("expected GOOD signature");
 	} else {
-		if (sv->signers != NULL)
+		if (result->validity && result->validity->signers != NULL)
 			ex = exception_new ("unexpected signature");
 	}
 	
-	g_mime_signature_validity_free (sv);
+	g_mime_decryption_result_free (result);
 	
 	if (ex != NULL) {
 		g_object_unref (stream);
diff --git a/tests/test-pgpmime.c b/tests/test-pgpmime.c
index 881043b..ca7988d 100644
--- a/tests/test-pgpmime.c
+++ b/tests/test-pgpmime.c
@@ -262,7 +262,7 @@ test_multipart_encrypted (GMimeCryptoContext *ctx, gboolean sign)
 {
 	GMimeStream *cleartext, *stream;
 	GMimeMultipartEncrypted *mpe;
-	GMimeSignatureValidity *sv;
+	GMimeDecryptionResult *result;
 	GMimeDataWrapper *content;
 	GMimeObject *decrypted;
 	GPtrArray *recipients;
@@ -342,26 +342,27 @@ test_multipart_encrypted (GMimeCryptoContext *ctx, gboolean sign)
 	mpe = (GMimeMultipartEncrypted *) message->mime_part;
 	
 	/* okay, now to test our decrypt function... */
-	decrypted = g_mime_multipart_encrypted_decrypt (mpe, ctx, &sv, &err);
+	decrypted = g_mime_multipart_encrypted_decrypt (mpe, ctx, &result, &err);
 	if (!decrypted || err != NULL) {
 		ex = exception_new ("decryption failed: %s", err->message);
-		g_mime_signature_validity_free (sv);
+		g_mime_decryption_result_free (result);
 		g_object_unref (cleartext);
 		g_error_free (err);
 		throw (ex);
 	}
 	
-	v(print_verify_results (sv));
+	if (result->validity)
+		v(print_verify_results (result->validity));
 	
 	if (sign) {
-		if (get_sig_status (sv->signers) != GMIME_SIGNER_STATUS_GOOD)
+		if (!result->validity || get_sig_status (result->validity->signers) != GMIME_SIGNER_STATUS_GOOD)
 			ex = exception_new ("signature status expected to be GOOD");
 	} else {
-		if (sv->signers != NULL)
+		if (result->validity && result->validity->signers != NULL)
 			ex = exception_new ("signature status expected to be NONE");
 	}
 	
-	g_mime_signature_validity_free (sv);
+	g_mime_decryption_result_free (result);
 	
 	if (ex != NULL) {
 		g_object_unref (cleartext);
diff --git a/tests/test-pkcs7.c b/tests/test-pkcs7.c
index 7c9df58..f168f48 100644
--- a/tests/test-pkcs7.c
+++ b/tests/test-pkcs7.c
@@ -141,7 +141,7 @@ test_encrypt (GMimeCryptoContext *ctx, gboolean sign, GMimeStream *cleartext, GM
 static void
 test_decrypt (GMimeCryptoContext *ctx, gboolean sign, GMimeStream *cleartext, GMimeStream *ciphertext)
 {
-	GMimeSignatureValidity *sv;
+	GMimeDecryptionResult *result;
 	Exception *ex = NULL;
 	GMimeStream *stream;
 	GError *err = NULL;
@@ -149,7 +149,7 @@ test_decrypt (GMimeCryptoContext *ctx, gboolean sign, GMimeStream *cleartext, GM
 	
 	stream = g_mime_stream_mem_new ();
 	
-	if (!(sv = g_mime_crypto_context_decrypt (ctx, ciphertext, stream, &err))) {
+	if (!(result = g_mime_crypto_context_decrypt (ctx, ciphertext, stream, &err))) {
 		g_object_unref (stream);
 		ex = exception_new ("%s", err->message);
 		g_error_free (err);
@@ -157,14 +157,14 @@ test_decrypt (GMimeCryptoContext *ctx, gboolean sign, GMimeStream *cleartext, GM
 	}
 	
 	if (sign) {
-		if (get_sig_status (sv->signers) != GMIME_SIGNER_STATUS_GOOD)
+		if (!result->validity || get_sig_status (result->validity->signers) != GMIME_SIGNER_STATUS_GOOD)
 			ex = exception_new ("expected GOOD signature");
 	} else {
-		if (sv->signers != NULL)
+		if (result->validity && result->validity->signers != NULL)
 			ex = exception_new ("unexpected signature");
 	}
 	
-	g_mime_signature_validity_free (sv);
+	g_mime_decryption_result_free (result);
 	
 	if (ex != NULL) {
 		g_object_unref (stream);
diff --git a/tests/test-smime.c b/tests/test-smime.c
index b1a088f..608dec9 100644
--- a/tests/test-smime.c
+++ b/tests/test-smime.c
@@ -263,7 +263,7 @@ test_multipart_encrypted (GMimeCryptoContext *ctx, gboolean sign)
 {
 	GMimeStream *cleartext, *stream;
 	GMimeMultipartEncrypted *mpe;
-	GMimeSignatureValidity *sv;
+	GMimeDecryptionResult *result;
 	GMimeDataWrapper *content;
 	GMimeObject *decrypted;
 	GPtrArray *recipients;
@@ -343,26 +343,27 @@ test_multipart_encrypted (GMimeCryptoContext *ctx, gboolean sign)
 	mpe = (GMimeMultipartEncrypted *) message->mime_part;
 	
 	/* okay, now to test our decrypt function... */
-	decrypted = g_mime_multipart_encrypted_decrypt (mpe, ctx, &sv, &err);
+	decrypted = g_mime_multipart_encrypted_decrypt (mpe, ctx, &result, &err);
 	if (!decrypted || err != NULL) {
 		ex = exception_new ("decryption failed: %s", err->message);
-		g_mime_signature_validity_free (sv);
+		g_mime_decryption_result_free (result);
 		g_object_unref (cleartext);
 		g_error_free (err);
 		throw (ex);
 	}
 	
-	v(print_verify_results (sv));
+	if (result->validity)
+		v(print_verify_results (result->validity));
 	
 	if (sign) {
-		if (get_sig_status (sv->signers) != GMIME_SIGNER_STATUS_GOOD)
+		if (!result->validity || get_sig_status (result->validity->signers) != GMIME_SIGNER_STATUS_GOOD)
 			ex = exception_new ("signature status expected to be GOOD");
 	} else {
-		if (sv->signers != NULL)
+		if (result->validity && result->validity->signers != NULL)
 			ex = exception_new ("signature status expected to be NONE");
 	}
 	
-	g_mime_signature_validity_free (sv);
+	g_mime_decryption_result_free (result);
 	
 	if (ex != NULL) {
 		g_object_unref (cleartext);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]