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.
26 * This file contains the data structures and interfaces needed for application,
27 * to interact with Email Engine.
28 * @file email-api-smime.c
29 * @brief This file contains the data structures and interfaces of SMIME related Functionality provided by
35 #include "email-api-mail.h"
36 #include "email-convert.h"
37 #include "email-api-account.h"
38 #include "email-api-private.h"
39 #include "email-storage.h"
40 #include "email-utilities.h"
41 #include "email-core-mail.h"
42 #include "email-core-mime.h"
43 #include "email-core-account.h"
44 #include "email-core-cert.h"
45 #include "email-core-smime.h"
46 #include "email-core-pgp.h"
47 #include "email-core-signal.h"
48 #include "email-ipc.h"
50 EXPORT_API int email_add_certificate(char *certificate_path, char *email_address)
52 CHECK_EMAILS_SUPPORTED(EMAIL_FEATURE);
53 EM_DEBUG_API_BEGIN("");
54 return EMAIL_ERROR_NOT_SUPPORTED;
57 EXPORT_API int email_delete_certificate(char *email_address)
59 CHECK_EMAILS_SUPPORTED(EMAIL_FEATURE);
60 EM_DEBUG_API_BEGIN("");
61 return EMAIL_ERROR_NOT_SUPPORTED;
64 EXPORT_API int email_get_certificate(char *email_address, email_certificate_t **certificate)
66 CHECK_EMAILS_SUPPORTED(EMAIL_FEATURE);
67 EM_DEBUG_API_BEGIN("");
68 return EMAIL_ERROR_NOT_SUPPORTED;
71 EXPORT_API int email_verify_certificate(char *certificate_path, int *verify)
73 CHECK_EMAILS_SUPPORTED(EMAIL_FEATURE);
74 EM_DEBUG_API_BEGIN("");
75 return EMAIL_ERROR_NOT_SUPPORTED;
78 EXPORT_API int email_get_decrypt_message(int mail_id, email_mail_data_t **output_mail_data,
79 email_attachment_data_t **output_attachment_data,
80 int *output_attachment_count, int *verify)
82 CHECK_EMAILS_SUPPORTED(EMAIL_FEATURE);
83 EM_DEBUG_API_BEGIN("mail_id[%d]", mail_id);
84 int err = EMAIL_ERROR_NONE;
85 int p_output_attachment_count = 0;
87 char *decrypt_filepath = NULL;
89 char *multi_user_name = NULL;
90 email_mail_data_t *p_output_mail_data = NULL;
91 email_attachment_data_t *p_output_attachment_data = NULL;
92 emstorage_account_tbl_t *p_account_tbl = NULL;
94 EM_IF_NULL_RETURN_VALUE(mail_id, EMAIL_ERROR_INVALID_PARAM);
96 if (!output_mail_data || !output_attachment_data || !output_attachment_count) {
97 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
98 err = EMAIL_ERROR_INVALID_PARAM;
102 if ((err = emipc_get_user_name(&multi_user_name)) != EMAIL_ERROR_NONE) {
103 EM_DEBUG_EXCEPTION("emipc_get_user_name failed : [%d]", err);
107 if ((err = emcore_get_mail_data(multi_user_name, mail_id, &p_output_mail_data)) != EMAIL_ERROR_NONE) {
108 EM_DEBUG_EXCEPTION("emcore_get_mail_data failed");
112 if (!emstorage_get_account_by_id(multi_user_name, p_output_mail_data->account_id, EMAIL_ACC_GET_OPT_OPTIONS, &p_account_tbl, false, &err)) {
113 EM_DEBUG_EXCEPTION("emstorage_get_account_by_id failed : [%d]", err);
117 if ((err = emcore_get_attachment_data_list(multi_user_name, mail_id, &p_output_attachment_data, &p_output_attachment_count)) != EMAIL_ERROR_NONE) {
118 EM_DEBUG_EXCEPTION("emcore_get_attachment_data_list failed");
122 for (i = 0; i < p_output_attachment_count; i++) {
123 EM_DEBUG_LOG("mime_type : [%s]", p_output_attachment_data[i].attachment_mime_type);
124 if (p_output_attachment_data[i].attachment_mime_type && (search = strcasestr(p_output_attachment_data[i].attachment_mime_type, "PKCS7-MIME"))) {
125 EM_DEBUG_LOG("Found the encrypt file");
127 } else if (p_output_attachment_data[i].attachment_mime_type && (search = strcasestr(p_output_attachment_data[i].attachment_mime_type, "octet-stream"))) {
128 EM_DEBUG_LOG("Found the encrypt file");
134 EM_DEBUG_EXCEPTION("No have a decrypt file");
135 err = EMAIL_ERROR_INVALID_PARAM;
139 if (p_output_mail_data->smime_type == EMAIL_SMIME_ENCRYPTED || p_output_mail_data->smime_type == EMAIL_SMIME_SIGNED_AND_ENCRYPTED) {
140 emcore_init_openssl_library();
141 if (!emcore_smime_get_decrypt_message(p_output_attachment_data[i].attachment_path, p_account_tbl->certificate_path, &decrypt_filepath, &err)) {
142 EM_DEBUG_EXCEPTION("emcore_smime_get_decrypt_message failed");
143 emcore_clean_openssl_library();
146 emcore_clean_openssl_library();
147 } else if (p_output_mail_data->smime_type == EMAIL_PGP_ENCRYPTED) {
148 if ((err = emcore_pgp_get_decrypted_message(p_output_attachment_data[i].attachment_path, p_output_mail_data->pgp_password, false, &decrypt_filepath, verify)) != EMAIL_ERROR_NONE) {
149 EM_DEBUG_EXCEPTION("emcore_pgp_get_decrypted_message failed : [%d]", err);
152 } else if (p_output_mail_data->smime_type == EMAIL_PGP_SIGNED_AND_ENCRYPTED) {
153 if ((err = emcore_pgp_get_decrypted_message(p_output_attachment_data[i].attachment_path, p_output_mail_data->pgp_password, true, &decrypt_filepath, verify)) != EMAIL_ERROR_NONE) {
154 EM_DEBUG_EXCEPTION("emcore_pgp_get_decrypted_message failed : [%d]", err);
158 EM_DEBUG_LOG("Invalid encrypted mail");
159 err = EMAIL_ERROR_INVALID_PARAM;
163 /* Change decrpyt_message to mail_data_t */
164 if (!emcore_parse_mime_file_to_mail(decrypt_filepath, output_mail_data, output_attachment_data, output_attachment_count, &err)) {
165 EM_DEBUG_EXCEPTION("emcore_parse_mime_file_to_mail failed : [%d]", err);
169 (*output_mail_data)->subject = EM_SAFE_STRDUP(p_output_mail_data->subject);
170 (*output_mail_data)->date_time = p_output_mail_data->date_time;
171 (*output_mail_data)->full_address_return = EM_SAFE_STRDUP(p_output_mail_data->full_address_return);
172 (*output_mail_data)->email_address_recipient = EM_SAFE_STRDUP(p_output_mail_data->email_address_recipient);
173 (*output_mail_data)->email_address_sender = EM_SAFE_STRDUP(p_output_mail_data->email_address_sender);
174 (*output_mail_data)->full_address_reply = EM_SAFE_STRDUP(p_output_mail_data->full_address_reply);
175 (*output_mail_data)->full_address_from = EM_SAFE_STRDUP(p_output_mail_data->full_address_from);
176 (*output_mail_data)->full_address_to = EM_SAFE_STRDUP(p_output_mail_data->full_address_to);
177 (*output_mail_data)->full_address_cc = EM_SAFE_STRDUP(p_output_mail_data->full_address_cc);
178 (*output_mail_data)->full_address_bcc = EM_SAFE_STRDUP(p_output_mail_data->full_address_bcc);
179 (*output_mail_data)->flags_flagged_field = p_output_mail_data->flags_flagged_field;
183 EM_SAFE_FREE(decrypt_filepath);
186 emstorage_free_account(&p_account_tbl, 1, NULL);
188 if (p_output_mail_data)
189 email_free_mail_data(&p_output_mail_data, 1);
191 if (p_output_attachment_data)
192 email_free_attachment_data(&p_output_attachment_data, p_output_attachment_count);
194 EM_SAFE_FREE(multi_user_name);
196 EM_DEBUG_API_END("err[%d]", err);
200 EXPORT_API int email_get_decrypt_message_ex(email_mail_data_t *input_mail_data,
201 email_attachment_data_t *input_attachment_data,
202 int input_attachment_count,
203 email_mail_data_t **output_mail_data,
204 email_attachment_data_t **output_attachment_data,
205 int *output_attachment_count,
208 CHECK_EMAILS_SUPPORTED(EMAIL_FEATURE);
209 EM_DEBUG_API_BEGIN();
210 int err = EMAIL_ERROR_NONE;
212 char *decrypt_filepath = NULL;
214 char *multi_user_name = NULL;
215 emstorage_account_tbl_t *p_account_tbl = NULL;
217 EM_IF_NULL_RETURN_VALUE(input_mail_data, EMAIL_ERROR_INVALID_PARAM);
219 if (!output_mail_data || !output_attachment_data || !output_attachment_count) {
220 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
221 err = EMAIL_ERROR_INVALID_PARAM;
225 if ((err = emipc_get_user_name(&multi_user_name)) != EMAIL_ERROR_NONE) {
226 EM_DEBUG_EXCEPTION("emipc_get_user_name failed : [%d]", err);
230 if (!emstorage_get_account_by_id(multi_user_name, input_mail_data->account_id, EMAIL_ACC_GET_OPT_OPTIONS, &p_account_tbl, false, &err)) {
231 EM_DEBUG_EXCEPTION("emstorage_get_account_by_id failed : [%d]", err);
235 for (i = 0; i < input_attachment_count; i++) {
236 EM_DEBUG_LOG("mime_type : [%s]", input_attachment_data[i].attachment_mime_type);
237 if (input_attachment_data[i].attachment_mime_type && (search = strcasestr(input_attachment_data[i].attachment_mime_type, "PKCS7-MIME"))) {
238 EM_DEBUG_LOG("Found the encrypt file");
240 } else if (input_attachment_data[i].attachment_mime_type && (search = strcasestr(input_attachment_data[i].attachment_mime_type, "octet-stream"))) {
241 EM_DEBUG_LOG("Found the encrypt file");
247 EM_DEBUG_EXCEPTION("No have a decrypt file");
248 err = EMAIL_ERROR_INVALID_PARAM;
252 if (input_mail_data->smime_type == EMAIL_SMIME_ENCRYPTED || input_mail_data->smime_type == EMAIL_SMIME_SIGNED_AND_ENCRYPTED) {
253 emcore_init_openssl_library();
254 if (!emcore_smime_get_decrypt_message(input_attachment_data[i].attachment_path, p_account_tbl->certificate_path, &decrypt_filepath, &err)) {
255 EM_DEBUG_EXCEPTION("emcore_smime_get_decrypt_message failed");
256 emcore_clean_openssl_library();
259 emcore_clean_openssl_library();
260 } else if (input_mail_data->smime_type == EMAIL_PGP_ENCRYPTED) {
261 if ((err = emcore_pgp_get_decrypted_message(input_attachment_data[i].attachment_path, input_mail_data->pgp_password, false, &decrypt_filepath, verify)) != EMAIL_ERROR_NONE) {
262 EM_DEBUG_EXCEPTION("emcore_pgp_get_decrypted_message failed : [%d]", err);
265 } else if (input_mail_data->smime_type == EMAIL_PGP_SIGNED_AND_ENCRYPTED) {
266 if ((err = emcore_pgp_get_decrypted_message(input_attachment_data[i].attachment_path, input_mail_data->pgp_password, true, &decrypt_filepath, verify)) != EMAIL_ERROR_NONE) {
267 EM_DEBUG_EXCEPTION("emcore_pgp_get_decrypted_message failed : [%d]", err);
271 EM_DEBUG_LOG("Invalid encrypted mail");
272 err = EMAIL_ERROR_INVALID_PARAM;
276 /* Change decrpyt_message to mail_data_t */
277 if (!emcore_parse_mime_file_to_mail(decrypt_filepath, output_mail_data, output_attachment_data, output_attachment_count, &err)) {
278 EM_DEBUG_EXCEPTION("emcore_parse_mime_file_to_mail failed : [%d]", err);
282 (*output_mail_data)->subject = EM_SAFE_STRDUP(input_mail_data->subject);
283 (*output_mail_data)->date_time = input_mail_data->date_time;
284 (*output_mail_data)->full_address_return = EM_SAFE_STRDUP(input_mail_data->full_address_return);
285 (*output_mail_data)->email_address_recipient = EM_SAFE_STRDUP(input_mail_data->email_address_recipient);
286 (*output_mail_data)->email_address_sender = EM_SAFE_STRDUP(input_mail_data->email_address_sender);
287 (*output_mail_data)->full_address_reply = EM_SAFE_STRDUP(input_mail_data->full_address_reply);
288 (*output_mail_data)->full_address_from = EM_SAFE_STRDUP(input_mail_data->full_address_from);
289 (*output_mail_data)->full_address_to = EM_SAFE_STRDUP(input_mail_data->full_address_to);
290 (*output_mail_data)->full_address_cc = EM_SAFE_STRDUP(input_mail_data->full_address_cc);
291 (*output_mail_data)->full_address_bcc = EM_SAFE_STRDUP(input_mail_data->full_address_bcc);
292 (*output_mail_data)->flags_flagged_field = input_mail_data->flags_flagged_field;
296 EM_SAFE_FREE(decrypt_filepath);
297 EM_SAFE_FREE(multi_user_name);
300 emstorage_free_account(&p_account_tbl, 1, NULL);
302 EM_DEBUG_API_END("err[%d]", err);
306 EXPORT_API int email_verify_signature(int mail_id, int *verify)
308 CHECK_EMAILS_SUPPORTED(EMAIL_FEATURE);
309 EM_DEBUG_API_BEGIN("mail_id[%d]", mail_id);
312 EM_DEBUG_EXCEPTION("Invalid parameter");
313 return EMAIL_ERROR_INVALID_PARAM;
316 int result_from_ipc = 0;
318 int err = EMAIL_ERROR_NONE;
320 HIPC_API hAPI = emipc_create_email_api(_EMAIL_API_VERIFY_SIGNATURE);
322 EM_DEBUG_EXCEPTION("emipc_create_email_api failed");
323 err = EMAIL_ERROR_NULL_VALUE;
327 if (!emipc_add_parameter(hAPI, ePARAMETER_IN, &mail_id, sizeof(int))) {
328 EM_DEBUG_EXCEPTION("emipc_add_parameter pass_phrase[%d] failed", mail_id);
329 err = EMAIL_ERROR_NULL_VALUE;
333 if (emipc_execute_proxy_api(hAPI) < 0) {
334 EM_DEBUG_EXCEPTION("emipc_execute_proxy_api failed");
335 err = EMAIL_ERROR_IPC_SOCKET_FAILURE;
339 result_from_ipc = emipc_get_parameter(hAPI, ePARAMETER_OUT, 0, sizeof(int), &p_verify);
340 if (result_from_ipc != EMAIL_ERROR_NONE) {
341 EM_DEBUG_EXCEPTION("emipc_get_parameter failed");
342 err = EMAIL_ERROR_IPC_CRASH;
349 emipc_destroy_email_api(hAPI);
354 EM_DEBUG_API_END("err[%d]", err);
358 EXPORT_API int email_verify_signature_ex(email_mail_data_t *input_mail_data, email_attachment_data_t *input_attachment_data, int input_attachment_count, int *verify)
360 CHECK_EMAILS_SUPPORTED(EMAIL_FEATURE);
361 EM_DEBUG_API_BEGIN();
363 if (!input_mail_data || !input_attachment_data || input_attachment_count <= 0) {
364 EM_DEBUG_EXCEPTION("Invalid parameter");
365 return EMAIL_ERROR_INVALID_PARAM;
369 int err = EMAIL_ERROR_NONE;
371 for (count = 0; count < input_attachment_count ; count++) {
372 if (input_attachment_data[count].attachment_mime_type && strcasestr(input_attachment_data[count].attachment_mime_type, "SIGNATURE"))
376 if (count == input_attachment_count) {
377 EM_DEBUG_LOG("No have the signed attachment");
378 EM_DEBUG_EXCEPTION("Invalid parameter");
379 return EMAIL_ERROR_INVALID_PARAM;
382 if (input_mail_data->smime_type == EMAIL_SMIME_SIGNED) {
383 emcore_init_openssl_library();
384 if (!emcore_verify_signature(input_attachment_data[count].attachment_path, input_mail_data->file_path_mime_entity, verify, &err))
385 EM_DEBUG_EXCEPTION("emcore_verify_signature failed : [%d]", err);
387 emcore_clean_openssl_library();
388 } else if (input_mail_data->smime_type == EMAIL_PGP_SIGNED) {
389 if ((err = emcore_pgp_get_verify_signature(input_attachment_data[count].attachment_path, input_mail_data->file_path_mime_entity, input_mail_data->digest_type, verify)) != EMAIL_ERROR_NONE)
390 EM_DEBUG_EXCEPTION("emcore_pgp_get_verify_siganture failed : [%d]", err);
392 EM_DEBUG_LOG("Invalid signed mail : mime_type[%d]", input_mail_data->smime_type);
393 err = EMAIL_ERROR_INVALID_PARAM;
397 EM_DEBUG_API_END("err[%d]", err);
401 EXPORT_API int email_validate_certificate(int account_id, char *email_address, unsigned *handle)
403 CHECK_EMAILS_SUPPORTED(EMAIL_FEATURE);
404 EM_DEBUG_API_BEGIN("account_id[%d]", account_id);
405 EM_DEBUG_FUNC_BEGIN_SEC("account_id[%d] email_address[%s] handle[%p]", account_id, email_address, handle);
407 EM_IF_NULL_RETURN_VALUE(account_id, EMAIL_ERROR_INVALID_PARAM);
408 EM_IF_NULL_RETURN_VALUE(email_address, EMAIL_ERROR_INVALID_PARAM);
410 int err = EMAIL_ERROR_NONE;
412 char *multi_user_name = NULL;
413 email_account_server_t account_server_type;
414 ASNotiData as_noti_data;
416 if ((err = emipc_get_user_name(&multi_user_name)) != EMAIL_ERROR_NONE) {
417 EM_DEBUG_EXCEPTION("emipc_get_user_name failed : [%d]", err);
421 memset(&as_noti_data, 0x00, sizeof(ASNotiData));
423 if (em_get_account_server_type_by_account_id(multi_user_name, account_id, &account_server_type, false, &err) == false) {
424 EM_DEBUG_EXCEPTION("em_get_account_server_type_by_account_id failed[%d]", err);
425 err = EMAIL_ERROR_ACTIVE_SYNC_NOTI_FAILURE;
429 if (account_server_type != EMAIL_SERVER_TYPE_ACTIVE_SYNC) {
430 EM_DEBUG_EXCEPTION("This api is not supported except of active sync");
431 err = EMAIL_ERROR_ACTIVE_SYNC_NOTI_FAILURE;
435 if (em_get_handle_for_activesync(&as_handle, &err) == false) {
436 EM_DEBUG_EXCEPTION("em_get_handle_for_activesync_failed[%d]", err);
437 err = EMAIL_ERROR_ACTIVE_SYNC_NOTI_FAILURE;
441 as_noti_data.validate_certificate.handle = as_handle;
442 as_noti_data.validate_certificate.account_id = account_id;
443 as_noti_data.validate_certificate.email_address = email_address;
444 as_noti_data.validate_certificate.multi_user_name = multi_user_name;
446 if (em_send_notification_to_active_sync_engine(ACTIVE_SYNC_NOTI_VALIDATE_CERTIFICATE, &as_noti_data) == false) {
447 EM_DEBUG_EXCEPTION("em_send_notification_to_active_sync_engine failed");
448 err = EMAIL_ERROR_ACTIVE_SYNC_NOTI_FAILURE;
457 EM_SAFE_FREE(multi_user_name);
458 EM_DEBUG_API_END("err[%d]", err);
462 EXPORT_API int email_get_resolve_recipients(int account_id, char *email_address, unsigned *handle)
464 CHECK_EMAILS_SUPPORTED(EMAIL_FEATURE);
465 EM_DEBUG_API_BEGIN("account_id[%d]", account_id);
466 EM_DEBUG_FUNC_BEGIN_SEC("account_id[%d] email_address[%s] handle[%p]", account_id, email_address, handle);
468 EM_IF_NULL_RETURN_VALUE(account_id, EMAIL_ERROR_INVALID_PARAM);
469 EM_IF_NULL_RETURN_VALUE(email_address, EMAIL_ERROR_INVALID_PARAM);
471 int err = EMAIL_ERROR_NONE;
473 char *multi_user_name = NULL;
474 email_account_server_t account_server_type;
475 ASNotiData as_noti_data;
477 if ((err = emipc_get_user_name(&multi_user_name)) != EMAIL_ERROR_NONE) {
478 EM_DEBUG_EXCEPTION("emipc_get_user_name failed : [%d]", err);
482 memset(&as_noti_data, 0x00, sizeof(ASNotiData));
484 if (em_get_account_server_type_by_account_id(multi_user_name, account_id, &account_server_type, false, &err) == false) {
485 EM_DEBUG_EXCEPTION("em_get_account_server_type_by_account_id failed[%d]", err);
486 err = EMAIL_ERROR_ACTIVE_SYNC_NOTI_FAILURE;
490 if (account_server_type != EMAIL_SERVER_TYPE_ACTIVE_SYNC) {
491 EM_DEBUG_EXCEPTION("This api is not supported except of active sync");
492 err = EMAIL_ERROR_ACTIVE_SYNC_NOTI_FAILURE;
496 if (em_get_handle_for_activesync(&as_handle, &err) == false) {
497 EM_DEBUG_EXCEPTION("em_get_handle_for_activesync_failed[%d]", err);
498 err = EMAIL_ERROR_ACTIVE_SYNC_NOTI_FAILURE;
502 as_noti_data.get_resolve_recipients.handle = as_handle;
503 as_noti_data.get_resolve_recipients.account_id = account_id;
504 as_noti_data.get_resolve_recipients.email_address = email_address;
505 as_noti_data.get_resolve_recipients.multi_user_name = multi_user_name;
507 if (em_send_notification_to_active_sync_engine(ACTIVE_SYNC_NOTI_RESOLVE_RECIPIENT, &as_noti_data) == false) {
508 EM_DEBUG_EXCEPTION("em_send_notification_to_active_sync_engine failed");
509 err = EMAIL_ERROR_ACTIVE_SYNC_NOTI_FAILURE;
518 EM_SAFE_FREE(multi_user_name);
519 EM_DEBUG_API_END("err[%d]", err);
523 EXPORT_API int email_free_certificate(email_certificate_t **certificate, int count)
525 CHECK_EMAILS_SUPPORTED(EMAIL_FEATURE);
526 EM_DEBUG_API_BEGIN("");
527 return EMAIL_ERROR_NOT_SUPPORTED;