diff -Nur evolution-data-server-2.30.0/camel/camel-cipher-context.c evolution-data-server-2.30.0/camel/camel-cipher-context.c
--- evolution-data-server-2.30.0/camel/camel-cipher-context.c	2010-03-17 12:17:30.000000000 +0100
+++ evolution-data-server-2.30.0/camel/camel-cipher-context.c	2010-04-18 04:16:12.000000000 +0200
@@ -25,6 +25,7 @@
 #endif
 
 #include <string.h>
+#include <stdarg.h>
 
 #include <glib.h>
 #include <glib/gi18n-lib.h>
@@ -111,7 +112,8 @@
  * @ipart: Input part.
  * @opart: output part.
  * @ex: exception
- *
+ * @gpg_ctx_mode: (optional) gpg mode (--sign/clearsign)
+ * 
  * Converts the (unsigned) part @ipart into a new self-contained mime part @opart.
  * This may be a multipart/signed part, or a simple part for enveloped types.
  *
@@ -119,9 +121,15 @@
  **/
 gint
 camel_cipher_sign (CamelCipherContext *context, const gchar *userid, CamelCipherHash hash,
-		   struct _CamelMimePart *ipart, struct _CamelMimePart *opart, CamelException *ex)
+		   struct _CamelMimePart *ipart, struct _CamelMimePart *opart, CamelException *ex, ...)
 {
 	gint retval;
+	_GpgCtxMode gpg_ctx_mode;
+	va_list al;
+
+	va_start (al, ex);
+	gpg_ctx_mode = va_arg (al, _GpgCtxMode);
+	va_end (al);
 
 	g_return_val_if_fail (CAMEL_IS_CIPHER_CONTEXT (context), -1);
 
@@ -129,7 +137,10 @@
 
 	CIPHER_LOCK(context);
 
-	retval = CCC_CLASS (context)->sign (context, userid, hash, ipart, opart, ex);
+	if ( gpg_ctx_mode == GPG_CTX_MODE_SIGN || gpg_ctx_mode == GPG_CTX_MODE_CLEARSIGN ) // gpg mode explicitly set?
+		retval = CCC_CLASS (context)->sign (context, userid, hash, ipart, opart, ex, gpg_ctx_mode);
+	else
+		retval = CCC_CLASS (context)->sign (context, userid, hash, ipart, opart, ex);
 
 	CIPHER_UNLOCK(context);
 
diff -Nur evolution-data-server-2.30.0/camel/camel-cipher-context.h evolution-data-server-2.30.0/camel/camel-cipher-context.h
--- evolution-data-server-2.30.0/camel/camel-cipher-context.h	2009-10-26 07:50:58.000000000 +0100
+++ evolution-data-server-2.30.0/camel/camel-cipher-context.h	2010-04-18 22:44:25.000000000 +0200
@@ -45,11 +45,25 @@
 	CAMEL_CIPHER_HASH_MD2,
 	CAMEL_CIPHER_HASH_MD5,
 	CAMEL_CIPHER_HASH_SHA1,
+	CAMEL_CIPHER_HASH_SHA224,
+	CAMEL_CIPHER_HASH_SHA256,
+	CAMEL_CIPHER_HASH_SHA384,
+	CAMEL_CIPHER_HASH_SHA512,
 	CAMEL_CIPHER_HASH_RIPEMD160,
 	CAMEL_CIPHER_HASH_TIGER192,
 	CAMEL_CIPHER_HASH_HAVAL5160
 } CamelCipherHash;
 
+typedef enum {
+	GPG_CTX_MODE_SIGN,
+	GPG_CTX_MODE_CLEARSIGN,
+	GPG_CTX_MODE_VERIFY,
+	GPG_CTX_MODE_ENCRYPT,
+	GPG_CTX_MODE_DECRYPT,
+	GPG_CTX_MODE_IMPORT,
+	GPG_CTX_MODE_EXPORT
+} _GpgCtxMode;
+
 typedef enum _camel_cipher_validity_sign_t {
 	CAMEL_CIPHER_VALIDITY_SIGN_NONE,
 	CAMEL_CIPHER_VALIDITY_SIGN_GOOD,
@@ -119,7 +133,7 @@
 	const gchar *	      (*hash_to_id)(CamelCipherContext *context, CamelCipherHash hash);
 
 	gint                   (*sign)      (CamelCipherContext *context, const gchar *userid, CamelCipherHash hash,
-					    struct _CamelMimePart *ipart, struct _CamelMimePart *opart, CamelException *ex);
+					     struct _CamelMimePart *ipart, struct _CamelMimePart *opart, CamelException *ex, ...);
 
 	CamelCipherValidity * (*verify)    (CamelCipherContext *context, struct _CamelMimePart *ipart, CamelException *ex);
 
@@ -154,7 +168,7 @@
 
 /* cipher routines */
 gint                  camel_cipher_sign (CamelCipherContext *context, const gchar *userid, CamelCipherHash hash,
-					struct _CamelMimePart *ipart, struct _CamelMimePart *opart, CamelException *ex);
+					 struct _CamelMimePart *ipart, struct _CamelMimePart *opart, CamelException *ex, ...);
 CamelCipherValidity *camel_cipher_verify (CamelCipherContext *context, struct _CamelMimePart *ipart, CamelException *ex);
 gint                  camel_cipher_encrypt (CamelCipherContext *context, const gchar *userid,
 					   GPtrArray *recipients, struct _CamelMimePart *ipart, struct _CamelMimePart *opart,
diff -Nur evolution-data-server-2.30.0/camel/camel-gpg-context.c evolution-data-server-2.30.0/camel/camel-gpg-context.c
--- evolution-data-server-2.30.0/camel/camel-gpg-context.c	2010-01-20 10:11:14.000000000 +0100
+++ evolution-data-server-2.30.0/camel/camel-gpg-context.c	2010-04-19 01:35:44.000000000 +0200
@@ -33,6 +33,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <stdarg.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/time.h>
@@ -66,6 +67,7 @@
 #include "camel-stream-fs.h"
 #include "camel-stream-mem.h"
 #include "camel-stream-null.h"
+#include "camel-stream-buffer.h"
 
 #define d(x)
 
@@ -127,6 +129,14 @@
 	case CAMEL_CIPHER_HASH_SHA1:
 	case CAMEL_CIPHER_HASH_DEFAULT:
 		return "pgp-sha1";
+	case CAMEL_CIPHER_HASH_SHA224:
+		return "pgp-sha224";
+	case CAMEL_CIPHER_HASH_SHA256:
+		return "pgp-sha256";
+	case CAMEL_CIPHER_HASH_SHA384:
+		return "pgp-sha384";
+	case CAMEL_CIPHER_HASH_SHA512:
+		return "pgp-sha512";
 	case CAMEL_CIPHER_HASH_RIPEMD160:
 		return "pgp-ripemd160";
 	case CAMEL_CIPHER_HASH_TIGER192:
@@ -134,8 +144,6 @@
 	case CAMEL_CIPHER_HASH_HAVAL5160:
 		return "pgp-haval-5-160";
 	}
-
-	return NULL;
 }
 
 static CamelCipherHash
@@ -148,6 +156,14 @@
 			return CAMEL_CIPHER_HASH_MD5;
 		else if (!strcmp (id, "pgp-sha1"))
 			return CAMEL_CIPHER_HASH_SHA1;
+		else if (!strcmp (id, "pgp-sha224"))
+			return CAMEL_CIPHER_HASH_SHA224;
+		else if (!strcmp (id, "pgp-sha256"))
+			return CAMEL_CIPHER_HASH_SHA256;
+		else if (!strcmp (id, "pgp-sha384"))
+			return CAMEL_CIPHER_HASH_SHA384;
+		else if (!strcmp (id, "pgp-sha512"))
+			return CAMEL_CIPHER_HASH_SHA512;
 		else if (!strcmp (id, "pgp-ripemd160"))
 			return CAMEL_CIPHER_HASH_RIPEMD160;
 		else if (!strcmp (id, "tiger192"))
@@ -159,14 +175,43 @@
 	return CAMEL_CIPHER_HASH_DEFAULT;
 }
 
-enum _GpgCtxMode {
-	GPG_CTX_MODE_SIGN,
-	GPG_CTX_MODE_VERIFY,
-	GPG_CTX_MODE_ENCRYPT,
-	GPG_CTX_MODE_DECRYPT,
-	GPG_CTX_MODE_IMPORT,
-	GPG_CTX_MODE_EXPORT
-};
+/**
+ * gpg_digest_algo_to_hash:
+ * @context: gpg context
+ * @digest_algo: name of a digest algo
+ *
+ * Maps digest algos to the corresponding CAMEL_CIPHER_HASH.
+ *
+ * Returns: CAMEL_CIPHER_HASH_*
+ **/
+CamelCipherHash
+gpg_digest_algo_to_hash (CamelCipherContext *context, const gchar *digest_algo)
+{
+	if (digest_algo) {
+		if (!strcasecmp (digest_algo, "md2"))
+			return CAMEL_CIPHER_HASH_MD2;
+		else if (!strcasecmp (digest_algo, "md5"))
+			return CAMEL_CIPHER_HASH_MD5;
+		else if (!strcasecmp (digest_algo, "sha1"))
+			return CAMEL_CIPHER_HASH_SHA1;
+		else if (!strcasecmp (digest_algo, "sha224"))
+			return CAMEL_CIPHER_HASH_SHA224;
+		else if (!strcasecmp (digest_algo, "sha256"))
+			return CAMEL_CIPHER_HASH_SHA256;
+		else if (!strcasecmp (digest_algo, "sha384"))
+			return CAMEL_CIPHER_HASH_SHA384;
+		else if (!strcasecmp (digest_algo, "sha512"))
+			return CAMEL_CIPHER_HASH_SHA512;
+		else if (!strcasecmp (digest_algo, "ripemd160"))
+			return CAMEL_CIPHER_HASH_RIPEMD160;
+		else if (!strcasecmp (digest_algo, "tiger192"))
+			return CAMEL_CIPHER_HASH_TIGER192;
+		else if (!strcasecmp (digest_algo, "haval-5-160"))
+			return CAMEL_CIPHER_HASH_HAVAL5160;
+	}
+
+	return CAMEL_CIPHER_HASH_DEFAULT;
+}
 
 enum _GpgTrustMetric {
 	GPG_TRUST_NONE,
@@ -178,7 +223,7 @@
 };
 
 struct _GpgCtx {
-	enum _GpgCtxMode mode;
+	_GpgCtxMode mode;
 	CamelSession *session;
 	GHashTable *userid_hint;
 	pid_t pid;
@@ -323,10 +368,10 @@
 }
 
 static void
-gpg_ctx_set_mode (struct _GpgCtx *gpg, enum _GpgCtxMode mode)
+gpg_ctx_set_mode (struct _GpgCtx *gpg, _GpgCtxMode mode)
 {
 	gpg->mode = mode;
-	gpg->need_passwd = ((gpg->mode == GPG_CTX_MODE_SIGN) || (gpg->mode == GPG_CTX_MODE_DECRYPT));
+	gpg->need_passwd = ((gpg->mode == GPG_CTX_MODE_SIGN) || (gpg->mode == GPG_CTX_MODE_CLEARSIGN) || (gpg->mode == GPG_CTX_MODE_DECRYPT));
 }
 
 static void
@@ -485,6 +530,14 @@
 		return "--digest-algo=MD5";
 	case CAMEL_CIPHER_HASH_SHA1:
 		return "--digest-algo=SHA1";
+	case CAMEL_CIPHER_HASH_SHA224:
+		return "--digest-algo=SHA224";
+	case CAMEL_CIPHER_HASH_SHA256:
+		return "--digest-algo=SHA256";
+	case CAMEL_CIPHER_HASH_SHA384:
+		return "--digest-algo=SHA384";
+	case CAMEL_CIPHER_HASH_SHA512:
+		return "--digest-algo=SHA512";
 	case CAMEL_CIPHER_HASH_RIPEMD160:
 		return "--digest-algo=RIPEMD160";
 	default:
@@ -492,6 +545,78 @@
 	}
 }
 
+CamelCipherHash
+gpg_ctx_get_default_digest ( CamelCipherContext *cipher, const gchar *pgp_userid, CamelException *ex ) {
+
+	CamelMimePart *part;
+	CamelMimePart *npart;
+	CamelDataWrapper *plain;
+	CamelStream *stream;
+	GByteArray *data;
+	gchar *buf;
+	gsize bufsize;
+	gssize dw_streamlen;
+	gssize bufread;
+	GRegex *regx;
+	GError *regxerr = NULL;
+	GMatchInfo *regxmi;
+
+	CamelCipherHash cch = CAMEL_CIPHER_HASH_SHA1;
+
+	part = camel_mime_part_new ();
+	npart = camel_mime_part_new ();
+
+	data = g_byte_array_new ();
+	g_byte_array_append (data, (guint8 *) "\n", 1);
+	stream = camel_stream_mem_new_with_byte_array (data);
+	plain = camel_data_wrapper_new ();
+	camel_data_wrapper_construct_from_stream (plain, stream);
+	camel_medium_set_content_object (CAMEL_MEDIUM (part), plain);
+
+	camel_cipher_sign (cipher, pgp_userid, CAMEL_CIPHER_HASH_DEFAULT, part, npart, ex, GPG_CTX_MODE_CLEARSIGN); // gpg --clearsign -u
+	plain = camel_medium_get_content_object (CAMEL_MEDIUM (npart));
+
+	if ( plain != NULL ) {
+		dw_streamlen = camel_data_wrapper_decode_to_stream (plain, stream);
+		if ( dw_streamlen != -1 ) {
+			bufsize = (gsize) dw_streamlen;
+			buf = g_malloc (bufsize + 1);
+			if ( buf != NULL ) {
+				camel_stream_reset (stream);
+				bufread = camel_stream_read (stream, buf, bufsize);
+				camel_stream_close (stream);
+				if ( bufread > -1 ) {
+					buf[bufread] = '\0';
+					regx = g_regex_new ("^-----BEGIN PGP SIGNED MESSAGE-----\nHash: (.*)$", G_REGEX_MULTILINE, G_REGEX_MATCH_NOTEOL, &regxerr);
+
+					g_regex_match (regx, buf, 0, &regxmi);
+					if ( regxerr == NULL ) {
+						if ( g_match_info_matches (regxmi) ) {
+							cch = gpg_digest_algo_to_hash (cipher, g_match_info_fetch (regxmi, 1));
+							g_match_info_free (regxmi);
+						}
+						g_free (buf);
+					} else {
+						g_error_free (regxerr);
+					}
+
+					g_regex_unref (regx);
+				}
+			}
+		}
+		camel_object_unref (plain);
+	}
+
+	g_byte_array_unref (data);
+	if ( stream != NULL ) {
+		camel_object_unref (stream);
+	}
+	camel_object_unref (part);
+	camel_object_unref (npart);
+
+	return cch;
+}
+
 static GPtrArray *
 gpg_ctx_get_argv (struct _GpgCtx *gpg, gint status_fd, gchar **sfd, gint passwd_fd, gchar **pfd)
 {
@@ -539,6 +664,19 @@
 		g_ptr_array_add (argv, (guint8 *) "--output");
 		g_ptr_array_add (argv, (guint8 *) "-");
 		break;
+	case GPG_CTX_MODE_CLEARSIGN:
+		g_ptr_array_add (argv, (guint8 *) "--clearsign");
+		g_ptr_array_add (argv, (guint8 *) "--detach");
+		hash_str = gpg_hash_str (gpg->hash);
+		if (hash_str)
+			g_ptr_array_add (argv, (guint8 *) hash_str);
+		if (gpg->userid) {
+			g_ptr_array_add (argv, (guint8 *) "-u");
+			g_ptr_array_add (argv, (guint8 *) gpg->userid);
+		}
+		g_ptr_array_add (argv, (guint8 *) "--output");
+		g_ptr_array_add (argv, (guint8 *) "-");
+		break;
 	case GPG_CTX_MODE_VERIFY:
 		if (!camel_session_is_online (gpg->session)) {
 			/* this is a deprecated flag to gpg since 1.0.7 */
@@ -908,6 +1046,11 @@
 				/* FIXME: save this state? */
 			}
 			break;
+		case GPG_CTX_MODE_CLEARSIGN:
+			if (!strncmp ((gchar *) status, "SIG_CREATED ", 12)) {
+				/* FIXME: save this state? */
+			}
+			break;
 		case GPG_CTX_MODE_DECRYPT:
 			if (!strncmp ((gchar *) status, "BEGIN_DECRYPTION", 16)) {
 				/* nothing to do... but we know to expect data on stdout soon */
@@ -1335,7 +1478,7 @@
 }
 
 static gint
-gpg_sign (CamelCipherContext *context, const gchar *userid, CamelCipherHash hash, CamelMimePart *ipart, CamelMimePart *opart, CamelException *ex)
+gpg_sign (CamelCipherContext *context, const gchar *userid, CamelCipherHash hash, CamelMimePart *ipart, CamelMimePart *opart, CamelException *ex, ...)
 {
 	struct _GpgCtx *gpg = NULL;
 	CamelStream *ostream = camel_stream_mem_new(), *istream;
@@ -1344,6 +1487,12 @@
 	gint res = -1;
 	CamelMimePart *sigpart;
 	CamelMultipartSigned *mps;
+	_GpgCtxMode gpg_ctx_mode;
+	va_list al;
+
+	va_start (al, ex);
+	gpg_ctx_mode = va_arg (al, _GpgCtxMode);
+	va_end (al);
 
 	/* Note: see rfc2015 or rfc3156, section 5 */
 
@@ -1375,7 +1524,8 @@
 #endif
 
 	gpg = gpg_ctx_new (context->session);
-	gpg_ctx_set_mode (gpg, GPG_CTX_MODE_SIGN);
+
+	gpg_ctx_set_mode (gpg, gpg_ctx_mode == GPG_CTX_MODE_CLEARSIGN ? GPG_CTX_MODE_CLEARSIGN : GPG_CTX_MODE_SIGN);
 	gpg_ctx_set_hash (gpg, hash);
 	gpg_ctx_set_armor (gpg, TRUE);
 	gpg_ctx_set_userid (gpg, userid);
diff -Nur evolution-data-server-2.30.0/camel/camel-gpg-context.h evolution-data-server-2.30.0/camel/camel-gpg-context.h
--- evolution-data-server-2.30.0/camel/camel-gpg-context.h	2009-10-23 12:22:21.000000000 +0200
+++ evolution-data-server-2.30.0/camel/camel-gpg-context.h	2010-04-19 01:39:25.000000000 +0200
@@ -52,6 +52,10 @@
 
 void camel_gpg_context_set_always_trust (CamelGpgContext *ctx, gboolean trust);
 
+CamelCipherHash gpg_digest_algo_to_hash (CamelCipherContext *context, const gchar *digest_algo);
+
+CamelCipherHash gpg_ctx_get_default_digest ( CamelCipherContext *cipher, const gchar *pgp_userid, CamelException *ex );
+
 G_END_DECLS
 
 #endif /* __CAMEL_GPG_CONTEXT_H__ */
diff -Nur evolution-data-server-2.30.0/docs/reference/camel/tmpl/camel-cipher-context.sgml evolution-data-server-2.30.0/docs/reference/camel/tmpl/camel-cipher-context.sgml
--- evolution-data-server-2.30.0/docs/reference/camel/tmpl/camel-cipher-context.sgml	2010-03-29 20:49:28.000000000 +0200
+++ evolution-data-server-2.30.0/docs/reference/camel/tmpl/camel-cipher-context.sgml	2010-04-18 22:45:33.000000000 +0200
@@ -63,6 +63,10 @@
 @CAMEL_CIPHER_HASH_MD2: 
 @CAMEL_CIPHER_HASH_MD5: 
 @CAMEL_CIPHER_HASH_SHA1: 
+@CAMEL_CIPHER_HASH_SHA224: 
+@CAMEL_CIPHER_HASH_SHA256: 
+@CAMEL_CIPHER_HASH_SHA384: 
+@CAMEL_CIPHER_HASH_SHA512: 
 @CAMEL_CIPHER_HASH_RIPEMD160: 
 @CAMEL_CIPHER_HASH_TIGER192: 
 @CAMEL_CIPHER_HASH_HAVAL5160: 
