[evolution-data-server] Bug #304415 - Allow change of signature hash algorithm
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Bug #304415 - Allow change of signature hash algorithm
- Date: Wed, 19 May 2010 21:08:20 +0000 (UTC)
commit ab727faeb7a8cbfcdfdaf5d076e687b6d744c10f
Author: Milan Crha <mcrha redhat com>
Date: Wed May 19 23:08:07 2010 +0200
Bug #304415 - Allow change of signature hash algorithm
camel/camel-cipher-context.h | 3 ++
camel/camel-gpg-context.c | 55 ++++++++++++++++++++++++++++--
camel/camel-smime-context.c | 78 +++++++++++++++++++++++++++++++++++++++---
libedataserver/e-account.c | 14 +++++++
libedataserver/e-account.h | 4 ++
5 files changed, 146 insertions(+), 8 deletions(-)
---
diff --git a/camel/camel-cipher-context.h b/camel/camel-cipher-context.h
index 6841d44..172731d 100644
--- a/camel/camel-cipher-context.h
+++ b/camel/camel-cipher-context.h
@@ -64,6 +64,9 @@ typedef enum {
CAMEL_CIPHER_HASH_MD2,
CAMEL_CIPHER_HASH_MD5,
CAMEL_CIPHER_HASH_SHA1,
+ CAMEL_CIPHER_HASH_SHA256,
+ CAMEL_CIPHER_HASH_SHA384,
+ CAMEL_CIPHER_HASH_SHA512,
CAMEL_CIPHER_HASH_RIPEMD160,
CAMEL_CIPHER_HASH_TIGER192,
CAMEL_CIPHER_HASH_HAVAL5160
diff --git a/camel/camel-gpg-context.c b/camel/camel-gpg-context.c
index 23a02fc..b7000d5 100644
--- a/camel/camel-gpg-context.c
+++ b/camel/camel-gpg-context.c
@@ -99,6 +99,12 @@ gpg_hash_to_id (CamelCipherContext *context, CamelCipherHash hash)
case CAMEL_CIPHER_HASH_SHA1:
case CAMEL_CIPHER_HASH_DEFAULT:
return "pgp-sha1";
+ 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:
@@ -120,6 +126,12 @@ gpg_id_to_hash (CamelCipherContext *context, const gchar *id)
return CAMEL_CIPHER_HASH_MD5;
else if (!strcmp (id, "pgp-sha1"))
return CAMEL_CIPHER_HASH_SHA1;
+ 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"))
@@ -461,6 +473,12 @@ gpg_hash_str (CamelCipherHash hash)
return "--digest-algo=MD5";
case CAMEL_CIPHER_HASH_SHA1:
return "--digest-algo=SHA1";
+ 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:
@@ -670,7 +688,7 @@ gpg_ctx_op_start (struct _GpgCtx *gpg)
errno = errnosave;
#else
/* FIXME: Port me */
- g_warning ("%s: Not implemented", __FUNCTION__);
+ g_warning ("%s: Not implemented", G_STRFUNC);
errno = EINVAL;
#endif
@@ -898,7 +916,38 @@ gpg_ctx_parse_status (struct _GpgCtx *gpg,
switch (gpg->mode) {
case GPG_CTX_MODE_SIGN:
if (!strncmp ((gchar *) status, "SIG_CREATED ", 12)) {
- /* FIXME: save this state? */
+ /* SIG_CREATED <type> <pubkey algo> <hash algo> <class> <timestamp> <key fpr> */
+ const gchar *str, *p;
+ gint i;
+
+ str = (const gchar *) status + 12;
+ while (p = strchr (str, ' '), i < 2 && p) {
+ str = p + 1;
+ i++;
+ }
+
+ if (str && *str && i == 2) {
+ struct {
+ gint gpg_hash_algo;
+ CamelCipherHash camel_hash_algo;
+ } hash_algos[] = {
+ /* the rest are deprecated/not supported by gpg any more */
+ { 2, CAMEL_CIPHER_HASH_SHA1 },
+ { 3, CAMEL_CIPHER_HASH_RIPEMD160 },
+ { 8, CAMEL_CIPHER_HASH_SHA256 },
+ { 9, CAMEL_CIPHER_HASH_SHA384 },
+ { 10, CAMEL_CIPHER_HASH_SHA512 }
+ };
+
+ gint gpg_hash = strtoul (str, NULL, 10);
+
+ for (i = 0; i < G_N_ELEMENTS (hash_algos); i++) {
+ if (hash_algos[i].gpg_hash_algo == gpg_hash) {
+ gpg->hash = hash_algos[i].camel_hash_algo;
+ break;
+ }
+ }
+ }
}
break;
case GPG_CTX_MODE_DECRYPT:
@@ -1440,7 +1489,7 @@ gpg_sign (CamelCipherContext *context,
mps = camel_multipart_signed_new();
ct = camel_content_type_new("multipart", "signed");
- camel_content_type_set_param(ct, "micalg", camel_cipher_hash_to_id(context, hash));
+ camel_content_type_set_param(ct, "micalg", camel_cipher_hash_to_id (context, hash == CAMEL_CIPHER_HASH_DEFAULT ? gpg->hash : hash));
camel_content_type_set_param(ct, "protocol", class->sign_protocol);
camel_data_wrapper_set_mime_type_field((CamelDataWrapper *)mps, ct);
camel_content_type_unref(ct);
diff --git a/camel/camel-smime-context.c b/camel/camel-smime-context.c
index 863d1b7..d5b2ef2 100644
--- a/camel/camel-smime-context.c
+++ b/camel/camel-smime-context.c
@@ -323,7 +323,7 @@ set_nss_error (CamelException *ex,
static NSSCMSMessage *
sm_signing_cmsmessage (CamelSMIMEContext *context,
const gchar *nick,
- SECOidTag hash,
+ SECOidTag *hash,
gint detached,
CamelException *ex)
{
@@ -334,6 +334,8 @@ sm_signing_cmsmessage (CamelSMIMEContext *context,
NSSCMSSignerInfo *signerinfo;
CERTCertificate *cert= NULL, *ekpcert = NULL;
+ g_return_val_if_fail (hash != NULL, NULL);
+
if ((cert = CERT_FindUserCertByUsage (p->certdb,
(gchar *)nick,
certUsageEmailSigner,
@@ -345,6 +347,28 @@ sm_signing_cmsmessage (CamelSMIMEContext *context,
return NULL;
}
+ if (*hash == SEC_OID_UNKNOWN) {
+ /* use signature algorithm from the certificate */
+ switch (SECOID_GetAlgorithmTag (&cert->signature)) {
+ case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
+ *hash = SEC_OID_SHA256;
+ break;
+ case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
+ *hash = SEC_OID_SHA384;
+ break;
+ case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
+ *hash = SEC_OID_SHA512;
+ break;
+ case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
+ *hash = SEC_OID_MD5;
+ break;
+ case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
+ default:
+ *hash = SEC_OID_SHA1;
+ break;
+ }
+ }
+
cmsg = NSS_CMSMessage_Create (NULL); /* create a message on its own pool */
if (cmsg == NULL) {
set_nss_error (ex, _("Cannot create CMS message"));
@@ -369,7 +393,7 @@ sm_signing_cmsmessage (CamelSMIMEContext *context,
goto fail;
}
- signerinfo = NSS_CMSSignerInfo_Create (cmsg, cert, hash);
+ signerinfo = NSS_CMSSignerInfo_Create (cmsg, cert, *hash);
if (signerinfo == NULL) {
set_nss_error (ex, _("Cannot create CMS Signer information"));
goto fail;
@@ -680,6 +704,12 @@ smime_context_hash_to_id (CamelCipherContext *context,
case CAMEL_CIPHER_HASH_SHA1:
case CAMEL_CIPHER_HASH_DEFAULT:
return "sha1";
+ case CAMEL_CIPHER_HASH_SHA256:
+ return "sha256";
+ case CAMEL_CIPHER_HASH_SHA384:
+ return "sha384";
+ case CAMEL_CIPHER_HASH_SHA512:
+ return "sha512";
default:
return NULL;
}
@@ -694,6 +724,33 @@ smime_context_id_to_hash (CamelCipherContext *context,
return CAMEL_CIPHER_HASH_MD5;
else if (!strcmp (id, "sha1"))
return CAMEL_CIPHER_HASH_SHA1;
+ else if (!strcmp (id, "sha256"))
+ return CAMEL_CIPHER_HASH_SHA256;
+ else if (!strcmp (id, "sha384"))
+ return CAMEL_CIPHER_HASH_SHA384;
+ else if (!strcmp (id, "sha512"))
+ return CAMEL_CIPHER_HASH_SHA512;
+ }
+
+ return CAMEL_CIPHER_HASH_DEFAULT;
+}
+
+static CamelCipherHash
+get_hash_from_oid (SECOidTag oidTag)
+{
+ switch (oidTag) {
+ case SEC_OID_SHA1:
+ return CAMEL_CIPHER_HASH_SHA1;
+ case SEC_OID_SHA256:
+ return CAMEL_CIPHER_HASH_SHA256;
+ case SEC_OID_SHA384:
+ return CAMEL_CIPHER_HASH_SHA384;
+ case SEC_OID_SHA512:
+ return CAMEL_CIPHER_HASH_SHA512;
+ case SEC_OID_MD5:
+ return CAMEL_CIPHER_HASH_MD5;
+ default:
+ break;
}
return CAMEL_CIPHER_HASH_DEFAULT;
@@ -720,18 +777,29 @@ smime_context_sign (CamelCipherContext *context,
class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context);
switch (hash) {
- case CAMEL_CIPHER_HASH_SHA1:
case CAMEL_CIPHER_HASH_DEFAULT:
default:
+ sechash = SEC_OID_UNKNOWN;
+ break;
+ case CAMEL_CIPHER_HASH_SHA1:
sechash = SEC_OID_SHA1;
break;
+ case CAMEL_CIPHER_HASH_SHA256:
+ sechash = SEC_OID_SHA256;
+ break;
+ case CAMEL_CIPHER_HASH_SHA384:
+ sechash = SEC_OID_SHA384;
+ break;
+ case CAMEL_CIPHER_HASH_SHA512:
+ sechash = SEC_OID_SHA512;
+ break;
case CAMEL_CIPHER_HASH_MD5:
sechash = SEC_OID_MD5;
break;
}
cmsg = sm_signing_cmsmessage (
- (CamelSMIMEContext *)context, userid, sechash,
+ (CamelSMIMEContext *)context, userid, &sechash,
((CamelSMIMEContext *)context)->priv->sign_mode == CAMEL_SMIME_SIGN_CLEARSIGN, ex);
if (cmsg == NULL)
return -1;
@@ -800,7 +868,7 @@ smime_context_sign (CamelCipherContext *context,
mps = camel_multipart_signed_new ();
ct = camel_content_type_new ("multipart", "signed");
- camel_content_type_set_param (ct, "micalg", camel_cipher_hash_to_id (context, hash));
+ camel_content_type_set_param (ct, "micalg", camel_cipher_hash_to_id (context, get_hash_from_oid (sechash)));
camel_content_type_set_param (ct, "protocol", class->sign_protocol);
camel_data_wrapper_set_mime_type_field ((CamelDataWrapper *)mps, ct);
camel_content_type_unref (ct);
diff --git a/libedataserver/e-account.c b/libedataserver/e-account.c
index baa9491..052ce6b 100644
--- a/libedataserver/e-account.c
+++ b/libedataserver/e-account.c
@@ -158,8 +158,10 @@ finalize (GObject *object)
g_free (account->bcc_addrs);
g_free (account->pgp_key);
+ g_free (account->pgp_hash_algorithm);
g_free (account->smime_sign_key);
g_free (account->smime_encrypt_key);
+ g_free (account->smime_hash_algorithm);
g_free (account->parent_uid);
@@ -464,6 +466,7 @@ e_account_set_from_xml (EAccount *account, const gchar *xml)
changed |= xml_set_bool (node, "always-trust", &account->pgp_always_trust);
changed |= xml_set_bool (node, "always-sign", &account->pgp_always_sign);
changed |= xml_set_bool (node, "no-imip-sign", &account->pgp_no_imip_sign);
+ changed |= xml_set_prop (node, "hash-algo", &account->pgp_hash_algorithm);
if (node->children) {
for (cur = node->children; cur; cur = cur->next) {
@@ -477,6 +480,7 @@ e_account_set_from_xml (EAccount *account, const gchar *xml)
changed |= xml_set_bool (node, "sign-default", &account->smime_sign_default);
changed |= xml_set_bool (node, "encrypt-to-self", &account->smime_encrypt_to_self);
changed |= xml_set_bool (node, "encrypt-default", &account->smime_encrypt_default);
+ changed |= xml_set_prop (node, "hash-algo", &account->smime_hash_algorithm);
if (node->children) {
for (cur = node->children; cur; cur = cur->next) {
@@ -561,6 +565,8 @@ e_account_import (EAccount *dest, EAccount *src)
g_free (dest->pgp_key);
dest->pgp_key = g_strdup (src->pgp_key);
+ g_free (dest->pgp_hash_algorithm);
+ dest->pgp_hash_algorithm = g_strdup (src->pgp_hash_algorithm);
dest->pgp_encrypt_to_self = src->pgp_encrypt_to_self;
dest->pgp_always_sign = src->pgp_always_sign;
dest->pgp_no_imip_sign = src->pgp_no_imip_sign;
@@ -569,6 +575,8 @@ e_account_import (EAccount *dest, EAccount *src)
dest->smime_sign_default = src->smime_sign_default;
g_free (dest->smime_sign_key);
dest->smime_sign_key = g_strdup (src->smime_sign_key);
+ g_free (dest->smime_hash_algorithm);
+ dest->smime_hash_algorithm = g_strdup (src->smime_hash_algorithm);
dest->smime_encrypt_default = src->smime_encrypt_default;
dest->smime_encrypt_to_self = src->smime_encrypt_to_self;
@@ -651,6 +659,8 @@ e_account_to_xml (EAccount *account)
xmlSetProp (node, (xmlChar*)"always-trust", (xmlChar*)(account->pgp_always_trust ? "true" : "false"));
xmlSetProp (node, (xmlChar*)"always-sign", (xmlChar*)(account->pgp_always_sign ? "true" : "false"));
xmlSetProp (node, (xmlChar*)"no-imip-sign", (xmlChar*)(account->pgp_no_imip_sign ? "true" : "false"));
+ if (account->pgp_hash_algorithm && *account->pgp_hash_algorithm)
+ xmlSetProp (node, (xmlChar*)"hash-algo", (xmlChar*) account->pgp_hash_algorithm);
if (account->pgp_key)
xmlNewTextChild (node, NULL, (xmlChar*)"key-id", (xmlChar*)account->pgp_key);
@@ -658,6 +668,8 @@ e_account_to_xml (EAccount *account)
xmlSetProp (node, (xmlChar*)"sign-default", (xmlChar*)(account->smime_sign_default ? "true" : "false"));
xmlSetProp (node, (xmlChar*)"encrypt-default", (xmlChar*)(account->smime_encrypt_default ? "true" : "false"));
xmlSetProp (node, (xmlChar*)"encrypt-to-self", (xmlChar*)(account->smime_encrypt_to_self ? "true" : "false"));
+ if (account->smime_hash_algorithm && *account->smime_hash_algorithm)
+ xmlSetProp (node, (xmlChar*)"hash-algo", (xmlChar*) account->smime_hash_algorithm);
if (account->smime_sign_key)
xmlNewTextChild (node, NULL, (xmlChar*)"sign-key-id", (xmlChar*)account->smime_sign_key);
if (account->smime_encrypt_key)
@@ -784,6 +796,7 @@ static struct _account_info {
{ /* E_ACCOUNT_RECEIPT_POLICY */ 0, TYPE_INT, G_STRUCT_OFFSET(EAccount, receipt_policy) },
{ /* E_ACCOUNT_PGP_KEY */ 0, TYPE_STRING, G_STRUCT_OFFSET(EAccount, pgp_key) },
+ { /* E_ACCOUNT_PGP_HASH_ALGORITHM */ 0, TYPE_STRING, G_STRUCT_OFFSET(EAccount, pgp_hash_algorithm) },
{ /* E_ACCOUNT_PGP_ENCRYPT_TO_SELF */ 0, TYPE_BOOL, G_STRUCT_OFFSET(EAccount, pgp_encrypt_to_self) },
{ /* E_ACCOUNT_PGP_ALWAYS_SIGN */ 0, TYPE_BOOL, G_STRUCT_OFFSET(EAccount, pgp_always_sign) },
{ /* E_ACCOUNT_PGP_NO_IMIP_SIGN */ 0, TYPE_BOOL, G_STRUCT_OFFSET(EAccount, pgp_no_imip_sign) },
@@ -791,6 +804,7 @@ static struct _account_info {
{ /* E_ACCOUNT_SMIME_SIGN_KEY */ 0, TYPE_STRING, G_STRUCT_OFFSET(EAccount, smime_sign_key) },
{ /* E_ACCOUNT_SMIME_ENCRYPT_KEY */ 0, TYPE_STRING, G_STRUCT_OFFSET(EAccount, smime_encrypt_key) },
+ { /* E_ACCOUNT_SMIME_HASH_ALGORITHM */ 0, TYPE_STRING, G_STRUCT_OFFSET(EAccount, smime_hash_algorithm) },
{ /* E_ACCOUNT_SMIME_SIGN_DEFAULT */ 0, TYPE_BOOL, G_STRUCT_OFFSET(EAccount, smime_sign_default) },
{ /* E_ACCOUNT_SMIME_ENCRYPT_TO_SELF */ 0, TYPE_BOOL, G_STRUCT_OFFSET(EAccount, smime_encrypt_to_self) },
{ /* E_ACCOUNT_SMIME_ENCRYPT_DEFAULT */ 0, TYPE_BOOL, G_STRUCT_OFFSET(EAccount, smime_encrypt_default) },
diff --git a/libedataserver/e-account.h b/libedataserver/e-account.h
index afe8d48..a9d5a6b 100644
--- a/libedataserver/e-account.h
+++ b/libedataserver/e-account.h
@@ -60,6 +60,7 @@ typedef enum _e_account_item_t {
E_ACCOUNT_RECEIPT_POLICY,
E_ACCOUNT_PGP_KEY,
+ E_ACCOUNT_PGP_HASH_ALGORITHM,
E_ACCOUNT_PGP_ENCRYPT_TO_SELF,
E_ACCOUNT_PGP_ALWAYS_SIGN,
E_ACCOUNT_PGP_NO_IMIP_SIGN,
@@ -67,6 +68,7 @@ typedef enum _e_account_item_t {
E_ACCOUNT_SMIME_SIGN_KEY,
E_ACCOUNT_SMIME_ENCRYPT_KEY,
+ E_ACCOUNT_SMIME_HASH_ALGORITHM,
E_ACCOUNT_SMIME_SIGN_DEFAULT,
E_ACCOUNT_SMIME_ENCRYPT_TO_SELF,
E_ACCOUNT_SMIME_ENCRYPT_DEFAULT,
@@ -126,6 +128,7 @@ typedef struct _EAccount {
EAccountReceiptPolicy receipt_policy;
gchar *pgp_key;
+ gchar *pgp_hash_algorithm; /* "sha1", "sha256", "sha384", "sha512" are supported now; anything else is default */
gboolean pgp_encrypt_to_self;
gboolean pgp_always_sign;
gboolean pgp_no_imip_sign;
@@ -135,6 +138,7 @@ typedef struct _EAccount {
gchar *smime_sign_key;
gchar *smime_encrypt_key;
+ gchar *smime_hash_algorithm; /* "sha1", "sha256", "sha384", "sha512" are supported now; anything else is default */
gboolean smime_sign_default;
gboolean smime_encrypt_to_self;
gboolean smime_encrypt_default;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]