diff options
Diffstat (limited to 'camel/camel-cipher-context.c')
-rw-r--r-- | camel/camel-cipher-context.c | 652 |
1 files changed, 0 insertions, 652 deletions
diff --git a/camel/camel-cipher-context.c b/camel/camel-cipher-context.c deleted file mode 100644 index 5725470855..0000000000 --- a/camel/camel-cipher-context.c +++ /dev/null @@ -1,652 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Authors: Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright 2001-2003 Ximian, Inc. (www.ximian.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * 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 Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <pthread.h> -#include <string.h> - -#include <glib.h> - -#include "camel-cipher-context.h" -#include "camel-stream.h" - -#include "camel-mime-utils.h" -#include "camel-medium.h" -#include "camel-multipart.h" -#include "camel-mime-message.h" -#include "camel-mime-filter-canon.h" -#include "camel-stream-filter.h" - -#define CIPHER_LOCK(ctx) g_mutex_lock (((CamelCipherContext *) ctx)->priv->lock) -#define CIPHER_UNLOCK(ctx) g_mutex_unlock (((CamelCipherContext *) ctx)->priv->lock); - -#define d(x) - -#define CCC_CLASS(o) CAMEL_CIPHER_CONTEXT_CLASS(CAMEL_OBJECT_GET_CLASS(o)) - -struct _CamelCipherContextPrivate { - GMutex *lock; -}; - -static CamelObjectClass *parent_class = NULL; - -/** - * camel_cipher_context_new: - * @session: CamelSession - * - * This creates a new CamelCipherContext object which is used to sign, - * verify, encrypt and decrypt streams. - * - * Return value: the new CamelCipherContext - **/ -CamelCipherContext * -camel_cipher_context_new (CamelSession *session) -{ - CamelCipherContext *context; - - g_return_val_if_fail (session != NULL, NULL); - - context = CAMEL_CIPHER_CONTEXT (camel_object_new (CAMEL_CIPHER_CONTEXT_TYPE)); - - camel_object_ref (session); - context->session = session; - - return context; -} - -/** - * camel_cipher_context_construct: - * @context: CamelCipherContext - * @session: CamelSession - * - * Constucts the CamelCipherContext - **/ -void -camel_cipher_context_construct (CamelCipherContext *context, CamelSession *session) -{ - g_return_if_fail (CAMEL_IS_CIPHER_CONTEXT (context)); - g_return_if_fail (CAMEL_IS_SESSION (session)); - - camel_object_ref (session); - context->session = session; -} - -static int -cipher_sign (CamelCipherContext *ctx, const char *userid, CamelCipherHash hash, - struct _CamelMimePart *ipart, struct _CamelMimePart *opart, CamelException *ex) -{ - camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, - _("Signing is not supported by this cipher")); - return -1; -} - -/** - * camel_cipher_sign: - * @context: Cipher Context - * @userid: private key to use to sign the stream - * @hash: preferred Message-Integrity-Check hash algorithm - * @ipart: Input part. - * @opart: output part. - * @ex: exception - * - * 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. - * - * Return value: 0 for success or -1 for failure. - **/ -int -camel_cipher_sign (CamelCipherContext *context, const char *userid, CamelCipherHash hash, - struct _CamelMimePart *ipart, struct _CamelMimePart *opart, CamelException *ex) -{ - int retval; - - g_return_val_if_fail (CAMEL_IS_CIPHER_CONTEXT (context), -1); - - CIPHER_LOCK(context); - - retval = CCC_CLASS (context)->sign (context, userid, hash, ipart, opart, ex); - - CIPHER_UNLOCK(context); - - return retval; -} - -static CamelCipherValidity * -cipher_verify (CamelCipherContext *context, struct _CamelMimePart *sigpart, CamelException *ex) -{ - camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, - _("Verifying is not supported by this cipher")); - return NULL; -} - -/** - * camel_cipher_verify: - * @context: Cipher Context - * @ipart: part to verify - * @ex: exception - * - * Verifies the signature. If @istream is a clearsigned stream, - * you should pass %NULL as the sigstream parameter. Otherwise - * @sigstream is assumed to be the signature stream and is used to - * verify the integirity of the @istream. - * - * Return value: a CamelCipherValidity structure containing information - * about the integrity of the input stream or %NULL on failure to - * execute at all. - **/ -CamelCipherValidity * -camel_cipher_verify (CamelCipherContext *context, struct _CamelMimePart *ipart, CamelException *ex) -{ - CamelCipherValidity *valid; - - g_return_val_if_fail (CAMEL_IS_CIPHER_CONTEXT (context), NULL); - - CIPHER_LOCK(context); - - valid = CCC_CLASS (context)->verify (context, ipart, ex); - - CIPHER_UNLOCK(context); - - return valid; -} - -static int -cipher_encrypt (CamelCipherContext *context, const char *userid, GPtrArray *recipients, - struct _CamelMimePart *ipart, struct _CamelMimePart *opart, CamelException *ex) -{ - camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, - _("Encryption is not supported by this cipher")); - return -1; -} - -/** - * camel_cipher_encrypt: - * @context: Cipher Context - * @userid: key id (or email address) to use when signing, or NULL to not sign. - * @recipients: an array of recipient key ids and/or email addresses - * @istream: cleartext input stream - * @ostream: ciphertext output stream - * @ex: exception - * - * Encrypts (and optionally signs) the cleartext input stream and - * writes the resulting ciphertext to the output stream. - * - * Return value: 0 for success or -1 for failure. - **/ -int -camel_cipher_encrypt (CamelCipherContext *context, const char *userid, GPtrArray *recipients, - struct _CamelMimePart *ipart, struct _CamelMimePart *opart, CamelException *ex) -{ - int retval; - - g_return_val_if_fail (CAMEL_IS_CIPHER_CONTEXT (context), -1); - - CIPHER_LOCK(context); - - retval = CCC_CLASS (context)->encrypt (context, userid, recipients, ipart, opart, ex); - - CIPHER_UNLOCK(context); - - return retval; -} - -static CamelCipherValidity * -cipher_decrypt(CamelCipherContext *context, struct _CamelMimePart *ipart, struct _CamelMimePart *opart, CamelException *ex) -{ - camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, - _("Decryption is not supported by this cipher")); - return NULL; -} - -/** - * camel_cipher_decrypt: - * @context: - * @ipart: - * @opart: - * @ex: - * - * Decrypts @ipart into @opart. - * - * Return value: A validity/encryption status. - **/ -CamelCipherValidity * -camel_cipher_decrypt(CamelCipherContext *context, struct _CamelMimePart *ipart, struct _CamelMimePart *opart, CamelException *ex) -{ - CamelCipherValidity *valid; - - g_return_val_if_fail (CAMEL_IS_CIPHER_CONTEXT (context), NULL); - - CIPHER_LOCK(context); - - valid = CCC_CLASS (context)->decrypt (context, ipart, opart, ex); - - CIPHER_UNLOCK(context); - - return valid; -} - -static int -cipher_import_keys (CamelCipherContext *context, struct _CamelStream *istream, CamelException *ex) -{ - camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, - _("You may not import keys with this cipher")); - - return -1; -} - -/** - * camel_cipher_import_keys: - * @ctx: Cipher Context - * @istream: input stream (containing keys) - * @ex: exception - * - * Imports a stream of keys/certificates contained within @istream - * into the key/certificate database controlled by @ctx. - * - * Returns 0 on success or -1 on fail. - **/ -int -camel_cipher_import_keys (CamelCipherContext *context, struct _CamelStream *istream, CamelException *ex) -{ - g_return_val_if_fail (CAMEL_IS_CIPHER_CONTEXT (context), -1); - g_return_val_if_fail (CAMEL_IS_STREAM (istream), -1); - - return CCC_CLASS (context)->import_keys (context, istream, ex); -} - -static int -cipher_export_keys (CamelCipherContext *context, GPtrArray *keys, - struct _CamelStream *ostream, CamelException *ex) -{ - camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, - _("You may not export keys with this cipher")); - - return -1; -} - -/** - * camel_cipher_export_keys: - * @ctx: Cipher Context - * @keys: an array of key ids - * @ostream: output stream - * @ex: exception - * - * Exports the keys/certificates in @keys to the stream @ostream from - * the key/certificate database controlled by @ctx. - * - * Returns 0 on success or -1 on fail. - **/ -int -camel_cipher_export_keys (CamelCipherContext *context, GPtrArray *keys, - struct _CamelStream *ostream, CamelException *ex) -{ - g_return_val_if_fail (CAMEL_IS_CIPHER_CONTEXT (context), -1); - g_return_val_if_fail (CAMEL_IS_STREAM (ostream), -1); - g_return_val_if_fail (keys != NULL, -1); - - return CCC_CLASS (context)->export_keys (context, keys, ostream, ex); -} - -static CamelCipherHash -cipher_id_to_hash(CamelCipherContext *context, const char *id) -{ - return CAMEL_CIPHER_HASH_DEFAULT; -} - -/* a couple of util functions */ -CamelCipherHash -camel_cipher_id_to_hash(CamelCipherContext *context, const char *id) -{ - g_return_val_if_fail (CAMEL_IS_CIPHER_CONTEXT (context), CAMEL_CIPHER_HASH_DEFAULT); - - return CCC_CLASS (context)->id_to_hash (context, id); -} - -static const char * -cipher_hash_to_id(CamelCipherContext *context, CamelCipherHash hash) -{ - return NULL; -} - -const char * -camel_cipher_hash_to_id(CamelCipherContext *context, CamelCipherHash hash) -{ - g_return_val_if_fail (CAMEL_IS_CIPHER_CONTEXT (context), NULL); - - return CCC_CLASS (context)->hash_to_id (context, hash); -} - -/* Cipher Validity stuff */ -static void -ccv_certinfo_free(CamelCipherCertInfo *info) -{ - g_free(info->name); - g_free(info->email); - g_free(info); -} - -CamelCipherValidity * -camel_cipher_validity_new (void) -{ - CamelCipherValidity *validity; - - validity = g_malloc(sizeof(*validity)); - camel_cipher_validity_init(validity); - - return validity; -} - -void -camel_cipher_validity_init (CamelCipherValidity *validity) -{ - g_assert (validity != NULL); - - memset(validity, 0, sizeof(*validity)); - e_dlist_init(&validity->children); - e_dlist_init(&validity->sign.signers); - e_dlist_init(&validity->encrypt.encrypters); -} - -gboolean -camel_cipher_validity_get_valid (CamelCipherValidity *validity) -{ - return validity != NULL - && validity->sign.status == CAMEL_CIPHER_VALIDITY_SIGN_GOOD; -} - -void -camel_cipher_validity_set_valid (CamelCipherValidity *validity, gboolean valid) -{ - g_assert (validity != NULL); - - validity->sign.status = valid?CAMEL_CIPHER_VALIDITY_SIGN_GOOD:CAMEL_CIPHER_VALIDITY_SIGN_BAD; -} - -gchar * -camel_cipher_validity_get_description (CamelCipherValidity *validity) -{ - if (validity == NULL) - return NULL; - - return validity->sign.description; -} - -void -camel_cipher_validity_set_description (CamelCipherValidity *validity, const gchar *description) -{ - g_assert (validity != NULL); - - g_free(validity->sign.description); - validity->sign.description = g_strdup(description); -} - -void -camel_cipher_validity_clear (CamelCipherValidity *validity) -{ - g_assert (validity != NULL); - - /* TODO: this doesn't free children/clear key lists */ - g_free(validity->sign.description); - g_free(validity->encrypt.description); - camel_cipher_validity_init(validity); -} - -CamelCipherValidity * -camel_cipher_validity_clone(CamelCipherValidity *vin) -{ - CamelCipherValidity *vo; - CamelCipherCertInfo *info; - - vo = camel_cipher_validity_new(); - vo->sign.status = vin->sign.status; - vo->sign.description = g_strdup(vin->sign.description); - vo->encrypt.status = vin->encrypt.status; - vo->encrypt.description = g_strdup(vin->encrypt.description); - - info = (CamelCipherCertInfo *)vin->sign.signers.head; - while (info->next) { - 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); - info = info->next; - } - - return vo; -} - -/** - * camel_cipher_validity_add_certinfo: - * @vin: - * @mode: - * @name: - * @email: - * - * Add a cert info to the signer or encrypter info. - **/ -void -camel_cipher_validity_add_certinfo(CamelCipherValidity *vin, enum _camel_cipher_validity_mode_t mode, const char *name, const char *email) -{ - CamelCipherCertInfo *info; - EDList *list; - - info = g_malloc0(sizeof(*info)); - info->name = g_strdup(name); - info->email = g_strdup(email); - - list = (mode==CAMEL_CIPHER_VALIDITY_SIGN)?&vin->sign.signers:&vin->encrypt.encrypters; - e_dlist_addtail(list, (EDListNode *)info); - - printf("adding certinfo %s <%s>\n", name?name:"unset", email?email:"unset"); -} - -/** - * camel_cipher_validity_envelope: - * @validity: - * @outer: - * - * Calculate a conglomerate validity based on wrapping one secure part inside - * another one. - **/ -void -camel_cipher_validity_envelope(CamelCipherValidity *parent, CamelCipherValidity *valid) -{ - CamelCipherCertInfo *info; - - if (parent->sign.status != CAMEL_CIPHER_VALIDITY_SIGN_NONE - && parent->encrypt.status == CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE - && valid->sign.status == CAMEL_CIPHER_VALIDITY_SIGN_NONE - && valid->encrypt.status != CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE) { - /* case 1: only signed inside only encrypted -> merge both */ - parent->encrypt.status = valid->encrypt.status; - parent->encrypt.description = g_strdup(valid->encrypt.description); - info = (CamelCipherCertInfo *)valid->encrypt.encrypters.head; - while (info->next) { - camel_cipher_validity_add_certinfo(parent, CAMEL_CIPHER_VALIDITY_ENCRYPT, info->name, info->email); - info = info->next; - } - } else if (parent->sign.status == CAMEL_CIPHER_VALIDITY_SIGN_NONE - && parent->encrypt.status != CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE - && valid->sign.status != CAMEL_CIPHER_VALIDITY_SIGN_NONE - && valid->encrypt.status == CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE) { - /* case 2: only encrypted inside only signed */ - parent->sign.status = valid->sign.status; - parent->sign.description = g_strdup(valid->sign.description); - info = (CamelCipherCertInfo *)valid->sign.signers.head; - while (info->next) { - camel_cipher_validity_add_certinfo(parent, CAMEL_CIPHER_VALIDITY_SIGN, info->name, info->email); - info = info->next; - } - } - /* Otherwise, I dunno - what do you do? */ -} - -void -camel_cipher_validity_free (CamelCipherValidity *validity) -{ - CamelCipherValidity *child; - CamelCipherCertInfo *info; - - if (validity == NULL) - return; - - while ((child = (CamelCipherValidity *)e_dlist_remhead(&validity->children))) - camel_cipher_validity_free(child); - - while ((info = (CamelCipherCertInfo *)e_dlist_remhead(&validity->sign.signers))) - ccv_certinfo_free(info); - - while ((info = (CamelCipherCertInfo *)e_dlist_remhead(&validity->encrypt.encrypters))) - ccv_certinfo_free(info); - - camel_cipher_validity_clear(validity); - g_free(validity); -} - -/* ********************************************************************** */ - -static void -camel_cipher_context_init (CamelCipherContext *context) -{ - context->priv = g_new0 (struct _CamelCipherContextPrivate, 1); - context->priv->lock = g_mutex_new (); -} - -static void -camel_cipher_context_finalise (CamelObject *o) -{ - CamelCipherContext *context = (CamelCipherContext *)o; - - camel_object_unref (CAMEL_OBJECT (context->session)); - - g_mutex_free (context->priv->lock); - - g_free (context->priv); -} - -static void -camel_cipher_context_class_init (CamelCipherContextClass *camel_cipher_context_class) -{ - parent_class = camel_type_get_global_classfuncs (camel_object_get_type ()); - - camel_cipher_context_class->hash_to_id = cipher_hash_to_id; - camel_cipher_context_class->id_to_hash = cipher_id_to_hash; - camel_cipher_context_class->sign = cipher_sign; - camel_cipher_context_class->verify = cipher_verify; - camel_cipher_context_class->encrypt = cipher_encrypt; - camel_cipher_context_class->decrypt = cipher_decrypt; - camel_cipher_context_class->import_keys = cipher_import_keys; - camel_cipher_context_class->export_keys = cipher_export_keys; -} - -CamelType -camel_cipher_context_get_type (void) -{ - static CamelType type = CAMEL_INVALID_TYPE; - - if (type == CAMEL_INVALID_TYPE) { - type = camel_type_register (camel_object_get_type (), - "CamelCipherContext", - sizeof (CamelCipherContext), - sizeof (CamelCipherContextClass), - (CamelObjectClassInitFunc) camel_cipher_context_class_init, - NULL, - (CamelObjectInitFunc) camel_cipher_context_init, - (CamelObjectFinalizeFunc) camel_cipher_context_finalise); - } - - return type; -} - -/* See rfc3156, section 2 and others */ -/* We do this simply: Anything not base64 must be qp - This is so that we can safely translate any occurance of "From " - into the quoted-printable escaped version safely. */ -static void -cc_prepare_sign(CamelMimePart *part) -{ - CamelDataWrapper *dw; - CamelTransferEncoding encoding; - int parts, i; - - dw = camel_medium_get_content_object((CamelMedium *)part); - if (!dw) - return; - - if (CAMEL_IS_MULTIPART (dw)) { - parts = camel_multipart_get_number((CamelMultipart *)dw); - for (i = 0; i < parts; i++) - cc_prepare_sign(camel_multipart_get_part((CamelMultipart *)dw, i)); - } else if (CAMEL_IS_MIME_MESSAGE (dw)) { - cc_prepare_sign((CamelMimePart *)dw); - } else { - encoding = camel_mime_part_get_encoding(part); - - if (encoding != CAMEL_TRANSFER_ENCODING_BASE64 - && encoding != CAMEL_TRANSFER_ENCODING_QUOTEDPRINTABLE) { - camel_mime_part_set_encoding(part, CAMEL_TRANSFER_ENCODING_QUOTEDPRINTABLE); - } - } -} - -/** - * camel_cipher_canonical_to_stream: - * @part: Part to write. - * @flags: flags for the canonicalisation filter (CamelMimeFilterCanon) - * @ostream: stream to write canonicalised output to. - * - * Writes a part to a stream in a canonicalised format, suitable for signing/encrypting. - * - * The transfer encoding paramaters for the part may be changed by this function. - * - * Return value: -1 on error; - **/ -int -camel_cipher_canonical_to_stream(CamelMimePart *part, guint32 flags, CamelStream *ostream) -{ - CamelStreamFilter *filter; - CamelMimeFilter *canon; - int res = -1; - - if (flags & (CAMEL_MIME_FILTER_CANON_FROM|CAMEL_MIME_FILTER_CANON_STRIP)) - cc_prepare_sign(part); - - filter = camel_stream_filter_new_with_stream(ostream); - canon = camel_mime_filter_canon_new(flags); - camel_stream_filter_add(filter, canon); - camel_object_unref(canon); - - if (camel_data_wrapper_write_to_stream((CamelDataWrapper *)part, (CamelStream *)filter) != -1 - && camel_stream_flush((CamelStream *)filter) != -1) - res = 0; - - camel_object_unref(filter); - camel_stream_reset(ostream); - - return res; -} |