aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/rfc822
diff options
context:
space:
mode:
authorGravatar Hoa V. DINH <dinh.viet.hoa@gmail.com>2014-09-23 22:20:51 -0700
committerGravatar Hoa V. DINH <dinh.viet.hoa@gmail.com>2014-09-23 22:21:12 -0700
commitb6da8d0ff12a4d5f4fe271e820249a957e9381e9 (patch)
tree8f5f50bcd89499eb44e278d030a757d90f81a10c /src/core/rfc822
parent1e02942c98780dbfb69940f525d8c56cf4be477d (diff)
Provided helpers for OpenPGP encryption and signature
Diffstat (limited to 'src/core/rfc822')
-rw-r--r--src/core/rfc822/MCMessageBuilder.cc171
-rw-r--r--src/core/rfc822/MCMessageBuilder.h4
2 files changed, 155 insertions, 20 deletions
diff --git a/src/core/rfc822/MCMessageBuilder.cc b/src/core/rfc822/MCMessageBuilder.cc
index 933a022b..b81daed8 100644
--- a/src/core/rfc822/MCMessageBuilder.cc
+++ b/src/core/rfc822/MCMessageBuilder.cc
@@ -37,6 +37,28 @@ static struct mailmime * get_multipart_related(const char * boundary_prefix)
return mime;
}
+static struct mailmime * get_multipart_signed_pgp(const char * boundary_prefix)
+{
+ struct mailmime * mime;
+
+ mime = part_multiple_new("multipart/signed", boundary_prefix);
+ struct mailmime_parameter * param = mailmime_param_new_with_data((char *) "protocol", (char *) "application/pgp-signature");
+ clist_append(mime->mm_content_type->ct_parameters, param);
+
+ return mime;
+}
+
+static struct mailmime * get_multipart_encrypted_pgp(const char * boundary_prefix)
+{
+ struct mailmime * mime;
+
+ mime = part_multiple_new("multipart/encrypted", boundary_prefix);
+ struct mailmime_parameter * param = mailmime_param_new_with_data((char *) "protocol", (char *) "application/pgp-encrypted");
+ clist_append(mime->mm_content_type->ct_parameters, param);
+
+ return mime;
+}
+
static int add_attachment(struct mailmime * mime,
struct mailmime * mime_sub,
const char * boundary_prefix)
@@ -662,43 +684,39 @@ String * MessageBuilder::boundaryPrefix()
return mBoundaryPrefix;
}
-Data * MessageBuilder::dataAndFilterBccAndForEncryption(bool filterBcc, bool forEncryption)
+struct mailmime * MessageBuilder::mimeAndFilterBccAndForEncryption(bool filterBcc, bool forEncryption)
{
- Data * data;
- MMAPString * str;
- int col;
-
struct mailmime * htmlPart;
struct mailmime * textPart;
struct mailmime * altPart;
struct mailmime * mainPart;
-
+
htmlPart = NULL;
textPart = NULL;
altPart = NULL;
mainPart = NULL;
-
+
if (htmlBody() != NULL) {
Attachment * htmlAttachment;
-
+
htmlAttachment = Attachment::attachmentWithHTMLString(htmlBody());
htmlPart = multipart_related_from_attachments(htmlAttachment, mRelatedAttachments,
- MCUTF8(mBoundaryPrefix), forEncryption);
+ MCUTF8(mBoundaryPrefix), forEncryption);
}
-
+
if (textBody() != NULL) {
Attachment * textAttachment;
-
+
textAttachment = Attachment::attachmentWithText(textBody());
textPart = mime_from_attachment(textAttachment, forEncryption);
}
else if (htmlBody() != NULL) {
Attachment * textAttachment;
-
+
textAttachment = Attachment::attachmentWithText(htmlBody()->flattenHTML());
textPart = mime_from_attachment(textAttachment, forEncryption);
}
-
+
if ((textPart != NULL) && (htmlPart != NULL)) {
altPart = get_multipart_alternative(MCUTF8(mBoundaryPrefix));
mailmime_smart_add_part(altPart, textPart);
@@ -711,38 +729,55 @@ Data * MessageBuilder::dataAndFilterBccAndForEncryption(bool filterBcc, bool for
else if (htmlPart != NULL) {
mainPart = htmlPart;
}
-
+
struct mailimf_fields * fields;
unsigned int i;
struct mailmime * mime;
-
+
fields = header()->createIMFFieldsAndFilterBcc(filterBcc);
-
+
mime = mailmime_new_message_data(NULL);
mailmime_set_imf_fields(mime, fields);
-
+
if (mainPart != NULL) {
add_attachment(mime, mainPart, MCUTF8(mBoundaryPrefix));
}
-
+
if (attachments() != NULL) {
for(i = 0 ; i < attachments()->count() ; i ++) {
Attachment * attachment;
struct mailmime * submime;
-
+
attachment = (Attachment *) attachments()->objectAtIndex(i);
submime = mime_from_attachment(attachment, forEncryption);
add_attachment(mime, submime, MCUTF8(mBoundaryPrefix));
}
}
+ struct mailmime * result = mime;
+ if (forEncryption) {
+ result = mime->mm_data.mm_message.mm_msg_mime;
+ mime->mm_data.mm_message.mm_msg_mime = NULL;
+ mailmime_free(mime);
+ }
+
+ return result;
+}
+
+Data * MessageBuilder::dataAndFilterBccAndForEncryption(bool filterBcc, bool forEncryption)
+{
+ Data * data;
+ MMAPString * str;
+ int col;
+
str = mmap_string_new("");
col = 0;
+ struct mailmime * mime = mimeAndFilterBccAndForEncryption(filterBcc, forEncryption);
mailmime_write_mem(str, &col, mime);
data = Data::dataWithBytes(str->str, (unsigned int) str->len);
mmap_string_free(str);
mailmime_free(mime);
-
+
return data;
}
@@ -780,3 +815,99 @@ String * MessageBuilder::plainTextBodyRendering(bool stripWhitespace)
return message->plainTextBodyRendering(stripWhitespace);
}
+struct mailmime * get_signature_part(Data * signature)
+{
+ struct mailmime * mime;
+ struct mailmime_content * content;
+
+ content = mailmime_content_new_with_str("application/pgp-signature");
+ struct mailmime_fields * mime_fields = mailmime_fields_new_empty();
+ mime = part_new_empty(content, mime_fields, NULL, 1);
+ mailmime_set_body_text(mime, signature->bytes(), signature->length());
+
+ return mime;
+}
+
+Data * MessageBuilder::openPGPSignedMessageDataWithSignatureData(Data * signature)
+{
+ struct mailimf_fields * fields;
+ struct mailmime * mime;
+
+ fields = header()->createIMFFieldsAndFilterBcc(false);
+
+ mime = mailmime_new_message_data(NULL);
+ mailmime_set_imf_fields(mime, fields);
+
+ struct mailmime * multipart = get_multipart_signed_pgp(MCUTF8(boundaryPrefix()));
+ add_attachment(mime, multipart, MCUTF8(boundaryPrefix()));
+ struct mailmime * part_to_sign = mimeAndFilterBccAndForEncryption(false, true);
+ add_attachment(multipart, part_to_sign, MCUTF8(boundaryPrefix()));
+ struct mailmime * signature_part = get_signature_part(signature);
+ add_attachment(multipart, signature_part, MCUTF8(boundaryPrefix()));
+
+ MMAPString * str = mmap_string_new("");
+ int col = 0;
+
+ mailmime_write_mem(str, &col, mime);
+ Data * data = Data::dataWithBytes(str->str, (unsigned int) str->len);
+ mmap_string_free(str);
+ mailmime_free(mime);
+
+ return data;
+}
+
+static struct mailmime * get_pgp_version_part(void)
+{
+ struct mailmime * mime;
+ struct mailmime_content * content;
+
+ content = mailmime_content_new_with_str("application/pgp-encrypted");
+ struct mailmime_fields * mime_fields = mailmime_fields_new_empty();
+ mime = part_new_empty(content, mime_fields, NULL, 1);
+ const char * version = "Version: 1\r\n";
+ mailmime_set_body_text(mime, (char *) version, strlen(version));
+
+ return mime;
+}
+
+static struct mailmime * get_encrypted_part(Data * encryptedData)
+{
+ struct mailmime * mime;
+ struct mailmime_content * content;
+
+ content = mailmime_content_new_with_str("application/octet-stream");
+ struct mailmime_fields * mime_fields = mailmime_fields_new_empty();
+ mime = part_new_empty(content, mime_fields, NULL, 1);
+ mailmime_set_body_text(mime, encryptedData->bytes(), encryptedData->length());
+
+ return mime;
+}
+
+Data * MessageBuilder::openPGPEncryptedMessageDataWithEncryptedData(Data * encryptedData)
+{
+ struct mailimf_fields * fields;
+ struct mailmime * mime;
+
+ fields = header()->createIMFFieldsAndFilterBcc(false);
+
+ mime = mailmime_new_message_data(NULL);
+ mailmime_set_imf_fields(mime, fields);
+
+ struct mailmime * multipart = get_multipart_encrypted_pgp(MCUTF8(boundaryPrefix()));
+ add_attachment(mime, multipart, MCUTF8(boundaryPrefix()));
+
+ struct mailmime * version_part = get_pgp_version_part();
+ add_attachment(multipart, version_part, MCUTF8(boundaryPrefix()));
+ struct mailmime * encrypted_part = get_encrypted_part(encryptedData);
+ add_attachment(multipart, encrypted_part, MCUTF8(boundaryPrefix()));
+
+ MMAPString * str = mmap_string_new("");
+ int col = 0;
+
+ mailmime_write_mem(str, &col, mime);
+ Data * data = Data::dataWithBytes(str->str, (unsigned int) str->len);
+ mmap_string_free(str);
+ mailmime_free(mime);
+
+ return data;
+}
diff --git a/src/core/rfc822/MCMessageBuilder.h b/src/core/rfc822/MCMessageBuilder.h
index d3b32a4f..482fe07c 100644
--- a/src/core/rfc822/MCMessageBuilder.h
+++ b/src/core/rfc822/MCMessageBuilder.h
@@ -47,6 +47,9 @@ namespace mailcore {
virtual String * plainTextRendering();
virtual String * plainTextBodyRendering(bool stripWhitespace);
+ virtual Data * openPGPSignedMessageDataWithSignatureData(Data * signature);
+ virtual Data * openPGPEncryptedMessageDataWithEncryptedData(Data * encryptedData);
+
public: // subclass behavior
MessageBuilder(MessageBuilder * other);
virtual String * description();
@@ -60,6 +63,7 @@ namespace mailcore {
String * mBoundaryPrefix;
void init();
Data * dataAndFilterBccAndForEncryption(bool filterBcc, bool forEncryption);
+ struct mailmime * mimeAndFilterBccAndForEncryption(bool filterBcc, bool forEncryption);
};
};