aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--camel/ChangeLog18
-rw-r--r--camel/camel-cipher-context.c101
-rw-r--r--camel/camel-cipher-context.h29
-rw-r--r--camel/camel-gpg-context.c164
-rw-r--r--camel/camel-gpg-context.h1
5 files changed, 277 insertions, 36 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index 4f5abb9031..24fc87d2bb 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,5 +1,23 @@
2002-10-31 Jeffrey Stedfast <fejj@ximian.com>
+ * camel-gpg-context.c (camel_gpg_context_class_init): Set the
+ virtual method pointers to the import/export methods.
+ (camel_gpg_context_init): Set the key_protocol string.
+ (gpg_hash_to_id): Handle 2 more hash types.
+ (gpg_id_to_hash): Same.
+ (gpg_ctx_op_step): Slight fixes to support import/export.
+ (gpg_ctx_parse_status): Fix to hack around the fact that importing
+ keys doesn't write to stdout.
+ (gpg_import_keys): Implemented.
+ (gpg_export_keys): Implemented.
+
+ * camel-cipher-context.c (camel_cipher_context_class_init): Hook
+ up default virtual methods for import/export.
+ (camel_cipher_import_keys): Implemented.
+ (camel_cipher_export_keys): Implemented.
+
+2002-10-31 Jeffrey Stedfast <fejj@ximian.com>
+
* Makefile.am: Removed hash-table-utils.[c,h] from the build.
* hash-table-utils.[c,h]: Removed.
diff --git a/camel/camel-cipher-context.c b/camel/camel-cipher-context.c
index 185002831f..c495a6479c 100644
--- a/camel/camel-cipher-context.c
+++ b/camel/camel-cipher-context.c
@@ -47,22 +47,28 @@ struct _CamelCipherContextPrivate {
#endif
};
-static int cipher_sign (CamelCipherContext *ctx, const char *userid, CamelCipherHash hash,
- CamelStream *istream, CamelStream *ostream, CamelException *ex);
-static CamelCipherValidity *cipher_verify (CamelCipherContext *context, CamelCipherHash hash,
- CamelStream *istream, CamelStream *sigstream,
- CamelException *ex);
+static const char *cipher_hash_to_id (CamelCipherContext *context, CamelCipherHash hash);
+static CamelCipherHash cipher_id_to_hash (CamelCipherContext *context, const char *id);
+
+static int cipher_sign (CamelCipherContext *context, const char *userid, CamelCipherHash hash,
+ CamelStream *istream, CamelStream *ostream, CamelException *ex);
+static CamelCipherValidity *cipher_verify (CamelCipherContext *context, CamelCipherHash hash,
+ CamelStream *istream, CamelStream *sigstream,
+ CamelException *ex);
static int cipher_encrypt (CamelCipherContext *context, gboolean sign, const char *userid,
GPtrArray *recipients, CamelStream *istream,
CamelStream *ostream, CamelException *ex);
static int cipher_decrypt (CamelCipherContext *context, CamelStream *istream,
CamelStream *ostream, CamelException *ex);
+static int cipher_import_keys (CamelCipherContext *context, CamelStream *istream,
+ CamelException *ex);
+static int cipher_export_keys (CamelCipherContext *context, GPtrArray *keys,
+ CamelStream *ostream, CamelException *ex);
-static const char *cipher_hash_to_id(CamelCipherContext *context, CamelCipherHash hash);
-static CamelCipherHash cipher_id_to_hash(CamelCipherContext *context, const char *id);
static CamelObjectClass *parent_class;
+
static void
camel_cipher_context_init (CamelCipherContext *context)
{
@@ -91,12 +97,14 @@ camel_cipher_context_class_init (CamelCipherContextClass *camel_cipher_context_c
{
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->hash_to_id = cipher_hash_to_id;
- camel_cipher_context_class->id_to_hash = cipher_id_to_hash;
+ camel_cipher_context_class->import_keys = cipher_import_keys;
+ camel_cipher_context_class->export_keys = cipher_export_keys;
}
CamelType
@@ -326,6 +334,73 @@ camel_cipher_decrypt (CamelCipherContext *context, CamelStream *istream,
return retval;
}
+
+static int
+cipher_import_keys (CamelCipherContext *context, 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, 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,
+ 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,
+ 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)
{
@@ -337,8 +412,8 @@ 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 ((CamelCipherContextClass *)((CamelObject *)context)->klass)->id_to_hash(context, id);
+
+ return CCC_CLASS (context)->id_to_hash (context, id);
}
static const char *
@@ -351,8 +426,8 @@ const char *
camel_cipher_hash_to_id(CamelCipherContext *context, CamelCipherHash hash)
{
g_return_val_if_fail (CAMEL_IS_CIPHER_CONTEXT (context), NULL);
-
- return ((CamelCipherContextClass *)((CamelObject *)context)->klass)->hash_to_id(context, hash);
+
+ return CCC_CLASS (context)->hash_to_id (context, hash);
}
/* Cipher Validity stuff */
diff --git a/camel/camel-cipher-context.h b/camel/camel-cipher-context.h
index 296d7e5b39..45444c26a0 100644
--- a/camel/camel-cipher-context.h
+++ b/camel/camel-cipher-context.h
@@ -44,7 +44,9 @@ typedef enum {
CAMEL_CIPHER_HASH_MD2,
CAMEL_CIPHER_HASH_MD5,
CAMEL_CIPHER_HASH_SHA1,
- CAMEL_CIPHER_HASH_RIPEMD160
+ CAMEL_CIPHER_HASH_RIPEMD160,
+ CAMEL_CIPHER_HASH_TIGER192,
+ CAMEL_CIPHER_HASH_HAVAL5160
} CamelCipherHash;
typedef struct _CamelCipherContext {
@@ -57,12 +59,16 @@ typedef struct _CamelCipherContext {
/* these MUST be set by implementors */
const char *sign_protocol;
const char *encrypt_protocol;
+ const char *key_protocol;
} CamelCipherContext;
typedef struct _CamelCipherContextClass {
CamelObjectClass parent_class;
- int (*sign) (CamelCipherContext *ctx, const char *userid, CamelCipherHash hash,
+ CamelCipherHash (*id_to_hash)(CamelCipherContext *context, const char *id);
+ const char * (*hash_to_id)(CamelCipherContext *context, CamelCipherHash hash);
+
+ int (*sign) (CamelCipherContext *context, const char *userid, CamelCipherHash hash,
CamelStream *istream, CamelStream *ostream, CamelException *ex);
CamelCipherValidity * (*verify) (CamelCipherContext *context, CamelCipherHash hash,
@@ -76,9 +82,11 @@ typedef struct _CamelCipherContextClass {
int (*decrypt) (CamelCipherContext *context, CamelStream *istream, CamelStream *ostream,
CamelException *ex);
- CamelCipherHash (*id_to_hash)(CamelCipherContext *context, const char *id);
- const char * (*hash_to_id)(CamelCipherContext *context, CamelCipherHash hash);
+ int (*import_keys) (CamelCipherContext *context, CamelStream *istream,
+ CamelException *ex);
+ int (*export_keys) (CamelCipherContext *context, GPtrArray *keys,
+ CamelStream *ostream, CamelException *ex);
} CamelCipherContextClass;
CamelType camel_cipher_context_get_type (void);
@@ -87,6 +95,10 @@ CamelCipherContext *camel_cipher_context_new (CamelSession *session);
void camel_cipher_context_construct (CamelCipherContext *context, CamelSession *session);
+/* cipher context util routines */
+CamelCipherHash camel_cipher_id_to_hash (CamelCipherContext *context, const char *id);
+const char * camel_cipher_hash_to_id (CamelCipherContext *context, CamelCipherHash hash);
+
/* cipher routines */
int camel_cipher_sign (CamelCipherContext *context, const char *userid, CamelCipherHash hash,
CamelStream *istream, CamelStream *ostream, CamelException *ex);
@@ -102,9 +114,12 @@ int camel_cipher_encrypt (CamelCipherContext *context, gboolean
int camel_cipher_decrypt (CamelCipherContext *context, CamelStream *istream, CamelStream *ostream,
CamelException *ex);
-/* cipher context util routines */
-CamelCipherHash camel_cipher_id_to_hash (CamelCipherContext *context, const char *id);
-const char * camel_cipher_hash_to_id (CamelCipherContext *context, CamelCipherHash hash);
+/* key/certificate routines */
+int camel_cipher_import_keys (CamelCipherContext *context, CamelStream *istream,
+ CamelException *ex);
+
+int camel_cipher_export_keys (CamelCipherContext *context, GPtrArray *keys,
+ CamelStream *ostream, CamelException *ex);
/* CamelCipherValidity utility functions */
CamelCipherValidity *camel_cipher_validity_new (void);
diff --git a/camel/camel-gpg-context.c b/camel/camel-gpg-context.c
index 8d948d0380..929e8f1769 100644
--- a/camel/camel-gpg-context.c
+++ b/camel/camel-gpg-context.c
@@ -51,20 +51,23 @@ static void camel_gpg_context_class_init (CamelGpgContextClass *klass);
static void camel_gpg_context_init (CamelGpgContext *obj);
static void camel_gpg_context_finalise (CamelObject *obj);
-static int gpg_sign (CamelCipherContext *ctx, const char *userid, CamelCipherHash hash,
- CamelStream *istream, CamelStream *ostream, CamelException *ex);
-static CamelCipherValidity *gpg_verify (CamelCipherContext *context, CamelCipherHash hash,
- CamelStream *istream, CamelStream *sigstream,
- CamelException *ex);
+static const char *gpg_hash_to_id (CamelCipherContext *context, CamelCipherHash hash);
+static CamelCipherHash gpg_id_to_hash (CamelCipherContext *context, const char *id);
+
+static int gpg_sign (CamelCipherContext *ctx, const char *userid, CamelCipherHash hash,
+ CamelStream *istream, CamelStream *ostream, CamelException *ex);
+static CamelCipherValidity *gpg_verify (CamelCipherContext *context, CamelCipherHash hash,
+ CamelStream *istream, CamelStream *sigstream,
+ CamelException *ex);
static int gpg_encrypt (CamelCipherContext *context, gboolean sign, const char *userid,
GPtrArray *recipients, CamelStream *istream, CamelStream *ostream,
CamelException *ex);
static int gpg_decrypt (CamelCipherContext *context, CamelStream *istream,
CamelStream *ostream, CamelException *ex);
-
-static const char *gpg_hash_to_id (CamelCipherContext *context, CamelCipherHash hash);
-static CamelCipherHash gpg_id_to_hash (CamelCipherContext *context, const char *id);
-
+static int gpg_import_keys (CamelCipherContext *context, CamelStream *istream,
+ CamelException *ex);
+static int gpg_export_keys (CamelCipherContext *context, GPtrArray *keys,
+ CamelStream *ostream, CamelException *ex);
static CamelCipherContextClass *parent_class = NULL;
@@ -95,12 +98,14 @@ camel_gpg_context_class_init (CamelGpgContextClass *klass)
parent_class = CAMEL_CIPHER_CONTEXT_CLASS (camel_type_get_global_classfuncs (camel_cipher_context_get_type ()));
+ cipher_class->hash_to_id = gpg_hash_to_id;
+ cipher_class->id_to_hash = gpg_id_to_hash;
cipher_class->sign = gpg_sign;
cipher_class->verify = gpg_verify;
cipher_class->encrypt = gpg_encrypt;
cipher_class->decrypt = gpg_decrypt;
- cipher_class->hash_to_id = gpg_hash_to_id;
- cipher_class->id_to_hash = gpg_id_to_hash;
+ cipher_class->import_keys = gpg_import_keys;
+ cipher_class->export_keys = gpg_export_keys;
}
static void
@@ -112,6 +117,7 @@ camel_gpg_context_init (CamelGpgContext *context)
cipher->sign_protocol = "application/pgp-signature";
cipher->encrypt_protocol = "application/pgp-encrypted";
+ cipher->key_protocol = "application/pgp-keys";
}
static void
@@ -177,6 +183,10 @@ gpg_hash_to_id (CamelCipherContext *context, CamelCipherHash hash)
return "pgp-sha1";
case CAMEL_CIPHER_HASH_RIPEMD160:
return "pgp-ripemd160";
+ case CAMEL_CIPHER_HASH_TIGER192:
+ return "pgp-tiger192";
+ case CAMEL_CIPHER_HASH_HAVAL5160:
+ return "pgp-haval-5-160";
}
return NULL;
@@ -194,6 +204,10 @@ gpg_id_to_hash (CamelCipherContext *context, const char *id)
return CAMEL_CIPHER_HASH_SHA1;
else if (!strcmp (id, "pgp-ripemd160"))
return CAMEL_CIPHER_HASH_RIPEMD160;
+ else if (!strcmp (id, "tiger192"))
+ return CAMEL_CIPHER_HASH_TIGER192;
+ else if (!strcmp (id, "haval-5-160"))
+ return CAMEL_CIPHER_HASH_HAVAL5160;
}
return CAMEL_CIPHER_HASH_DEFAULT;
@@ -205,6 +219,8 @@ enum _GpgCtxMode {
GPG_CTX_MODE_VERIFY,
GPG_CTX_MODE_ENCRYPT,
GPG_CTX_MODE_DECRYPT,
+ GPG_CTX_MODE_IMPORT,
+ GPG_CTX_MODE_EXPORT,
};
enum _GpgTrustMetric {
@@ -342,7 +358,7 @@ gpg_ctx_set_userid (struct _GpgCtx *gpg, const char *userid)
static void
gpg_ctx_add_recipient (struct _GpgCtx *gpg, const char *keyid)
{
- if (gpg->mode != GPG_CTX_MODE_ENCRYPT)
+ if (gpg->mode != GPG_CTX_MODE_ENCRYPT && gpg->mode != GPG_CTX_MODE_EXPORT)
return;
if (!gpg->recipients)
@@ -543,6 +559,17 @@ gpg_ctx_get_argv (struct _GpgCtx *gpg, int status_fd, char **sfd, int passwd_fd,
g_ptr_array_add (argv, "--output");
g_ptr_array_add (argv, "-");
break;
+ case GPG_CTX_MODE_IMPORT:
+ g_ptr_array_add (argv, "--import");
+ g_ptr_array_add (argv, "-");
+ break;
+ case GPG_CTX_MODE_EXPORT:
+ if (gpg->armor)
+ g_ptr_array_add (argv, "--armor");
+ g_ptr_array_add (argv, "--export");
+ for (i = 0; i < gpg->recipients->len; i++)
+ g_ptr_array_add (argv, gpg->recipients->pdata[i]);
+ break;
}
g_ptr_array_add (argv, NULL);
@@ -838,6 +865,13 @@ gpg_ctx_parse_status (struct _GpgCtx *gpg, CamelException *ex)
/* nothing to do, but we know the end is near? */
}
break;
+ case GPG_CTX_MODE_IMPORT:
+ /* hack to work around the fact that gpg
+ doesn't write anything to stdout when
+ importing keys */
+ if (!strncmp (status, "IMPORT_RES", 10))
+ gpg->seen_eof1 = TRUE;
+ break;
}
}
@@ -1021,7 +1055,7 @@ gpg_ctx_op_step (struct _GpgCtx *gpg, CamelException *ex)
gpg->send_passwd = FALSE;
}
- if (wrsetp && gpg->stdin_fd != -1 && FD_ISSET (gpg->stdin_fd, &wrset)) {
+ if (gpg->istream && wrsetp && gpg->stdin_fd != -1 && FD_ISSET (gpg->stdin_fd, &wrset)) {
char buffer[4096];
ssize_t nread;
@@ -1071,6 +1105,12 @@ gpg_ctx_op_step (struct _GpgCtx *gpg, CamelException *ex)
case GPG_CTX_MODE_DECRYPT:
mode = "decrypt";
break;
+ case GPG_CTX_MODE_IMPORT:
+ mode = "import keys";
+ break;
+ case GPG_CTX_MODE_EXPORT:
+ mode = "export keys";
+ break;
default:
g_assert_not_reached ();
mode = NULL;
@@ -1079,13 +1119,13 @@ gpg_ctx_op_step (struct _GpgCtx *gpg, CamelException *ex)
if (gpg->diagnostics->len) {
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed to GPG %s message: %s\n\n%.*s"),
+ _("Failed to GPG %s: %s\n\n%.*s"),
mode, g_strerror (errno),
gpg->diagnostics->len,
gpg->diagnostics->data);
} else {
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed to GPG %s message: %s\n"),
+ _("Failed to GPG %s: %s\n"),
mode, g_strerror (errno));
}
@@ -1475,3 +1515,97 @@ gpg_decrypt (CamelCipherContext *context, CamelStream *istream,
return 0;
}
+
+static int
+gpg_import_keys (CamelCipherContext *context, CamelStream *istream, CamelException *ex)
+{
+ struct _GpgCtx *gpg;
+
+ gpg = gpg_ctx_new (context->session);
+ gpg_ctx_set_mode (gpg, GPG_CTX_MODE_IMPORT);
+ gpg_ctx_set_istream (gpg, istream);
+
+ if (gpg_ctx_op_start (gpg) == -1) {
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
+ _("Failed to execute gpg: %s"),
+ errno ? g_strerror (errno) : _("Unknown"));
+ gpg_ctx_free (gpg);
+
+ return -1;
+ }
+
+ while (!gpg_ctx_op_complete (gpg)) {
+ if (gpg_ctx_op_step (gpg, ex) == -1) {
+ gpg_ctx_op_cancel (gpg);
+ gpg_ctx_free (gpg);
+
+ return -1;
+ }
+ }
+
+ if (gpg_ctx_op_wait (gpg) != 0) {
+ char *diagnostics;
+
+ diagnostics = gpg_ctx_get_diagnostics (gpg);
+ camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, diagnostics);
+ g_free (diagnostics);
+
+ gpg_ctx_free (gpg);
+
+ return -1;
+ }
+
+ gpg_ctx_free (gpg);
+
+ return 0;
+}
+
+static int
+gpg_export_keys (CamelCipherContext *context, GPtrArray *keys, CamelStream *ostream, CamelException *ex)
+{
+ struct _GpgCtx *gpg;
+ int i;
+
+ gpg = gpg_ctx_new (context->session);
+ gpg_ctx_set_mode (gpg, GPG_CTX_MODE_EXPORT);
+ gpg_ctx_set_armor (gpg, TRUE);
+ gpg_ctx_set_ostream (gpg, ostream);
+
+ for (i = 0; i < keys->len; i++) {
+ gpg_ctx_add_recipient (gpg, keys->pdata[i]);
+ }
+
+ if (gpg_ctx_op_start (gpg) == -1) {
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
+ _("Failed to execute gpg: %s"),
+ errno ? g_strerror (errno) : _("Unknown"));
+ gpg_ctx_free (gpg);
+
+ return -1;
+ }
+
+ while (!gpg_ctx_op_complete (gpg)) {
+ if (gpg_ctx_op_step (gpg, ex) == -1) {
+ gpg_ctx_op_cancel (gpg);
+ gpg_ctx_free (gpg);
+
+ return -1;
+ }
+ }
+
+ if (gpg_ctx_op_wait (gpg) != 0) {
+ char *diagnostics;
+
+ diagnostics = gpg_ctx_get_diagnostics (gpg);
+ camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, diagnostics);
+ g_free (diagnostics);
+
+ gpg_ctx_free (gpg);
+
+ return -1;
+ }
+
+ gpg_ctx_free (gpg);
+
+ return 0;
+}
diff --git a/camel/camel-gpg-context.h b/camel/camel-gpg-context.h
index 6a2f56f304..0d98fed75d 100644
--- a/camel/camel-gpg-context.h
+++ b/camel/camel-gpg-context.h
@@ -62,4 +62,3 @@ void camel_gpg_context_set_always_trust (CamelGpgContext *ctx, gboolean trust);
#endif /* __cplusplus */
#endif /* __CAMEL_GPG_CONTEXT_H__ */
-