4 * Copyright (c) 2012 - 2013 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>
40 #include <openssl/ssl.h>
42 #include "email-utilities.h"
43 #include "email-core-global.h"
44 #include "email-core-utils.h"
45 #include "email-core-mail.h"
46 #include "email-core-smtp.h"
47 #include "email-storage.h"
48 #include "email-core-smime.h"
49 #include "email-core-pgp.h"
50 #include "email-core-cert.h"
51 #include "email-debug-log.h"
53 /* /opt/share/cert-svc/certs is a base path */
55 #define SMIME_SIGNED_FILE "smime.p7s"
56 #define SMIME_ENCRYPT_FILE "smime.p7m"
57 #define DECRYPT_TEMP_FILE "decrypt_temp_file.eml"
59 /* If not present then the default digest algorithm for signing key will be used SHA1 */
60 static const EVP_MD *emcore_get_digest_algorithm(email_digest_type digest_type)
62 const EVP_MD *digest_algo = NULL;
64 switch (digest_type) {
66 digest_algo = EVP_md5();
68 case DIGEST_TYPE_SHA1:
70 digest_algo = EVP_sha1();
77 /* If not present then the default cipher algorithm for signing key will be used RC2(40) */
78 static const EVP_CIPHER *emcore_get_cipher_algorithm(email_cipher_type cipher_type)
80 const EVP_CIPHER *cipher = NULL;
82 switch (cipher_type) {
83 case CIPHER_TYPE_RC2_128 :
84 cipher = EVP_rc2_cbc();
86 case CIPHER_TYPE_RC2_64 :
87 cipher = EVP_rc2_64_cbc();
89 case CIPHER_TYPE_DES3 :
90 cipher = EVP_des_ede3_cbc();
92 case CIPHER_TYPE_DES :
93 cipher = EVP_des_cbc();
95 #ifdef __FEATURE_USE_MORE_CIPHER_TYPE__
96 case CIPHER_TYPE_SEED :
97 cipher = EVP_seed_cbc();
99 case CIPHER_TYPE_AES128 :
100 cipher = EVP_aes_128_cbc();
102 case CIPHER_TYPE_AES192 :
103 cipher = EVP_aes_192_cbc();
105 case CIPHER_TYPE_AES256 :
106 cipher = EVP_aes_256_cbc();
108 #ifndef OPENSSL_NO_CAMELLIA
109 case CIPHER_TYPE_CAMELLIA128 :
110 cipher = EVP_camellia_128_cbc();
112 case CIPHER_TYPE_CAMELLIA192 :
113 cipher = EVP_camellia_192_cbc();
115 case CIPHER_TYPE_CAMELLIA256 :
116 cipher = EVP_camellia_256_cbc();
120 case CIPHER_TYPE_RC2_40 :
122 cipher = EVP_rc2_40_cbc();
129 static int get_x509_stack_of_recipient_certs(char *multi_user_name,
131 STACK_OF(X509) **output_recipient_certs,
134 EM_DEBUG_FUNC_BEGIN("recipients : [%s], STACK_OF(X509) : [%p]", recipients, output_recipient_certs);
136 int err = EMAIL_ERROR_NONE;
140 char *temp_recipients = NULL;
141 char *email_address = NULL;
142 char file_name[512] = {0, };
143 const unsigned char *in_cert = NULL;
145 ADDRESS *token_address = NULL;
147 X509 *x509_cert = NULL;
148 STACK_OF(X509) *temp_recipient_certs = NULL;
150 CERT_CONTEXT *context = NULL;
151 emstorage_certificate_tbl_t *cert = NULL;
153 if (!recipients || !output_recipient_certs) {
154 EM_DEBUG_EXCEPTION("Invalid parameter");
155 err = EMAIL_ERROR_INVALID_PARAM;
159 /* Initialize the variable */
160 temp_recipient_certs = sk_X509_new_null();
162 temp_recipients = g_strdup(recipients);
164 for (i = 0, j = EM_SAFE_STRLEN(temp_recipients); i < j; i++)
165 if (temp_recipients[i] == ';') temp_recipients[i] = ',';
167 rfc822_parse_adrlist(&token_address, temp_recipients, NULL);
169 while (token_address) {
170 context = cert_svc_cert_context_init();
171 if (!context) { /*prevent 20162*/
172 EM_DEBUG_EXCEPTION("cert_svc_cert_context_init failed");
176 EM_DEBUG_LOG_SEC("email_address_mailbox : [%s], email_address_host : [%s]", token_address->mailbox,
177 token_address->host);
179 email_address = g_strdup_printf("<%s@%s>", token_address->mailbox, token_address->host);
180 if (!emstorage_get_certificate_by_email_address(multi_user_name, email_address, &cert, false, 0, &err)) {
181 EM_DEBUG_EXCEPTION("emstorage_get_certificate_by_email_address failed : [%d]", err);
185 if (!cert) { /*prevent 20161*/
186 EM_DEBUG_EXCEPTION("cert is NULL");
191 SNPRINTF(file_name, sizeof(file_name), "%s", cert->filepath);
192 EM_DEBUG_LOG_SEC("file_name : [%s]", file_name);
193 int cert_err = cert_svc_load_file_to_context(context, file_name);
194 if (cert_err != CERT_SVC_ERR_NO_ERROR) {
195 EM_DEBUG_EXCEPTION("cert_svc_load_file_to_context failed : [%d]", err);
196 err = EMAIL_ERROR_SYSTEM_FAILURE;
200 in_cert = context->certBuf->data;
201 cert_size = context->certBuf->size;
203 if (d2i_X509(&x509_cert, &in_cert, cert_size) == NULL) {
204 EM_DEBUG_EXCEPTION("d2i_X509 failed");
205 err = EMAIL_ERROR_SYSTEM_FAILURE;
209 if (!sk_X509_push(temp_recipient_certs, x509_cert)) {
210 EM_DEBUG_EXCEPTION("sk_X509_push failed");
211 err = EMAIL_ERROR_SYSTEM_FAILURE;
215 cert_svc_cert_context_final(context);
218 emstorage_free_certificate(&cert, 1, NULL);
223 token_address = token_address->next;
226 *output_recipient_certs = temp_recipient_certs;
233 if (temp_recipient_certs)
234 sk_X509_pop_free(temp_recipient_certs, X509_free);
237 X509_free(x509_cert);
241 emstorage_free_certificate(&cert, 1, NULL);
244 cert_svc_cert_context_final(context);
246 EM_SAFE_FREE(temp_recipients);
247 EM_SAFE_FREE(email_address);
249 mail_free_address(&token_address);
254 EM_DEBUG_FUNC_END("err : [%d]", err);
258 /* Opaque signed and encrypted method */
260 static PKCS7 *opaque_signed_and_encrypt(STACK_OF(X509) *recipients_cert,
262 EVP_PKEY *private_key,
264 const EVP_CIPHER *cipher,
268 EM_DEBUG_FUNC_BEGIN();
274 if (!(pkcs7 = PKCS7_new())) {
275 EM_DEBUG_EXCEPTION("PKCS7 malloc failed");
279 if (!PKCS7_set_type(pkcs7, NID_pkcs7_signedAndEnveloped)) {
280 EM_DEBUG_EXCEPTION("Set type failed");
284 if (!PKCS7_add_signature(pkcs7, signer, private_key, md)) {
285 EM_DEBUG_EXCEPTION("PKCS7_add_signature failed");
289 if (!PKCS7_add_certificate(pkcs7, signer)) {
290 EM_DEBUG_EXCEPTION("PKCS7_add_certificate failed");
294 for (i = 0; i < sk_X509_num(recipients_cert); i++) {
295 x509 = sk_X509_value(recipients_cert, i);
296 if (!PKCS7_add_recipient(pkcs7, x509)) {
297 EM_DEBUG_EXCEPTION("PKCS7_add_recipient failed");
302 if (!PKCS7_set_cipher(pkcs7, cipher)) {
303 EM_DEBUG_EXCEPTION("Cipher failed");
307 if (flags & PKCS7_STREAM)
310 if (PKCS7_final(pkcs7, mime_entity, flags))
320 INTERNAL_FUNC int emcore_smime_set_signed_message(char *certificate,
322 email_digest_type digest_type,
326 EM_DEBUG_FUNC_BEGIN_SEC("certificate path : [%s], mime_entity : [%s]", certificate, mime_entity);
327 int err, ret = false;
328 char temp_smime_filepath[512];
330 STACK_OF(X509) *other_certs = NULL;
331 EVP_PKEY *private_key = NULL;
332 const EVP_MD *digest = NULL;
333 BIO *bio_mime_entity = NULL, *bio_cert = NULL, *bio_prikey = NULL;
334 BIO *smime_attachment = NULL;
335 PKCS7 *signed_message = NULL;
336 int flags = PKCS7_DETACHED | PKCS7_PARTIAL;
338 SNPRINTF(temp_smime_filepath, sizeof(temp_smime_filepath), "%s%s%s", MAILTEMP, DIR_SEPERATOR, SMIME_SIGNED_FILE);
339 EM_DEBUG_LOG_SEC("attachment file path of smime : [%s]", temp_smime_filepath);
341 smime_attachment = BIO_new_file(temp_smime_filepath, OUTMODE);
342 if (!smime_attachment) {
343 EM_DEBUG_EXCEPTION_SEC("Cannot open output file %s", temp_smime_filepath);
344 err = EMAIL_ERROR_SYSTEM_FAILURE;
348 /* Load certificate for getting the certificate and private key */
349 if (!emcore_load_PFX_file(certificate, &private_key, &cert, &other_certs, &err)) {
350 EM_DEBUG_EXCEPTION("Load the private certificate failed : [%d]", err);
354 bio_mime_entity = BIO_new_file(mime_entity, READMODE);
355 if (!bio_mime_entity) {
356 EM_DEBUG_EXCEPTION("Cannot open file[%s]", mime_entity);
357 err = EMAIL_ERROR_SYSTEM_FAILURE;
361 signed_message = PKCS7_sign(NULL, NULL, other_certs, bio_mime_entity, flags);
362 if (!signed_message) {
363 EM_DEBUG_EXCEPTION("Error creating PKCS#7 structure");
364 err = EMAIL_ERROR_SYSTEM_FAILURE;
368 /* Get the digest algorithm */
369 digest = emcore_get_digest_algorithm(digest_type);
371 if (!PKCS7_sign_add_signer(signed_message, cert, private_key, digest, flags)) {
372 EM_DEBUG_EXCEPTION("PKCS7_sign_add_signer failed");
373 err = EMAIL_ERROR_SYSTEM_FAILURE;
377 if (!PKCS7_final(signed_message, bio_mime_entity, flags)) {
378 EM_DEBUG_EXCEPTION("PKCS7_final failed");
379 err = EMAIL_ERROR_SYSTEM_FAILURE;
383 if (!i2d_PKCS7_bio_stream(smime_attachment, signed_message, bio_mime_entity, flags)) {
384 EM_DEBUG_EXCEPTION("i2d_PKCS7_bio_stream failed");
385 err = EMAIL_ERROR_SYSTEM_FAILURE;
388 BIO_flush(smime_attachment);
392 if (file_path && ret)
393 *file_path = g_strdup(temp_smime_filepath);
396 sk_X509_pop_free(other_certs, X509_free);
397 EVP_PKEY_free(private_key);
398 PKCS7_free(signed_message);
400 BIO_free(bio_mime_entity);
402 BIO_free(bio_prikey);
403 BIO_free_all(smime_attachment);
405 if (err_code != NULL)
408 EM_DEBUG_FUNC_END("err [%d]", err);
412 INTERNAL_FUNC int emcore_smime_set_encrypt_message(char *multi_user_name,
413 char *recipient_list,
415 email_cipher_type cipher_type,
419 EM_DEBUG_FUNC_BEGIN("certificate path : [%p], mime_entity : [%p]", recipient_list, mime_entity);
420 char temp_smime_filepath[512];
421 int err = EMAIL_ERROR_NONE, ret = false;
422 // int flags = PKCS7_DETACHED | PKCS7_STREAM;
423 int flags = PKCS7_BINARY;
425 CERT_CONTEXT *loaded_cert = NULL;
426 STACK_OF(X509) *recipient_certs = NULL;
428 BIO *bio_mime_entity = NULL, *bio_cert = NULL;
429 BIO *smime_attachment = NULL;
430 PKCS7 *encrypt_message = NULL;
431 const EVP_CIPHER *cipher = NULL;
433 loaded_cert = cert_svc_cert_context_init();
435 SNPRINTF(temp_smime_filepath, sizeof(temp_smime_filepath), "%s%s%s", MAILTEMP, DIR_SEPERATOR, SMIME_ENCRYPT_FILE);
436 EM_DEBUG_LOG_SEC("attachment file path of smime : [%s]", temp_smime_filepath);
438 smime_attachment = BIO_new_file(temp_smime_filepath, OUTMODE);
439 if (!smime_attachment) {
440 EM_DEBUG_EXCEPTION_SEC("Cannot open output file %s", temp_smime_filepath);
441 err = EMAIL_ERROR_SYSTEM_FAILURE;
445 if (!get_x509_stack_of_recipient_certs(multi_user_name, recipient_list, &recipient_certs, &err)) {
446 EM_DEBUG_EXCEPTION("get_x509_stack_of_recipient_certs failed [%d]", err);
450 bio_mime_entity = BIO_new_file(mime_entity, READMODE);
451 if (!bio_mime_entity) {
452 EM_DEBUG_EXCEPTION("Cannot open file[%s]", mime_entity);
456 /* Get cipher algorithm */
457 cipher = emcore_get_cipher_algorithm(cipher_type);
459 encrypt_message = PKCS7_encrypt(recipient_certs, bio_mime_entity, cipher, flags);
460 if (encrypt_message == NULL) {
461 EM_DEBUG_EXCEPTION("PKCS7_encrypt failed [%ld]", ERR_get_error());
462 err = EMAIL_ERROR_SYSTEM_FAILURE;
466 if (!i2d_PKCS7_bio_stream(smime_attachment, encrypt_message, bio_mime_entity, flags)) {
467 EM_DEBUG_EXCEPTION("i2d_PKCS7_bio_stream failed");
468 err = EMAIL_ERROR_SYSTEM_FAILURE;
471 BIO_flush(smime_attachment);
476 if (file_path && ret)
477 *file_path = g_strdup(temp_smime_filepath);
479 PKCS7_free(encrypt_message);
482 sk_X509_pop_free(recipient_certs, X509_free);
485 BIO_free(bio_mime_entity);
486 BIO_free_all(smime_attachment);
488 cert_svc_cert_context_final(loaded_cert);
489 if (err_code != NULL)
492 EM_DEBUG_FUNC_END("err [%d]", err);
496 INTERNAL_FUNC int emcore_smime_set_signed_and_encrypt_message(char *multi_user_name,
497 char *recipient_list,
500 email_cipher_type cipher_type,
501 email_digest_type digest_type,
505 EM_DEBUG_FUNC_BEGIN_SEC("certificate path : [%s], mime_entity : [%s]", recipient_list, mime_entity);
506 char temp_smime_filepath[512];
507 char temp_mime_entity_path[512];
508 int err = EMAIL_ERROR_NONE, ret = false;
509 int flags = PKCS7_DETACHED | PKCS7_PARTIAL | PKCS7_STREAM;
511 STACK_OF(X509) *recipient_certs = NULL;
512 STACK_OF(X509) *other_certs = NULL;
513 BIO *bio_mime_entity = NULL, *bio_cert = NULL;
514 BIO *bio_signed_message = NULL;
515 BIO *smime_attachment = NULL;
516 PKCS7 *signed_message = NULL;
517 PKCS7 *encrypt_message = NULL;
518 const EVP_CIPHER *cipher = NULL;
519 const EVP_MD *digest = NULL;
521 /* Variable for private certificate */
522 EVP_PKEY *private_key = NULL;
525 SNPRINTF(temp_smime_filepath, sizeof(temp_smime_filepath), "%s%s%s", MAILTEMP, DIR_SEPERATOR, SMIME_ENCRYPT_FILE);
526 EM_DEBUG_LOG_SEC("attachment file path of smime : [%s]", temp_smime_filepath);
528 smime_attachment = BIO_new_file(temp_smime_filepath, OUTMODE);
529 if (!smime_attachment) {
530 EM_DEBUG_EXCEPTION_SEC("Cannot open output file %s", temp_smime_filepath);
531 err = EMAIL_ERROR_SYSTEM_FAILURE;
535 /* Signing the mail */
536 /* 1. Load the private certificate */
537 if (!emcore_load_PFX_file(certificate, &private_key, &cert, &other_certs, &err)) {
538 EM_DEBUG_EXCEPTION("Load the private certificate failed : [%d]", err);
542 /* 2. Read mime entity */
543 bio_mime_entity = BIO_new_file(mime_entity, READMODE);
544 if (!bio_mime_entity) {
545 EM_DEBUG_EXCEPTION("Cannot open file[%s]", mime_entity);
546 err = EMAIL_ERROR_SYSTEM_FAILURE;
551 signed_message = PKCS7_sign(NULL, NULL, other_certs, bio_mime_entity, flags);
552 if (!signed_message) {
553 EM_DEBUG_EXCEPTION("Error creating PKCS#7 structure");
554 err = EMAIL_ERROR_SYSTEM_FAILURE;
558 /* 4. Get the digest algorithm */
559 digest = emcore_get_digest_algorithm(digest_type);
561 /* 5. Apply a digest algorithm */
562 if (!PKCS7_sign_add_signer(signed_message, cert, private_key, digest, flags)) {
563 EM_DEBUG_EXCEPTION("PKCS7_sign_add_signer failed");
564 err = EMAIL_ERROR_SYSTEM_FAILURE;
568 /* 6. Create signing message */
569 SNPRINTF(temp_mime_entity_path, sizeof(temp_mime_entity_path), "%s%smime_entity", MAILTEMP, DIR_SEPERATOR);
570 EM_DEBUG_LOG_SEC("attachment file path of smime : [%s]", temp_mime_entity_path);
572 bio_signed_message = BIO_new_file(temp_mime_entity_path, WRITEMODE);
573 if (!bio_signed_message) {
574 EM_DEBUG_EXCEPTION_SEC("Cannot open output file %s", temp_mime_entity_path);
575 err = EMAIL_ERROR_SYSTEM_FAILURE;
579 if (!SMIME_write_PKCS7(bio_signed_message, signed_message, bio_mime_entity, flags | SMIME_OLDMIME | SMIME_CRLFEOL)) {
580 EM_DEBUG_EXCEPTION("SMIME_write_PKCS7 error");
581 err = EMAIL_ERROR_SYSTEM_FAILURE;
585 BIO_free(bio_signed_message);
587 /* Encrypting the mail */
588 /* 1. Get the recipient certs */
589 if (!get_x509_stack_of_recipient_certs(multi_user_name, recipient_list, &recipient_certs, &err)) {
590 EM_DEBUG_EXCEPTION("get_x509_stack_of_recipient_certs failed [%d]", err);
594 /* 2. Get cipher algorithm */
595 cipher = emcore_get_cipher_algorithm(cipher_type);
597 flags = PKCS7_BINARY;
599 /* 3. Encrypt the signing message */
600 bio_signed_message = BIO_new_file(temp_mime_entity_path, READMODE);
601 if (!bio_signed_message) {
602 EM_DEBUG_EXCEPTION_SEC("Cannot open output file %s", temp_mime_entity_path);
603 err = EMAIL_ERROR_SYSTEM_FAILURE;
607 encrypt_message = PKCS7_encrypt(recipient_certs, bio_signed_message, cipher, flags);
608 if (encrypt_message == NULL) {
609 EM_DEBUG_EXCEPTION("PKCS7_encrypt failed [%ld]", ERR_get_error());
610 err = EMAIL_ERROR_SYSTEM_FAILURE;
614 /* 4. Write the encrypt message in file */
615 if (!i2d_PKCS7_bio_stream(smime_attachment, encrypt_message, bio_mime_entity, flags)) {
616 EM_DEBUG_EXCEPTION("i2d_PKCS7_bio_stream failed");
617 err = EMAIL_ERROR_SYSTEM_FAILURE;
620 BIO_flush(smime_attachment);
625 if (file_path && ret)
626 *file_path = g_strdup(temp_smime_filepath);
628 emstorage_delete_file(temp_mime_entity_path, NULL);
630 PKCS7_free(signed_message);
631 PKCS7_free(encrypt_message);
632 EVP_PKEY_free(private_key);
635 sk_X509_pop_free(other_certs, X509_free);
636 sk_X509_pop_free(recipient_certs, X509_free);
639 BIO_free(bio_mime_entity);
640 BIO_free(bio_signed_message);
641 BIO_free_all(smime_attachment);
643 if (err_code != NULL)
646 EM_DEBUG_FUNC_END("err [%d]", err);
650 INTERNAL_FUNC int emcore_smime_get_decrypt_message(char *encrypt_message,
652 char **decrypt_message,
655 EM_DEBUG_FUNC_BEGIN_SEC("encrypt_file : [%s], certificate : [%s]", encrypt_message, certificate);
657 int err = EMAIL_ERROR_NONE;
658 char temp_decrypt_filepath[512] = {0, };
661 EVP_PKEY *private_key = NULL;
662 BIO *infile = NULL, *out_buf = NULL;
663 PKCS7 *p7_encrypt_message = NULL;
664 STACK_OF(X509) *recipient_certs = NULL;
666 /* Load the encrypted message */
667 infile = BIO_new_file(encrypt_message, INMODE);
668 if (infile == NULL) {
669 EM_DEBUG_EXCEPTION("Cannot open output file %s", encrypt_message);
670 err = EMAIL_ERROR_SYSTEM_FAILURE;
674 p7_encrypt_message = d2i_PKCS7_bio(infile, NULL);
675 if (!p7_encrypt_message) {
676 EM_DEBUG_EXCEPTION("Error reading S/MIME message");
677 err = EMAIL_ERROR_INVALID_PARAM;
681 /* Initialize the output file for decrypted message */
682 SNPRINTF(temp_decrypt_filepath, sizeof(temp_decrypt_filepath), "%s%s%s", MAILTEMP, DIR_SEPERATOR, DECRYPT_TEMP_FILE);
683 EM_DEBUG_LOG_SEC("attachment file path of smime : [%s]", temp_decrypt_filepath);
685 out_buf = BIO_new_file(temp_decrypt_filepath, OUTMODE);
687 EM_DEBUG_EXCEPTION_SEC("Cannot open output file %s", temp_decrypt_filepath);
688 err = EMAIL_ERROR_SYSTEM_FAILURE;
692 /* Search private cert */
693 if (!emcore_load_PFX_file(certificate, &private_key, &cert, NULL, &err)) {
694 EM_DEBUG_EXCEPTION("Load the private certificate failed : [%d]", err);
698 if (!PKCS7_decrypt(p7_encrypt_message, private_key, cert, out_buf, 0)) {
699 EM_DEBUG_EXCEPTION("Decrpyt failed");
700 err = EMAIL_ERROR_DECRYPT_FAILED;
708 if (decrypt_message && ret)
709 *decrypt_message = g_strdup(temp_decrypt_filepath);
712 EVP_PKEY_free(private_key);
714 BIO_free_all(infile);
715 sk_X509_pop_free(recipient_certs, X509_free);
717 if (err_code != NULL)
720 EM_DEBUG_FUNC_END("err [%d]", err);
725 INTERNAL_FUNC int emcore_smime_verify_signed_message(char *signed_message, char *ca_file, char *ca_path, int *verify)
731 X509_STORE *store = NULL;
732 X509_LOOKUP *lookup = NULL;
735 if (BIO_write(indata, signed_message, sizeof(signed_message)) <= 0) {
736 EM_DEBUG_EXCEPTION("Char to Bio failed");
740 p7 = SMIME_read_PKCS7(indata, &content);
742 EM_DEBUG_EXCEPTION("SMIME_read_PKCS7 failed");
746 if (!(store = X509_STORE_new())) {
747 EM_DEBUG_EXCEPTION("Initialize x509_store failed");
751 lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
752 if (lookup == NULL) {
753 EM_DEBUG_EXCEPTION("Initialize lookup store failed");
758 if (!X509_LOOKUP_load_file(lookup, ca_file, X509_FILETYPE_PEM)) {
759 EM_DEBUG_EXCEPTION("X509_LOOKUP_load_file failed");
763 X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT);
766 lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
767 if (lookup == NULL) {
768 EM_DEBUG_EXCEPTION("X509_STORE_add_lookup failed");
773 if (!X509_LOOKUP_add_dir(lookup, ca_path, X509_FILETYPE_PEM)) {
774 EM_DEBUG_EXCEPTION("CA path load failed");
778 X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
781 temp_verify = PKCS7_verify(p7, NULL, store, content, NULL, 0);
783 EM_DEBUG_LOG("Verification Successful\n");
789 X509_STORE_free(store);
797 *verify = temp_verify;
804 INTERNAL_FUNC int emcore_convert_mail_data_to_smime_data(char *multi_user_name,
805 emstorage_account_tbl_t *account_tbl_item,
806 email_mail_data_t *input_mail_data,
807 email_attachment_data_t *input_attachment_data_list,
808 int input_attachment_count,
809 email_mail_data_t **output_mail_data,
810 email_attachment_data_t **output_attachment_data_list,
811 int *output_attachment_count)
813 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]",
814 input_mail_data, input_attachment_data_list, input_attachment_count,
815 output_mail_data, output_attachment_data_list);
818 int err = EMAIL_ERROR_NONE;
819 int smime_type = EMAIL_SMIME_NONE;
820 int attachment_count = input_attachment_count;
823 char *smime_file_path = NULL;
824 char *other_certificate_list = NULL;
825 email_attachment_data_t new_attachment_data = {0};
826 email_attachment_data_t *new_attachment_list = NULL;
828 /* Validating parameters */
829 if (!input_mail_data || !(input_mail_data->account_id) || !(input_mail_data->mailbox_id)
830 || !output_attachment_count || !output_mail_data || !output_attachment_data_list ) { /*prevent#53051*/
831 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
832 err = EMAIL_ERROR_INVALID_PARAM;
836 smime_type = input_mail_data->smime_type;
838 smime_type = account_tbl_item->smime_type;
840 /* Signed and Encrypt the message */
841 switch (smime_type) {
842 case EMAIL_SMIME_SIGNED: /* Clear signed message */
843 if (!emcore_smime_set_signed_message(account_tbl_item->certificate_path,
844 input_mail_data->file_path_mime_entity,
845 account_tbl_item->digest_type,
848 EM_DEBUG_EXCEPTION("em_core_smime_set_clear_signed_message is failed : [%d]", err);
852 EM_DEBUG_LOG_SEC("smime_file_path : %s", smime_file_path);
853 name = strrchr(smime_file_path, '/');
855 new_attachment_data.attachment_name = g_strdup(name + 1);
856 new_attachment_data.attachment_path = g_strdup(smime_file_path);
857 new_attachment_data.attachment_mime_type = strdup("pkcs7-signature");
859 attachment_count += 1;
863 case EMAIL_SMIME_ENCRYPTED: /* Encryption message */
864 other_certificate_list = g_strconcat(input_mail_data->full_address_from, ";",
865 input_mail_data->full_address_to, ";",
866 input_mail_data->full_address_cc, ";",
867 input_mail_data->full_address_bcc, NULL);
869 if (!emcore_smime_set_encrypt_message(multi_user_name,
870 other_certificate_list,
871 input_mail_data->file_path_mime_entity,
872 account_tbl_item->cipher_type,
875 EM_DEBUG_EXCEPTION("emcore_smime_set_encrypt_message is failed : [%d]", err);
879 EM_DEBUG_LOG_SEC("smime_file_path : %s", smime_file_path);
880 name = strrchr(smime_file_path, '/');
882 new_attachment_data.attachment_name = g_strdup(name + 1);
883 new_attachment_data.attachment_path = g_strdup(smime_file_path);
884 new_attachment_data.attachment_mime_type = strdup("pkcs7-mime");
886 attachment_count = 1;
890 case EMAIL_SMIME_SIGNED_AND_ENCRYPTED: /* Signed and Encryption message */
891 other_certificate_list = g_strconcat(input_mail_data->full_address_from, ";",
892 input_mail_data->full_address_to, ";",
893 input_mail_data->full_address_cc, ";",
894 input_mail_data->full_address_bcc, NULL);
896 if (!emcore_smime_set_signed_and_encrypt_message(multi_user_name,
897 other_certificate_list,
898 account_tbl_item->certificate_path,
899 input_mail_data->file_path_mime_entity,
900 account_tbl_item->cipher_type,
901 account_tbl_item->digest_type,
904 EM_DEBUG_EXCEPTION("em_core_smime_set_signed_and_encrypt_message is failed : [%d]", err);
908 EM_DEBUG_LOG_SEC("smime_file_path : %s", smime_file_path);
909 name = strrchr(smime_file_path, '/');
911 new_attachment_data.attachment_name = g_strdup(name + 1);
912 new_attachment_data.attachment_path = g_strdup(smime_file_path);
913 new_attachment_data.attachment_mime_type = strdup("pkcs7-mime");
915 attachment_count = 1;
919 case EMAIL_PGP_SIGNED:
920 if ((err = emcore_pgp_set_signed_message(NULL,
921 input_mail_data->pgp_password,
922 input_mail_data->file_path_mime_entity,
923 input_mail_data->key_id,
924 account_tbl_item->digest_type,
925 &smime_file_path)) != EMAIL_ERROR_NONE) {
926 EM_DEBUG_EXCEPTION("emcore_pgp_set_signed_message is failed : [%d]", err);
930 EM_DEBUG_LOG_SEC("smime_file_path : %s", smime_file_path);
931 name = strrchr(smime_file_path, '/');
933 new_attachment_data.attachment_name = g_strdup(name + 1);
934 new_attachment_data.attachment_path = g_strdup(smime_file_path);
935 new_attachment_data.attachment_mime_type = strdup("pgp-signature");
937 attachment_count += 1;
941 case EMAIL_PGP_ENCRYPTED:
943 other_certificate_list = g_strconcat(input_mail_data->full_address_from, ";",
944 input_mail_data->full_address_to, ";",
945 input_mail_data->full_address_cc, ";",
946 input_mail_data->full_address_bcc, NULL);
948 other_certificate_list = g_strdup(input_mail_data->key_list);
949 if ((err = emcore_pgp_set_encrypted_message(other_certificate_list,
951 input_mail_data->pgp_password,
952 input_mail_data->file_path_mime_entity,
953 account_tbl_item->user_email_address,
954 input_mail_data->digest_type,
955 &smime_file_path)) != EMAIL_ERROR_NONE) {
956 EM_DEBUG_EXCEPTION("emcore_pgp_set_encrypted_message failed : [%d]", err);
960 name = strrchr(smime_file_path, '/');
962 new_attachment_data.attachment_name = g_strdup(name + 1);
963 new_attachment_data.attachment_path = g_strdup(smime_file_path);
964 new_attachment_data.attachment_mime_type = strdup("octet-stream");
966 attachment_count = 1;
970 case EMAIL_PGP_SIGNED_AND_ENCRYPTED:
972 other_certificate_list = g_strconcat(input_mail_data->full_address_from, ";",
973 input_mail_data->full_address_to, ";",
974 input_mail_data->full_address_cc, ";",
975 input_mail_data->full_address_bcc, NULL);
977 other_certificate_list = g_strdup(input_mail_data->key_list);
978 if ((err = emcore_pgp_set_signed_and_encrypted_message(other_certificate_list,
980 input_mail_data->pgp_password,
981 input_mail_data->file_path_mime_entity,
982 input_mail_data->key_id,
983 input_mail_data->digest_type,
984 &smime_file_path)) != EMAIL_ERROR_NONE) {
985 EM_DEBUG_EXCEPTION("emcore_pgp_set_signed_and_encrypted_message failed : [%d]", err);
989 name = strrchr(smime_file_path, '/');
991 new_attachment_data.attachment_name = g_strdup(name + 1);
992 new_attachment_data.attachment_path = g_strdup(smime_file_path);
993 new_attachment_data.attachment_mime_type = strdup("octet-stream");
995 attachment_count = 1;
1000 EM_DEBUG_LOG("MIME none");
1005 if (!emcore_get_file_size(smime_file_path, &file_size, NULL)) {
1006 EM_DEBUG_EXCEPTION("emcore_get_file_size failed");
1010 new_attachment_data.attachment_size = file_size;
1011 new_attachment_data.save_status = 1;
1013 new_attachment_list = (email_attachment_data_t *)em_malloc(sizeof(email_attachment_data_t) * attachment_count);
1014 if (new_attachment_list == NULL) {
1015 EM_DEBUG_EXCEPTION("em_malloc failed");
1016 err = EMAIL_ERROR_OUT_OF_MEMORY;
1020 if (smime_type == EMAIL_SMIME_SIGNED) {
1021 for (i = 0; i < input_attachment_count; i++) {
1022 new_attachment_list[i].attachment_id = input_attachment_data_list[i].attachment_id;
1023 new_attachment_list[i].attachment_name = g_strdup(input_attachment_data_list[i].attachment_name);
1024 new_attachment_list[i].attachment_path = g_strdup(input_attachment_data_list[i].attachment_path);
1025 new_attachment_list[i].content_id = g_strdup(input_attachment_data_list[i].content_id);
1026 new_attachment_list[i].attachment_size = input_attachment_data_list[i].attachment_size;
1027 new_attachment_list[i].mail_id = input_attachment_data_list[i].mail_id;
1028 new_attachment_list[i].account_id = input_attachment_data_list[i].account_id;
1029 new_attachment_list[i].mailbox_id = input_attachment_data_list[i].mailbox_id;
1030 new_attachment_list[i].save_status = input_attachment_data_list[i].save_status;
1031 new_attachment_list[i].drm_status = input_attachment_data_list[i].drm_status;
1032 new_attachment_list[i].inline_content_status = input_attachment_data_list[i].inline_content_status;
1033 new_attachment_list[i].attachment_mime_type = g_strdup(input_attachment_data_list[i].attachment_mime_type);
1037 new_attachment_list[attachment_count - 1].attachment_id = new_attachment_data.attachment_id;
1038 new_attachment_list[attachment_count - 1].attachment_name = g_strdup(new_attachment_data.attachment_name);
1039 new_attachment_list[attachment_count - 1].attachment_path = g_strdup(new_attachment_data.attachment_path);
1040 new_attachment_list[attachment_count - 1].content_id = g_strdup(new_attachment_data.content_id);
1041 new_attachment_list[attachment_count - 1].attachment_size = new_attachment_data.attachment_size;
1042 new_attachment_list[attachment_count - 1].mail_id = new_attachment_data.mail_id;
1043 new_attachment_list[attachment_count - 1].account_id = new_attachment_data.account_id;
1044 new_attachment_list[attachment_count - 1].mailbox_id = new_attachment_data.mailbox_id;
1045 new_attachment_list[attachment_count - 1].save_status = new_attachment_data.save_status;
1046 new_attachment_list[attachment_count - 1].drm_status = new_attachment_data.drm_status;
1047 new_attachment_list[attachment_count - 1].inline_content_status = new_attachment_data.inline_content_status;
1048 new_attachment_list[attachment_count - 1].attachment_mime_type = g_strdup(new_attachment_data.attachment_mime_type);
1050 input_mail_data->smime_type = smime_type;
1051 input_mail_data->digest_type = account_tbl_item->digest_type;
1055 EM_SAFE_FREE(other_certificate_list);
1056 EM_SAFE_FREE(smime_file_path);
1058 *output_attachment_count = attachment_count;
1060 *output_attachment_data_list = new_attachment_list;
1062 *output_mail_data = input_mail_data;
1064 EM_SAFE_FREE(new_attachment_data.attachment_name);
1065 EM_SAFE_FREE(new_attachment_data.attachment_path);
1066 EM_SAFE_FREE(new_attachment_data.attachment_mime_type);
1067 EM_SAFE_FREE(new_attachment_data.content_id);
1069 EM_DEBUG_LOG("err : [%d]", err);
1073 INTERNAL_FUNC void emcore_init_openssl_library()
1075 EM_DEBUG_FUNC_BEGIN();
1077 ERR_load_crypto_strings();
1078 EM_DEBUG_FUNC_END();
1081 INTERNAL_FUNC void emcore_clean_openssl_library()
1083 EM_DEBUG_FUNC_BEGIN();
1086 EM_DEBUG_FUNC_END();