aboutsummaryrefslogtreecommitdiffstats
path: root/camel
diff options
context:
space:
mode:
Diffstat (limited to 'camel')
-rw-r--r--camel/ChangeLog20
-rw-r--r--camel/camel-cipher-context.c86
-rw-r--r--camel/camel-cipher-context.h7
-rw-r--r--camel/camel-gpg-context.c102
-rw-r--r--camel/camel-multipart-encrypted.c6
-rw-r--r--camel/camel-multipart-signed.c4
-rw-r--r--camel/camel-smime-context.c165
-rw-r--r--camel/camel-smime-context.h8
8 files changed, 291 insertions, 107 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index d5c01bbca9..a1d59ee9e1 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,3 +1,23 @@
+2003-11-05 Not Zed <NotZed@Ximian.com>
+
+ * camel-smime-context.c (camel_smime_context_describe_part): new
+ (unfinished) api to peek inside smime parts to tell us whats in
+ it.
+
+2003-11-03 Not Zed <NotZed@Ximian.com>
+
+ * camel-gpg-context.c (gpg_encrypt): Make this output the
+ full multipart/encrypted part, not just the encrypted content part.
+
+ * camel-cipher-context.c (camel_cipher_sign): change to output
+ full mime part, not just a stream.
+ (camel_cipher_canonical_to_stream): utility function to
+ canonicalise a mimepart to a stream.
+
+ * camel-smime-context.c (sm_encode_cmsmessage): removed.
+ (sm_sign): change interface to output a full mime-part, not just a
+ part of a mime part in multipart/signed mode.
+
2003-11-04 Jeffrey Stedfast <fejj@ximian.com>
* camel-gpg-context.c (gpg_ctx_parse_status): We might need to
diff --git a/camel/camel-cipher-context.c b/camel/camel-cipher-context.c
index 212c0fb98c..dff60c25aa 100644
--- a/camel/camel-cipher-context.c
+++ b/camel/camel-cipher-context.c
@@ -30,6 +30,13 @@
#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);
@@ -86,7 +93,7 @@ camel_cipher_context_construct (CamelCipherContext *context, CamelSession *sessi
static int
cipher_sign (CamelCipherContext *ctx, const char *userid, CamelCipherHash hash,
- struct _CamelStream *istream, struct _CamelMimePart *sigpart, CamelException *ex)
+ struct _CamelMimePart *ipart, struct _CamelMimePart *opart, CamelException *ex)
{
camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM,
_("Signing is not supported by this cipher"));
@@ -98,17 +105,18 @@ cipher_sign (CamelCipherContext *ctx, const char *userid, CamelCipherHash hash,
* @context: Cipher Context
* @userid: private key to use to sign the stream
* @hash: preferred Message-Integrity-Check hash algorithm
- * @istream: input stream
- * @sigpart: output signature part.
+ * @ipart: Input part.
+ * @opart: output part.
* @ex: exception
*
- * Signs the input stream and writes the resulting signature to output @sigpart.
+ * 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 _CamelStream *istream, struct _CamelMimePart *sigpart, CamelException *ex)
+ struct _CamelMimePart *ipart, struct _CamelMimePart *opart, CamelException *ex)
{
int retval;
@@ -116,7 +124,7 @@ camel_cipher_sign (CamelCipherContext *context, const char *userid, CamelCipherH
CIPHER_LOCK(context);
- retval = CCC_CLASS (context)->sign (context, userid, hash, istream, sigpart, ex);
+ retval = CCC_CLASS (context)->sign (context, userid, hash, ipart, opart, ex);
CIPHER_UNLOCK(context);
@@ -468,3 +476,69 @@ camel_cipher_context_get_type (void)
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.
+ * @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, CamelStream *ostream)
+{
+ CamelStreamFilter *filter;
+ CamelMimeFilter *canon;
+ int res = -1;
+
+ cc_prepare_sign(part);
+
+ filter = camel_stream_filter_new_with_stream(ostream);
+ canon = camel_mime_filter_canon_new(CAMEL_MIME_FILTER_CANON_STRIP|CAMEL_MIME_FILTER_CANON_CRLF|CAMEL_MIME_FILTER_CANON_FROM);
+ 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;
+}
diff --git a/camel/camel-cipher-context.h b/camel/camel-cipher-context.h
index 5d9218b83e..db83e92438 100644
--- a/camel/camel-cipher-context.h
+++ b/camel/camel-cipher-context.h
@@ -71,7 +71,7 @@ typedef struct _CamelCipherContextClass {
const char * (*hash_to_id)(CamelCipherContext *context, CamelCipherHash hash);
int (*sign) (CamelCipherContext *context, const char *userid, CamelCipherHash hash,
- struct _CamelStream *istream, struct _CamelMimePart *sigpart, CamelException *ex);
+ struct _CamelMimePart *ipart, struct _CamelMimePart *opart, CamelException *ex);
CamelCipherValidity * (*verify) (CamelCipherContext *context, CamelCipherHash hash,
struct _CamelStream *istream, struct _CamelMimePart *sigpart,
@@ -107,7 +107,7 @@ const char * camel_cipher_hash_to_id (CamelCipherContext *context, CamelCip
/* cipher routines */
int camel_cipher_sign (CamelCipherContext *context, const char *userid, CamelCipherHash hash,
- struct _CamelStream *istream, struct _CamelMimePart *sigpart, CamelException *ex);
+ struct _CamelMimePart *ipart, struct _CamelMimePart *opart, CamelException *ex);
CamelCipherValidity *camel_cipher_verify (CamelCipherContext *context, CamelCipherHash hash,
struct _CamelStream *istream, struct _CamelMimePart *sigpart,
CamelException *ex);
@@ -132,6 +132,9 @@ void camel_cipher_validity_set_description (CamelCipherValidity
void camel_cipher_validity_clear (CamelCipherValidity *validity);
void camel_cipher_validity_free (CamelCipherValidity *validity);
+/* utility functions */
+int camel_cipher_canonical_to_stream(CamelMimePart *part, CamelStream *ostream);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/camel/camel-gpg-context.c b/camel/camel-gpg-context.c
index ea27ac2926..a3b158d943 100644
--- a/camel/camel-gpg-context.c
+++ b/camel/camel-gpg-context.c
@@ -52,6 +52,9 @@
#include "camel-mime-part.h"
#include "camel-mime-filter-canon.h"
+#include "camel-multipart-signed.h"
+#include "camel-multipart-encrypted.h"
+
#define d(x)
static CamelCipherContextClass *parent_class = NULL;
@@ -1209,14 +1212,26 @@ gpg_ctx_op_wait (struct _GpgCtx *gpg)
static int
-gpg_sign (CamelCipherContext *context, const char *userid, CamelCipherHash hash,
- CamelStream *istream, CamelMimePart *sigpart, CamelException *ex)
+gpg_sign (CamelCipherContext *context, const char *userid, CamelCipherHash hash, CamelMimePart *ipart, CamelMimePart *opart, CamelException *ex)
{
struct _GpgCtx *gpg;
- CamelStream *ostream = camel_stream_mem_new();
+ CamelStream *ostream = camel_stream_mem_new(), *istream;
CamelDataWrapper *dw;
CamelContentType *ct;
int res = -1;
+ CamelMimePart *sigpart;
+ CamelMultipartSigned *mps;
+
+ /* Note: see rfc2015 or rfc3156, section 5 */
+
+ /* FIXME: stream this, we stream output at least */
+ /*prepare_sign(content);*/
+ istream = camel_stream_mem_new();
+ if (camel_cipher_canonical_to_stream(ipart, istream) == -1) {
+ camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
+ _("Could not generate signing data: %s"), g_strerror(errno));
+ goto fail;
+ }
gpg = gpg_ctx_new (context->session);
gpg_ctx_set_mode (gpg, GPG_CTX_MODE_SIGN);
@@ -1262,6 +1277,7 @@ gpg_sign (CamelCipherContext *context, const char *userid, CamelCipherHash hash,
camel_stream_reset(ostream);
camel_data_wrapper_construct_from_stream(dw, ostream);
+ sigpart = camel_mime_part_new();
ct = camel_content_type_new("application", "pgp-signature");
camel_content_type_set_param(ct, "name", "signature.asc");
camel_data_wrapper_set_mime_type_field(dw, ct);
@@ -1269,8 +1285,23 @@ gpg_sign (CamelCipherContext *context, const char *userid, CamelCipherHash hash,
camel_medium_set_content_object((CamelMedium *)sigpart, dw);
camel_object_unref(dw);
+
camel_mime_part_set_description(sigpart, _("This is a digitally signed message part"));
+ 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, "protocol", context->sign_protocol);
+ camel_data_wrapper_set_mime_type_field((CamelDataWrapper *)mps, ct);
+ camel_content_type_unref(ct);
+ camel_multipart_set_boundary((CamelMultipart *)mps, NULL);
+
+ mps->signature = sigpart;
+ mps->contentraw = istream;
+ camel_stream_reset(istream);
+ camel_object_ref(istream);
+
+ camel_medium_set_content_object((CamelMedium *)opart, (CamelDataWrapper *)mps);
fail:
camel_object_unref(ostream);
gpg_ctx_free (gpg);
@@ -1397,33 +1428,25 @@ gpg_encrypt (CamelCipherContext *context, const char *userid, GPtrArray *recipie
CamelGpgContext *ctx = (CamelGpgContext *) context;
struct _GpgCtx *gpg;
int i, res = -1;
- CamelStream *istream, *filtered_stream, *ostream;
- CamelMimeFilter *filter;
+ CamelStream *istream, *ostream, *vstream;
+ CamelMimePart *encpart, *verpart;
CamelDataWrapper *dw;
CamelContentType *ct;
+ CamelMultipartEncrypted *mpe;
ostream = camel_stream_mem_new();
-
- /* TODO: Should this just return a mimepart with an embedded multipart-encrypted? */
-
- /* Canonicalise the input */
- /* FIXME: Move this to a common routine */
istream = camel_stream_mem_new();
- filtered_stream = (CamelStream *)camel_stream_filter_new_with_stream(istream);
- filter = camel_mime_filter_canon_new(CAMEL_MIME_FILTER_CANON_CRLF);
- camel_stream_filter_add((CamelStreamFilter *)filtered_stream, filter);
- camel_object_unref(filter);
- camel_data_wrapper_write_to_stream((CamelDataWrapper *)ipart, filtered_stream);
- camel_stream_flush(filtered_stream);
- camel_object_unref(filtered_stream);
- camel_stream_reset(istream);
+ if (camel_cipher_canonical_to_stream(ipart, istream) == -1) {
+ camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
+ _("Could not generate encrypting data: %s"), g_strerror(errno));
+ goto fail1;
+ }
gpg = gpg_ctx_new (context->session);
gpg_ctx_set_mode (gpg, GPG_CTX_MODE_ENCRYPT);
gpg_ctx_set_armor (gpg, TRUE);
gpg_ctx_set_userid (gpg, userid);
gpg_ctx_set_istream (gpg, istream);
- camel_object_unref(istream);
gpg_ctx_set_ostream (gpg, ostream);
gpg_ctx_set_always_trust (gpg, ctx->always_trust);
@@ -1462,17 +1485,52 @@ gpg_encrypt (CamelCipherContext *context, const char *userid, GPtrArray *recipie
res = 0;
dw = camel_data_wrapper_new();
+ camel_data_wrapper_construct_from_stream(dw, ostream);
+
+ encpart = camel_mime_part_new();
ct = camel_content_type_new("application", "octet-stream");
camel_content_type_set_param(ct, "name", "encrypted.asc");
camel_data_wrapper_set_mime_type_field(dw, ct);
camel_content_type_unref(ct);
- camel_data_wrapper_construct_from_stream(dw, ostream);
- camel_medium_set_content_object((CamelMedium *)opart, dw);
+
+ camel_medium_set_content_object((CamelMedium *)encpart, dw);
camel_object_unref(dw);
+ camel_mime_part_set_description(encpart, _("This is a digitally encrypted message part"));
+
+ vstream = camel_stream_mem_new();
+ camel_stream_write(vstream, "Version: 1\n", strlen("Version: 1\n"));
+ camel_stream_reset(vstream);
+
+ verpart = camel_mime_part_new();
+ dw = camel_data_wrapper_new();
+ camel_data_wrapper_set_mime_type(dw, context->encrypt_protocol);
+ camel_data_wrapper_construct_from_stream(dw, vstream);
+ camel_object_unref(vstream);
+ camel_medium_set_content_object((CamelMedium *)verpart, dw);
+ camel_object_unref(dw);
+
+ mpe = camel_multipart_encrypted_new();
+ ct = camel_content_type_new("multipart", "encrypted");
+ camel_content_type_set_param(ct, "protocol", context->sign_protocol);
+ camel_data_wrapper_set_mime_type_field((CamelDataWrapper *)mpe, ct);
+ camel_content_type_unref(ct);
+ camel_multipart_set_boundary((CamelMultipart *)mpe, NULL);
+
+ mpe->decrypted = ipart;
+ camel_object_ref(ipart);
+
+ camel_multipart_add_part((CamelMultipart *)mpe, verpart);
+ camel_object_unref(verpart);
+ camel_multipart_add_part((CamelMultipart *)mpe, encpart);
+ camel_object_unref(encpart);
+
+ camel_medium_set_content_object((CamelMedium *)opart, (CamelDataWrapper *)mpe);
fail:
- camel_object_unref(ostream);
gpg_ctx_free(gpg);
+fail1:
+ camel_object_unref(istream);
+ camel_object_unref(ostream);
return res;
}
diff --git a/camel/camel-multipart-encrypted.c b/camel/camel-multipart-encrypted.c
index d906ae80fc..2dfe3b4914 100644
--- a/camel/camel-multipart-encrypted.c
+++ b/camel/camel-multipart-encrypted.c
@@ -142,6 +142,9 @@ camel_multipart_encrypted_encrypt (CamelMultipartEncrypted *mpe, CamelMimePart *
CamelCipherContext *cipher, const char *userid,
GPtrArray *recipients, CamelException *ex)
{
+ abort();
+
+#if 0
CamelMimePart *version_part, *encrypted_part;
CamelContentType *mime_type;
CamelDataWrapper *wrapper;
@@ -189,7 +192,8 @@ camel_multipart_encrypted_encrypt (CamelMultipartEncrypted *mpe, CamelMimePart *
camel_data_wrapper_set_mime_type_field (CAMEL_DATA_WRAPPER (mpe), mime_type);
camel_content_type_unref (mime_type);
camel_multipart_set_boundary ((CamelMultipart *) mpe, NULL);
-
+#endif
+
return 0;
}
diff --git a/camel/camel-multipart-signed.c b/camel/camel-multipart-signed.c
index bc5e363c8d..2647ba6591 100644
--- a/camel/camel-multipart-signed.c
+++ b/camel/camel-multipart-signed.c
@@ -592,6 +592,8 @@ prepare_sign(CamelMimePart *mime_part)
int
camel_multipart_signed_sign(CamelMultipartSigned *mps, CamelCipherContext *context, CamelMimePart *content, const char *userid, CamelCipherHash hash, CamelException *ex)
{
+ abort();
+#if 0
CamelMimeFilter *canon_filter;
CamelStream *mem;
CamelStreamFilter *filter;
@@ -649,7 +651,7 @@ camel_multipart_signed_sign(CamelMultipartSigned *mps, CamelCipherContext *conte
camel_object_unref((CamelObject *) ((CamelDataWrapper *)mps)->stream);
((CamelDataWrapper *)mps)->stream = NULL;
}
-
+#endif
return 0;
}
diff --git a/camel/camel-smime-context.c b/camel/camel-smime-context.c
index 9fad5a1f11..75cbba9e2b 100644
--- a/camel/camel-smime-context.c
+++ b/camel/camel-smime-context.c
@@ -39,11 +39,14 @@
#include <pkcs11t.h>
#include <pk11func.h>
+#include <errno.h>
+
#include <camel/camel-exception.h>
#include <camel/camel-stream-mem.h>
#include <camel/camel-data-wrapper.h>
#include <camel/camel-mime-part.h>
+#include <camel/camel-multipart-signed.h>
#include <camel/camel-stream-fs.h>
#include <camel/camel-stream-filter.h>
#include <camel/camel-mime-filter-basic.h>
@@ -105,6 +108,12 @@ camel_smime_context_set_sign_mode(CamelSMIMEContext *context, camel_smime_sign_t
context->priv->sign_mode = type;
}
+guint32
+camel_smime_context_describe_part(CamelSMIMEContext *context, CamelMimePart *part)
+{
+ return 0;
+}
+
static const char *
sm_hash_to_id(CamelCipherContext *context, CamelCipherHash hash)
{
@@ -307,13 +316,44 @@ fail:
}
static int
-sm_encode_cmsmessage(CamelSMIMEContext *context, NSSCMSMessage *cmsg, CamelStream *instream, CamelStream *out, CamelException *ex)
+sm_sign(CamelCipherContext *context, const char *userid, CamelCipherHash hash, CamelMimePart *ipart, CamelMimePart *opart, CamelException *ex)
{
+ int res = -1;
+ NSSCMSMessage *cmsg;
+ CamelStream *ostream, *istream;
+ SECOidTag sechash;
NSSCMSEncoderContext *enc;
- CamelStreamMem *mem = NULL;
+ CamelDataWrapper *dw;
+ CamelContentType *ct;
+
+ switch (hash) {
+ case CAMEL_CIPHER_HASH_SHA1:
+ case CAMEL_CIPHER_HASH_DEFAULT:
+ default:
+ sechash = SEC_OID_SHA1;
+ break;
+ case CAMEL_CIPHER_HASH_MD5:
+ sechash = SEC_OID_MD5;
+ break;
+ }
+
+ cmsg = sm_signing_cmsmessage((CamelSMIMEContext *)context, userid, sechash,
+ ((CamelSMIMEContext *)context)->priv->sign_mode == CAMEL_SMIME_SIGN_CLEARSIGN, ex);
+ if (cmsg == NULL)
+ return -1;
+
+ ostream = camel_stream_mem_new();
+
+ /* FIXME: stream this, we stream output at least */
+ istream = camel_stream_mem_new();
+ if (camel_cipher_canonical_to_stream(ipart, istream) == -1) {
+ camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
+ _("Could not generate signing data: %s"), g_strerror(errno));
+ goto fail;
+ }
enc = NSS_CMSEncoder_Start(cmsg,
- sm_write_stream, out, /* DER output callback */
+ sm_write_stream, ostream, /* DER output callback */
NULL, NULL, /* destination storage */
sm_get_passwd, context, /* password callback */
NULL, NULL, /* decrypt key callback */
@@ -323,13 +363,7 @@ sm_encode_cmsmessage(CamelSMIMEContext *context, NSSCMSMessage *cmsg, CamelStrea
goto fail;
}
- /* Note: see rfc2015 or rfc3156, section 5 */
-
- /* FIXME: stream this, we stream output at least */
- mem = (CamelStreamMem *)camel_stream_mem_new();
- camel_stream_write_to_stream(instream, (CamelStream *)mem);
-
- if (NSS_CMSEncoder_Update(enc, mem->buffer->data, mem->buffer->len) != SECSuccess) {
+ if (NSS_CMSEncoder_Update(enc, ((CamelStreamMem *)istream)->buffer->data, ((CamelStreamMem *)istream)->buffer->len) != SECSuccess) {
NSS_CMSEncoder_Cancel(enc);
camel_exception_setv(ex, 1, "Failed to add data to CMS encoder");
goto fail;
@@ -340,81 +374,62 @@ sm_encode_cmsmessage(CamelSMIMEContext *context, NSSCMSMessage *cmsg, CamelStrea
goto fail;
}
- camel_object_unref(mem);
-
- return 0;
-
-fail:
- if (mem)
- camel_object_unref(mem);
+ res = 0;
- return -1;
-}
-
-static int
-sm_sign(CamelCipherContext *ctx, const char *userid, CamelCipherHash hash, CamelStream *istream, CamelMimePart *sigpart, CamelException *ex)
-{
- int res;
- NSSCMSMessage *cmsg;
- CamelStream *ostream;
- SECOidTag sechash;
-
- switch (hash) {
- case CAMEL_CIPHER_HASH_SHA1:
- case CAMEL_CIPHER_HASH_DEFAULT:
- default:
- sechash = SEC_OID_SHA1;
- break;
- case CAMEL_CIPHER_HASH_MD5:
- sechash = SEC_OID_MD5;
- break;
- }
-
- cmsg = sm_signing_cmsmessage((CamelSMIMEContext *)ctx, userid, sechash,
- ((CamelSMIMEContext *)ctx)->priv->sign_mode == CAMEL_SMIME_SIGN_CLEARSIGN, ex);
- if (cmsg == NULL)
- return -1;
-
- ostream = camel_stream_mem_new();
- res = sm_encode_cmsmessage((CamelSMIMEContext *)ctx, cmsg, istream, ostream, ex);
- NSS_CMSMessage_Destroy(cmsg);
-
- if (res == 0) {
- CamelDataWrapper *dw;
- CamelContentType *ct;
+ dw = camel_data_wrapper_new();
+ camel_stream_reset(ostream);
+ camel_data_wrapper_construct_from_stream(dw, ostream);
+ dw->encoding = CAMEL_TRANSFER_ENCODING_BINARY;
- dw = camel_data_wrapper_new();
- camel_stream_reset(ostream);
- camel_data_wrapper_construct_from_stream(dw, ostream);
- dw->encoding = CAMEL_TRANSFER_ENCODING_BINARY;
+ if (((CamelSMIMEContext *)context)->priv->sign_mode == CAMEL_SMIME_SIGN_CLEARSIGN) {
+ CamelMultipartSigned *mps;
+ CamelMimePart *sigpart;
- if (((CamelSMIMEContext *)ctx)->priv->sign_mode == CAMEL_SMIME_SIGN_CLEARSIGN) {
- ct = camel_content_type_new("application", "x-pkcs7-signature");
- camel_content_type_set_param(ct, "name", "smime.p7s");
- camel_data_wrapper_set_mime_type_field(dw, ct);
- camel_content_type_unref(ct);
+ sigpart = camel_mime_part_new();
+ ct = camel_content_type_new("application", "x-pkcs7-signature");
+ camel_content_type_set_param(ct, "name", "smime.p7s");
+ camel_data_wrapper_set_mime_type_field(dw, ct);
+ camel_content_type_unref(ct);
- camel_mime_part_set_filename(sigpart, "smime.p7s");
- } else {
- ct = camel_content_type_new("application", "x-pkcs7-mime");
- camel_content_type_set_param(ct, "name", "smime.p7m");
- camel_content_type_set_param(ct, "smime-type", "signed-data");
- camel_data_wrapper_set_mime_type_field(dw, ct);
- camel_content_type_unref(ct);
-
- camel_mime_part_set_filename(sigpart, "smime.p7m");
- camel_mime_part_set_description(sigpart, "S/MIME Signed Message");
- }
+ camel_medium_set_content_object((CamelMedium *)sigpart, dw);
+ camel_mime_part_set_filename(sigpart, "smime.p7s");
camel_mime_part_set_disposition(sigpart, "attachment");
camel_mime_part_set_encoding(sigpart, CAMEL_TRANSFER_ENCODING_BASE64);
- camel_medium_set_content_object((CamelMedium *)sigpart, dw);
- camel_object_unref(dw);
+ 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, "protocol", context->sign_protocol);
+ camel_data_wrapper_set_mime_type_field((CamelDataWrapper *)mps, ct);
+ camel_content_type_unref(ct);
+ camel_multipart_set_boundary((CamelMultipart *)mps, NULL);
+
+ mps->signature = sigpart;
+ mps->contentraw = istream;
+ camel_stream_reset(istream);
+ camel_object_ref(istream);
+
+ camel_medium_set_content_object((CamelMedium *)opart, (CamelDataWrapper *)mps);
+ } else {
+ ct = camel_content_type_new("application", "x-pkcs7-mime");
+ camel_content_type_set_param(ct, "name", "smime.p7m");
+ camel_content_type_set_param(ct, "smime-type", "signed-data");
+ camel_data_wrapper_set_mime_type_field(dw, ct);
+ camel_content_type_unref(ct);
+
+ camel_medium_set_content_object((CamelMedium *)opart, dw);
+
+ camel_mime_part_set_filename(opart, "smime.p7m");
+ camel_mime_part_set_description(opart, "S/MIME Signed Message");
+ camel_mime_part_set_disposition(opart, "attachment");
+ camel_mime_part_set_encoding(opart, CAMEL_TRANSFER_ENCODING_BASE64);
}
-
-
+
+ camel_object_unref(dw);
+fail:
camel_object_unref(ostream);
+ camel_object_unref(istream);
return res;
}
diff --git a/camel/camel-smime-context.h b/camel/camel-smime-context.h
index a68d5e1646..f0e8d45c3b 100644
--- a/camel/camel-smime-context.h
+++ b/camel/camel-smime-context.h
@@ -41,6 +41,12 @@ typedef enum _camel_smime_sign_t {
CAMEL_SMIME_SIGN_ENVELOPED
} camel_smime_sign_t;
+typedef enum _camel_smime_describe_t {
+ CAMEL_SMIME_SIGNED = 1,
+ CAMEL_SMIME_ENCRYPTED = 2,
+ CAMEL_SMIME_CERTS = 4,
+} camel_smime_describe_t;
+
typedef struct _CamelSMIMEContext CamelSMIMEContext;
typedef struct _CamelSMIMEContextClass CamelSMIMEContextClass;
@@ -63,6 +69,8 @@ void camel_smime_context_set_encrypt_key(CamelSMIMEContext *context, gboolean us
/* set signing mode, clearsigned multipart/signed or enveloped */
void camel_smime_context_set_sign_mode(CamelSMIMEContext *context, camel_smime_sign_t type);
+guint32 camel_smime_context_describe_part(CamelSMIMEContext *, struct _CamelMimePart *);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */