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 if (!emcore_smime_get_decrypt_message(p_output_attachment_data[i].attachment_path, p_account_tbl->certificate_path, &decrypt_filepath, &err)) {
141 EM_DEBUG_EXCEPTION("emcore_smime_get_decrypt_message failed");
144 } else if (p_output_mail_data->smime_type == EMAIL_PGP_ENCRYPTED) {
145 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) {
146 EM_DEBUG_EXCEPTION("emcore_pgp_get_decrypted_message failed : [%d]", err);
149 } else if (p_output_mail_data->smime_type == EMAIL_PGP_SIGNED_AND_ENCRYPTED) {
150 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) {
151 EM_DEBUG_EXCEPTION("emcore_pgp_get_decrypted_message failed : [%d]", err);
155 EM_DEBUG_LOG("Invalid encrypted mail");
156 err = EMAIL_ERROR_INVALID_PARAM;
160 /* Change decrpyt_message to mail_data_t */
161 if (!emcore_parse_mime_file_to_mail(decrypt_filepath, output_mail_data, output_attachment_data, output_attachment_count, &err)) {
162 EM_DEBUG_EXCEPTION("emcore_parse_mime_file_to_mail failed : [%d]", err);
166 (*output_mail_data)->subject = EM_SAFE_STRDUP(p_output_mail_data->subject);
167 (*output_mail_data)->date_time = p_output_mail_data->date_time;
168 (*output_mail_data)->full_address_return = EM_SAFE_STRDUP(p_output_mail_data->full_address_return);
169 (*output_mail_data)->email_address_recipient = EM_SAFE_STRDUP(p_output_mail_data->email_address_recipient);
170 (*output_mail_data)->email_address_sender = EM_SAFE_STRDUP(p_output_mail_data->email_address_sender);
171 (*output_mail_data)->full_address_reply = EM_SAFE_STRDUP(p_output_mail_data->full_address_reply);
172 (*output_mail_data)->full_address_from = EM_SAFE_STRDUP(p_output_mail_data->full_address_from);
173 (*output_mail_data)->full_address_to = EM_SAFE_STRDUP(p_output_mail_data->full_address_to);
174 (*output_mail_data)->full_address_cc = EM_SAFE_STRDUP(p_output_mail_data->full_address_cc);
175 (*output_mail_data)->full_address_bcc = EM_SAFE_STRDUP(p_output_mail_data->full_address_bcc);
176 (*output_mail_data)->flags_flagged_field = p_output_mail_data->flags_flagged_field;
180 EM_SAFE_FREE(decrypt_filepath);
183 emstorage_free_account(&p_account_tbl, 1, NULL);
185 if (p_output_mail_data)
186 email_free_mail_data(&p_output_mail_data, 1);
188 if (p_output_attachment_data)
189 email_free_attachment_data(&p_output_attachment_data, p_output_attachment_count);
191 EM_SAFE_FREE(multi_user_name);
193 EM_DEBUG_API_END("err[%d]", err);
197 EXPORT_API int email_get_decrypt_message_ex(email_mail_data_t *input_mail_data,
198 email_attachment_data_t *input_attachment_data,
199 int input_attachment_count,
200 email_mail_data_t **output_mail_data,
201 email_attachment_data_t **output_attachment_data,
202 int *output_attachment_count,
205 CHECK_EMAILS_SUPPORTED(EMAIL_FEATURE);
206 EM_DEBUG_API_BEGIN();
207 int err = EMAIL_ERROR_NONE;
209 char *decrypt_filepath = NULL;
211 char *multi_user_name = NULL;
212 emstorage_account_tbl_t *p_account_tbl = NULL;
214 EM_IF_NULL_RETURN_VALUE(input_mail_data, EMAIL_ERROR_INVALID_PARAM);
216 if (!output_mail_data || !output_attachment_data || !output_attachment_count) {
217 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
218 err = EMAIL_ERROR_INVALID_PARAM;
222 if ((err = emipc_get_user_name(&multi_user_name)) != EMAIL_ERROR_NONE) {
223 EM_DEBUG_EXCEPTION("emipc_get_user_name failed : [%d]", err);
227 if (!emstorage_get_account_by_id(multi_user_name, input_mail_data->account_id, EMAIL_ACC_GET_OPT_OPTIONS, &p_account_tbl, false, &err)) {
228 EM_DEBUG_EXCEPTION("emstorage_get_account_by_id failed : [%d]", err);
232 for (i = 0; i < input_attachment_count; i++) {
233 EM_DEBUG_LOG("mime_type : [%s]", input_attachment_data[i].attachment_mime_type);
234 if (input_attachment_data[i].attachment_mime_type && (search = strcasestr(input_attachment_data[i].attachment_mime_type, "PKCS7-MIME"))) {
235 EM_DEBUG_LOG("Found the encrypt file");
237 } else if (input_attachment_data[i].attachment_mime_type && (search = strcasestr(input_attachment_data[i].attachment_mime_type, "octet-stream"))) {
238 EM_DEBUG_LOG("Found the encrypt file");
244 EM_DEBUG_EXCEPTION("No have a decrypt file");
245 err = EMAIL_ERROR_INVALID_PARAM;
249 if (input_mail_data->smime_type == EMAIL_SMIME_ENCRYPTED || input_mail_data->smime_type == EMAIL_SMIME_SIGNED_AND_ENCRYPTED) {
250 if (!emcore_smime_get_decrypt_message(input_attachment_data[i].attachment_path, p_account_tbl->certificate_path, &decrypt_filepath, &err)) {
251 EM_DEBUG_EXCEPTION("emcore_smime_get_decrypt_message failed");
254 } else if (input_mail_data->smime_type == EMAIL_PGP_ENCRYPTED) {
255 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) {
256 EM_DEBUG_EXCEPTION("emcore_pgp_get_decrypted_message failed : [%d]", err);
259 } else if (input_mail_data->smime_type == EMAIL_PGP_SIGNED_AND_ENCRYPTED) {
260 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) {
261 EM_DEBUG_EXCEPTION("emcore_pgp_get_decrypted_message failed : [%d]", err);
265 EM_DEBUG_LOG("Invalid encrypted mail");
266 err = EMAIL_ERROR_INVALID_PARAM;
270 /* Change decrpyt_message to mail_data_t */
271 if (!emcore_parse_mime_file_to_mail(decrypt_filepath, output_mail_data, output_attachment_data, output_attachment_count, &err)) {
272 EM_DEBUG_EXCEPTION("emcore_parse_mime_file_to_mail failed : [%d]", err);
276 (*output_mail_data)->subject = EM_SAFE_STRDUP(input_mail_data->subject);
277 (*output_mail_data)->date_time = input_mail_data->date_time;
278 (*output_mail_data)->full_address_return = EM_SAFE_STRDUP(input_mail_data->full_address_return);
279 (*output_mail_data)->email_address_recipient = EM_SAFE_STRDUP(input_mail_data->email_address_recipient);
280 (*output_mail_data)->email_address_sender = EM_SAFE_STRDUP(input_mail_data->email_address_sender);
281 (*output_mail_data)->full_address_reply = EM_SAFE_STRDUP(input_mail_data->full_address_reply);
282 (*output_mail_data)->full_address_from = EM_SAFE_STRDUP(input_mail_data->full_address_from);
283 (*output_mail_data)->full_address_to = EM_SAFE_STRDUP(input_mail_data->full_address_to);
284 (*output_mail_data)->full_address_cc = EM_SAFE_STRDUP(input_mail_data->full_address_cc);
285 (*output_mail_data)->full_address_bcc = EM_SAFE_STRDUP(input_mail_data->full_address_bcc);
286 (*output_mail_data)->flags_flagged_field = input_mail_data->flags_flagged_field;
290 EM_SAFE_FREE(decrypt_filepath);
291 EM_SAFE_FREE(multi_user_name);
294 emstorage_free_account(&p_account_tbl, 1, NULL);
296 EM_DEBUG_API_END("err[%d]", err);
300 EXPORT_API int email_verify_signature(int mail_id, int *verify)
302 CHECK_EMAILS_SUPPORTED(EMAIL_FEATURE);
303 EM_DEBUG_API_BEGIN("mail_id[%d]", mail_id);
306 EM_DEBUG_EXCEPTION("Invalid parameter");
307 return EMAIL_ERROR_INVALID_PARAM;
310 int result_from_ipc = 0;
312 int err = EMAIL_ERROR_NONE;
314 HIPC_API hAPI = emipc_create_email_api(_EMAIL_API_VERIFY_SIGNATURE);
316 EM_DEBUG_EXCEPTION("emipc_create_email_api failed");
317 err = EMAIL_ERROR_NULL_VALUE;
321 if (!emipc_add_parameter(hAPI, ePARAMETER_IN, &mail_id, sizeof(int))) {
322 EM_DEBUG_EXCEPTION("emipc_add_parameter pass_phrase[%d] failed", mail_id);
323 err = EMAIL_ERROR_NULL_VALUE;
327 if (emipc_execute_proxy_api(hAPI) < 0) {
328 EM_DEBUG_EXCEPTION("emipc_execute_proxy_api failed");
329 err = EMAIL_ERROR_IPC_SOCKET_FAILURE;
333 result_from_ipc = emipc_get_parameter(hAPI, ePARAMETER_OUT, 0, sizeof(int), &p_verify);
334 if (result_from_ipc != EMAIL_ERROR_NONE) {
335 EM_DEBUG_EXCEPTION("emipc_get_parameter failed");
336 err = EMAIL_ERROR_IPC_CRASH;
343 emipc_destroy_email_api(hAPI);
348 EM_DEBUG_API_END("err[%d]", err);
352 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)
354 CHECK_EMAILS_SUPPORTED(EMAIL_FEATURE);
355 EM_DEBUG_API_BEGIN();
357 if (!input_mail_data || !input_attachment_data || input_attachment_count <= 0) {
358 EM_DEBUG_EXCEPTION("Invalid parameter");
359 return EMAIL_ERROR_INVALID_PARAM;
363 int err = EMAIL_ERROR_NONE;
365 for (count = 0; count < input_attachment_count ; count++) {
366 if (input_attachment_data[count].attachment_mime_type && strcasestr(input_attachment_data[count].attachment_mime_type, "SIGNATURE"))
370 if (count == input_attachment_count) {
371 EM_DEBUG_LOG("No have the signed attachment");
372 EM_DEBUG_EXCEPTION("Invalid parameter");
373 return EMAIL_ERROR_INVALID_PARAM;
376 if (input_mail_data->smime_type == EMAIL_SMIME_SIGNED) {
377 if (!emcore_verify_signature(input_attachment_data[count].attachment_path, input_mail_data->file_path_mime_entity, verify, &err))
378 EM_DEBUG_EXCEPTION("emcore_verify_signature failed : [%d]", err);
380 } else if (input_mail_data->smime_type == EMAIL_PGP_SIGNED) {
381 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)
382 EM_DEBUG_EXCEPTION("emcore_pgp_get_verify_siganture failed : [%d]", err);
384 EM_DEBUG_LOG("Invalid signed mail : mime_type[%d]", input_mail_data->smime_type);
385 err = EMAIL_ERROR_INVALID_PARAM;
389 EM_DEBUG_API_END("err[%d]", err);
393 EXPORT_API int email_validate_certificate(int account_id, char *email_address, unsigned *handle)
395 CHECK_EMAILS_SUPPORTED(EMAIL_FEATURE);
396 EM_DEBUG_API_BEGIN("account_id[%d]", account_id);
397 EM_DEBUG_FUNC_BEGIN_SEC("account_id[%d] email_address[%s] handle[%p]", account_id, email_address, handle);
399 EM_IF_NULL_RETURN_VALUE(account_id, EMAIL_ERROR_INVALID_PARAM);
400 EM_IF_NULL_RETURN_VALUE(email_address, EMAIL_ERROR_INVALID_PARAM);
402 int err = EMAIL_ERROR_NONE;
404 char *multi_user_name = NULL;
405 email_account_server_t account_server_type;
406 ASNotiData as_noti_data;
408 if ((err = emipc_get_user_name(&multi_user_name)) != EMAIL_ERROR_NONE) {
409 EM_DEBUG_EXCEPTION("emipc_get_user_name failed : [%d]", err);
413 memset(&as_noti_data, 0x00, sizeof(ASNotiData));
415 if (em_get_account_server_type_by_account_id(multi_user_name, account_id, &account_server_type, false, &err) == false) {
416 EM_DEBUG_EXCEPTION("em_get_account_server_type_by_account_id failed[%d]", err);
417 err = EMAIL_ERROR_ACTIVE_SYNC_NOTI_FAILURE;
421 if (account_server_type != EMAIL_SERVER_TYPE_ACTIVE_SYNC) {
422 EM_DEBUG_EXCEPTION("This api is not supported except of active sync");
423 err = EMAIL_ERROR_ACTIVE_SYNC_NOTI_FAILURE;
427 if (em_get_handle_for_activesync(&as_handle, &err) == false) {
428 EM_DEBUG_EXCEPTION("em_get_handle_for_activesync_failed[%d]", err);
429 err = EMAIL_ERROR_ACTIVE_SYNC_NOTI_FAILURE;
433 as_noti_data.validate_certificate.handle = as_handle;
434 as_noti_data.validate_certificate.account_id = account_id;
435 as_noti_data.validate_certificate.email_address = email_address;
436 as_noti_data.validate_certificate.multi_user_name = multi_user_name;
438 if (em_send_notification_to_active_sync_engine(ACTIVE_SYNC_NOTI_VALIDATE_CERTIFICATE, &as_noti_data) == false) {
439 EM_DEBUG_EXCEPTION("em_send_notification_to_active_sync_engine failed");
440 err = EMAIL_ERROR_ACTIVE_SYNC_NOTI_FAILURE;
449 EM_SAFE_FREE(multi_user_name);
450 EM_DEBUG_API_END("err[%d]", err);
454 EXPORT_API int email_get_resolve_recipients(int account_id, char *email_address, unsigned *handle)
456 CHECK_EMAILS_SUPPORTED(EMAIL_FEATURE);
457 EM_DEBUG_API_BEGIN("account_id[%d]", account_id);
458 EM_DEBUG_FUNC_BEGIN_SEC("account_id[%d] email_address[%s] handle[%p]", account_id, email_address, handle);
460 EM_IF_NULL_RETURN_VALUE(account_id, EMAIL_ERROR_INVALID_PARAM);
461 EM_IF_NULL_RETURN_VALUE(email_address, EMAIL_ERROR_INVALID_PARAM);
463 int err = EMAIL_ERROR_NONE;
465 char *multi_user_name = NULL;
466 email_account_server_t account_server_type;
467 ASNotiData as_noti_data;
469 if ((err = emipc_get_user_name(&multi_user_name)) != EMAIL_ERROR_NONE) {
470 EM_DEBUG_EXCEPTION("emipc_get_user_name failed : [%d]", err);
474 memset(&as_noti_data, 0x00, sizeof(ASNotiData));
476 if (em_get_account_server_type_by_account_id(multi_user_name, account_id, &account_server_type, false, &err) == false) {
477 EM_DEBUG_EXCEPTION("em_get_account_server_type_by_account_id failed[%d]", err);
478 err = EMAIL_ERROR_ACTIVE_SYNC_NOTI_FAILURE;
482 if (account_server_type != EMAIL_SERVER_TYPE_ACTIVE_SYNC) {
483 EM_DEBUG_EXCEPTION("This api is not supported except of active sync");
484 err = EMAIL_ERROR_ACTIVE_SYNC_NOTI_FAILURE;
488 if (em_get_handle_for_activesync(&as_handle, &err) == false) {
489 EM_DEBUG_EXCEPTION("em_get_handle_for_activesync_failed[%d]", err);
490 err = EMAIL_ERROR_ACTIVE_SYNC_NOTI_FAILURE;
494 as_noti_data.get_resolve_recipients.handle = as_handle;
495 as_noti_data.get_resolve_recipients.account_id = account_id;
496 as_noti_data.get_resolve_recipients.email_address = email_address;
497 as_noti_data.get_resolve_recipients.multi_user_name = multi_user_name;
499 if (em_send_notification_to_active_sync_engine(ACTIVE_SYNC_NOTI_RESOLVE_RECIPIENT, &as_noti_data) == false) {
500 EM_DEBUG_EXCEPTION("em_send_notification_to_active_sync_engine failed");
501 err = EMAIL_ERROR_ACTIVE_SYNC_NOTI_FAILURE;
510 EM_SAFE_FREE(multi_user_name);
511 EM_DEBUG_API_END("err[%d]", err);
515 EXPORT_API int email_free_certificate(email_certificate_t **certificate, int count)
517 CHECK_EMAILS_SUPPORTED(EMAIL_FEATURE);
518 EM_DEBUG_API_BEGIN("");
519 return EMAIL_ERROR_NOT_SUPPORTED;