40f8ce66d47e0023c4eb4189034a44672f6d442a
[platform/core/messaging/email-service.git] / email-core / email-core-cert.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  * File :  email-core-cert.h
25  * Desc :  Certificate API
26  *
27  * Auth :
28  *
29  * History :
30  *    2006.08.16  :  created
31  *****************************************************************************/
32 #include <openssl/pkcs7.h>
33 #include <openssl/pkcs12.h>
34 #include <openssl/pem.h>
35 #include <openssl/err.h>
36 #include <cert-service.h>
37 #include <glib.h>
38 #include <cert-svc/ccert.h>
39 #include <cert-svc/cstring.h>
40 #include <cert-svc/cpkcs12.h>
41 #include <cert-svc/cinstance.h>
42 #include <cert-svc/cprimitives.h>
43
44 #include "email-core-cert.h"
45 #include "email-core-mail.h"
46 #include "email-core-utils.h"
47 #include "email-utilities.h"
48 #include "email-storage.h"
49 #include "email-debug-log.h"
50
51 #define READ_MODE "r"
52 #define WRITE_MODE "w"
53
54 #define TRUSTED_USER "trusteduser/email/"
55
56 typedef enum {
57         CERT_TYPE_ETC          = 0,
58         CERT_TYPE_PKCS12,
59         CERT_TYPE_PKCS7,
60         CERT_TYPE_P7S
61 } cert_type;
62
63 static int emcore_get_certificate_type(char *extension, int *err_code)
64 {
65         EM_DEBUG_FUNC_BEGIN("extensiong is [%s]", extension);
66         int index = 0;
67         int type = 0;
68         int err = EMAIL_ERROR_NONE;
69         char *supported_file_type[] = {"pfx", "p12", "p7s", "pem", "der", "crt", "cer", NULL};
70
71         if (!extension) {
72                 EM_DEBUG_EXCEPTION("Invalid parameter");
73                 err = EMAIL_ERROR_INVALID_PARAM;
74                 goto FINISH_OFF;
75         }
76
77         while(supported_file_type[index]) {
78                 EM_DEBUG_LOG_SEC("certificate extension[%d]:[%s]", index, supported_file_type[index]);
79                 if (strcasecmp(extension, supported_file_type[index]) == 0) {
80                         switch (index) {
81                         case 0:
82                         case 1:
83                                 type = CERT_TYPE_PKCS12;
84                                 err = EMAIL_ERROR_INVALID_CERTIFICATE;
85                                 break;
86                         case 2:
87                                 type = CERT_TYPE_P7S;
88                                 break;
89                         case 3:
90                         case 4:
91                         case 5:
92                         case 6:
93                                 type = CERT_TYPE_PKCS7;
94                                 break;
95                         default:
96                                 type = CERT_TYPE_ETC;
97                                 err = EMAIL_ERROR_INVALID_CERTIFICATE;
98                                 break;
99                         }
100                 }
101                 index++;
102         }
103
104 FINISH_OFF:
105
106         if (err_code) {
107                 *err_code = err;
108         }
109
110         EM_DEBUG_FUNC_END("File type is [%d]", type);
111         return type;
112 }
113 /*
114 static GList *emcore_make_glist_from_string(char *email_address_list)
115 {
116         EM_DEBUG_FUNC_BEGIN_SEC("email_address list : [%s]", email_address_list);
117         int index = 0;
118         const gchar seperator = 0x01;
119         GList *email_list = NULL;
120         gchar *p_email_address_list = NULL;
121         gchar **token_list = NULL;
122
123         p_email_address_list = g_strdup(email_address_list);
124
125         token_list = g_strsplit(p_email_address_list, &seperator, -1);
126         while (token_list[index] != NULL) {
127                 email_list = g_list_append(email_list, token_list[index]);
128                 index++;
129         }
130
131         if (p_email_address_list)
132                 g_free(p_email_address_list);
133
134         return email_list;
135 }
136
137 static char *emcore_store_public_certificate(STACK_OF(X509) *certificates, char *email_address, int *err_code)
138 {
139         EM_DEBUG_FUNC_BEGIN();
140         int index = 0;
141         int err = EMAIL_ERROR_NONE;
142         char *file_path = NULL;
143         BIO *outfile = NULL;
144
145         file_path = (char *)em_malloc(256);
146         if (file_path == NULL) {
147                 EM_DEBUG_EXCEPTION("em_malloc failed");
148                 err = EMAIL_ERROR_OUT_OF_MEMORY;
149                 goto FINISH_OFF;
150         }
151
152         SNPRINTF(file_path, 256, "%s%s%s", CERT_SVC_STORE_PATH, TRUSTED_USER, email_address);
153         outfile = BIO_new_file(file_path, WRITE_MODE);
154         if (outfile == NULL) {
155                 EM_DEBUG_EXCEPTION("File open failed[write mode]");
156                 err = EMAIL_ERROR_SYSTEM_FAILURE;
157                 goto FINISH_OFF;
158         }
159
160         for (index = 0; index < sk_X509_num(certificates); index++) {
161                 EM_DEBUG_LOG("Write the certificate in pem file : [%d]", index);
162                 PEM_write_bio_X509(outfile, sk_X509_value(certificates, index));
163         }
164
165 FINISH_OFF:
166
167         if (outfile)
168                 BIO_free(outfile);
169
170         EM_DEBUG_FUNC_END();
171
172         return file_path;
173 }
174 */
175 #if 0
176 INTERNAL_FUNC int emcore_load_PFX_file(char *certificate, char *password, EVP_PKEY **pri_key, X509 **cert, STACK_OF(X509) **ca, int *err_code)
177 {
178         EM_DEBUG_FUNC_BEGIN_SEC("Certificate path : [%s], password : [%s]", certificate, password);
179
180         int err = EMAIL_ERROR_NONE;
181         int ret = false;
182         FILE *fp = NULL;
183         PKCS12 *p12 = NULL;
184
185         err = em_fopen(certificate, "rb", &fp);
186         if (err != EMAIL_ERROR_NONE) {
187                 EM_DEBUG_EXCEPTION_SEC("em_fopen failed : [%s] [%d]", certificate, err);
188                 goto FINISH_OFF;
189         }
190
191         p12 = d2i_PKCS12_fp(fp, NULL);
192         if (!p12) {
193                 EM_DEBUG_EXCEPTION("d2i_PKCS12_fp failed");
194                 err = EMAIL_ERROR_SYSTEM_FAILURE;
195                 goto FINISH_OFF;
196         }
197
198         if (!PKCS12_parse(p12, password, pri_key, cert, ca)) {
199                 EM_DEBUG_EXCEPTION("PKCS12_parse failed");
200                 err = EMAIL_ERROR_SYSTEM_FAILURE;
201                 goto FINISH_OFF;
202         }
203
204         ret = true;
205
206 FINISH_OFF:
207
208         if (fp)
209                 fclose(fp);
210
211         if (p12)
212                 PKCS12_free(p12);
213
214         if (err_code)
215                 *err_code = err;
216
217         return ret;
218 }
219 #endif
220
221 INTERNAL_FUNC int emcore_load_PFX_file(char *certificate, EVP_PKEY **pri_key, X509 **cert, STACK_OF(X509) **ca, int *err_code)
222 {
223         EM_DEBUG_FUNC_BEGIN_SEC("certificate : [%s]", certificate);
224         int err = EMAIL_ERROR_NONE;
225         int ret = false;
226         size_t key_size = 0;
227         char *private_key = NULL;
228
229         /* Variable for certificate */
230         X509 *t_cert = NULL;
231         BIO *bio_mem = NULL;
232 //      STACK_OF(X509) *t_ca = NULL;
233
234         /* Variable for private key */
235         EVP_PKEY *t_pri_key = NULL;
236
237         CertSvcString csstring;
238         CertSvcInstance cert_instance;
239         CertSvcCertificate csc_cert;
240         CertSvcCertificateList certificate_list;
241         CertSvcStoreCertList* certList = NULL;
242         CertSvcStoreCertList* tempList = NULL;
243         char *alias =  NULL;
244         size_t length = 0;
245
246         if (certificate == NULL) {
247                 EM_DEBUG_EXCEPTION("Invalid parameter");
248                 err = EMAIL_ERROR_INVALID_PARAM;
249                 goto FINISH_OFF;
250         }
251
252         EM_DEBUG_EXCEPTION("emcore_load_PFX_file - certificate passed : %s", certificate);
253
254         /* Create instance */
255         err = certsvc_instance_new(&cert_instance);
256         if (err != CERTSVC_SUCCESS) {
257                 EM_DEBUG_EXCEPTION("certsvc_instance_new failed : [%d]", err);
258                 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
259                 goto FINISH_OFF;
260         }
261
262         /* Make the pfxID string */
263         err = certsvc_string_new(cert_instance, certificate, EM_SAFE_STRLEN(certificate), &csstring);
264         if (err != CERTSVC_SUCCESS) {
265                 EM_DEBUG_EXCEPTION("certsvc_string_new failed : [%d]", err);
266                 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
267                 goto FINISH_OFF;
268         }
269
270         if (certsvc_pkcs12_get_end_user_certificate_list_from_store(
271                         cert_instance,
272                         EMAIL_STORE,
273                         &certList,
274                         &length) != CERTSVC_SUCCESS) {
275                 EM_DEBUG_EXCEPTION("certsvc_string_new failed : [%d]", err);
276                 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
277                 goto FINISH_OFF;
278         }
279
280         tempList = certList;
281         while (tempList) {
282                 if (strcmp(tempList->title, certificate) == 0
283                                 || strcmp(tempList->gname, certificate) == 0) {
284                         alias = strdup(tempList->gname);
285                         break;
286                 }
287
288                 tempList = tempList->next;
289         }
290
291         certsvc_pkcs12_free_certificate_list_loaded_from_store(cert_instance, &certList);
292         if (alias == NULL) {
293                 EM_DEBUG_EXCEPTION("Failed to strdup");
294                 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
295                 goto FINISH_OFF;
296         }
297
298         /* Make the pfxID string */
299         err = certsvc_string_new(cert_instance, alias, EM_SAFE_STRLEN(alias), &csstring);
300         if (err != CERTSVC_SUCCESS) {
301                 EM_DEBUG_EXCEPTION("certsvc_string_new failed : [%d]", err);
302                 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
303                 goto FINISH_OFF;
304         }
305
306         err = certsvc_pkcs12_load_certificate_list_from_store(cert_instance, EMAIL_STORE, csstring, &certificate_list);
307         if (err != CERTSVC_SUCCESS) {
308                 certsvc_string_free(csstring);
309                 err = certsvc_string_new(cert_instance, certificate, EM_SAFE_STRLEN(certificate), &csstring);
310                 if (err != CERTSVC_SUCCESS) {
311                         EM_DEBUG_EXCEPTION("certsvc_string_new failed : [%d]", err);
312                         err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
313                         goto FINISH_OFF;
314                 }
315
316                 /* Load the certificate list of pkcs12 type */
317                 err = certsvc_pkcs12_load_certificate_list_from_store(cert_instance, EMAIL_STORE, csstring, &certificate_list);
318                 if (err != CERTSVC_SUCCESS) {
319                         EM_DEBUG_EXCEPTION("certsvc_pkcs12_load_certificate_list_from_store failed : [%d]", err);
320                         err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
321                         goto FINISH_OFF;
322                 }
323         }
324
325
326         /* Get a certificate */
327         err = certsvc_certificate_list_get_one(certificate_list, 0, &csc_cert);
328         if (err != CERTSVC_SUCCESS) {
329                 EM_DEBUG_EXCEPTION("certsvc_certificate_list_get_one failed : [%d]", err);
330                 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
331                 goto FINISH_OFF;
332         }
333
334         /* Convert from char to X509 */
335         err = certsvc_certificate_dup_x509(csc_cert, &t_cert);
336         if (t_cert == NULL || err != CERTSVC_SUCCESS) {
337                 EM_DEBUG_EXCEPTION("certsvc_certificate_dup_x509 failed");
338                 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
339                 goto FINISH_OFF;
340         }
341
342         /* Get the private key */
343         err = certsvc_pkcs12_private_key_dup_from_store(cert_instance, EMAIL_STORE, csstring, &private_key, &key_size);
344         if (err != CERTSVC_SUCCESS) {
345                 EM_DEBUG_EXCEPTION("certsvc_pkcs12_private_key_dup_from_store failed : [%d]", err);
346                 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
347                 goto FINISH_OFF;
348         }
349
350         EM_DEBUG_LOG_DEV("key_size : [%u], private_key : [%s]", key_size, private_key);
351
352         /* Convert char to pkey */
353         bio_mem = BIO_new(BIO_s_mem());
354         if (bio_mem == NULL) {
355                 EM_DEBUG_EXCEPTION("malloc failed");
356                 err = EMAIL_ERROR_OUT_OF_MEMORY;
357                 goto FINISH_OFF;
358         }
359
360         if (BIO_write(bio_mem, private_key, (int)key_size) <= 0) {
361                 EM_DEBUG_EXCEPTION("BIO_write failed");
362                 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
363                 goto FINISH_OFF;
364         }
365
366         t_pri_key = PEM_read_bio_PrivateKey(bio_mem, NULL, 0, NULL);
367         if (t_pri_key == NULL) {
368                 EM_DEBUG_EXCEPTION("PEM_read_bio_PrivateKey failed");
369                 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
370                 goto FINISH_OFF;
371         }
372
373         ret = true;
374
375 FINISH_OFF:
376
377         if (bio_mem)
378                 BIO_free(bio_mem);
379
380         if (true) {
381                 if (cert)
382                         *cert = t_cert;
383
384                 if (pri_key)
385                         *pri_key = t_pri_key;
386         } else {
387                 X509_free(t_cert);
388                 EVP_PKEY_free(t_pri_key);
389         }
390
391         if (private_key)
392                 EM_SAFE_FREE(private_key);
393
394         if (err_code)
395                 *err_code = err;
396
397         if (alias)
398                 free(alias);
399
400         certsvc_instance_free(cert_instance);
401
402         return ret;
403 }
404
405 INTERNAL_FUNC int emcore_add_public_certificate(char *multi_user_name, char *public_cert_path, char *save_name, int *err_code)
406 {
407         EM_DEBUG_FUNC_BEGIN_SEC("Path [%s], filename [%s]", public_cert_path, save_name);
408         int err = EMAIL_ERROR_NONE;
409         int ret = false;
410         int validity = 0;
411         int cert_type = 0;
412         char temp_file[512] = {0, };
413         char temp_save_name[512] = {0, };
414         char filepath[512] = {0, };
415         char *extension = NULL;
416         emstorage_certificate_tbl_t *cert = NULL;
417         CERT_CONTEXT *context = NULL;
418
419         if (public_cert_path == NULL || save_name == NULL) {
420                 EM_DEBUG_EXCEPTION("Invalid parameter");
421                 err = EMAIL_ERROR_INVALID_PARAM;
422                 goto FINISH_OFF;
423         }
424
425         /* Initilize the structure of certificate */
426         context = cert_svc_cert_context_init();
427
428         /* Parse the file type */
429         extension = em_get_extension_from_file_path(public_cert_path, NULL);
430         if (extension == NULL) {
431                 EM_DEBUG_EXCEPTION("Invalid parameter");
432                 err = EMAIL_ERROR_INVALID_PARAM;
433                 goto FINISH_OFF;
434         }
435
436         /* Get the file type information */
437         cert_type = emcore_get_certificate_type(extension, &err);
438         if (!cert_type || err == EMAIL_ERROR_INVALID_CERTIFICATE) {
439                 EM_DEBUG_EXCEPTION("Invalid certificate");
440                 goto FINISH_OFF;
441         }
442
443         /* Create temp file and rename */
444         if (cert_type == CERT_TYPE_P7S) {
445                 extension = "der";
446         }
447
448         SNPRINTF(temp_file, sizeof(temp_file), "%s%s%s.%s", MAILTEMP, DIR_SEPERATOR, save_name, extension);
449         EM_DEBUG_LOG_SEC("temp cert path : [%s]", temp_file);
450
451         if (!emstorage_copy_file(public_cert_path, temp_file, false, &err)) {
452                 EM_DEBUG_EXCEPTION("emstorage_copy_file failed [%d]", err);
453                 goto FINISH_OFF;
454         }
455
456         /* Load the public certificate */
457         err = cert_svc_load_file_to_context(context, temp_file);
458         if (err != CERT_SVC_ERR_NO_ERROR) {
459                 EM_DEBUG_EXCEPTION("Load cert failed : [%d]", err);
460                 err = EMAIL_ERROR_INVALID_CERTIFICATE;
461                 goto FINISH_OFF;
462         }
463
464         /* Verify the certificate */
465         if (cert_svc_verify_certificate(context, &validity) != CERT_SVC_ERR_NO_ERROR) {
466                 EM_DEBUG_EXCEPTION("cert_svc_verify_certificate failed");
467 //              err = EMAIL_ERROR_INVALID_CERTIFICATE;
468 //              goto FINISH_OFF;
469         }
470
471         if (validity <= 0) {
472                 EM_DEBUG_LOG("Invalid certificate");
473         }
474
475         /* Load the certificate information */
476         if (cert_svc_extract_certificate_data(context) != CERT_SVC_ERR_NO_ERROR) {
477                 EM_DEBUG_EXCEPTION("Extract the certificate failed");
478                 err = EMAIL_ERROR_UNKNOWN;
479                 goto FINISH_OFF;
480         }
481
482         /* Store the certificate file to trusted folder */
483         if (cert_svc_add_certificate_to_store(temp_file, TRUSTED_USER) != CERT_SVC_ERR_NO_ERROR) {
484                 EM_DEBUG_EXCEPTION("Add certificate to trusted folder");
485                 err = EMAIL_ERROR_UNKNOWN;
486                 goto FINISH_OFF;
487         }
488
489         /* Store the certificate to DB */
490         SNPRINTF(filepath, sizeof(filepath), "%s%s%s.%s", CERT_SVC_STORE_PATH, TRUSTED_USER, save_name, extension);
491         SNPRINTF(temp_save_name, sizeof(temp_save_name), "<%s>", save_name);
492
493         cert = (emstorage_certificate_tbl_t *)em_malloc(sizeof(emstorage_certificate_tbl_t));
494         if (cert == NULL) {
495                 EM_DEBUG_EXCEPTION("em_malloc failed");
496                 err = EMAIL_ERROR_OUT_OF_MEMORY;
497                 goto FINISH_OFF;
498         }
499
500         cert->issue_year = context->certDesc->info.validPeriod.firstYear;
501         cert->issue_year = context->certDesc->info.validPeriod.firstYear;
502         cert->issue_month = context->certDesc->info.validPeriod.firstMonth;
503         cert->issue_day = context->certDesc->info.validPeriod.firstDay;
504         cert->expiration_year= context->certDesc->info.validPeriod.secondYear;
505         cert->expiration_month = context->certDesc->info.validPeriod.secondMonth;
506         cert->expiration_day = context->certDesc->info.validPeriod.secondDay;
507         cert->issue_organization_name = EM_SAFE_STRDUP(context->certDesc->info.issuer.organizationName);
508         cert->email_address = EM_SAFE_STRDUP(temp_save_name);
509         cert->subject_str = EM_SAFE_STRDUP(context->certDesc->info.issuerStr);
510         cert->filepath = EM_SAFE_STRDUP(filepath);
511
512         if (emstorage_add_certificate(multi_user_name, cert, true, &err)) {
513                 EM_DEBUG_EXCEPTION("emstorage_add_certificate failed");
514                 goto FINISH_OFF;
515         }
516
517         if (!emstorage_delete_file(public_cert_path, &err)) {
518                 EM_DEBUG_EXCEPTION("emstorage_delete_file failed [%d]", err);
519                 goto FINISH_OFF;
520         }
521
522         ret = true;
523
524 FINISH_OFF:
525
526         emstorage_delete_file(temp_file, NULL);
527
528         emstorage_free_certificate(&cert, 1, NULL);
529
530         cert_svc_cert_context_final(context);
531
532         if (err_code != NULL) {
533                 *err_code = err;
534         }
535
536         EM_DEBUG_FUNC_END();
537
538         return ret;
539
540 }
541
542 INTERNAL_FUNC int emcore_delete_public_certificate(char *multi_user_name, char *email_address, int *err_code)
543 {
544         EM_DEBUG_FUNC_BEGIN();
545         int ret = false;
546         int err = EMAIL_ERROR_NONE;
547         emstorage_certificate_tbl_t *certificate = NULL;
548
549         if (email_address == NULL) {
550                 EM_DEBUG_EXCEPTION("Invalid parameter");
551                 err = EMAIL_ERROR_INVALID_PARAM;
552                 goto FINISH_OFF;
553         }
554
555         if (!emstorage_get_certificate_by_email_address(multi_user_name, email_address, &certificate, false, 0, &err)) {
556                 EM_DEBUG_EXCEPTION("emstorage_get_certificate failed");
557                 goto FINISH_OFF;
558         }
559
560         if (remove(certificate->filepath) < 0) {
561                 EM_DEBUG_EXCEPTION_SEC("remove failed : [%s]", certificate->filepath);
562                 goto FINISH_OFF;
563         }
564
565         if (!emstorage_delete_certificate(multi_user_name, certificate->certificate_id, true, &err)) {
566                 EM_DEBUG_EXCEPTION("emstorage_delete_certificate failed");
567                 goto FINISH_OFF;
568         }
569
570         ret = true;
571 FINISH_OFF:
572
573         if (certificate != NULL)
574                 emstorage_free_certificate(&certificate, 1, NULL);
575
576         if (err_code != NULL)
577                 *err_code = err;
578
579         EM_DEBUG_FUNC_END();
580
581         return ret;
582 }
583
584 INTERNAL_FUNC int emcore_verify_signature(char *p7s_file_path, char *mime_entity, int *validity, int *err_code)
585 {
586         EM_DEBUG_FUNC_BEGIN_SEC("path : [%s], mime_entity : [%s]", p7s_file_path, mime_entity);
587         int ret = false;
588         int err = EMAIL_ERROR_NONE;
589         int t_validity = 0;
590         int flags = PKCS7_NOVERIFY;
591
592         BIO *bio_p7s = NULL;
593
594         BIO *bio_indata = NULL;
595
596         PKCS7 *pkcs7_p7s = NULL;
597
598         /* Open p7s file */
599         bio_p7s = BIO_new_file(p7s_file_path, INMODE);
600         if (!bio_p7s) {
601                 EM_DEBUG_EXCEPTION("File open failed");
602                 err = EMAIL_ERROR_SYSTEM_FAILURE;
603                 goto FINISH_OFF;
604         }
605
606         /* Open input data file */
607         bio_indata = BIO_new_file(mime_entity, INMODE);
608         if (!bio_p7s) {
609                 EM_DEBUG_EXCEPTION("File open failed");
610                 err = EMAIL_ERROR_SYSTEM_FAILURE;
611                 goto FINISH_OFF;
612         }
613
614         /* Load the p7s file */
615         pkcs7_p7s = d2i_PKCS7_bio(bio_p7s, NULL);
616         if (!pkcs7_p7s) {
617                 EM_DEBUG_EXCEPTION("d2i_PKCS7_bio failed");
618                 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
619                 goto FINISH_OFF;
620         }
621
622         if (!PKCS7_verify(pkcs7_p7s, NULL, NULL, bio_indata, NULL, flags)) {
623                 EM_DEBUG_EXCEPTION("PKCS7_verify failed");
624                 goto FINISH_OFF;
625         }
626
627         t_validity = 1;
628
629         ret = true;
630
631 FINISH_OFF:
632
633         if (pkcs7_p7s)
634                 PKCS7_free(pkcs7_p7s);
635
636         if (bio_p7s)
637                 BIO_free(bio_p7s);
638
639         if (bio_indata)
640                 BIO_free(bio_indata);
641
642         if (validity)
643                 *validity = t_validity;
644
645         if (err_code)
646                 *err_code = err;
647
648         EM_DEBUG_FUNC_END();
649         return ret;
650 }
651
652 INTERNAL_FUNC int emcore_verify_certificate(char *certificate, int *validity, int *err_code)
653 {
654         EM_DEBUG_FUNC_BEGIN();
655         int ret = false;
656         int err = EMAIL_ERROR_NONE;
657         int p_validity = 0;
658
659         CERT_CONTEXT *context = NULL;
660
661         context = cert_svc_cert_context_init();
662
663         err = cert_svc_load_file_to_context(context, certificate);
664         if (err != CERT_SVC_ERR_NO_ERROR) {
665                 EM_DEBUG_EXCEPTION("Certificate load failed");
666                 goto FINISH_OFF;
667         }
668
669         err = cert_svc_verify_certificate(context, &p_validity);
670         if (err != CERT_SVC_ERR_NO_ERROR) {
671                 EM_DEBUG_EXCEPTION("Certificate verify failed");
672                 goto FINISH_OFF;
673         }
674
675         ret = true;
676
677 FINISH_OFF:
678
679         if (validity != NULL)
680                 *validity = p_validity;
681
682         if (err_code != NULL) {
683                 *err_code = err;
684         }
685
686         cert_svc_cert_context_final(context);
687
688         EM_DEBUG_FUNC_END();
689         return ret;
690 }
691
692 INTERNAL_FUNC int emcore_free_certificate(email_certificate_t **certificate, int count, int *err_code)
693 {
694         EM_DEBUG_FUNC_BEGIN("certificate [%p], count [%d]", certificate, count);
695
696         if (count <= 0 || !certificate || !*certificate) {
697                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
698                 if (err_code)
699                         *err_code = EMAIL_ERROR_INVALID_PARAM;
700                 return false;
701         }
702
703         email_certificate_t *p_certificate = *certificate;
704         int i;
705
706         for (i=0;i<count;i++) {
707                 EM_SAFE_FREE(p_certificate[i].issue_organization_name);
708                 EM_SAFE_FREE(p_certificate[i].email_address);
709                 EM_SAFE_FREE(p_certificate[i].subject_str);
710                 EM_SAFE_FREE(p_certificate[i].filepath);
711         }
712
713         EM_SAFE_FREE(p_certificate);
714         *certificate = NULL;
715
716         if (err_code)
717                 *err_code = EMAIL_ERROR_NONE;
718
719         EM_DEBUG_FUNC_END();
720         return true;
721 }