4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
24 /* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ***
25 *File : email-core-smime.c
26 *Desc : MIME Operation
31 * 2011.04.14 : created
32 ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ***/
35 #include <openssl/pkcs7.h>
36 #include <openssl/pkcs12.h>
37 #include <openssl/buffer.h>
38 #include <openssl/pem.h>
39 #include <openssl/err.h>
41 #include "email-utilities.h"
42 #include "email-core-global.h"
43 #include "email-core-utils.h"
44 #include "email-core-mail.h"
45 #include "email-core-smtp.h"
46 #include "email-storage.h"
47 #include "email-core-smime.h"
48 #include "email-core-cert.h"
49 #include "email-debug-log.h"
51 /* /opt/share/cert-svc/certs is a base path */
53 #define SMIME_SIGNED_FILE "smime.p7s"
54 #define SMIME_ENCRYPT_FILE "smime.p7m"
60 /* If not present then the default digest algorithm for signing key will be used SHA1 */
61 static const EVP_MD *emcore_get_digest_algorithm(email_digest_type digest_type)
63 const EVP_MD *digest_algo = NULL;
65 switch (digest_type) {
67 digest_algo = EVP_md5();
69 case DIGEST_TYPE_SHA1:
71 digest_algo = EVP_sha1();
78 /* If not present then the default cipher algorithm for signing key will be used RC2(40) */
79 static const EVP_CIPHER *emcore_get_cipher_algorithm(email_cipher_type cipher_type)
81 const EVP_CIPHER *cipher = NULL;
83 switch (cipher_type) {
84 case CIPHER_TYPE_RC2_128 :
85 cipher = EVP_rc2_cbc();
87 case CIPHER_TYPE_RC2_64 :
88 cipher = EVP_rc2_64_cbc();
90 case CIPHER_TYPE_DES3 :
91 cipher = EVP_des_ede3_cbc();
93 case CIPHER_TYPE_DES :
94 cipher = EVP_des_cbc();
96 #ifdef __FEATURE_USE_MORE_CIPHER_TYPE__
97 case CIPHER_TYPE_SEED :
98 cipher = EVP_seed_cbc();
100 case CIPHER_TYPE_AES128 :
101 cipher = EVP_aes_128_cbc();
103 case CIPHER_TYPE_AES192 :
104 cipher = EVP_aes_192_cbc();
106 case CIPHER_TYPE_AES256 :
107 cipher = EVP_aes_256_cbc();
109 #ifndef OPENSSL_NO_CAMELLIA
110 case CIPHER_TYPE_CAMELLIA128 :
111 cipher = EVP_camellia_128_cbc();
113 case CIPHER_TYPE_CAMELLIA192 :
114 cipher = EVP_camellia_192_cbc();
116 case CIPHER_TYPE_CAMELLIA256 :
117 cipher = EVP_camellia_256_cbc();
121 case CIPHER_TYPE_RC2_40 :
123 cipher = EVP_rc2_40_cbc();
130 static int get_x509_stack_of_recipient_certs(char *recipients, STACK_OF(X509) **output_recipient_certs, int *err_code)
132 EM_DEBUG_FUNC_BEGIN("recipients : [%s], STACK_OF(X509) : [%p]", recipients, output_recipient_certs);
134 int err = EMAIL_ERROR_NONE;
137 char *temp_recipients = NULL;
140 char file_name[512] = {0, };
141 const unsigned char *in_cert = NULL;
143 X509 *x509_cert = NULL;
144 STACK_OF(X509) *temp_recipient_certs = NULL;
146 CERT_CONTEXT *context = NULL;
147 emstorage_certificate_tbl_t *cert = NULL;
149 if (!recipients || !output_recipient_certs) {
150 EM_DEBUG_EXCEPTION("Invalid parameter");
151 err = EMAIL_ERROR_INVALID_PARAM;
155 /* Initialize the variable */
156 context = cert_svc_cert_context_init();
157 temp_recipient_certs = sk_X509_new_null();
159 temp_recipients = EM_SAFE_STRDUP(recipients);
160 token = strtok_r(temp_recipients, ";", &str);
163 if (!emstorage_get_certificate_by_email_address(token, &cert, false, 0, &err)) {
164 EM_DEBUG_EXCEPTION("emstorage_get_certificate_by_email_address failed : [%d]", err);
168 SNPRINTF(file_name, sizeof(file_name), "%s", cert->filepath);
169 EM_DEBUG_LOG("file_name : [%s]", file_name);
170 err = cert_svc_load_file_to_context(context, file_name);
171 if (err != CERT_SVC_ERR_NO_ERROR) {
172 EM_DEBUG_EXCEPTION("cert_svc_load_file_to_context failed : [%d]", err);
173 err = EMAIL_ERROR_SYSTEM_FAILURE;
177 in_cert = context->certBuf->data;
178 cert_size = context->certBuf->size;
180 if (d2i_X509(&x509_cert, &in_cert, cert_size) == NULL) {
181 EM_DEBUG_EXCEPTION("d2i_X509 failed");
182 err = EMAIL_ERROR_SYSTEM_FAILURE;
186 if (!sk_X509_push(temp_recipient_certs, x509_cert)) {
187 EM_DEBUG_EXCEPTION("sk_X509_push failed");
188 err = EMAIL_ERROR_SYSTEM_FAILURE;
194 emstorage_free_certificate(&cert, 1, NULL);
196 } while ((token = strtok_r(NULL, ";", &str)));
198 *output_recipient_certs = temp_recipient_certs;
206 X509_free(x509_cert);
208 if (temp_recipient_certs)
209 sk_X509_pop_free(temp_recipient_certs, X509_free);
213 emstorage_free_certificate(&cert, 1, NULL);
215 cert_svc_cert_context_final(context);
217 EM_SAFE_FREE(temp_recipients);
225 /* Opaque signed and encrypted method */
227 static PKCS7 *opaque_signed_and_encrypt(STACK_OF(X509) *recipients_cert, X509 *signer, EVP_PKEY *private_key, BIO *mime_entity, const EVP_CIPHER *cipher, const EVP_MD *md, int flags)
229 EM_DEBUG_FUNC_BEGIN();
235 if (!(pkcs7 = PKCS7_new())) {
236 EM_DEBUG_EXCEPTION("PKCS7 malloc failed");
240 if (!PKCS7_set_type(pkcs7, NID_pkcs7_signedAndEnveloped)) {
241 EM_DEBUG_EXCEPTION("Set type failed");
245 if (!PKCS7_add_signature(pkcs7, signer, private_key, md)) {
246 EM_DEBUG_EXCEPTION("PKCS7_add_signature failed");
250 if (!PKCS7_add_certificate(pkcs7, signer)) {
251 EM_DEBUG_EXCEPTION("PKCS7_add_certificate failed");
255 for (i = 0; i < sk_X509_num(recipients_cert); i++) {
256 x509 = sk_X509_value(recipients_cert, i);
257 if (!PKCS7_add_recipient(pkcs7, x509)) {
258 EM_DEBUG_EXCEPTION("PKCS7_add_recipient failed");
263 if (!PKCS7_set_cipher(pkcs7, cipher)) {
264 EM_DEBUG_EXCEPTION("Cipher failed");
268 if (flags & PKCS7_STREAM)
271 if (PKCS7_final(pkcs7, mime_entity, flags))
280 #define SMIME_DEBUG 1
283 #define TEMP_PASSWORD_PATH "/opt/data/cert_password"
286 INTERNAL_FUNC int emcore_smime_set_signed_message(char *certificate, char *password, char *mime_entity, email_digest_type digest_type, char **file_path, int *err_code)
288 EM_DEBUG_FUNC_BEGIN("certificate path : [%s], password : [%s], mime_entity : [%s]", certificate, password, mime_entity);
289 int err, ret = false;
290 char temp_smime_filepath[512];
292 STACK_OF(X509) *other_certs = NULL;
293 EVP_PKEY *private_key = NULL;
294 const EVP_MD *digest = NULL;
295 BIO *bio_mime_entity = NULL, *bio_cert = NULL, *bio_prikey = NULL;
296 BIO *smime_attachment = NULL;
297 PKCS7 *signed_message = NULL;
298 int flags = PKCS7_DETACHED | PKCS7_PARTIAL;
300 OpenSSL_add_all_algorithms();
301 ERR_load_crypto_strings();
303 SNPRINTF(temp_smime_filepath, sizeof(temp_smime_filepath), "%s%s%s%s%s", MAILHOME, DIR_SEPERATOR, MAILTEMP, DIR_SEPERATOR, SMIME_SIGNED_FILE);
304 EM_DEBUG_LOG("attachment file path of smime : [%s]", temp_smime_filepath);
306 smime_attachment = BIO_new_file(temp_smime_filepath, OUTMODE);
307 if (!smime_attachment) {
308 EM_DEBUG_EXCEPTION("Cannot open output file %s", temp_smime_filepath);
309 err = EMAIL_ERROR_FILE_NOT_FOUND;
313 /* Load certificate for getting the certificate and private key */
314 if (!emcore_load_PFX_file(certificate, password, &private_key, &cert, &other_certs, &err)) {
315 EM_DEBUG_EXCEPTION("Load the private certificate failed : [%d]", err);
319 bio_mime_entity = BIO_new_file(mime_entity, READMODE);
320 if (!bio_mime_entity) {
321 EM_DEBUG_EXCEPTION("Cannot open file[%s]", mime_entity);
325 signed_message = PKCS7_sign(NULL, NULL, other_certs, bio_mime_entity, flags);
326 if (!signed_message) {
327 EM_DEBUG_EXCEPTION("Error creating PKCS#7 structure");
331 /* Get the digest algorithm */
332 digest = emcore_get_digest_algorithm(digest_type);
334 if (!PKCS7_sign_add_signer(signed_message, cert, private_key, digest, flags)) {
335 EM_DEBUG_EXCEPTION("PKCS7_sign_add_signer failed");
339 if (!PKCS7_final(signed_message, bio_mime_entity, flags)) {
340 EM_DEBUG_EXCEPTION("PKCS7_final failed");
344 if (!i2d_PKCS7_bio_stream(smime_attachment, signed_message, bio_mime_entity, flags)) {
345 EM_DEBUG_EXCEPTION("i2d_PKCS7_bio_stream failed");
346 err = EMAIL_ERROR_SYSTEM_FAILURE;
349 BIO_flush(smime_attachment);
353 out = BIO_new_file("/opt/data/email/.emfdata/tmp/smout.txt", "w");
357 if (!SMIME_write_PKCS7(out, signed_message, bio_mime_entity, flags))
367 *file_path = temp_smime_filepath;
370 EVP_PKEY_free(private_key);
371 PKCS7_free(signed_message);
373 BIO_free(bio_mime_entity);
375 BIO_free(bio_prikey);
376 BIO_free_all(smime_attachment);
379 if (err_code != NULL)
382 EM_DEBUG_FUNC_END("err [%d]", err);
386 INTERNAL_FUNC int emcore_smime_set_encrypt_message(char *recipient_list, char *mime_entity, email_cipher_type cipher_type, char **file_path, int *err_code)
388 EM_DEBUG_FUNC_BEGIN("certificate path : [%p], mime_entity : [%p]", recipient_list, mime_entity);
389 char temp_smime_filepath[512];
390 int err = EMAIL_ERROR_NONE, ret = false;
391 // int flags = PKCS7_DETACHED | PKCS7_STREAM;
394 CERT_CONTEXT *loaded_cert = NULL;
395 STACK_OF(X509) *recipient_certs = NULL;
397 BIO *bio_mime_entity = NULL, *bio_cert = NULL;
398 BIO *smime_attachment = NULL;
399 PKCS7 *encrypt_message = NULL;
400 const EVP_CIPHER *cipher = NULL;
402 OpenSSL_add_all_algorithms();
403 ERR_load_crypto_strings();
405 loaded_cert = cert_svc_cert_context_init();
407 SNPRINTF(temp_smime_filepath, sizeof(temp_smime_filepath), "%s%s%s%s%s", MAILHOME, DIR_SEPERATOR, MAILTEMP, DIR_SEPERATOR, SMIME_ENCRYPT_FILE);
408 EM_DEBUG_LOG("attachment file path of smime : [%s]", temp_smime_filepath);
410 smime_attachment = BIO_new_file(temp_smime_filepath, OUTMODE);
411 if (!smime_attachment) {
412 EM_DEBUG_EXCEPTION("Cannot open output file %s", temp_smime_filepath);
413 err = EMAIL_ERROR_FILE_NOT_FOUND;
417 if (!get_x509_stack_of_recipient_certs(recipient_list, &recipient_certs, &err)) {
418 EM_DEBUG_EXCEPTION("get_x509_stack_of_recipient_certs failed [%d]", err);
422 bio_mime_entity = BIO_new_file(mime_entity, READMODE);
423 if (!bio_mime_entity) {
424 EM_DEBUG_EXCEPTION("Cannot open file[%s]", mime_entity);
428 /* Get cipher algorithm */
429 cipher = emcore_get_cipher_algorithm(cipher_type);
431 encrypt_message = PKCS7_encrypt(recipient_certs, bio_mime_entity, cipher, flags);
432 if (encrypt_message == NULL) {
433 EM_DEBUG_EXCEPTION("PKCS7_encrypt failed [%ld]", ERR_get_error());
437 if (!i2d_PKCS7_bio_stream(smime_attachment, encrypt_message, bio_mime_entity, flags)) {
438 EM_DEBUG_EXCEPTION("i2d_PKCS7_bio_stream failed");
439 err = EMAIL_ERROR_SYSTEM_FAILURE;
442 BIO_flush(smime_attachment);
447 out = BIO_new_file("/opt/data/email/.emfdata/tmp/smout.txt", "w");
451 if (!SMIME_write_PKCS7(out, encrypt_message, bio_mime_entity, flags))
462 *file_path = temp_smime_filepath;
464 PKCS7_free(encrypt_message);
467 sk_X509_pop_free(recipient_certs, X509_free);
470 BIO_free(bio_mime_entity);
471 BIO_free_all(smime_attachment);
473 cert_svc_cert_context_final(loaded_cert);
475 if (err_code != NULL)
478 EM_DEBUG_FUNC_END("err [%d]", err);
482 INTERNAL_FUNC int emcore_smime_set_signed_and_encrypt_message(char *recipient_list, char *certificate, char *password, char *mime_entity, email_cipher_type cipher_type, email_digest_type digest_type, char **file_path, int *err_code)
484 EM_DEBUG_FUNC_BEGIN("certificate path : [%s], mime_entity : [%s]", recipient_list, mime_entity);
485 char temp_smime_filepath[512];
486 int err = EMAIL_ERROR_NONE, ret = false;
487 int flags = PKCS7_DETACHED | PKCS7_PARTIAL | PKCS7_STREAM;
489 STACK_OF(X509) *recipient_certs = NULL;
490 STACK_OF(X509) *other_certs = NULL;
491 BIO *bio_mime_entity = NULL, *bio_cert = NULL;
492 BIO *bio_signed_message = BIO_new(BIO_s_mem());
493 BIO *smime_attachment = NULL;
494 PKCS7 *signed_message = NULL;
495 PKCS7 *encrypt_message = NULL;
496 const EVP_CIPHER *cipher = NULL;
497 const EVP_MD *digest = NULL;
500 char *signed_string = NULL;
501 BUF_MEM *buf_mem = NULL;
503 /* Variable for private certificate */
504 EVP_PKEY *private_key = NULL;
507 OpenSSL_add_all_algorithms();
508 ERR_load_crypto_strings();
510 SNPRINTF(temp_smime_filepath, sizeof(temp_smime_filepath), "%s%s%s%s%s", MAILHOME, DIR_SEPERATOR, MAILTEMP, DIR_SEPERATOR, SMIME_ENCRYPT_FILE);
511 EM_DEBUG_LOG("attachment file path of smime : [%s]", temp_smime_filepath);
513 smime_attachment = BIO_new_file(temp_smime_filepath, OUTMODE);
514 if (!smime_attachment) {
515 EM_DEBUG_EXCEPTION("Cannot open output file %s", temp_smime_filepath);
516 err = EMAIL_ERROR_FILE_NOT_FOUND;
520 /* Signing the mail */
521 /* 1. Load the private certificate */
522 if (!emcore_load_PFX_file(certificate, password, &private_key, &cert, &other_certs, &err)) {
523 EM_DEBUG_EXCEPTION("Load the certificate failed : [%d]", err);
527 /* 2. Read mime entity */
528 bio_mime_entity = BIO_new_file(mime_entity, READMODE);
529 if (!bio_mime_entity) {
530 EM_DEBUG_EXCEPTION("Cannot open file[%s]", mime_entity);
535 signed_message = PKCS7_sign(NULL, NULL, other_certs, bio_mime_entity, flags);
536 if (!signed_message) {
537 EM_DEBUG_EXCEPTION("Error creating PKCS#7 structure");
541 /* 4. Get the digest algorithm */
542 digest = emcore_get_digest_algorithm(digest_type);
544 /* 5. Apply a digest algorithm */
545 if (!PKCS7_sign_add_signer(signed_message, cert, private_key, digest, flags)) {
546 EM_DEBUG_EXCEPTION("PKCS7_sign_add_signer failed");
550 /* 6. Create signing message */
551 if (!SMIME_write_PKCS7(bio_signed_message, signed_message, bio_mime_entity, flags | SMIME_OLDMIME | SMIME_CRLFEOL)) {
552 EM_DEBUG_EXCEPTION("SMIME_write_PKCS7 error");
557 BIO_get_mem_ptr(bio_signed_message, &buf_mem);
558 signed_string = em_malloc(buf_mem->length);
559 memcpy(signed_string, buf_mem->data, buf_mem->length-1);
560 EM_DEBUG_LOG("Signed message : [%d]", buf_mem->length);
561 EM_DEBUG_LOG("%s", signed_string);
562 EM_DEBUG_LOG("buf data: \n, %s", buf_mem->data);
563 EM_SAFE_FREE(signed_string);
566 /* Encrypting the mail */
567 /* 1. Get the recipient certs */
568 if (!get_x509_stack_of_recipient_certs(recipient_list, &recipient_certs, &err)) {
569 EM_DEBUG_EXCEPTION("get_x509_stack_of_recipient_certs failed [%d]", err);
573 /* 2. Get cipher algorithm */
574 cipher = emcore_get_cipher_algorithm(cipher_type);
578 /* 3. Encrypt the signing message */
579 encrypt_message = PKCS7_encrypt(recipient_certs, bio_signed_message, cipher, flags);
580 if (encrypt_message == NULL) {
581 EM_DEBUG_EXCEPTION("PKCS7_encrypt failed [%ld]", ERR_get_error());
585 /* 4. Write the encrypt message in file */
586 if (!i2d_PKCS7_bio_stream(smime_attachment, encrypt_message, bio_mime_entity, flags)) {
587 EM_DEBUG_EXCEPTION("i2d_PKCS7_bio_stream failed");
588 err = EMAIL_ERROR_SYSTEM_FAILURE;
591 BIO_flush(smime_attachment);
596 out = BIO_new_file("/opt/data/email/.emfdata/tmp/smout.txt", "w");
600 if (!SMIME_write_PKCS7(out, encrypt_message, bio_mime_entity, flags))
611 *file_path = temp_smime_filepath;
613 PKCS7_free(signed_message);
614 PKCS7_free(encrypt_message);
617 sk_X509_pop_free(other_certs, X509_free);
618 sk_X509_pop_free(recipient_certs, X509_free);
621 BIO_free(bio_mime_entity);
622 BIO_free(bio_signed_message);
623 BIO_free_all(smime_attachment);
626 if (err_code != NULL)
629 EM_DEBUG_FUNC_END("err [%d]", err);
635 INTERNAL_FUNC int emcore_smime_set_decrypt_message(char *encrypt_message, char *certificate, char *password, char **decrypt_message, int *err_code)
638 int err = EMAIL_ERROR_NONE;
640 char *temp_decrypt_message;
644 STACK_OF(X509) *ca = NULL;
645 EVP_PKEY *private_key = NULL;
646 BIO *bio_cert = NULL, *bio_prikey = NULL;
647 BIO *infile = NULL, *out_buf = NULL;
648 PKCS7 *p7_encrypt_message = NULL;
650 CERT_CONTEXT *loaded_cert = NULL;
652 infile = BIO_new_file(encrypt_message, INMODE);
654 p7_encrypt_message = d2i_PKCS7_bio(infile, NULL);
655 if (!p7_encrypt_message) {
656 EM_DEBUG_EXCEPTION("Error reading S/MIME message");
657 err = EMAIL_ERROR_INVALID_PARAM;
661 loaded_cert = cert_svc_cert_context_init();
663 fp = fopen(certificate, INMODE);
665 EM_DEBUG_EXCEPTION("Certificate file open failed");
669 p12 = d2i_PKCS12_fp(fp, NULL);
673 EM_DEBUG_EXCEPTION("Error reading PKCS#12 file\n");
677 if (!PKCS12_parse(p12, password, &private_key, &cert, &ca)) {
678 EM_DEBUG_EXCEPTION("PKCS12_parse failed");
682 out_buf = BIO_new(BIO_s_mem());
684 EM_DEBUG_EXCEPTION("There is not enough memory.");
685 err = EMAIL_ERROR_OUT_OF_MEMORY;
689 PKCS7_decrypt(p7_encrypt_message, private_key, cert, out_buf, 0);
690 string_len = BIO_get_mem_data(out_buf, &temp_decrypt_message);
695 *decrypt_message = temp_decrypt_message;
700 BIO_free(bio_prikey);
701 BIO_free_all(infile);
703 if (err_code != NULL)
706 cert_svc_cert_context_final(loaded_cert);
707 EM_DEBUG_FUNC_END("err [%d]", err);
712 INTERNAL_FUNC int emcore_smime_verify_signed_message(char *signed_message, char *ca_file, char *ca_path, int *verify)
718 X509_STORE *store = NULL;
719 X509_LOOKUP *lookup = NULL;
722 OpenSSL_add_all_algorithms();
723 ERR_load_crypto_strings();
725 if (BIO_write(indata, signed_message, sizeof(signed_message)) <= 0) {
726 EM_DEBUG_EXCEPTION("Char to Bio failed");
730 p7 = SMIME_read_PKCS7(indata, &content);
732 EM_DEBUG_EXCEPTION("SMIME_read_PKCS7 failed");
736 if (!(store = X509_STORE_new())) {
737 EM_DEBUG_EXCEPTION("Initialize x509_store failed");
741 lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
742 if (lookup == NULL) {
743 EM_DEBUG_EXCEPTION("Initialize lookup store failed");
748 if (!X509_LOOKUP_load_file(lookup, ca_file, X509_FILETYPE_PEM)) {
749 EM_DEBUG_EXCEPTION("X509_LOOKUP_load_file failed");
753 X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT);
756 lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
757 if (lookup == NULL) {
758 EM_DEBUG_EXCEPTION("X509_STORE_add_lookup failed");
763 if (!X509_LOOKUP_add_dir(lookup, ca_path, X509_FILETYPE_PEM)) {
764 EM_DEBUG_EXCEPTION("CA path load failed");
768 X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
771 temp_verify = PKCS7_verify(p7, NULL, store, content, NULL, 0);
773 EM_DEBUG_LOG("Verification Successful\n");
779 X509_STORE_free(store);
787 *verify = temp_verify;
795 static char *emcore_get_mime_entity(char *mime_path)
797 EM_DEBUG_FUNC_BEGIN("mime_path : [%s]", mime_path);
798 FILE *fp_read = NULL;
799 FILE *fp_write = NULL;
800 char *mime_entity = NULL;
801 char *mime_entity_path = NULL;
802 char temp_buffer[255] = {0,};
806 if (!emcore_get_temp_file_name(&mime_entity_path, &err)) {
807 EM_DEBUG_EXCEPTION(" em_core_get_temp_file_name failed[%d]", err);
811 /* get mime entity */
812 if (mime_path != NULL) {
813 fp_read = fopen(mime_path, "r");
814 if (fp_read == NULL) {
815 EM_DEBUG_EXCEPTION("File open(read) is failed : filename [%s]", mime_path);
819 fp_write = fopen(mime_entity_path, "w");
820 if (fp_write == NULL) {
821 EM_DEBUG_EXCEPTION("File open(write) is failed : filename [%s]", mime_entity_path);
825 fseek(fp_read, 0, SEEK_SET);
826 fseek(fp_write, 0, SEEK_SET);
828 while (fgets(temp_buffer, 255, fp_read) != NULL) {
829 mime_entity = strcasestr(temp_buffer, "content-type");
830 if (mime_entity != NULL && !searched)
834 EM_DEBUG_LOG("temp_buffer : %s", temp_buffer);
835 fprintf(fp_write, "%s", temp_buffer);
847 EM_SAFE_FREE(mime_entity);
848 EM_SAFE_FREE(mime_path);
851 return mime_entity_path;
854 INTERNAL_FUNC int emcore_convert_mail_data_to_smime_data(emstorage_account_tbl_t *account_tbl_item, email_mail_data_t *input_mail_data, email_attachment_data_t *input_attachment_data_list, int input_attachment_count, email_mail_data_t **output_mail_data, email_attachment_data_t **output_attachment_data_list, int *output_attachment_count)
856 EM_DEBUG_FUNC_BEGIN("input_mail_data[%p], input_attachment_data_list [%p], input_attachment_count [%d], output_mail_data [%p], output_attachment_data_list [%p]", input_mail_data, input_attachment_data_list, input_attachment_count, output_mail_data, output_attachment_data_list);
859 int err = EMAIL_ERROR_NONE;
860 int smime_type = EMAIL_SMIME_NONE;
861 int address_length = 0;
862 int attachment_count = input_attachment_count;
864 char *rfc822_file = NULL;
865 char *mime_entity = NULL;
866 char *smime_file_path = NULL;
867 char *other_certificate_list = NULL;
869 char *buf_pointer = NULL;
870 char *password = NULL;
871 char buf[81] = {0, };
874 email_attachment_data_t new_attachment_data = {0};
875 email_attachment_data_t *temp_attachment_data = NULL;
877 /* Validating parameters */
879 if (!input_mail_data || !(input_mail_data->account_id) || !(input_mail_data->mailbox_id)) {
880 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
886 fp = fopen(TEMP_PASSWORD_PATH, "r");
888 EM_DEBUG_EXCEPTION("Open failed");
889 err = EMAIL_ERROR_SYSTEM_FAILURE;
894 buf_pointer = fgets(buf, 80, fp);
899 EM_DEBUG_LOG("password : [%s], strlen : [%d]", buf, strlen(buf)-1);
900 password = em_malloc(sizeof(buf));
901 memcpy(password, buf, strlen(buf) - 1);
905 if (!emcore_make_rfc822_file(input_mail_data, input_attachment_data_list, attachment_count, &rfc822_file, &err)) {
906 EM_DEBUG_EXCEPTION("emcore_make_rfc822_file_from_mail failed [%d]", err);
910 mime_entity = emcore_get_mime_entity(rfc822_file);
912 smime_type = input_mail_data->smime_type;
914 smime_type = account_tbl_item->smime_type;
916 /* Signed and Encrypt the message */
917 switch (smime_type) {
918 case EMAIL_SMIME_SIGNED: /* Clear signed message */
919 if (!emcore_smime_set_signed_message(account_tbl_item->certificate_path, password, mime_entity, account_tbl_item->digest_type, &smime_file_path, &err)) {
920 EM_DEBUG_EXCEPTION("em_core_smime_set_clear_signed_message is failed : [%d]", err);
924 EM_DEBUG_LOG("smime_file_path : %s", smime_file_path);
925 name = strrchr(smime_file_path, '/');
927 new_attachment_data.attachment_name = EM_SAFE_STRDUP(name + 1);
928 new_attachment_data.attachment_path = EM_SAFE_STRDUP(smime_file_path);
929 new_attachment_data.attachment_size = 1;
930 new_attachment_data.save_status = 1;
932 attachment_count += 1;
935 case EMAIL_SMIME_ENCRYPTED: /* Encryption message */
936 address_length = EM_SAFE_STRLEN(input_mail_data->full_address_to) + EM_SAFE_STRLEN(input_mail_data->full_address_cc) + EM_SAFE_STRLEN(input_mail_data->full_address_bcc);
938 other_certificate_list = em_malloc(address_length + 3);
940 SNPRINTF(other_certificate_list, address_length + 2, "%s;%s;%s", input_mail_data->full_address_to, input_mail_data->full_address_cc, input_mail_data->full_address_bcc);
942 EM_DEBUG_LOG("to:[%s], cc:[%s], bcc:[%s]", input_mail_data->full_address_to, input_mail_data->full_address_cc, input_mail_data->full_address_bcc);
943 EM_DEBUG_LOG("length : [%d], email_address : [%s]", address_length, other_certificate_list);
945 if (!emcore_smime_set_encrypt_message(other_certificate_list, mime_entity, account_tbl_item->cipher_type, &smime_file_path, &err)) {
946 EM_DEBUG_EXCEPTION("emcore_smime_set_encrypt_message is failed : [%d]", err);
950 EM_DEBUG_LOG("smime_file_path : %s", smime_file_path);
951 name = strrchr(smime_file_path, '/');
953 new_attachment_data.attachment_name = EM_SAFE_STRDUP(name + 1);
954 new_attachment_data.attachment_path = EM_SAFE_STRDUP(smime_file_path);
955 new_attachment_data.attachment_size = 1;
956 new_attachment_data.save_status = 1;
958 attachment_count += 1;
961 case EMAIL_SMIME_SIGNED_AND_ENCRYPTED: /* Signed and Encryption message */
962 address_length = EM_SAFE_STRLEN(input_mail_data->full_address_to) + EM_SAFE_STRLEN(input_mail_data->full_address_cc) + EM_SAFE_STRLEN(input_mail_data->full_address_bcc);
964 other_certificate_list = em_malloc(address_length + 3);
966 SNPRINTF(other_certificate_list, address_length + 2, "%s;%s;%s", input_mail_data->full_address_to, input_mail_data->full_address_cc, input_mail_data->full_address_bcc);
968 EM_DEBUG_LOG("to:[%s], cc:[%s], bcc:[%s]", input_mail_data->full_address_to, input_mail_data->full_address_cc, input_mail_data->full_address_bcc);
969 EM_DEBUG_LOG("length : [%d], email_address : [%s]", address_length, other_certificate_list);
971 if (!emcore_smime_set_signed_and_encrypt_message(other_certificate_list, account_tbl_item->certificate_path, password, mime_entity, account_tbl_item->cipher_type, account_tbl_item->digest_type, &smime_file_path, &err)) {
972 EM_DEBUG_EXCEPTION("em_core_smime_set_signed_and_encrypt_message is failed : [%d]", err);
976 EM_DEBUG_LOG("smime_file_path : %s", smime_file_path);
977 name = strrchr(smime_file_path, '/');
979 new_attachment_data.attachment_name = EM_SAFE_STRDUP(name + 1);
980 new_attachment_data.attachment_path = EM_SAFE_STRDUP(smime_file_path);
981 new_attachment_data.attachment_size = 1;
982 new_attachment_data.save_status = 1;
984 attachment_count = 1;
991 temp_attachment_data = (email_attachment_data_t *)em_malloc(sizeof(email_attachment_data_t) * attachment_count);
992 if (input_attachment_data_list != NULL)
993 temp_attachment_data = input_attachment_data_list;
995 temp_attachment_data[attachment_count-1] = new_attachment_data;
997 input_mail_data->smime_type = smime_type;
998 input_mail_data->file_path_mime_entity = EM_SAFE_STRDUP(mime_entity);
999 input_mail_data->digest_type = account_tbl_item->digest_type;
1004 if (output_attachment_count)
1005 *output_attachment_count = attachment_count;
1007 if (output_attachment_data_list)
1008 *output_attachment_data_list = temp_attachment_data;
1011 *output_mail_data = input_mail_data;
1013 if (!ret && temp_attachment_data)
1014 emcore_free_attachment_data(&temp_attachment_data, attachment_count, NULL);
1018 EM_SAFE_FREE(password);