Index: camel/camel-smime-context.c
===================================================================
--- camel/camel-smime-context.c	(revision 10126)
+++ camel/camel-smime-context.c	(working copy)
@@ -62,6 +62,9 @@
 
 #define d(x)
 
+void smime_cert_data_free (void *cert_data);
+void *smime_cert_data_clone (void *cert_data);
+
 struct _CamelSMIMEContextPrivate {
 	CERTCertDBHandle *certdb;
 
@@ -716,6 +719,22 @@ sm_status_description(NSSCMSVerification
 	}
 }
 
+void
+smime_cert_data_free (void *cert_data)
+{
+	g_return_if_fail (cert_data != NULL);
+
+	CERT_DestroyCertificate (cert_data);
+}
+
+void *
+smime_cert_data_clone (void *cert_data)
+{
+	g_return_val_if_fail (cert_data != NULL, NULL);
+
+	return CERT_DupCertificate (cert_data);
+}
+
 static CamelCipherValidity *
 sm_verify_cmsg(CamelCipherContext *context, NSSCMSMessage *cmsg, CamelStream *extstream, CamelException *ex)
 {
@@ -848,7 +867,7 @@ sm_verify_cmsg(CamelCipherContext *conte
 							       cn?cn:"<unknown>", em?em:"<unknown>",
 							       sm_status_description(status));
 					
-					camel_cipher_validity_add_certinfo(valid, CAMEL_CIPHER_VALIDITY_SIGN, cn, em);
+					camel_cipher_validity_add_certinfo_ex (valid, CAMEL_CIPHER_VALIDITY_SIGN, cn, em, smime_cert_data_clone (NSS_CMSSignerInfo_GetSigningCertificate (si, p->certdb)), smime_cert_data_free, smime_cert_data_clone);
 
 					if (cn)
 						PORT_Free(cn);
Index: camel/ChangeLog
===================================================================
--- camel/ChangeLog	(revision 10126)
+++ camel/ChangeLog	(working copy)
@@ -1,3 +1,17 @@
+2009-03-03  Milan Crha  <mcrha@redhat.com>
+
+	** Part of fix for bug #372435
+
+	* camel-cipher-context.h: (struct _CamelCipherCertInfo),
+	(camel_cipher_validity_add_certinfo_ex):
+	* camel-cipher-context.c: (ccv_certinfo_free),
+	(camel_cipher_validity_clone), (camel_cipher_validity_add_certinfo),
+	(camel_cipher_validity_add_certinfo_ex): Allow adding cert_data to
+	the structure. Value depends on the context type.
+	* camel-smime-context.c: (smime_cert_data_free),
+	(smime_cert_data_clone), (sm_verify_cmsg):
+	Pass signer's certificate to the camel_cipher_validity structure.
+
 2009-03-02  Matt McCutchen  <matt@mattmccutchen.net>
 
 	* evolution-data-server/camel/camel-mime-filter-tohtml.c:
Index: camel/camel-cipher-context.c
===================================================================
--- camel/camel-cipher-context.c	(revision 10126)
+++ camel/camel-cipher-context.c	(working copy)
@@ -361,6 +361,10 @@ ccv_certinfo_free(CamelCipherCertInfo *i
 {
 	g_free(info->name);
 	g_free(info->email);
+
+	if (info->cert_data && info->cert_data_free)
+		info->cert_data_free (info->cert_data);
+
 	g_free(info);
 }
 
@@ -444,13 +448,19 @@ camel_cipher_validity_clone(CamelCipherV
 
 	info = (CamelCipherCertInfo *)vin->sign.signers.head;
 	while (info->next) {
-		camel_cipher_validity_add_certinfo(vo, CAMEL_CIPHER_VALIDITY_SIGN, info->name, info->email);
+		if (info->cert_data && info->cert_data_clone && info->cert_data_free)
+			camel_cipher_validity_add_certinfo_ex (vo, CAMEL_CIPHER_VALIDITY_SIGN, info->name, info->email, info->cert_data_clone (info->cert_data), info->cert_data_free, info->cert_data_clone);
+		else
+			camel_cipher_validity_add_certinfo (vo, CAMEL_CIPHER_VALIDITY_SIGN, info->name, info->email);
 		info = info->next;
 	}
 
 	info = (CamelCipherCertInfo *)vin->encrypt.encrypters.head;
 	while (info->next) {
-		camel_cipher_validity_add_certinfo(vo, CAMEL_CIPHER_VALIDITY_ENCRYPT, info->name, info->email);
+		if (info->cert_data && info->cert_data_clone && info->cert_data_free)
+			camel_cipher_validity_add_certinfo_ex (vo, CAMEL_CIPHER_VALIDITY_SIGN, info->name, info->email, info->cert_data_clone (info->cert_data), info->cert_data_free, info->cert_data_clone);
+		else
+			camel_cipher_validity_add_certinfo (vo, CAMEL_CIPHER_VALIDITY_ENCRYPT, info->name, info->email);
 		info = info->next;
 	}
 
@@ -469,17 +479,38 @@ camel_cipher_validity_clone(CamelCipherV
 void
 camel_cipher_validity_add_certinfo(CamelCipherValidity *vin, enum _camel_cipher_validity_mode_t mode, const char *name, const char *email)
 {
+	camel_cipher_validity_add_certinfo_ex (vin, mode, name, email, NULL, NULL, NULL);
+}
+
+/**
+ * camel_cipher_validity_add_certinfo_ex:
+ *
+ * Add a cert info to the signer or encrypter info, with extended data set.
+ **/
+void
+camel_cipher_validity_add_certinfo_ex (CamelCipherValidity *vin, camel_cipher_validity_mode_t mode, const char *name, const char *email, void *cert_data, void (*cert_data_free)(void *cert_data), void *(*cert_data_clone)(void *cert_data))
+{
 	CamelCipherCertInfo *info;
 	CamelDList *list;
 
 	info = g_malloc0(sizeof(*info));
 	info->name = g_strdup(name);
 	info->email = g_strdup(email);
+	if (cert_data) {
+		if (cert_data_free && cert_data_clone) {
+			info->cert_data = cert_data;
+			info->cert_data_free = cert_data_free;
+			info->cert_data_clone = cert_data_clone;
+		} else {
+			if (!cert_data_free)
+				g_warning ("%s: requires non-NULL cert_data_free function!", G_STRFUNC);
+			if (!cert_data_clone)
+				g_warning ("%s: requires non-NULL cert_data_clone function!", G_STRFUNC);
+		}
+	}
 
 	list = (mode==CAMEL_CIPHER_VALIDITY_SIGN)?&vin->sign.signers:&vin->encrypt.encrypters;
 	camel_dlist_addtail(list, (CamelDListNode *)info);
-
-	printf("adding certinfo %s <%s>\n", name?name:"unset", email?email:"unset");
 }
 
 /**
Index: camel/camel-cipher-context.h
===================================================================
--- camel/camel-cipher-context.h	(revision 10126)
+++ camel/camel-cipher-context.h	(working copy)
@@ -76,6 +76,10 @@ struct _CamelCipherCertInfo {
 
 	char *name;		/* common name */
 	char *email;
+
+	void *cert_data;  /* custom certificate data; can be NULL */
+	void (*cert_data_free)(void *cert_data); /* called to free cert_data; can be NULL only if cert_data is NULL */
+	void *(*cert_data_clone)(void *cert_data); /* called to clone cert_data; can be NULL only if cert_data is NULL */
 };
 
 struct _CamelCipherValidity {
@@ -174,6 +178,14 @@ void                 camel_cipher_validi
 void                 camel_cipher_validity_clear (CamelCipherValidity *validity);
 CamelCipherValidity *camel_cipher_validity_clone(CamelCipherValidity *vin);
 void		     camel_cipher_validity_add_certinfo(CamelCipherValidity *vin, camel_cipher_validity_mode_t mode, const char *name, const char *email);
+void		     camel_cipher_validity_add_certinfo_ex (
+					CamelCipherValidity *vin,
+					camel_cipher_validity_mode_t mode,
+					const char *name,
+					const char *email,
+					void *cert_data,
+					void (*cert_data_free)(void *cert_data),
+					void *(*cert_data_clone)(void *cert_data));
 void		     camel_cipher_validity_envelope(CamelCipherValidity *parent, CamelCipherValidity *valid);
 void                 camel_cipher_validity_free (CamelCipherValidity *validity);
 
