Removed the certificate api
[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 INTERNAL_FUNC int emcore_load_PFX_file(char *certificate, EVP_PKEY **pri_key, X509 **cert, 
64                                                                         STACK_OF(X509) **ca, int *err_code)
65 {
66         EM_DEBUG_FUNC_BEGIN_SEC("certificate : [%s]", certificate);
67         int err = EMAIL_ERROR_NONE;
68         int ret = false;
69         size_t key_size = 0;
70         char *private_key = NULL;
71
72         /* Variable for certificate */
73         X509 *t_cert = NULL;
74         BIO *bio_mem = NULL;
75 //      STACK_OF(X509) *t_ca = NULL;
76
77         /* Variable for private key */
78         EVP_PKEY *t_pri_key = NULL;
79
80         CertSvcString csstring;
81         CertSvcInstance cert_instance;
82         CertSvcCertificate csc_cert;
83         CertSvcCertificateList certificate_list;
84         CertSvcStoreCertList* certList = NULL;
85         CertSvcStoreCertList* tempList = NULL;
86         char *alias =  NULL;
87         size_t length = 0;
88
89         if (certificate == NULL) {
90                 EM_DEBUG_EXCEPTION("Invalid parameter");
91                 err = EMAIL_ERROR_INVALID_PARAM;
92                 goto FINISH_OFF;
93         }
94
95         EM_DEBUG_EXCEPTION("emcore_load_PFX_file - certificate passed : %s", certificate);
96
97         /* Create instance */
98         err = certsvc_instance_new(&cert_instance);
99         if (err != CERTSVC_SUCCESS) {
100                 EM_DEBUG_EXCEPTION("certsvc_instance_new failed : [%d]", err);
101                 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
102                 goto FINISH_OFF;
103         }
104
105         /* Make the pfxID string */
106         err = certsvc_string_new(cert_instance, certificate, EM_SAFE_STRLEN(certificate), &csstring);
107         if (err != CERTSVC_SUCCESS) {
108                 EM_DEBUG_EXCEPTION("certsvc_string_new failed : [%d]", err);
109                 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
110                 goto FINISH_OFF;
111         }
112
113         if (certsvc_pkcs12_get_end_user_certificate_list_from_store(
114                         cert_instance,
115                         EMAIL_STORE,
116                         &certList,
117                         &length) != CERTSVC_SUCCESS) {
118                 EM_DEBUG_EXCEPTION("certsvc_string_new failed : [%d]", err);
119                 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
120                 goto FINISH_OFF;
121         }
122
123         tempList = certList;
124         while (tempList) {
125                 if (strcmp(tempList->title, certificate) == 0
126                                 || strcmp(tempList->gname, certificate) == 0) {
127                         alias = strdup(tempList->gname);
128                         break;
129                 }
130
131                 tempList = tempList->next;
132         }
133
134         certsvc_pkcs12_free_certificate_list_loaded_from_store(cert_instance, &certList);
135         if (alias == NULL) {
136                 EM_DEBUG_EXCEPTION("Failed to strdup");
137                 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
138                 goto FINISH_OFF;
139         }
140
141         /* Make the pfxID string */
142         err = certsvc_string_new(cert_instance, alias, EM_SAFE_STRLEN(alias), &csstring);
143         if (err != CERTSVC_SUCCESS) {
144                 EM_DEBUG_EXCEPTION("certsvc_string_new failed : [%d]", err);
145                 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
146                 goto FINISH_OFF;
147         }
148
149         err = certsvc_pkcs12_load_certificate_list_from_store(cert_instance, EMAIL_STORE, csstring, &certificate_list);
150         if (err != CERTSVC_SUCCESS) {
151                 certsvc_string_free(csstring);
152                 err = certsvc_string_new(cert_instance, certificate, EM_SAFE_STRLEN(certificate), &csstring);
153                 if (err != CERTSVC_SUCCESS) {
154                         EM_DEBUG_EXCEPTION("certsvc_string_new failed : [%d]", err);
155                         err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
156                         goto FINISH_OFF;
157                 }
158
159                 /* Load the certificate list of pkcs12 type */
160                 err = certsvc_pkcs12_load_certificate_list_from_store(cert_instance, EMAIL_STORE, csstring, &certificate_list);
161                 if (err != CERTSVC_SUCCESS) {
162                         EM_DEBUG_EXCEPTION("certsvc_pkcs12_load_certificate_list_from_store failed : [%d]", err);
163                         err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
164                         goto FINISH_OFF;
165                 }
166         }
167
168
169         /* Get a certificate */
170         err = certsvc_certificate_list_get_one(certificate_list, 0, &csc_cert);
171         if (err != CERTSVC_SUCCESS) {
172                 EM_DEBUG_EXCEPTION("certsvc_certificate_list_get_one failed : [%d]", err);
173                 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
174                 goto FINISH_OFF;
175         }
176
177         /* Convert from char to X509 */
178         err = certsvc_certificate_dup_x509(csc_cert, &t_cert);
179         if (t_cert == NULL || err != CERTSVC_SUCCESS) {
180                 EM_DEBUG_EXCEPTION("certsvc_certificate_dup_x509 failed");
181                 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
182                 goto FINISH_OFF;
183         }
184
185         /* Get the private key */
186         err = certsvc_pkcs12_private_key_dup_from_store(cert_instance, EMAIL_STORE, csstring, &private_key, &key_size);
187         if (err != CERTSVC_SUCCESS) {
188                 EM_DEBUG_EXCEPTION("certsvc_pkcs12_private_key_dup_from_store failed : [%d]", err);
189                 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
190                 goto FINISH_OFF;
191         }
192
193         EM_DEBUG_LOG_DEV("key_size : [%u], private_key : [%s]", key_size, private_key);
194
195         /* Convert char to pkey */
196         bio_mem = BIO_new(BIO_s_mem());
197         if (bio_mem == NULL) {
198                 EM_DEBUG_EXCEPTION("malloc failed");
199                 err = EMAIL_ERROR_OUT_OF_MEMORY;
200                 goto FINISH_OFF;
201         }
202
203         if (BIO_write(bio_mem, private_key, (int)key_size) <= 0) {
204                 EM_DEBUG_EXCEPTION("BIO_write failed");
205                 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
206                 goto FINISH_OFF;
207         }
208
209         t_pri_key = PEM_read_bio_PrivateKey(bio_mem, NULL, 0, NULL);
210         if (t_pri_key == NULL) {
211                 EM_DEBUG_EXCEPTION("PEM_read_bio_PrivateKey failed");
212                 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
213                 goto FINISH_OFF;
214         }
215
216         ret = true;
217
218 FINISH_OFF:
219
220         if (bio_mem)
221                 BIO_free(bio_mem);
222
223         if (true) {
224                 if (cert)
225                         *cert = t_cert;
226
227                 if (pri_key)
228                         *pri_key = t_pri_key;
229         } else {
230                 X509_free(t_cert);
231                 EVP_PKEY_free(t_pri_key);
232         }
233
234         if (private_key)
235                 EM_SAFE_FREE(private_key);
236
237         if (err_code)
238                 *err_code = err;
239
240         if (alias)
241                 free(alias);
242
243         certsvc_instance_free(cert_instance);
244
245         return ret;
246 }
247
248 INTERNAL_FUNC int emcore_verify_signature(char *p7s_file_path, char *mime_entity, int *validity, int *err_code)
249 {
250         EM_DEBUG_FUNC_BEGIN_SEC("path : [%s], mime_entity : [%s]", p7s_file_path, mime_entity);
251         int ret = false;
252         int err = EMAIL_ERROR_NONE;
253         int t_validity = 0;
254         int flags = PKCS7_NOVERIFY;
255
256         BIO *bio_p7s = NULL;
257
258         BIO *bio_indata = NULL;
259
260         PKCS7 *pkcs7_p7s = NULL;
261
262         /* Open p7s file */
263         bio_p7s = BIO_new_file(p7s_file_path, INMODE);
264         if (!bio_p7s) {
265                 EM_DEBUG_EXCEPTION("File open failed");
266                 err = EMAIL_ERROR_SYSTEM_FAILURE;
267                 goto FINISH_OFF;
268         }
269
270         /* Open input data file */
271         bio_indata = BIO_new_file(mime_entity, INMODE);
272         if (!bio_p7s) {
273                 EM_DEBUG_EXCEPTION("File open failed");
274                 err = EMAIL_ERROR_SYSTEM_FAILURE;
275                 goto FINISH_OFF;
276         }
277
278         /* Load the p7s file */
279         pkcs7_p7s = d2i_PKCS7_bio(bio_p7s, NULL);
280         if (!pkcs7_p7s) {
281                 EM_DEBUG_EXCEPTION("d2i_PKCS7_bio failed");
282                 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
283                 goto FINISH_OFF;
284         }
285
286         if (!PKCS7_verify(pkcs7_p7s, NULL, NULL, bio_indata, NULL, flags)) {
287                 EM_DEBUG_EXCEPTION("PKCS7_verify failed");
288                 goto FINISH_OFF;
289         }
290
291         t_validity = 1;
292
293         ret = true;
294
295 FINISH_OFF:
296
297         if (pkcs7_p7s)
298                 PKCS7_free(pkcs7_p7s);
299
300         if (bio_p7s)
301                 BIO_free(bio_p7s);
302
303         if (bio_indata)
304                 BIO_free(bio_indata);
305
306         if (validity)
307                 *validity = t_validity;
308
309         if (err_code)
310                 *err_code = err;
311
312         EM_DEBUG_FUNC_END();
313         return ret;
314 }