diff options
author | Jeffrey Stedfast <fejj@ximian.com> | 2001-04-21 05:21:34 +0800 |
---|---|---|
committer | Jeffrey Stedfast <fejj@src.gnome.org> | 2001-04-21 05:21:34 +0800 |
commit | 986252ceaf4239d36294d90e75c6acd305e06dfa (patch) | |
tree | 199ef1cc4117b3a9065f0052e7cbca6f42ba4b33 /camel | |
parent | c36302e415de5eabc850fac77ff570a40d8e129e (diff) | |
download | gsoc2013-evolution-986252ceaf4239d36294d90e75c6acd305e06dfa.tar gsoc2013-evolution-986252ceaf4239d36294d90e75c6acd305e06dfa.tar.gz gsoc2013-evolution-986252ceaf4239d36294d90e75c6acd305e06dfa.tar.bz2 gsoc2013-evolution-986252ceaf4239d36294d90e75c6acd305e06dfa.tar.lz gsoc2013-evolution-986252ceaf4239d36294d90e75c6acd305e06dfa.tar.xz gsoc2013-evolution-986252ceaf4239d36294d90e75c6acd305e06dfa.tar.zst gsoc2013-evolution-986252ceaf4239d36294d90e75c6acd305e06dfa.zip |
Implemented using the secmime.h convenience functions. (smime_clearsign):
2001-04-20 Jeffrey Stedfast <fejj@ximian.com>
* camel-smime-context.c (smime_sign): Implemented using the
secmime.h convenience functions.
(smime_clearsign): We just error our here, there is no clearsign
for smime.
(smime_verify): Copied code over from the pkcs7 verify - same
state, ugly and unknown :-)
(smime_encrypt): Implemented using the secmime.h convenience
functions.
(smime_decrypt): Same as the code in pkcs7-context.
svn path=/trunk/; revision=9480
Diffstat (limited to 'camel')
-rw-r--r-- | camel/ChangeLog | 12 | ||||
-rw-r--r-- | camel/camel-pkcs7-context.c | 41 | ||||
-rw-r--r-- | camel/camel-smime-context.c | 643 | ||||
-rw-r--r-- | camel/camel-smime-context.h | 73 |
4 files changed, 754 insertions, 15 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog index 18e38249bf..0e0014d5df 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,15 @@ +2001-04-20 Jeffrey Stedfast <fejj@ximian.com> + + * camel-smime-context.c (smime_sign): Implemented using the + secmime.h convenience functions. + (smime_clearsign): We just error our here, there is no clearsign + for smime. + (smime_verify): Copied code over from the pkcs7 verify - same + state, ugly and unknown :-) + (smime_encrypt): Implemented using the secmime.h convenience + functions. + (smime_decrypt): Same as the code in pkcs7-context. + 2001-04-19 Jeffrey Stedfast <fejj@ximian.com> * camel-pkcs7-context.c (pkcs7_sign): Implemented. diff --git a/camel/camel-pkcs7-context.c b/camel/camel-pkcs7-context.c index 7d9091758a..fee277e079 100644 --- a/camel/camel-pkcs7-context.c +++ b/camel/camel-pkcs7-context.c @@ -412,18 +412,18 @@ pkcs7_clearsign (CamelCipherContext *ctx, const char *userid, CamelCipherHash ha #if 0 /* this is just meant as a reference so I can see what the valid enums are */ typedef enum { - certUsageSSLClient, - certUsageSSLServer, - certUsageSSLServerWithStepUp, - certUsageSSLCA, - certUsageEmailSigner, - certUsageEmailRecipient, - certUsageObjectSigner, - certUsageUserCertImport, - certUsageVerifyCA, - certUsageProtectedObjectSigner, - certUsageStatusResponder, - certUsageAnyCA + certUsageSSLClient, + certUsageSSLServer, + certUsageSSLServerWithStepUp, + certUsageSSLCA, + certUsageEmailSigner, + certUsageEmailRecipient, + certUsageObjectSigner, + certUsageUserCertImport, + certUsageVerifyCA, + certUsageProtectedObjectSigner, + certUsageStatusResponder, + certUsageAnyCA } SECCertUsage; #endif @@ -509,6 +509,9 @@ pkcs7_verify (CamelCipherContext *ctx, CamelCipherHash hash, CamelStream *istrea SEC_PKCS7DestroyContentInfo (cinfo); + /* FIXME: set a meaningful description...in UTF8 */ + camel_cipher_validity_set_description (valid, ""); + return valid; } @@ -549,9 +552,17 @@ pkcs7_encrypt (CamelCipherContext *ctx, gboolean sign, const char *userid, GPtrA goto exception; } - cinfo = SEC_PKCS7CreateEnvelopedData (cert, certUsageEmailRecipient, - NULL, SEC_OID_DES_EDE3_CBC, 0, - NULL, NULL); + data = g_new (struct _GetPasswdData, 1); + data->session = session; + data->userid = userid; + data->ex = ex; + + /* FIXME: extend CamelCipherContext to allow selecting an encryption algorithm?? */ + cinfo = SEC_PKCS7CreateEncryptedData (SEC_OID_DES_EDE3_CBC, 0, + get_password, data); + + g_free (data); + if (!cinfo) { camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Could not encrypt: failed to create enveloped data.")); diff --git a/camel/camel-smime-context.c b/camel/camel-smime-context.c new file mode 100644 index 0000000000..b1d9fb28d7 --- /dev/null +++ b/camel/camel-smime-context.c @@ -0,0 +1,643 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Authors: Jeffrey Stedfast <fejj@ximian.com> + * + * Copyright 2001 Ximian, Inc. (www.ximian.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "camel-smime-context.h" + +#include "camel-stream-fs.h" +#include "camel-stream-mem.h" + +#include <nss.h> +#include <cert.h> +#include <secpkcs7.h> + +#include <gtk/gtk.h> /* for _() macro */ + +#define d(x) + +struct _CamelSMimeContextPrivate { + CERTCertDBHandle *certdb; +}; + + +static int smime_sign (CamelCipherContext *ctx, const char *userid, CamelCipherHash hash, + CamelStream *istream, CamelStream *ostream, CamelException *ex); +static int smime_clearsign (CamelCipherContext *context, const char *userid, + CamelCipherHash hash, CamelStream *istream, + CamelStream *ostream, CamelException *ex); +static CamelCipherValidity *smime_verify (CamelCipherContext *context, CamelStream *istream, + CamelStream *sigstream, CamelException *ex); +static int smime_encrypt (CamelCipherContext *context, gboolean sign, const char *userid, + GPtrArray *recipients, CamelStream *istream, CamelStream *ostream, + CamelException *ex); +static int smime_decrypt (CamelCipherContext *context, CamelStream *istream, + CamelStream *ostream, CamelException *ex); + + +static CamelCipherContextClass *parent_class; + +static void +camel_smime_context_init (CamelSMimeContext *context) +{ + context->priv = g_new0 (struct _CamelSMimeContextPrivate, 1); +} + +static void +camel_smime_context_finalise (CamelObject *o) +{ + CamelSMimeContext *context = (CamelSMimeContext *)o; + + CERT_ClosePermCertDB (context->priv->certdb); + g_free (context->priv->certdb); + + g_free (context->priv); +} + +static void +camel_smime_context_class_init (CamelSMimeContextClass *camel_smime_context_class) +{ + CamelCipherContextClass *camel_cipher_context_class = + CAMEL_CIPHER_CONTEXT_CLASS (camel_smime_context_class); + + parent_class = CAMEL_CIPHER_CONTEXT_CLASS (camel_type_get_global_classfuncs (camel_cipher_context_get_type ())); + + camel_cipher_context_class->sign = smime_sign; + camel_cipher_context_class->clearsign = smime_clearsign; + camel_cipher_context_class->verify = smime_verify; + camel_cipher_context_class->encrypt = smime_encrypt; + camel_cipher_context_class->decrypt = smime_decrypt; +} + +CamelType +camel_smime_context_get_type (void) +{ + static CamelType type = CAMEL_INVALID_TYPE; + + if (type == CAMEL_INVALID_TYPE) { + type = camel_type_register (camel_cipher_context_get_type (), + "CamelSMimeContext", + sizeof (CamelSMimeContext), + sizeof (CamelSMimeContextClass), + (CamelObjectClassInitFunc) camel_smime_context_class_init, + NULL, + (CamelObjectInitFunc) camel_smime_context_init, + (CamelObjectFinalizeFunc) camel_smime_context_finalise); + } + + return type; +} + + +/** + * camel_smime_context_new: + * @session: CamelSession + * @certdb: certificate db + * + * This creates a new CamelSMimeContext object which is used to sign, + * verify, encrypt and decrypt streams. + * + * Return value: the new CamelSMimeContext + **/ +CamelSMimeContext * +camel_smime_context_new (CamelSession *session, const char *certdb) +{ + CamelSMimeContext *context; + CERTCertDBHandle *handle; + + g_return_val_if_fail (session != NULL, NULL); + + context = CAMEL_SMIME_CONTEXT (camel_object_new (CAMEL_SMIME_CONTEXT_TYPE)); + + camel_cipher_construct (CAMEL_CIPHER_CONTEXT (context), session); + + handle = g_new0 (CERTCertDBHandle, 1); + if (certdb) { + if (!CERT_OpenCertDBFilename (handle, certdb, FALSE)) { + g_free (handle); + return NULL; + } + } else { + if (!CERT_OpenVolatileCertDB (handle)) { + g_free (handle); + return NULL; + } + } + + context->priv->certdb = handle; + + return context; +} + +/*----------------------------------------------------------------------* + * Public crypto functions + *----------------------------------------------------------------------*/ + +struct _GetPasswdData { + CamelSession *session; + CamelException *ex; + const char *userid; +}; + +static SECItem * +get_zero_len_passwd (SECKEYKeyDBHandle *handle) +{ + SECItem *pwitem; + SECStatus rv; + + /* hash the empty string as a password */ + pwitem = SECKEY_DeriveKeyDBPassword (handle, ""); + if (pwitem == NULL) + return NULL; + + /* check to see if this is the right password */ + rv = SECKEY_CheckKeyDBPassword (handle, pwitem); + if (rv == SECFailure) + return NULL; + + return pwitem; +} + +static SECItem * +get_password (void *arg, SECKEYKeyDBHandle *handle) +{ + CamelSession *session = ((struct _GetPasswdData *) arg)->session; + CamelException *ex = ((struct _GetPasswdData *) arg)->ex; + const char *userid = ((struct _GetPasswdData *) arg)->userid; + char *prompt, *passwd = NULL; + SECItem *pwitem; + SECStatus rv; + + /* Check to see if zero length password or not */ + pwitem = get_zero_len_passwd (handle); + if (pwitem) + return pwitem; + + prompt = g_strdup_printf (_("Please enter your password for %s"), userid); + passwd = camel_session_query_authenticator (session, CAMEL_AUTHENTICATOR_ASK, + prompt, TRUE, NULL, userid, + NULL); + g_free (prompt); + + /* hash the password */ + pwitem = SECKEY_DeriveKeyDBPassword (handle, passwd ? passwd : ""); + + /* clear out the password strings */ + if (passwd) { + memset (passwd, 0, strlen (passwd)); + g_free (passwd); + } + + if (pwitem == NULL) { + camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, + _("Error hashing password.")); + + return NULL; + } + + /* confirm the password */ + rv = SECKEY_CheckKeyDBPassword (handle, pwitem); + if (rv) { + camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, + _("Invalid password.")); + + SECITEM_ZfreeItem (pwitem, PR_TRUE); + + return NULL; + } + + return pwitem; +} + +static HASH_HashType +camel_cipher_hash_to_nss (CamelCipherHash hash) +{ + switch (hash) { + case CAMEL_CIPHER_HASH_DEFAULT: + return HASH_AlgSHA1; + case CAMEL_CIPHER_HASH_MD2: + return HASH_AlgMD2; + case CAMEL_CIPHER_HASH_MD5: + return HASH_AlgMD5; + case CAMEL_CIPHER_HASH_SHA1: + return HASH_AlgSHA1; + } + + return HASH_AlgNULL; +} + +static SECOidTag +nss_hash_to_sec_oid (HASH_HashType hash) +{ + switch (hash) { + case HASH_AlgMD2: + return SEC_OID_MD2; + case HASH_AlgMD5: + return SEC_OID_MD5; + case Hash_AlgSHA1: + return SEC_OID_SHA1; + default: + g_assert_not_reached (); + return 0; + } +} + +static int +smime_digest (SECItem *data, char *digestdata, unsigned int *len, unsigned int maxlen, HASH_HashType hash) +{ + SECHashObject *hashObj; + void *hashcx; + + hashObj = &SECHashObjects[hash]; + + hashcx = (* hashObj->create)(); + if (hashcx == NULL) + return -1; + + (* hashObj->begin)(hashcx); + (* hashObj->update)(hashcx, data->data, data->len); + (* hashObj->end)(hashcx, (unsigned char *)digestdata, len, maxlen); + (* hashObj->destroy)(hashcx, PR_TRUE); + + return 0; +} + +static void +smime_output_cb (void *arg, const char *buf, unsigned long len) +{ + CamelStream *stream; + + stream = CAMEL_STREAM (arg); + camel_stream_write (stream, buf, len); +} + +static int +smime_sign (CamelCipherContext *ctx, const char *userid, CamelCipherHash hash, + CamelStream *istream, CamelStream *ostream, CamelException *ex) +{ + CamelSMimeContext *context = CAMEL_SMIME_CONTEXT (ctx); + SEC_PKCS7EncoderContext *ecx = NULL; + struct _GetPasswdData *data = NULL; + SEC_PKCS7ContentInfo *cinfo = NULL; + SECItem data2sign, digest; + HASH_HashType hash_type; + CERTCertificate *cert; + guchar digestdata[32]; + CamelStream *stream; + GByteArray *buf; + guint len; + + g_return_val_if_fail (userid != NULL, -1); + g_return_val_if_fail (istream != NULL, -1); + g_return_val_if_fail (ostream != NULL, -1); + + stream = camel_stream_mem_new (); + camel_stream_write_to_stream (istream, stream); + buf = CAMEL_STREAM_MEM (stream)->buffer; + data2sign.data = buf->data; + data2sign.len = buf->len; + + hash_type = camel_cipher_hash_to_nss (hash); + smime_digest (&data2sign, digestdata, &len, 32, hash_type); + digest.data = (unsigned char *)digestdata; + digest.len = len; + + camel_object_unref (CAMEL_OBJECT (stream)); + + cert = CERT_FindCertByNickname (context->priv->certdb, userid); + if (!cert) { + camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, + _("Could not sign: certificate not found for \"%s\"."), + userid); + return -1; + } + + data = g_new (struct _GetPasswdData, 1); + data->session = ctx->session; + data->userid = userid; + data->ex = ex; + + cinfo = SECMIME_CreateSigned (cert, cert, context->priv->certdb, + nss_hash_to_sec_oid (hash_type), + &digest, get_password, data); + + if (cinfo == NULL) { + camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, + _("Could not sign: failed to create content info.")); + goto exception; + } + + ecx = SEC_PKCS7EncoderStart (cinfo, smime_output_cb, ostream, NULL); + if (ecx == NULL) { + camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, + _("Could not sign: failed to create signing context.")); + goto exception; + } + + if (SEC_PKCS7EncoderFinish (ecx, NULL, NULL) != SECSuccess) { + camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, + _("Could not sign: failed to create signature.")); + goto exception; + } + + g_free (data); + + SEC_PKCS7DestroyContentInfo (cinfo); + + return 0; + + exception: + + if (cinfo) + SEC_PKCS7DestroyContentInfo (cinfo); + + if (data) + g_free (data); + + return -1; +} + + +static int +smime_clearsign (CamelCipherContext *ctx, const char *userid, CamelCipherHash hash, + CamelStream *istream, CamelStream *ostream, CamelException *ex) +{ + camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, + _("'clearsign' is not supported by S/MIME.")); + return -1; +} + +#if 0 +/* this is just meant as a reference so I can see what the valid enums are */ +typedef enum { + certUsageSSLClient, + certUsageSSLServer, + certUsageSSLServerWithStepUp, + certUsageSSLCA, + certUsageEmailSigner, + certUsageEmailRecipient, + certUsageObjectSigner, + certUsageUserCertImport, + certUsageVerifyCA, + certUsageProtectedObjectSigner, + certUsageStatusResponder, + certUsageAnyCA +} SECCertUsage; +#endif + +/* FIXME: god knows if this code works, NSS "docs" are so not helpful at all */ +static CamelCipherValidity * +smime_verify (CamelCipherContext *ctx, CamelCipherHash hash, CamelStream *istream, + CamelStream *sigstream, CamelException *ex) +{ + CamelSMimeContext *context = CAMEL_SMIME_CONTEXT (ctx); + CamelCipherValidity *valid = NULL; + SEC_PKCS7ContentInfo *cinfo; + SECCertUsage usage; + GByteArray *plaintext; + CamelStream *stream; + + /* create our ContentInfo object */ + stream = camel_stream_mem_new (); + camel_stream_write_to_stream (istream, stream); + plaintext = CAMEL_STREAM_MEM (stream)->buffer; + cinfo = SEC_PKCS7CreateData (); + SEC_PKCS7SetContent (cinfo, plaintext->data, plaintext->len); + camel_object_unref (CAMEL_OBJECT (stream)); + + usage = certUsageEmailSigner; /* just a guess. or maybe certUsageVerifyCA?? */ + + valid = camel_cipher_validity_new (); + + if (sigstream) { + HASH_HashType digest_type; + GByteArray *signature; + SECItem digest; + + /* create our digest object */ + stream = camel_stream_mem_new (); + camel_stream_write_to_stream (sigstream, stream); + signature = CAMEL_STREAM_MEM (stream)->buffer; + digest.data = signature->data; + digest.len = signature->len; + + switch (hash) { + default: + case CAMEL_CIPHER_HASH_DEFAULT: + digest_type = HASH_AlgNULL; + break; + case CAMEL_CIPHER_HASH_MD2: + digest_type = HASH_AlgMD2; + break; + case CAMEL_CIPHER_HASH_MD5: + digest_type = HASH_AlgMD5; + break; + case CAMEL_CIPHER_HASH_SHA1: + digest_type = HASH_AlgSHA1; + break; + } + + valid->valid = SEC_PKCS7VerifyDetachedSignature (cinfo, usage, &digest, + digest_type, PR_FALSE); + camel_object_unref (CAMEL_OBJECT (stream)); + } else { + valid->valid = SEC_PKCS7VerifySignature (cinfo, usage, PR_FALSE); + } + + SEC_PKCS7DestroyContentInfo (cinfo); + + /* FIXME: set a meaningful description...in UTF8 */ + camel_cipher_validity_set_description (valid, ""); + + return valid; +} + +static int +smime_encrypt (CamelCipherContext *ctx, gboolean sign, const char *userid, GPtrArray *recipients, + CamelStream *istream, CamelStream *ostream, CamelException *ex) +{ + CamelSMimeContext *context = CAMEL_SMIME_CONTEXT (ctx); + const char *invalid_userkey = NULL; + SEC_PKCS7ContentInfo *cinfo = NULL; + GPtrArray *certificates = NULL; + SEC_PKCS7EncoderContext *ecx; + struct _GetPasswdData *data; + CamelStream *stream = NULL; + CERTCertificate *scert; + SECItem secdata; + GByteArray *buf; + int i = 0; + + g_return_val_if_fail (userid != NULL, -1); + g_return_val_if_fail (recipients != NULL, -1); + g_return_val_if_fail (recipients->len != 0, -1); + g_return_val_if_fail (istream != NULL, -1); + g_return_val_if_fail (ostream != NULL, -1); + + scert = CERT_FindCertByNickname (context->priv->certdb, userid); + if (!scert) { + invalid_userkey = recipients->pdata[i]; + goto exception; + } + + certificates = g_ptr_array_new (); + for (i = 0; i < recipients->len; i++) { + CERTCertificate *cert; + + cert = CERT_FindCertByNickname (context->priv->certdb, recipients->pdata[i]); + if (!cert) { + invalid_userkey = recipients->pdata[i]; + goto exception; + } + + g_ptr_array_add (certificates, cert); + } + g_ptr_array_add (certificates, NULL); + + data = g_new (struct _GetPasswdData, 1); + data->session = session; + data->userid = userid; + data->ex = ex; + + cinfo = SECMIME_CreateEncrypted (scert, (CERTCertificate **) certificates->pdata, + context->priv->certdb, get_password, data); + + g_free (data); + + if (!cinfo) { + camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, + _("Could not encrypt: failed to create enveloped data.")); + goto exception; + } + + ecx = SEC_PKCS7EncoderStart (cinfo, smime_output_cb, ostream, NULL); + if (ecx == NULL) { + camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, + _("Could not encrypt: failed to create encryption context.")); + goto exception; + } + + stream = camel_stream_mem_new (); + camel_stream_write_to_stream (istream, stream); + buf = CAMEL_STREAM_MEM (stream)->buffer; + if (SEC_PKCS7EncoderUpdate (ecx, buf->data, buf->len) != SECSuccess) + goto exception; + + camel_object_unref (CAMEL_OBJECT (stream)); + stream = NULL; + + if (SEC_PKCS7EncoderFinish (ecx, NULL, NULL) != SECSuccess) + goto exception; + + g_ptr_array_free (certificates, TRUE); + + SEC_PKCS7DestroyContentInfo (cinfo); + + return 0; + + exception: + + if (certificates) + g_ptr_array_free (certificates, TRUE); + + if (stream) + camel_object_unref (CAMEL_OBJECT (stream)); + + if (cinfo) + SEC_PKCS7DestroyContentInfo (cinfo); + + if (invalid_userkey) { + camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, + _("Could not encrypt data: invalid user key: \"%s\"."), + invalid_userkey); + } + + if (!camel_exception_is_set (ex)) { + camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, + _("Could not encrypt: encoding failed.")); + } + + return -1; +} + +static PRBool +decryption_allowed (SECAlgorithmID *algid, PK11SymKey *key) +{ + return PR_TRUE; +} + +static int +smime_decrypt (CamelCipherContext *ctx, CamelStream *istream, + CamelStream *ostream, CamelException *ex) +{ + CamelSMimeContext *context = CAMEL_SMIME_CONTEXT (ctx); + struct _GetPasswdData *data; + SEC_PKCS7DecoderContext *dcx; + SEC_PKCS7ContentInfo *cinfo; + CamelStream *stream = NULL; + SECItem secdata; + GByteArray *buf; + + g_return_val_if_fail (istream != NULL, -1); + g_return_val_if_fail (ostream != NULL, -1); + + stream = camel_stream_mem_new (); + camel_stream_write_to_stream (istream, stream); + buf = CAMEL_STREAM_MEM (stream)->buffer; + secdata.data = buf->data; + secdata.len = buf->len; + + data = g_new (struct _GetPasswdData, 1); + data->session = ctx->session; + data->userid = NULL; + data->ex = ex; + + dcx = SEC_PKCS7DecoderStart (smime_output_cb, ostream, get_password, data, + NULL, NULL, decryption_allowed); + if (dcx == NULL) + goto exception; + + SEC_PKCS7DecoderUpdate (dcx, secdata.data, secdata.len); + cinfo = SEC_PKCS7DecoderFinish (dcx); + + camel_object_unref (CAMEL_OBJECT (stream)); + g_free (data); + + if (cinfo == NULL) { + camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, + _("Failed to decrypt: Unknown")); + return -1; + } + + SEC_PKCS7DestroyContentInfo (cinfo); + + return 0; + + exception: + + if (stream) + camel_object_unref (CAMEL_OBJECT (stream)); + + return -1; +} diff --git a/camel/camel-smime-context.h b/camel/camel-smime-context.h new file mode 100644 index 0000000000..a132c3918f --- /dev/null +++ b/camel/camel-smime-context.h @@ -0,0 +1,73 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Authors: Jeffrey Stedfast <fejj@ximian.com> + * + * Copyright 2001 Ximian, Inc. (www.ximian.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef CAMEL_SMIME_CONTEXT_H +#define CAMEL_SMIME_CONTEXT_H + +#include <camel/camel-session.h> +#include <camel/camel-stream.h> +#include <camel/camel-exception.h> +#include <camel/camel-cipher-context.h> + +#ifdef __cplusplus +extern "C" { +#pragma } +#endif /* __cplusplus */ + +#define CAMEL_SMIME_CONTEXT_TYPE (camel_smime_context_get_type ()) +#define CAMEL_SMIME_CONTEXT(obj) (CAMEL_CHECK_CAST((obj), CAMEL_SMIME_CONTEXT_TYPE, CamelSMimeContext)) +#define CAMEL_SMIME_CONTEXT_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_SMIME_CONTEXT_TYPE, CamelSMimeContextClass)) +#define CAMEL_IS_SMIME_CONTEXT(o) (CAMEL_CHECK_TYPE((o), CAMEL_SMIME_CONTEXT_TYPE)) + +typedef struct _CamelSMimeContext { + CamelCipherContext parent_object; + + struct _CamelSMimeContextPrivate *priv; + +} CamelSMimeContext; + +typedef struct _CamelSMimeContextClass { + CamelCipherContextClass parent_class; + +} CamelSMimeContextClass; + + +CamelType camel_smime_context_get_type (void); + +CamelSMimeContext *camel_smime_context_new (CamelSession *session, const char *certdb_path); + +/* SMIME routines */ +#define camel_smime_sign(c, u, h, i, o, e) camel_cipher_sign (CAMEL_CIPHER_CONTEXT (c), u, h, i, o, e) + +#define camel_smime_clearsign(c, u, h, i, o, e) camel_cipher_clearsign (CAMEL_CIPHER_CONTEXT (c), u, h, i, o, e) + +#define camel_smime_verify(c, i, s, e) camel_cipher_verify (CAMEL_CIPHER_CONTEXT (c), i, s, e) + +#define camel_smime_encrypt(c, s, u, r, i, o, e) camel_cipher_encrypt (CAMEL_CIPHER_CONTEXT (c), s, u, r, i, o, e) + +#define camel_smime_decrypt(c, i, o, e) camel_cipher_decrypt (CAMEL_CIPHER_CONTEXT (c), i, o, e) + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* CAMEL_SMIME_CONTEXT_H */ |