Coverity issue fixes for email service
[platform/core/messaging/email-service.git] / email-core / email-core-pgp.c
1 /*
2 *  email-service
3 *
4 * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
5 *
6 * Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com>
7 *
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
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
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.
19 *
20 */
21
22
23
24 /* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ***
25  *File :  email-core-smime.c
26  *Desc :  MIME Operation
27  *
28  *Auth :
29  *
30  *History :
31  *   2011.04.14  :  created
32  ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ***/
33 #undef close
34
35 #include <glib.h>
36 #include <gmime/gmime.h>
37
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <fcntl.h>
42 #include <vconf.h>
43 #include <ctype.h>
44 #include <sys/stat.h>
45 #include <sys/time.h>
46 #include <glib.h>
47 #include <glib/gstdio.h>
48
49 #include "email-utilities.h"
50 #include "email-core-global.h"
51 #include "email-core-utils.h"
52 #include "email-core-mail.h"
53 #include "email-core-smtp.h"
54 #include "email-storage.h"
55 #include "email-core-cert.h"
56 #include "email-debug-log.h"
57
58 #define PGP_SIGNED_FILE     "signature.asc"
59 #define PGP_ENCRYPTED_FILE  "encrypted.asc"
60 #define DECRYPTED_TEMP_FILE "decrypted_temp_file.eml"
61
62 static char *passphrase = NULL;
63
64 static gboolean request_passwd(GMimeCryptoContext *ctx, const char *user_id,
65                                                                 const char *prompt_ctx, gboolean reprompt,
66                                                                 GMimeStream *response, GError **err)
67 {
68         EM_DEBUG_FUNC_BEGIN();
69         EM_DEBUG_LOG("passpharse : [%s]", passphrase);
70         if (g_mime_stream_write_string(response, passphrase) == -1 ||
71             g_mime_stream_write(response, "\n", 1) == -1) {
72                 g_set_error(err, GMIME_ERROR, errno, "%s", g_strerror(errno));
73                 return false;
74         }
75
76         EM_SAFE_FREE(passphrase);
77
78         EM_DEBUG_FUNC_END();
79         return true;
80 }
81
82 static int emcore_pgp_get_gmime_digest_algo(email_digest_type digest_type)
83 {
84         EM_DEBUG_FUNC_BEGIN();
85         int gmime_digest_algo = GMIME_DIGEST_ALGO_DEFAULT;
86
87         switch (digest_type) {
88         case DIGEST_TYPE_SHA1:
89                 gmime_digest_algo = GMIME_DIGEST_ALGO_SHA1;
90                 break;
91         case DIGEST_TYPE_MD5:
92                 gmime_digest_algo = GMIME_DIGEST_ALGO_MD5;
93                 break;
94         case DIGEST_TYPE_RIPEMD160:
95                 gmime_digest_algo = GMIME_DIGEST_ALGO_RIPEMD160;
96                 break;
97         case DIGEST_TYPE_MD2:
98                 gmime_digest_algo = GMIME_DIGEST_ALGO_MD2;
99                 break;
100         case DIGEST_TYPE_TIGER192:
101                 gmime_digest_algo = GMIME_DIGEST_ALGO_TIGER192;
102                 break;
103         case DIGEST_TYPE_HAVAL5160:
104                 gmime_digest_algo = GMIME_DIGEST_ALGO_HAVAL5160;
105                 break;
106         case DIGEST_TYPE_SHA256:
107                 gmime_digest_algo = GMIME_DIGEST_ALGO_SHA256;
108                 break;
109         case DIGEST_TYPE_SHA384:
110                 gmime_digest_algo = GMIME_DIGEST_ALGO_SHA384;
111                 break;
112         case DIGEST_TYPE_SHA512:
113                 gmime_digest_algo = GMIME_DIGEST_ALGO_SHA512;
114                 break;
115         case DIGEST_TYPE_SHA224:
116                 gmime_digest_algo = GMIME_DIGEST_ALGO_SHA224;
117                 break;
118         case DIGEST_TYPE_MD4:
119                 gmime_digest_algo = GMIME_DIGEST_ALGO_MD4;
120                 break;
121         default:
122                 gmime_digest_algo = GMIME_DIGEST_ALGO_DEFAULT;
123                 break;
124         }
125
126         EM_DEBUG_FUNC_END();
127         return gmime_digest_algo;
128 }
129
130 static int get_stack_of_recipients(char *recipients, GPtrArray **output_recipients_array)
131 {
132         EM_DEBUG_FUNC_BEGIN();
133         int err                       = EMAIL_ERROR_NONE;
134         char *temp_key                = NULL;
135         char *keys                    = NULL;
136         GPtrArray *p_recipients_array = NULL;
137         gchar **strings               = NULL;
138         gchar **ptr                   = NULL;
139
140         p_recipients_array = g_ptr_array_new();
141         if (p_recipients_array == NULL) {
142                 EM_DEBUG_EXCEPTION("g_ptr_array_new failed");
143                 err = EMAIL_ERROR_OUT_OF_MEMORY;
144                 goto FINISH_OFF;
145         }
146
147         keys = EM_SAFE_STRDUP(recipients);
148         strings = g_strsplit(keys, ",", -1);
149
150         for (ptr = strings; *ptr; ptr++) {
151                 temp_key = NULL;
152                 temp_key = g_strdup_printf("0x%s", *(ptr));
153                 g_ptr_array_add(p_recipients_array, temp_key);
154           }
155
156 FINISH_OFF:
157         g_strfreev(strings);
158         EM_SAFE_FREE(keys);
159         if (err != EMAIL_ERROR_NONE)
160                 g_ptr_array_free(p_recipients_array, true);
161         else
162                 *output_recipients_array = p_recipients_array;
163
164         EM_DEBUG_FUNC_END();
165         return err;
166 }
167
168 static GMimeSignatureStatus get_signature_status(GMimeSignatureList *signatures)
169 {
170         EM_DEBUG_FUNC_BEGIN();
171
172         int i = 0;
173
174         GMimeSignature *sig = NULL;
175         GMimeSignatureStatus status = GMIME_SIGNATURE_STATUS_GOOD;
176
177         if (!signatures || signatures->array->len == 0)
178                 return GMIME_SIGNATURE_STATUS_ERROR;
179
180         for (i = 0; i < g_mime_signature_list_length(signatures); i++) {
181                 sig = g_mime_signature_list_get_signature(signatures, i);
182                 if (sig) status = MAX(status, sig->status);
183         }
184
185         EM_DEBUG_FUNC_END();
186
187         return status;
188 }
189
190 INTERNAL_FUNC int emcore_pgp_set_signed_message(char *certificate,
191                                                                                                 char *password,
192                                                                                                 char *mime_entity,
193                                                                                                 char *user_id,
194                                                                                                 email_digest_type digest_type,
195                                                                                                 char **file_path)
196 {
197         EM_DEBUG_FUNC_BEGIN_SEC("Certificate path : [%s], mime_entity : [%s]", certificate, mime_entity);
198
199 #ifdef __FEATURE_SECURE_PGP__
200         int err = EMAIL_ERROR_NONE;
201         int clear_fd = 0;
202         int gpg_fd = 0;
203         int p_digest_type = 0;
204         char temp_pgp_filepath[512] = {0, };
205
206         GMimeCryptoContext *ctx  = NULL;
207         GMimeStream *clear_text  = NULL;
208         GMimeStream *signed_text = NULL;
209         GError *g_err            = NULL;
210
211         if (!password || !mime_entity || !user_id) {
212                 EM_DEBUG_EXCEPTION("Invalid param");
213                 err = EMAIL_ERROR_INVALID_PARAM;
214                 return err;
215         }
216
217         /* Initialized the output stream (signed stream) */
218         EM_SAFE_FREE(passphrase);
219         passphrase = EM_SAFE_STRDUP(password);
220
221 #if !GLIB_CHECK_VERSION(2, 31, 0)
222         g_thread_init(NULL);
223 #endif
224         g_mime_init(0);
225
226         SNPRINTF(temp_pgp_filepath, sizeof(temp_pgp_filepath), "%s%s%s", MAIL_TEMP, DIR_SEPERATOR, PGP_SIGNED_FILE);
227         EM_DEBUG_LOG_SEC("attachment file path of pgp : [%s]", temp_pgp_filepath);
228
229         err = em_open(temp_pgp_filepath, O_CREAT|O_TRUNC|O_RDWR, S_IRUSR|S_IWUSR|S_IWGRP|S_IRGRP|S_IROTH, &gpg_fd);
230         if (err != EMAIL_ERROR_NONE) {
231                 EM_DEBUG_EXCEPTION("em_open failed : [%s] [%d]", temp_pgp_filepath, err);
232                 goto FINISH_OFF;
233         }
234
235         signed_text = g_mime_stream_fs_new(gpg_fd);
236         if (g_mime_stream_reset(signed_text) == -1) {
237                 EM_DEBUG_EXCEPTION("g_mime_stream_reset signed_text failed");
238                 err = EMAIL_ERROR_SYSTEM_FAILURE;
239                 goto FINISH_OFF;
240         }
241
242         ctx = g_mime_gpg_context_new(request_passwd, "/usr/bin/gpg");
243         g_mime_gpg_context_set_always_trust((GMimeGpgContext *)ctx, true);
244
245         /* Initialized the input stream (clear text stream) */
246         EM_DEBUG_LOG("mime_entity : [%s]", mime_entity);
247         err = em_open(mime_entity, O_RDONLY, 0, &clear_fd);
248         if (err != EMAIL_ERROR_NONE) {
249                 EM_DEBUG_EXCEPTION("em_open failed : [%s] [%d]", mime_entity, err);
250                 goto FINISH_OFF;
251         }
252
253         clear_text = g_mime_stream_fs_new(clear_fd);
254         if (g_mime_stream_reset(clear_text) == -1) {
255                 EM_DEBUG_EXCEPTION("g_mime_stream_reset clear_text failed");
256                 err = EMAIL_ERROR_SYSTEM_FAILURE;
257                 goto FINISH_OFF;
258         }
259
260         /* Get the digest type of gmime */
261         p_digest_type = emcore_pgp_get_gmime_digest_algo(digest_type);
262
263         /* Set the signed message */
264         if ((g_mime_crypto_context_sign(ctx,
265                                                                         user_id,
266                                                                         p_digest_type,
267                                                                         clear_text,
268                                                                         signed_text,
269                                                                         &g_err) < 0) && (g_err != NULL)) {
270                 EM_DEBUG_EXCEPTION("g_mime_crypto_context_sign failed : [%s]", g_err->message);
271                 err = EMAIL_ERROR_SYSTEM_FAILURE;
272                 goto FINISH_OFF;
273         }
274
275 FINISH_OFF:
276
277         if (g_err)
278                 g_error_free(g_err);
279
280         if (clear_text)
281                 g_object_unref(clear_text);
282
283         if (signed_text)
284                 g_object_unref(signed_text);
285
286         if (ctx)
287                 g_object_unref(ctx);
288
289         g_mime_shutdown();
290
291         close(clear_fd);
292         close(gpg_fd);
293
294         if (file_path)
295                 *file_path = EM_SAFE_STRDUP(temp_pgp_filepath);
296
297         return err;
298 #else /* __FEATURE_SECURE_PGP__ */
299
300         return EMAIL_ERROR_NOT_SUPPORTED;
301
302 #endif
303 }
304
305 INTERNAL_FUNC int emcore_pgp_set_encrypted_message(char *recipient_list,
306                                                                                                         char *certificate,
307                                                                                                         char *password,
308                                                                                                         char *mime_entity,
309                                                                                                         char *user_id,
310                                                                                                         email_digest_type digest_type,
311                                                                                                         char **file_path)
312 {
313         EM_DEBUG_FUNC_BEGIN_SEC("Certificate path : [%s], mime_entity : [%s]", certificate, mime_entity);
314
315 #ifdef __FEATURE_SECURE_PGP__
316         int err = EMAIL_ERROR_NONE;
317         int clear_fd = 0;
318         int gpg_fd = 0;
319         int p_digest_type = 0;
320         char temp_pgp_filepath[512] = {0, };
321
322         GPtrArray *recipients = NULL;
323
324         GMimeCryptoContext *ctx     = NULL;
325         GMimeStream *clear_text     = NULL;
326         GMimeStream *encrypted_text = NULL;
327         GError *g_err               = NULL;
328
329         if (!recipient_list || !mime_entity || !user_id) {
330                 EM_DEBUG_EXCEPTION("Invalid param");
331                 err = EMAIL_ERROR_INVALID_PARAM;
332                 return err;
333         }
334
335         /* Initialized the output stream (signed stream) */
336 #if !GLIB_CHECK_VERSION(2, 31, 0)
337         g_thread_init(NULL);
338 #endif
339         g_mime_init(0);
340
341         SNPRINTF(temp_pgp_filepath, sizeof(temp_pgp_filepath), "%s%s%s", MAIL_TEMP, DIR_SEPERATOR, PGP_ENCRYPTED_FILE);
342         EM_DEBUG_LOG_SEC("attachment file path of pgp : [%s]", temp_pgp_filepath);
343
344         err = em_open(temp_pgp_filepath, O_CREAT|O_TRUNC|O_RDWR, S_IRUSR|S_IWUSR|S_IWGRP|S_IRGRP|S_IROTH, &gpg_fd);
345         if (err != EMAIL_ERROR_NONE) {
346                 EM_DEBUG_EXCEPTION("em_open failed : [%s] [%d]", temp_pgp_filepath, err);
347                 goto FINISH_OFF;
348         }
349
350         encrypted_text = g_mime_stream_fs_new(gpg_fd);
351         if (g_mime_stream_reset(encrypted_text) == -1) {
352                 EM_DEBUG_EXCEPTION("g_mime_stream_reset encrypted_text failed");
353                 err = EMAIL_ERROR_SYSTEM_FAILURE;
354                 goto FINISH_OFF;
355         }
356
357         ctx = g_mime_gpg_context_new(request_passwd, "/usr/bin/gpg");
358         g_mime_gpg_context_set_always_trust((GMimeGpgContext *)ctx, true);
359
360         /* Initialized the input stream (clear text stream) */
361         EM_DEBUG_LOG("mime_entity : [%s]", mime_entity);
362         err = em_open(mime_entity, O_RDONLY, 0, &clear_fd);
363         if (err != EMAIL_ERROR_NONE) {
364                 EM_DEBUG_EXCEPTION("em_open failed : [%s] [%d]", mime_entity, err);
365                 goto FINISH_OFF;
366         }
367
368         clear_text = g_mime_stream_fs_new(clear_fd);
369         if (g_mime_stream_reset(clear_text) == -1) {
370                 EM_DEBUG_EXCEPTION("g_mime_stream_reset clear_text failed");
371                 err = EMAIL_ERROR_SYSTEM_FAILURE;
372                 goto FINISH_OFF;
373         }
374
375         /* Get the digest type of gmime */
376         p_digest_type = emcore_pgp_get_gmime_digest_algo(digest_type);
377
378         /* Set the recipients list */
379         if ((err = get_stack_of_recipients(recipient_list, &recipients)) != EMAIL_ERROR_NONE) {
380                 EM_DEBUG_EXCEPTION("get_stack_of_recipients failed : [%d]", err);
381                 goto FINISH_OFF;
382         }
383
384         /* Set the signed message */
385         if ((g_mime_crypto_context_encrypt(ctx,
386                                                                                 false,
387                                                                                 user_id,
388                                                                                 p_digest_type,
389                                                                                 recipients,
390                                                                                 clear_text,
391                                                                                 encrypted_text,
392                                                                                 &g_err) < 0) && (g_err != NULL)) {
393                 EM_DEBUG_EXCEPTION("NO signature : g_mime_crypto_context_encrypt failed : [%s]", g_err->message);
394                 err = EMAIL_ERROR_SYSTEM_FAILURE;
395                 goto FINISH_OFF;
396         }
397
398 FINISH_OFF:
399
400         g_ptr_array_free(recipients, true);
401
402         if (g_err)
403                 g_error_free(g_err);
404
405         if (clear_text)
406                 g_object_unref(clear_text);
407
408         if (encrypted_text)
409                 g_object_unref(encrypted_text);
410
411         if (ctx)
412                 g_object_unref(ctx);
413
414         g_mime_shutdown();
415
416         close(clear_fd);
417         close(gpg_fd);
418
419         if (file_path)
420                 *file_path = EM_SAFE_STRDUP(temp_pgp_filepath);
421
422         return err;
423 #else /* __FEATURE_SECURE_PGP__ */
424
425         return EMAIL_ERROR_NOT_SUPPORTED;
426
427 #endif
428
429 }
430
431 INTERNAL_FUNC int emcore_pgp_set_signed_and_encrypted_message(char *recipient_list,
432                                                                                                                                 char *certificate,
433                                                                                                                                 char *password,
434                                                                                                                                 char *mime_entity,
435                                                                                                                                 char *user_id,
436                                                                                                                                 email_digest_type digest_type,
437                                                                                                                                 char **file_path)
438 {
439         EM_DEBUG_FUNC_BEGIN_SEC("mime_entity : [%s]", mime_entity);
440
441 #ifdef __FEATURE_SECURE_PGP__
442         int err                     = EMAIL_ERROR_NONE;
443         int clear_fd                = 0;
444         int gpg_fd                  = 0;
445         int p_digest_type           = 0;
446         char temp_pgp_filepath[512] = {0, };
447
448         GPtrArray *recipients       = NULL;
449         GMimeCryptoContext *ctx     = NULL;
450         GMimeStream *clear_text     = NULL;
451         GMimeStream *encrypted_text = NULL;
452         GError *g_err               = NULL;
453
454         if (!recipient_list || !password || !mime_entity || !user_id) {
455                 EM_DEBUG_EXCEPTION("Invalid param");
456                 err = EMAIL_ERROR_INVALID_PARAM;
457                 return err;
458         }
459
460         /* Initialized the output stream (signed stream) */
461         EM_SAFE_FREE(passphrase);
462         passphrase = strdup(password);
463
464 #if !GLIB_CHECK_VERSION(2, 31, 0)
465         g_thread_init(NULL);
466 #endif
467         g_mime_init(0);
468
469         SNPRINTF(temp_pgp_filepath, sizeof(temp_pgp_filepath), "%s%s%s", MAIL_TEMP, DIR_SEPERATOR, PGP_ENCRYPTED_FILE);
470         EM_DEBUG_LOG_SEC("attachment file path of pgp : [%s]", temp_pgp_filepath);
471
472         err = em_open(temp_pgp_filepath, O_CREAT|O_TRUNC|O_RDWR, S_IRUSR|S_IWUSR|S_IWGRP|S_IRGRP|S_IROTH, &gpg_fd);
473         if (err != EMAIL_ERROR_NONE) {
474                 EM_DEBUG_EXCEPTION("em_open failed : [%s], [%d]", temp_pgp_filepath, err);
475                 goto FINISH_OFF;
476         }
477
478         encrypted_text = g_mime_stream_fs_new(gpg_fd);
479         if (g_mime_stream_reset(encrypted_text) == -1) {
480                 EM_DEBUG_EXCEPTION("g_mime_stream_reset encrypted_text failed");
481                 err = EMAIL_ERROR_SYSTEM_FAILURE;
482                 goto FINISH_OFF;
483         }
484
485         ctx = g_mime_gpg_context_new(request_passwd, "/usr/bin/gpg");
486         g_mime_gpg_context_set_always_trust((GMimeGpgContext *)ctx, true);
487
488         /* Initialized the input stream (clear text stream) */
489         EM_DEBUG_LOG("mime_entity : [%s]", mime_entity);
490         err = em_open(mime_entity, O_RDONLY, 0, &clear_fd);
491         if (err != EMAIL_ERROR_NONE) {
492                 EM_DEBUG_EXCEPTION("em_open failed : [%s] [%d]", mime_entity, err);
493                 goto FINISH_OFF;
494         }
495
496         clear_text = g_mime_stream_fs_new(clear_fd);
497         if (g_mime_stream_reset(clear_text) == -1) {
498                 EM_DEBUG_EXCEPTION("g_mime_stream_reset clear_text failed");
499                 err = EMAIL_ERROR_SYSTEM_FAILURE;
500                 goto FINISH_OFF;
501         }
502
503         /* Get the digest type of gmime */
504         p_digest_type = emcore_pgp_get_gmime_digest_algo(digest_type);
505
506         /* Set the recipients list */
507         if ((err = get_stack_of_recipients(recipient_list, &recipients)) != EMAIL_ERROR_NONE) {
508                 EM_DEBUG_EXCEPTION("get_stack_of_recipients failed : [%d]", err);
509                 goto FINISH_OFF;
510         }
511
512         /* Set the signed message */
513         if ((g_mime_crypto_context_encrypt(ctx,
514                                                                                 true,
515                                                                                 user_id,
516                                                                                 p_digest_type,
517                                                                                 recipients,
518                                                                                 clear_text,
519                                                                                 encrypted_text,
520                                                                                 &g_err) < 0) && (g_err != NULL)) {
521                 EM_DEBUG_EXCEPTION("Signature : g_mime_crypto_context_encrypt failed : [%s]", g_err->message);
522                 err = EMAIL_ERROR_SYSTEM_FAILURE;
523                 goto FINISH_OFF;
524         }
525
526 FINISH_OFF:
527
528         g_ptr_array_free(recipients, true);
529
530         if (g_err)
531                 g_error_free(g_err);
532
533         if (clear_text)
534                 g_object_unref(clear_text);
535
536         if (encrypted_text)
537                 g_object_unref(encrypted_text);
538
539         if (ctx)
540                 g_object_unref(ctx);
541
542         g_mime_shutdown();
543
544         close(clear_fd);
545         close(gpg_fd);
546
547         if (file_path)
548                 *file_path = EM_SAFE_STRDUP(temp_pgp_filepath);
549
550         return err;
551 #else /* __FEATURE_SECURE_PGP__ */
552
553         return EMAIL_ERROR_NOT_SUPPORTED;
554
555 #endif
556
557 }
558
559 INTERNAL_FUNC int emcore_pgp_get_verify_signature(char *signature_path,
560                                                                                                         char *mime_entity,
561                                                                                                         email_digest_type digest_type,
562                                                                                                         int *verify)
563 {
564         EM_DEBUG_FUNC_BEGIN_SEC("signature path : [%s], mime_entity : [%s]", signature_path, mime_entity);
565
566 #ifdef __FEATURE_SECURE_PGP__
567         int err = EMAIL_ERROR_NONE;
568         int clear_fd = 0;
569         int signed_fd = 0;
570         int p_digest_type = 0;
571         int p_verify = false;
572
573         GMimeCryptoContext *ctx        = NULL;
574         GMimeStream *clear_text        = NULL;
575         GMimeStream *signed_text       = NULL;
576         GMimeSignatureList *signatures = NULL;
577         GError *g_err                  = NULL;
578
579         if (!signature_path || !mime_entity) {
580                 EM_DEBUG_EXCEPTION("Invalid param");
581                 err = EMAIL_ERROR_INVALID_PARAM;
582                 return err;
583         }
584
585         /* Initialized the Context */
586 #if !GLIB_CHECK_VERSION(2, 31, 0)
587         g_thread_init(NULL);
588 #endif
589         g_mime_init(0);
590
591         ctx = g_mime_gpg_context_new(request_passwd, "/usr/bin/gpg");
592         g_mime_gpg_context_set_always_trust((GMimeGpgContext *)ctx, true);
593
594         /* Initialized the input stream (clear text stream) */
595         EM_DEBUG_LOG("mime_entity : [%s]", mime_entity);
596         err = em_open(mime_entity, O_RDONLY, 0, &clear_fd);
597         if (err != EMAIL_ERROR_NONE) {
598                 EM_DEBUG_EXCEPTION("em_open failed : [%s] [%d]", mime_entity, err);
599                 goto FINISH_OFF;
600         }
601
602         clear_text = g_mime_stream_fs_new(clear_fd);
603         if (g_mime_stream_reset(clear_text) == -1) {
604                 EM_DEBUG_EXCEPTION("g_mime_stream_reset clear_text failed");
605                 err = EMAIL_ERROR_SYSTEM_FAILURE;
606                 goto FINISH_OFF;
607         }
608
609         /* Initialized the output stream (signed stream) */
610         EM_DEBUG_LOG("signature_path : [%s]", signature_path);
611         err = em_open(signature_path, O_RDONLY, 0, &signed_fd);
612         if (err != EMAIL_ERROR_NONE) {
613                 EM_DEBUG_EXCEPTION("em_open failed : [%s] [%d]", signature_path, err);
614                 goto FINISH_OFF;
615         }
616
617         signed_text = g_mime_stream_fs_new(signed_fd);
618         if (g_mime_stream_reset(signed_text) == -1) {
619                 EM_DEBUG_EXCEPTION("g_mime_stream_reset signed_text failed");
620                 err = EMAIL_ERROR_SYSTEM_FAILURE;
621                 goto FINISH_OFF;
622         }
623
624         /* Get the digest type of gmime */
625         p_digest_type = emcore_pgp_get_gmime_digest_algo(digest_type);
626
627         /* Verify the signature */
628         signatures = g_mime_crypto_context_verify(ctx, p_digest_type, clear_text, signed_text, &g_err);
629         if (signatures == NULL) {
630                 EM_DEBUG_EXCEPTION("g_mime_crypto_context_verify failed : [%s]", g_err->message);
631                 err = EMAIL_ERROR_SYSTEM_FAILURE;
632                 goto FINISH_OFF;
633         }
634
635         if (get_signature_status(signatures) != GMIME_SIGNATURE_STATUS_GOOD) {
636                 EM_DEBUG_LOG("Invalid the signature");
637                 goto FINISH_OFF;
638         }
639
640         p_verify = true;
641
642 FINISH_OFF:
643
644         if (g_err)
645                 g_error_free(g_err);
646
647         if (signatures)
648                 g_object_unref(signatures);
649
650         if (clear_text)
651                 g_object_unref(clear_text);
652
653         if (signed_text)
654                 g_object_unref(signed_text);
655
656         if (ctx)
657                 g_object_unref(ctx);
658
659         g_mime_shutdown();
660
661         close(clear_fd);
662         close(signed_fd);
663
664         if (verify)
665                 *verify = p_verify;
666
667         return err;
668 #else /* __FEATURE_SECURE_PGP__ */
669
670         return EMAIL_ERROR_NOT_SUPPORTED;
671
672 #endif
673
674 }
675
676 INTERNAL_FUNC int emcore_pgp_get_decrypted_message(char *encrypted_message,
677                                                                                                         char *password,
678                                                                                                         int sign,
679                                                                                                         char **decrypted_file,
680                                                                                                         int *verify)
681 {
682         EM_DEBUG_FUNC_BEGIN_SEC("Encrypted message : [%s], password : [%s]", encrypted_message, password);
683
684 #ifdef __FEATURE_SECURE_PGP__
685         int err                         = EMAIL_ERROR_NONE;
686         int p_verify                    = false;
687         int decrypted_fd                = 0;
688         int encrypted_fd                = 0;
689         char temp_decrypt_filepath[512] = {0, };
690
691         GError *g_err                   = NULL;
692         GMimeCryptoContext *ctx         = NULL;
693         GMimeDecryptResult *result      = NULL;
694         GMimeStream *encrypted_text     = NULL;
695         GMimeStream *decrypted_text     = NULL;
696
697         if (!encrypted_message && !password) {
698                 EM_DEBUG_EXCEPTION("Invalid parameter");
699                 err = EMAIL_ERROR_INVALID_PARAM;
700                 return err;
701         }
702
703         EM_SAFE_FREE(passphrase);
704         passphrase = EM_SAFE_STRDUP(password);
705
706 #if !GLIB_CHECK_VERSION(2, 31, 0)
707         g_thread_init(NULL);
708 #endif
709         g_mime_init(0);
710
711         /* Initialized the context */
712         ctx = g_mime_gpg_context_new(request_passwd, "/usr/bin/gpg");
713         g_mime_gpg_context_set_always_trust((GMimeGpgContext *)ctx, true);
714
715         /* Initialized the input stream (clear text stream) */
716         err = em_open(encrypted_message, O_RDONLY, 0, &encrypted_fd);
717         if (err != EMAIL_ERROR_NONE) {
718                 EM_DEBUG_EXCEPTION("em_open failed : [%s] [%d]", encrypted_message, err);
719                 goto FINISH_OFF;
720         }
721
722         encrypted_text = g_mime_stream_fs_new(encrypted_fd);
723         if (g_mime_stream_reset(encrypted_text) == -1) {
724                 EM_DEBUG_EXCEPTION("g_mime_stream_reset encrypted_text failed");
725                 err = EMAIL_ERROR_SYSTEM_FAILURE;
726                 goto FINISH_OFF;
727         }
728
729         /* Initialized the output stream (signed stream) */
730         SNPRINTF(temp_decrypt_filepath, sizeof(temp_decrypt_filepath), "%s%s%s", MAIL_TEMP, DIR_SEPERATOR, DECRYPTED_TEMP_FILE);
731         EM_DEBUG_LOG_SEC("tmp decrypt file path : [%s]", temp_decrypt_filepath);
732
733         err = em_open(temp_decrypt_filepath, O_CREAT|O_TRUNC|O_RDWR, S_IRUSR|S_IWUSR|S_IWGRP|S_IRGRP|S_IROTH, &decrypted_fd);
734         if (err != EMAIL_ERROR_NONE) {
735                 EM_DEBUG_EXCEPTION("em_open failed : [%s] [%d]", temp_decrypt_filepath, err);
736                 goto FINISH_OFF;
737         }
738
739         decrypted_text = g_mime_stream_fs_new(decrypted_fd);
740         if (g_mime_stream_reset(decrypted_text) == -1) {
741                 EM_DEBUG_EXCEPTION("g_mime_stream_reset decrypted_text failed");
742                 err = EMAIL_ERROR_SYSTEM_FAILURE;
743                 goto FINISH_OFF;
744         }
745
746         /* Get the decrypt message */
747         result = g_mime_crypto_context_decrypt(ctx, encrypted_text, decrypted_text, &g_err);
748         if (result == NULL) {
749                 EM_DEBUG_EXCEPTION("g_mime_crypto_context_decrypt failed : [%s]", g_err->message);
750                 err = EMAIL_ERROR_DECRYPT_FAILED;
751                 goto FINISH_OFF;
752         }
753
754         if (result->signatures) {
755                 if (get_signature_status(result->signatures) != GMIME_SIGNATURE_STATUS_GOOD)
756                         p_verify = false;
757                 else
758                         p_verify = true;
759         } else {
760                    p_verify = -1;
761         }
762
763 FINISH_OFF:
764
765         if (g_err)
766                 g_error_free(g_err);
767
768         if (ctx)
769                 g_object_unref(ctx);
770
771         if (encrypted_text)
772                 g_object_unref(encrypted_text);
773
774         if (decrypted_text)
775                 g_object_unref(decrypted_text);
776
777         if (result)
778                 g_object_unref(result);
779
780         g_mime_shutdown();
781
782         close(encrypted_fd);
783         close(decrypted_fd);
784
785         if (verify)
786                 *verify = p_verify;
787
788         if (decrypted_file)
789                 *decrypted_file = EM_SAFE_STRDUP(temp_decrypt_filepath);
790
791         return err;
792 #else /* __FEATURE_SECURE_PGP__ */
793
794         return EMAIL_ERROR_NOT_SUPPORTED;
795
796 #endif
797 }
798