[gmime] Changed CryptoContext to provide accessors for protocol strings



commit 5575d9d1ca8c35b77d3328aa69bdd7736f30b8b7
Author: Jeffrey Stedfast <fejj gnome org>
Date:   Fri Mar 4 08:04:26 2011 -0500

    Changed CryptoContext to provide accessors for protocol strings
    
    2011-03-04  Jeffrey Stedfast  <fejj novell com>
    
    	API cleanup as well as preparing for the possibility of a
    	multi-protocol CryptoContext.
    
    	* gmime/gmime-multipart-encrypted.c
    	* (g_mime_multipart_encrypted_encrypt):
    	Updated to use new APIs for getting the encryption protocol.
    	(g_mime_multipart_encrypted_decrypt): Same.
    
    	* gmime/gmime-multipart-signed.c (g_mime_multipart_signed_sign):
    	Updated to use new APIs for getting the signature protocol.
    	(g_mime_multipart_signed_verify): Same.
    
    	* gmime/gmime-crypto-context.c
    	* (g_mime_crypto_context_get_*_protocol):
    	New methods for getting the crypto protocol strings used by
    	multipart/encrypted and multipart/signed parts.
    
    	* gmime/gmime-pkcs7-context.c (pkcs7_get_*_protocol):
    	* Implemented.
    
    	* gmime/gmime-gpg-context.c (gpg_get_*_protocol): Implemented.

 ChangeLog                         |   21 ++++++++++
 gmime/gmime-crypto-context.c      |   81 +++++++++++++++++++++++++++++++++++++
 gmime/gmime-crypto-context.h      |   23 ++++++----
 gmime/gmime-gpg-context.c         |   33 +++++++++++++--
 gmime/gmime-multipart-encrypted.c |   48 ++++++++++++++--------
 gmime/gmime-multipart-signed.c    |   49 +++++++++++++++-------
 gmime/gmime-pkcs7-context.c       |   35 ++++++++++++----
 tests/test-pkcs7.c                |    2 +-
 8 files changed, 236 insertions(+), 56 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 37d898b..f1b2a29 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2011-03-04  Jeffrey Stedfast  <fejj novell com>
+
+	API cleanup as well as preparing for the possibility of a
+	multi-protocol CryptoContext.
+
+	* gmime/gmime-multipart-encrypted.c (g_mime_multipart_encrypted_encrypt):
+	Updated to use new APIs for getting the encryption protocol.
+	(g_mime_multipart_encrypted_decrypt): Same.
+
+	* gmime/gmime-multipart-signed.c (g_mime_multipart_signed_sign):
+	Updated to use new APIs for getting the signature protocol.
+	(g_mime_multipart_signed_verify): Same.
+
+	* gmime/gmime-crypto-context.c (g_mime_crypto_context_get_*_protocol):
+	New methods for getting the crypto protocol strings used by
+	multipart/encrypted and multipart/signed parts.
+
+	* gmime/gmime-pkcs7-context.c (pkcs7_get_*_protocol): Implemented.
+
+	* gmime/gmime-gpg-context.c (gpg_get_*_protocol): Implemented.
+
 2011-03-03  Jeffrey Stedfast  <fejj novell com>
 
 	* gmime/gmime-pkcs7-context.c (pkcs7_stream_seek): Added.
diff --git a/gmime/gmime-crypto-context.c b/gmime/gmime-crypto-context.c
index 1c27f1a..7e1b516 100644
--- a/gmime/gmime-crypto-context.c
+++ b/gmime/gmime-crypto-context.c
@@ -46,6 +46,12 @@ static GMimeCryptoHash crypto_hash_id (GMimeCryptoContext *ctx, const char *hash
 
 static const char *crypto_hash_name (GMimeCryptoContext *ctx, GMimeCryptoHash hash);
 
+static const char *crypto_get_signature_protocol (GMimeCryptoContext *ctx);
+
+static const char *crypto_get_encryption_protocol (GMimeCryptoContext *ctx);
+
+static const char *crypto_get_key_exchange_protocol (GMimeCryptoContext *ctx);
+
 static int crypto_sign (GMimeCryptoContext *ctx, const char *userid,
 			GMimeCryptoHash hash, GMimeStream *istream,
 			GMimeStream *ostream, GError **err);
@@ -114,6 +120,9 @@ g_mime_crypto_context_class_init (GMimeCryptoContextClass *klass)
 	klass->decrypt = crypto_decrypt;
 	klass->import_keys = crypto_import_keys;
 	klass->export_keys = crypto_export_keys;
+	klass->get_signature_protocol = crypto_get_signature_protocol;
+	klass->get_encryption_protocol = crypto_get_encryption_protocol;
+	klass->get_key_exchange_protocol = crypto_get_key_exchange_protocol;
 }
 
 static void
@@ -217,6 +226,78 @@ g_mime_crypto_context_hash_name (GMimeCryptoContext *ctx, GMimeCryptoHash hash)
 }
 
 
+static const char *
+crypto_get_signature_protocol (GMimeCryptoContext *ctx)
+{
+	return NULL;
+}
+
+
+/**
+ * g_mime_crypto_context_get_signature_protocol:
+ * @ctx: a #GMimeCryptoContext
+ *
+ * Gets the signature protocol for the crypto context.
+ *
+ * Returns: the signature protocol or %NULL if not supported.
+ **/
+const char *
+g_mime_crypto_context_get_signature_protocol (GMimeCryptoContext *ctx)
+{
+	g_return_val_if_fail (GMIME_IS_CRYPTO_CONTEXT (ctx), NULL);
+	
+	return GMIME_CRYPTO_CONTEXT_GET_CLASS (ctx)->get_signature_protocol (ctx);
+}
+
+
+static const char *
+crypto_get_encryption_protocol (GMimeCryptoContext *ctx)
+{
+	return NULL;
+}
+
+
+/**
+ * g_mime_crypto_context_get_encryption_protocol:
+ * @ctx: a #GMimeCryptoContext
+ *
+ * Gets the encryption protocol for the crypto context.
+ *
+ * Returns: the encryption protocol or %NULL if not supported.
+ **/
+const char *
+g_mime_crypto_context_get_encryption_protocol (GMimeCryptoContext *ctx)
+{
+	g_return_val_if_fail (GMIME_IS_CRYPTO_CONTEXT (ctx), NULL);
+	
+	return GMIME_CRYPTO_CONTEXT_GET_CLASS (ctx)->get_encryption_protocol (ctx);
+}
+
+
+static const char *
+crypto_get_key_exchange_protocol (GMimeCryptoContext *ctx)
+{
+	return NULL;
+}
+
+
+/**
+ * g_mime_crypto_context_get_key_exchange_protocol:
+ * @ctx: a #GMimeCryptoContext
+ *
+ * Gets the key exchange protocol for the crypto context.
+ *
+ * Returns: the key exchange protocol or %NULL if not supported.
+ **/
+const char *
+g_mime_crypto_context_get_key_exchange_protocol (GMimeCryptoContext *ctx)
+{
+	g_return_val_if_fail (GMIME_IS_CRYPTO_CONTEXT (ctx), NULL);
+	
+	return GMIME_CRYPTO_CONTEXT_GET_CLASS (ctx)->get_key_exchange_protocol (ctx);
+}
+
+
 static int
 crypto_sign (GMimeCryptoContext *ctx, const char *userid, GMimeCryptoHash hash,
 	     GMimeStream *istream, GMimeStream *ostream, GError **err)
diff --git a/gmime/gmime-crypto-context.h b/gmime/gmime-crypto-context.h
index 3699975..4f1ddb6 100644
--- a/gmime/gmime-crypto-context.h
+++ b/gmime/gmime-crypto-context.h
@@ -124,9 +124,6 @@ typedef enum {
  * GMimeCryptoContext:
  * @parent_object: parent #GObject
  * @request_passwd: a callback for requesting a password
- * @sign_protocol: signature protocol (must be set by subclass)
- * @encrypt_protocol: encryption protocol (must be set by subclass)
- * @key_protocol: key exchange protocol (must be set by subclass)
  *
  * A crypto context for use with MIME.
  **/
@@ -134,11 +131,6 @@ struct _GMimeCryptoContext {
 	GObject parent_object;
 	
 	GMimePasswordRequestFunc request_passwd;
-	
-	/* these must be set by the subclass in the instance_init() */
-	const char *sign_protocol;
-	const char *encrypt_protocol;
-	const char *key_protocol;
 };
 
 struct _GMimeCryptoContextClass {
@@ -148,6 +140,12 @@ struct _GMimeCryptoContextClass {
 	
 	const char *             (* hash_name)   (GMimeCryptoContext *ctx, GMimeCryptoHash hash);
 	
+	const char *             (* get_signature_protocol) (GMimeCryptoContext *ctx);
+	
+	const char *             (* get_encryption_protocol) (GMimeCryptoContext *ctx);
+	
+	const char *             (* get_key_exchange_protocol) (GMimeCryptoContext *ctx);
+	
 	int                      (* sign)        (GMimeCryptoContext *ctx, const char *userid,
 						  GMimeCryptoHash hash, GMimeStream *istream,
 						  GMimeStream *ostream, GError **err);
@@ -179,7 +177,14 @@ void g_mime_crypto_context_set_request_password (GMimeCryptoContext *ctx, GMimeP
 /* hash routines */
 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_encryption_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,
diff --git a/gmime/gmime-gpg-context.c b/gmime/gmime-gpg-context.c
index b7257eb..69efcad 100644
--- a/gmime/gmime-gpg-context.c
+++ b/gmime/gmime-gpg-context.c
@@ -81,7 +81,13 @@ static const char *gpg_hash_name (GMimeCryptoContext *ctx, GMimeCryptoHash hash)
 static int gpg_sign (GMimeCryptoContext *ctx, const char *userid,
 		     GMimeCryptoHash hash, GMimeStream *istream,
 		     GMimeStream *ostream, GError **err);
-	
+
+static const char *gpg_get_signature_protocol (GMimeCryptoContext *ctx);
+
+static const char *gpg_get_encryption_protocol (GMimeCryptoContext *ctx);
+
+static const char *gpg_get_key_exchange_protocol (GMimeCryptoContext *ctx);
+
 static GMimeSignatureValidity *gpg_verify (GMimeCryptoContext *ctx, GMimeCryptoHash hash,
 					   GMimeStream *istream, GMimeStream *sigstream,
 					   GError **err);
@@ -146,6 +152,9 @@ g_mime_gpg_context_class_init (GMimeGpgContextClass *klass)
 	crypto_class->decrypt = gpg_decrypt;
 	crypto_class->import_keys = gpg_import_keys;
 	crypto_class->export_keys = gpg_export_keys;
+	crypto_class->get_signature_protocol = gpg_get_signature_protocol;
+	crypto_class->get_encryption_protocol = gpg_get_encryption_protocol;
+	crypto_class->get_key_exchange_protocol = gpg_get_key_exchange_protocol;
 }
 
 static void
@@ -156,10 +165,6 @@ g_mime_gpg_context_init (GMimeGpgContext *ctx, GMimeGpgContextClass *klass)
 	ctx->auto_key_retrieve = FALSE;
 	ctx->always_trust = FALSE;
 	ctx->path = NULL;
-	
-	crypto->sign_protocol = "application/pgp-signature";
-	crypto->encrypt_protocol = "application/pgp-encrypted";
-	crypto->key_protocol = "application/pgp-keys";
 }
 
 static void
@@ -238,6 +243,24 @@ gpg_hash_name (GMimeCryptoContext *ctx, GMimeCryptoHash hash)
 	}
 }
 
+static const char *
+gpg_get_signature_protocol (GMimeCryptoContext *ctx)
+{
+	return "application/pgp-signature";
+}
+
+static const char *
+gpg_get_encryption_protocol (GMimeCryptoContext *ctx)
+{
+	return "application/pgp-encrypted";
+}
+
+static const char *
+gpg_get_key_exchange_protocol (GMimeCryptoContext *ctx)
+{
+	return "application/pgp-keys";
+}
+
 enum _GpgCtxMode {
 	GPG_CTX_MODE_SIGN,
 	GPG_CTX_MODE_VERIFY,
diff --git a/gmime/gmime-multipart-encrypted.c b/gmime/gmime-multipart-encrypted.c
index 3b18556..c6ce660 100644
--- a/gmime/gmime-multipart-encrypted.c
+++ b/gmime/gmime-multipart-encrypted.c
@@ -36,8 +36,13 @@
 #include "gmime-part.h"
 #include "gmime-error.h"
 
-
+#ifdef ENABLE_DEBUG
+#define d(x) x
+#else
 #define d(x)
+#endif
+
+#define _(x) x
 
 
 /**
@@ -163,12 +168,17 @@ g_mime_multipart_encrypted_encrypt (GMimeMultipartEncrypted *mpe, GMimeObject *c
 	GMimeContentType *content_type;
 	GMimeDataWrapper *wrapper;
 	GMimeFilter *crlf_filter;
+	const char *protocol;
 	
 	g_return_val_if_fail (GMIME_IS_MULTIPART_ENCRYPTED (mpe), -1);
 	g_return_val_if_fail (GMIME_IS_CRYPTO_CONTEXT (ctx), -1);
-	g_return_val_if_fail (ctx->encrypt_protocol != NULL, -1);
 	g_return_val_if_fail (GMIME_IS_OBJECT (content), -1);
 	
+	if (!(protocol = g_mime_crypto_context_get_encryption_protocol (ctx))) {
+		g_set_error_literal (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED, _("Encryption not supported."));
+		return -1;
+	}
+	
 	/* get the cleartext */
 	stream = g_mime_stream_mem_new ();
 	filtered_stream = g_mime_stream_filter_new (stream);
@@ -196,11 +206,11 @@ g_mime_multipart_encrypted_encrypt (GMimeMultipartEncrypted *mpe, GMimeObject *c
 	g_mime_stream_reset (ciphertext);
 	
 	/* construct the version part */
-	content_type = g_mime_content_type_new_from_string (ctx->encrypt_protocol);
+	content_type = g_mime_content_type_new_from_string (protocol);
 	version_part = g_mime_part_new_with_type (content_type->type, content_type->subtype);
 	g_object_unref (content_type);
 	
-	content_type = g_mime_content_type_new_from_string (ctx->encrypt_protocol);
+	content_type = g_mime_content_type_new_from_string (protocol);
 	g_mime_object_set_content_type (GMIME_OBJECT (version_part), content_type);
 	g_mime_part_set_content_encoding (version_part, GMIME_CONTENT_ENCODING_7BIT);
 	stream = g_mime_stream_mem_new_with_buffer ("Version: 1\n", strlen ("Version: 1\n"));
@@ -225,8 +235,7 @@ g_mime_multipart_encrypted_encrypt (GMimeMultipartEncrypted *mpe, GMimeObject *c
 	g_object_unref (version_part);
 	
 	/* set the content-type params for this multipart/encrypted part */
-	g_mime_object_set_content_type_parameter (GMIME_OBJECT (mpe), "protocol",
-						  ctx->encrypt_protocol);
+	g_mime_object_set_content_type_parameter (GMIME_OBJECT (mpe), "protocol", protocol);
 	g_mime_multipart_set_boundary (GMIME_MULTIPART (mpe), NULL);
 	
 	return 0;
@@ -257,36 +266,41 @@ g_mime_multipart_encrypted_decrypt (GMimeMultipartEncrypted *mpe, GMimeCryptoCon
 {
 	GMimeObject *decrypted, *version, *encrypted;
 	GMimeStream *stream, *ciphertext;
+	const char *protocol, *supported;
 	GMimeStream *filtered_stream;
 	GMimeContentType *mime_type;
 	GMimeSignatureValidity *sv;
 	GMimeDataWrapper *wrapper;
 	GMimeFilter *crlf_filter;
 	GMimeParser *parser;
-	const char *protocol;
 	char *content_type;
 	
 	g_return_val_if_fail (GMIME_IS_MULTIPART_ENCRYPTED (mpe), NULL);
 	g_return_val_if_fail (GMIME_IS_CRYPTO_CONTEXT (ctx), NULL);
-	g_return_val_if_fail (ctx->encrypt_protocol != NULL, NULL);
 	
 	if (validity)
 		*validity = NULL;
 	
 	protocol = g_mime_object_get_content_type_parameter (GMIME_OBJECT (mpe), "protocol");
+	supported = g_mime_crypto_context_get_encryption_protocol (ctx);
 	
 	if (protocol) {
 		/* make sure the protocol matches the crypto encrypt protocol */
-		if (g_ascii_strcasecmp (ctx->encrypt_protocol, protocol) != 0) {
+		if (!supported || g_ascii_strcasecmp (supported, protocol) != 0) {
 			g_set_error (err, GMIME_ERROR, GMIME_ERROR_PROTOCOL_ERROR,
-				     "Cannot decrypt multipart/encrypted part: unsupported encryption protocol '%s'.",
+				     _("Cannot decrypt multipart/encrypted part: unsupported encryption protocol '%s'."),
 				     protocol);
 			
 			return NULL;
 		}
-	} else {
+	} else if (supported != NULL) {
 		/* *shrug* - I guess just go on as if they match? */
-		protocol = ctx->encrypt_protocol;
+		protocol = supported;
+	} else {
+		g_set_error_literal (err, GMIME_ERROR, GMIME_ERROR_PROTOCOL_ERROR,
+				     _("Cannot decrypt multipart/encrypted part: unspecified encryption protocol."));
+		
+		return NULL;
 	}
 	
 	version = g_mime_multipart_get_part (GMIME_MULTIPART (mpe), GMIME_MULTIPART_ENCRYPTED_VERSION);
@@ -294,8 +308,8 @@ g_mime_multipart_encrypted_decrypt (GMimeMultipartEncrypted *mpe, GMimeCryptoCon
 	/* 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_literal (err, GMIME_ERROR, GMIME_ERROR_PROTOCOL_ERROR,
-				     "Cannot decrypt multipart/encrypted part: content-type does not match protocol.");
+		g_set_error_literal (err, GMIME_ERROR, GMIME_ERROR_PARSE_ERROR,
+				     _("Cannot decrypt multipart/encrypted part: content-type does not match protocol."));
 		
 		g_free (content_type);
 		
@@ -307,8 +321,8 @@ g_mime_multipart_encrypted_decrypt (GMimeMultipartEncrypted *mpe, GMimeCryptoCon
 	encrypted = g_mime_multipart_get_part (GMIME_MULTIPART (mpe), GMIME_MULTIPART_ENCRYPTED_CONTENT);
 	mime_type = g_mime_object_get_content_type (encrypted);
 	if (!g_mime_content_type_is_type (mime_type, "application", "octet-stream")) {
-		g_set_error_literal (err, GMIME_ERROR, GMIME_ERROR_PROTOCOL_ERROR,
-				     "Cannot decrypt multipart/encrypted part: unexpected content type");
+		g_set_error_literal (err, GMIME_ERROR, GMIME_ERROR_PARSE_ERROR,
+				     _("Cannot decrypt multipart/encrypted part: unexpected content type."));
 		
 		return NULL;
 	}
@@ -345,7 +359,7 @@ g_mime_multipart_encrypted_decrypt (GMimeMultipartEncrypted *mpe, GMimeCryptoCon
 	
 	if (!decrypted) {
 		g_set_error_literal (err, GMIME_ERROR, GMIME_ERROR_PARSE_ERROR,
-				     "Cannot decrypt multipart/encrypted part: failed to parse decrypted content");
+				     _("Cannot decrypt multipart/encrypted part: failed to parse decrypted content."));
 		
 		g_mime_signature_validity_free (sv);
 		
diff --git a/gmime/gmime-multipart-signed.c b/gmime/gmime-multipart-signed.c
index 4c9e286..5cb6a4b 100644
--- a/gmime/gmime-multipart-signed.c
+++ b/gmime/gmime-multipart-signed.c
@@ -37,7 +37,13 @@
 #include "gmime-error.h"
 #include "gmime-part.h"
 
+#ifdef ENABLE_DEBUG
+#define d(x) x
+#else
 #define d(x)
+#endif
+
+#define _(x) x
 
 
 /**
@@ -217,14 +223,19 @@ g_mime_multipart_signed_sign (GMimeMultipartSigned *mps, GMimeObject *content,
 	GMimePart *signature;
 	GMimeFilter *filter;
 	GMimeParser *parser;
+	const char *protocol;
 	const char *micalg;
 	int rv;
 	
 	g_return_val_if_fail (GMIME_IS_MULTIPART_SIGNED (mps), -1);
 	g_return_val_if_fail (GMIME_IS_CRYPTO_CONTEXT (ctx), -1);
-	g_return_val_if_fail (ctx->sign_protocol != NULL, -1);
 	g_return_val_if_fail (GMIME_IS_OBJECT (content), -1);
 	
+	if (!(protocol = g_mime_crypto_context_get_signature_protocol (ctx))) {
+		g_set_error_literal (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED, _("Signing not supported."));
+		return -1;
+	}
+	
 	/* Prepare all the parts for signing... */
 	sign_prepare (content);
 	
@@ -270,7 +281,7 @@ g_mime_multipart_signed_sign (GMimeMultipartSigned *mps, GMimeObject *content,
 	
 	/* set the multipart/signed protocol and micalg */
 	content_type = g_mime_object_get_content_type (GMIME_OBJECT (mps));
-	g_mime_content_type_set_parameter (content_type, "protocol", ctx->sign_protocol);
+	g_mime_content_type_set_parameter (content_type, "protocol", protocol);
 	micalg = g_strdup (g_mime_crypto_context_hash_name (ctx, (GMimeCryptoHash) rv));
 	g_mime_content_type_set_parameter (content_type, "micalg", micalg);
 	g_mime_multipart_set_boundary (GMIME_MULTIPART (mps), NULL);
@@ -282,7 +293,7 @@ g_mime_multipart_signed_sign (GMimeMultipartSigned *mps, GMimeObject *content,
 	g_object_unref (parser);
 	
 	/* construct the signature part */
-	content_type = g_mime_content_type_new_from_string (ctx->sign_protocol);
+	content_type = g_mime_content_type_new_from_string (protocol);
 	signature = g_mime_part_new_with_type (content_type->type, content_type->subtype);
 	g_object_unref (content_type);
 	
@@ -295,7 +306,7 @@ g_mime_multipart_signed_sign (GMimeMultipartSigned *mps, GMimeObject *content,
 	/* FIXME: temporary hack, this info should probably be set in
 	 * the CryptoContext class - maybe ::sign can take/output a
 	 * GMimePart instead. */
-	if (!g_ascii_strcasecmp (ctx->sign_protocol, "application/pkcs7-signature")) {
+	if (!g_ascii_strcasecmp (protocol, "application/pkcs7-signature")) {
 		g_mime_part_set_content_encoding (signature, GMIME_CONTENT_ENCODING_BASE64);
 		g_mime_part_set_filename (signature, "smime.p7m");
 	}
@@ -328,40 +339,46 @@ GMimeSignatureValidity *
 g_mime_multipart_signed_verify (GMimeMultipartSigned *mps, GMimeCryptoContext *ctx,
 				GError **err)
 {
+	const char *supported, *protocol, *micalg;
 	GMimeObject *content, *signature;
-	GMimeDataWrapper *wrapper;
-	GMimeStream *filtered_stream;
-	GMimeFilter *crlf_filter;
 	GMimeStream *stream, *sigstream;
-	const char *protocol, *micalg;
 	GMimeSignatureValidity *valid;
+	GMimeStream *filtered_stream;
+	GMimeDataWrapper *wrapper;
+	GMimeFilter *crlf_filter;
 	GMimeCryptoHash hash;
 	char *content_type;
 	
 	g_return_val_if_fail (GMIME_IS_MULTIPART_SIGNED (mps), NULL);
 	g_return_val_if_fail (GMIME_IS_CRYPTO_CONTEXT (ctx), NULL);
-	g_return_val_if_fail (ctx->sign_protocol != NULL, NULL);
 	
 	if (g_mime_multipart_get_count ((GMimeMultipart *) mps) < 2) {
 		g_set_error_literal (err, GMIME_ERROR, GMIME_ERROR_PARSE_ERROR,
-				     "Cannot verify multipart/signed part due to missing subparts.");
+				     _("Cannot verify multipart/signed part due to missing subparts."));
 		return NULL;
 	}
 	
 	protocol = g_mime_object_get_content_type_parameter (GMIME_OBJECT (mps), "protocol");
 	micalg = g_mime_object_get_content_type_parameter (GMIME_OBJECT (mps), "micalg");
 	
+	supported = g_mime_crypto_context_get_signature_protocol (ctx);
+	
 	if (protocol) {
 		/* make sure the protocol matches the crypto sign protocol */
-		if (g_ascii_strcasecmp (ctx->sign_protocol, protocol) != 0) {
-			g_set_error (err, GMIME_ERROR, GMIME_ERROR_PARSE_ERROR,
-				     "Cannot verify multipart/signed part: unsupported signature protocol '%s'.",
+		if (!supported || g_ascii_strcasecmp (supported, protocol) != 0) {
+			g_set_error (err, GMIME_ERROR, GMIME_ERROR_PROTOCOL_ERROR,
+				     _("Cannot verify multipart/signed part: unsupported signature protocol '%s'."),
 				     protocol);
 			return NULL;
 		}
-	} else {
+	} else if (supported != NULL) {
 		/* *shrug* - I guess just go on as if they match? */
-		protocol = ctx->sign_protocol;
+		protocol = supported;
+	} else {
+		g_set_error_literal (err, GMIME_ERROR, GMIME_ERROR_PROTOCOL_ERROR,
+				     _("Cannot verify multipart/signed part: unspecified signature protocol."));
+		
+		return NULL;
 	}
 	
 	signature = g_mime_multipart_get_part (GMIME_MULTIPART (mps), GMIME_MULTIPART_SIGNED_SIGNATURE);
@@ -370,7 +387,7 @@ g_mime_multipart_signed_verify (GMimeMultipartSigned *mps, GMimeCryptoContext *c
 	content_type = g_mime_content_type_to_string (signature->content_type);
 	if (g_ascii_strcasecmp (content_type, protocol) != 0) {
 		g_set_error_literal (err, GMIME_ERROR, GMIME_ERROR_PARSE_ERROR,
-				     "Cannot verify multipart/signed part: signature content-type does not match protocol.");
+				     _("Cannot verify multipart/signed part: signature content-type does not match protocol."));
 		g_free (content_type);
 		
 		return NULL;
diff --git a/gmime/gmime-pkcs7-context.c b/gmime/gmime-pkcs7-context.c
index 932fc5a..fb4afa2 100644
--- a/gmime/gmime-pkcs7-context.c
+++ b/gmime/gmime-pkcs7-context.c
@@ -76,6 +76,12 @@ static GMimeCryptoHash pkcs7_hash_id (GMimeCryptoContext *ctx, const char *hash)
 
 static const char *pkcs7_hash_name (GMimeCryptoContext *ctx, GMimeCryptoHash hash);
 
+static const char *pkcs7_get_signature_protocol (GMimeCryptoContext *ctx);
+
+static const char *pkcs7_get_encryption_protocol (GMimeCryptoContext *ctx);
+
+static const char *pkcs7_get_key_exchange_protocol (GMimeCryptoContext *ctx);
+
 static int pkcs7_sign (GMimeCryptoContext *ctx, const char *userid,
 		       GMimeCryptoHash hash, GMimeStream *istream,
 		       GMimeStream *ostream, GError **err);
@@ -144,6 +150,9 @@ g_mime_pkcs7_context_class_init (GMimePkcs7ContextClass *klass)
 	crypto_class->decrypt = pkcs7_decrypt;
 	crypto_class->import_keys = pkcs7_import_keys;
 	crypto_class->export_keys = pkcs7_export_keys;
+	crypto_class->get_signature_protocol = pkcs7_get_signature_protocol;
+	crypto_class->get_encryption_protocol = pkcs7_get_encryption_protocol;
+	crypto_class->get_key_exchange_protocol = pkcs7_get_key_exchange_protocol;
 }
 
 static void
@@ -156,10 +165,6 @@ g_mime_pkcs7_context_init (GMimePkcs7Context *ctx, GMimePkcs7ContextClass *klass
 #ifdef ENABLE_SMIME
 	ctx->priv->ctx = NULL;
 #endif
-	
-	crypto->sign_protocol = "application/pkcs7-signature";
-	crypto->encrypt_protocol = "application/pkcs7-mime";
-	crypto->key_protocol = "application/pkcs7-keys";
 }
 
 static void
@@ -240,6 +245,24 @@ pkcs7_hash_name (GMimeCryptoContext *ctx, GMimeCryptoHash hash)
 	}
 }
 
+static const char *
+pkcs7_get_signature_protocol (GMimeCryptoContext *ctx)
+{
+	return "application/pkcs7-signature";
+}
+
+static const char *
+pkcs7_get_encryption_protocol (GMimeCryptoContext *ctx)
+{
+	return "application/pkcs7-mime";
+}
+
+static const char *
+pkcs7_get_key_exchange_protocol (GMimeCryptoContext *ctx)
+{
+	return "application/pkcs7-keys";
+}
+
 #ifdef ENABLE_SMIME
 static gpgme_error_t
 pkcs7_passphrase_cb (void *hook, const char *uid_hint, const char *passphrase_info, int prev_was_bad, int fd)
@@ -271,21 +294,18 @@ pkcs7_passphrase_cb (void *hook, const char *uid_hint, const char *passphrase_in
 static ssize_t
 pkcs7_stream_read (void *stream, void *buffer, size_t size)
 {
-	//printf ("reading...\n"); fflush (stdout);
 	return g_mime_stream_read ((GMimeStream *) stream, (char *) buffer, size);
 }
 
 static ssize_t
 pkcs7_stream_write (void *stream, const void *buffer, size_t size)
 {
-	//printf ("writing...\n"); fflush (stdout);
 	return g_mime_stream_write ((GMimeStream *) stream, (const char *) buffer, size);
 }
 
 static off_t
 pkcs7_stream_seek (void *stream, off_t offset, int whence)
 {
-	//printf ("seeking...\n"); fflush (stdout);
 	switch (whence) {
 	case SEEK_SET:
 		return (off_t) g_mime_stream_seek ((GMimeStream *) stream, (gint64) offset, GMIME_STREAM_SEEK_SET);
@@ -300,7 +320,6 @@ static void
 pkcs7_stream_free (void *stream)
 {
 	/* no-op */
-	//printf ("releasing stream handle\n");
 }
 
 static struct gpgme_data_cbs pkcs7_stream_funcs = {
diff --git a/tests/test-pkcs7.c b/tests/test-pkcs7.c
index 8940564..7c9df58 100644
--- a/tests/test-pkcs7.c
+++ b/tests/test-pkcs7.c
@@ -263,7 +263,7 @@ import_key (GMimeCryptoContext *ctx, const char *path)
 	g_object_unref (stream);
 	
 	if (err != NULL) {
-		ex = exception_new ("%s", err->message);
+		ex = exception_new ("%s: %s", err->message, gpg_strerror (err->code));
 		g_error_free (err);
 		throw (ex);
 	}



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