diff options
-rw-r--r-- | camel/ChangeLog | 7 | ||||
-rw-r--r-- | camel/camel-cipher-context.h | 1 | ||||
-rw-r--r-- | camel/camel-pkcs7-context.c | 249 | ||||
-rw-r--r-- | camel/camel-pkcs7-context.h | 73 |
4 files changed, 330 insertions, 0 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog index f5aab711b8..a9e251c2cd 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,10 @@ +2001-04-17 Jeffrey Stedfast <fejj@ximian.com> + + * camel-pkcs7-context.[c,h]: New source files to handle Pkcs7 + encryption, decryption, signing, and verifying. Not yet + complete. I'm sensing this is going to take a while seeing as how + NSS is just so well documented. + 2001-04-17 Dan Winship <danw@ximian.com> * camel-filter-driver.c (camel_filter_driver_filter_message): Fix diff --git a/camel/camel-cipher-context.h b/camel/camel-cipher-context.h index a2f0dd885f..acc1a88f90 100644 --- a/camel/camel-cipher-context.h +++ b/camel/camel-cipher-context.h @@ -41,6 +41,7 @@ typedef struct _CamelCipherValidity CamelCipherValidity; typedef enum { CAMEL_CIPHER_HASH_DEFAULT, + CAMEL_CIPHER_HASH_MD2, CAMEL_CIPHER_HASH_MD5, CAMEL_CIPHER_HASH_SHA1 } CamelCipherHash; diff --git a/camel/camel-pkcs7-context.c b/camel/camel-pkcs7-context.c new file mode 100644 index 0000000000..e9a629327f --- /dev/null +++ b/camel/camel-pkcs7-context.c @@ -0,0 +1,249 @@ +/* -*- 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-pkcs7-context.h" + +#include "camel-stream-fs.h" +#include "camel-stream-mem.h" + +#include <cert.h> +#include <secpkcs7.h> + +#include <gtk/gtk.h> /* for _() macro */ + +#define d(x) + +struct _CamelPkcs7ContextPrivate { + CERTCertDBHandle *certdb; +}; + + +static int pkcs7_sign (CamelCipherContext *ctx, const char *userid, CamelCipherHash hash, + CamelStream *istream, CamelStream *ostream, CamelException *ex); +static int pkcs7_clearsign (CamelCipherContext *context, const char *userid, + CamelCipherHash hash, CamelStream *istream, + CamelStream *ostream, CamelException *ex); +static CamelCipherValidity *pkcs7_verify (CamelCipherContext *context, CamelStream *istream, + CamelStream *sigstream, CamelException *ex); +static int pkcs7_encrypt (CamelCipherContext *context, gboolean sign, const char *userid, + GPtrArray *recipients, CamelStream *istream, CamelStream *ostream, + CamelException *ex); +static int pkcs7_decrypt (CamelCipherContext *context, CamelStream *istream, + CamelStream *ostream, CamelException *ex); + + +static CamelCipherContextClass *parent_class; + +static void +camel_pkcs7_context_init (CamelPkcs7Context *context) +{ + context->priv = g_new0 (struct _CamelPkcs7ContextPrivate, 1); +} + +static void +camel_pkcs7_context_finalise (CamelObject *o) +{ + CamelPkcs7Context *context = (CamelPkcs7Context *)o; + + CERT_ClosePermCertDB (context->priv->certdb); + g_free (context->priv->certdb); + + g_free (context->priv); +} + +static void +camel_pkcs7_context_class_init (CamelPkcs7ContextClass *camel_pkcs7_context_class) +{ + CamelCipherContextClass *camel_cipher_context_class = + CAMEL_CIPHER_CONTEXT_CLASS (camel_pkcs7_context_class); + + parent_class = CAMEL_CIPHER_CONTEXT_CLASS (camel_type_get_global_classfuncs (camel_cipher_context_get_type ())); + + camel_cipher_context_class->sign = pkcs7_sign; + camel_cipher_context_class->clearsign = pkcs7_clearsign; + camel_cipher_context_class->verify = pkcs7_verify; + camel_cipher_context_class->encrypt = pkcs7_encrypt; + camel_cipher_context_class->decrypt = pkcs7_decrypt; +} + +CamelType +camel_pkcs7_context_get_type (void) +{ + static CamelType type = CAMEL_INVALID_TYPE; + + if (type == CAMEL_INVALID_TYPE) { + type = camel_type_register (camel_cipher_context_get_type (), + "CamelPkcs7Context", + sizeof (CamelPkcs7Context), + sizeof (CamelPkcs7ContextClass), + (CamelObjectClassInitFunc) camel_pkcs7_context_class_init, + NULL, + (CamelObjectInitFunc) camel_pkcs7_context_init, + (CamelObjectFinalizeFunc) camel_pkcs7_context_finalise); + } + + return type; +} + + +/** + * camel_pkcs7_context_new: + * @session: CamelSession + * @certdb: certificate db + * + * This creates a new CamelPkcs7Context object which is used to sign, + * verify, encrypt and decrypt streams. + * + * Return value: the new CamelPkcs7Context + **/ +CamelPkcs7Context * +camel_pkcs7_context_new (CamelSession *session, const char *certdb) +{ + CamelPkcs7Context *context; + CERTCertDBHandle *handle; + + g_return_val_if_fail (session != NULL, NULL); + + context = CAMEL_PKCS7_CONTEXT (camel_object_new (CAMEL_PKCS7_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 + *----------------------------------------------------------------------*/ + +static int +pkcs7_sign (CamelCipherContext *ctx, const char *userid, CamelCipherHash hash, + CamelStream *istream, CamelStream *ostream, CamelException *ex) +{ + CamelPkcs7Context *context = CAMEL_PKCS7_CONTEXT (ctx); + + + + return -1; +} + + +static int +pkcs7_clearsign (CamelCipherContext *ctx, const char *userid, CamelCipherHash hash, + CamelStream *istream, CamelStream *ostream, CamelException *ex) +{ + CamelPkcs7Context *context = CAMEL_PKCS7_CONTEXT (ctx); + + return -1; +} + +static CamelCipherValidity * +pkcs7_verify (CamelCipherContext *ctx, CamelCipherHash hash, CamelStream *istream, + CamelStream *sigstream, CamelException *ex) +{ + CamelPkcs7Context *context = CAMEL_PKCS7_CONTEXT (ctx); + CamelCipherValidity *valid = NULL; + SEC_PKCS7ContentInfo *cinfo; + SECCertUsage certusage; + 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)); + + certusage = 0; + + valid = camel_cipher_validity_new (); + + if (sigstream) { + HASH_HashType digest_type; + GByteArray *signature; + SECItem *digest; + + 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, certusage, digest, digest_type, TRUE); + } else { + valid->valid = SEC_PKCS7VerifySignature (cinfo, certusage, TRUE); + } + + SEC_PKCS7DestroyContentInfo (cinfo); + + return valid; +} + + +static int +pkcs7_encrypt (CamelCipherContext *ctx, gboolean sign, const char *userid, GPtrArray *recipients, + CamelStream *istream, CamelStream *ostream, CamelException *ex) +{ + CamelPkcs7Context *context = CAMEL_PKCS7_CONTEXT (ctx); + + return -1; +} + + +static int +pkcs7_decrypt (CamelCipherContext *ctx, CamelStream *istream, + CamelStream *ostream, CamelException *ex) +{ + CamelPkcs7Context *context = CAMEL_PKCS7_CONTEXT (ctx); + + return -1; +} diff --git a/camel/camel-pkcs7-context.h b/camel/camel-pkcs7-context.h new file mode 100644 index 0000000000..200ba527a0 --- /dev/null +++ b/camel/camel-pkcs7-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_PKCS7_CONTEXT_H +#define CAMEL_PKCS7_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_PKCS7_CONTEXT_TYPE (camel_pkcs7_context_get_type ()) +#define CAMEL_PKCS7_CONTEXT(obj) (CAMEL_CHECK_CAST((obj), CAMEL_PKCS7_CONTEXT_TYPE, CamelPkcs7Context)) +#define CAMEL_PKCS7_CONTEXT_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_PKCS7_CONTEXT_TYPE, CamelPkcs7ContextClass)) +#define CAMEL_IS_PKCS7_CONTEXT(o) (CAMEL_CHECK_TYPE((o), CAMEL_PKCS7_CONTEXT_TYPE)) + +typedef struct _CamelPkcs7Context { + CamelCipherContext parent_object; + + struct _CamelPkcs7ContextPrivate *priv; + +} CamelPkcs7Context; + +typedef struct _CamelPkcs7ContextClass { + CamelCipherContextClass parent_class; + +} CamelPkcs7ContextClass; + + +CamelType camel_pkcs7_context_get_type (void); + +CamelPkcs7Context *camel_pkcs7_context_new (CamelSession *session, const char *certdb_path); + +/* PKCS7 routines */ +#define camel_pkcs7_sign(c, u, h, i, o, e) camel_cipher_sign (CAMEL_CIPHER_CONTEXT (c), u, h, i, o, e) + +#define camel_pkcs7_clearsign(c, u, h, i, o, e) camel_cipher_clearsign (CAMEL_CIPHER_CONTEXT (c), u, h, i, o, e) + +#define camel_pkcs7_verify(c, i, s, e) camel_cipher_verify (CAMEL_CIPHER_CONTEXT (c), i, s, e) + +#define camel_pkcs7_encrypt(c, s, u, r, i, o, e) camel_cipher_encrypt (CAMEL_CIPHER_CONTEXT (c), s, u, r, i, o, e) + +#define camel_pkcs7_decrypt(c, i, o, e) camel_cipher_decrypt (CAMEL_CIPHER_CONTEXT (c), i, o, e) + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* CAMEL_PKCS7_CONTEXT_H */ |