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.
23 /******************************************************************************
24 * File : email-core-cert.h
25 * Desc : Certificate API
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>
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>
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"
52 #define WRITE_MODE "w"
54 #define TRUSTED_USER "trusteduser/email/"
63 INTERNAL_FUNC int emcore_load_PFX_file(char *certificate, EVP_PKEY **pri_key, X509 **cert,
64 STACK_OF(X509) **ca, int *err_code)
66 EM_DEBUG_FUNC_BEGIN_SEC("certificate : [%s]", certificate);
67 int err = EMAIL_ERROR_NONE;
70 char *private_key = NULL;
72 /* Variable for certificate */
75 // STACK_OF(X509) *t_ca = NULL;
77 /* Variable for private key */
78 EVP_PKEY *t_pri_key = NULL;
80 CertSvcString csstring;
81 CertSvcInstance cert_instance;
82 CertSvcCertificate csc_cert;
83 CertSvcCertificateList certificate_list;
84 CertSvcStoreCertList* certList = NULL;
85 CertSvcStoreCertList* tempList = NULL;
89 if (certificate == NULL) {
90 EM_DEBUG_EXCEPTION("Invalid parameter");
91 err = EMAIL_ERROR_INVALID_PARAM;
95 EM_DEBUG_EXCEPTION("emcore_load_PFX_file - certificate passed : %s", certificate);
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;
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;
113 if (certsvc_pkcs12_get_end_user_certificate_list_from_store(
117 &length) != CERTSVC_SUCCESS) {
118 EM_DEBUG_EXCEPTION("certsvc_string_new failed : [%d]", err);
119 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
125 if (strcmp(tempList->title, certificate) == 0
126 || strcmp(tempList->gname, certificate) == 0) {
127 alias = strdup(tempList->gname);
131 tempList = tempList->next;
134 certsvc_pkcs12_free_certificate_list_loaded_from_store(cert_instance, &certList);
136 EM_DEBUG_EXCEPTION("Failed to strdup");
137 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
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;
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;
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;
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;
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;
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;
193 EM_DEBUG_LOG_DEV("key_size : [%u], private_key : [%s]", key_size, private_key);
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;
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;
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;
228 *pri_key = t_pri_key;
231 EVP_PKEY_free(t_pri_key);
235 EM_SAFE_FREE(private_key);
243 certsvc_instance_free(cert_instance);
248 INTERNAL_FUNC int emcore_verify_signature(char *p7s_file_path, char *mime_entity, int *validity, int *err_code)
250 EM_DEBUG_FUNC_BEGIN_SEC("path : [%s], mime_entity : [%s]", p7s_file_path, mime_entity);
252 int err = EMAIL_ERROR_NONE;
254 int flags = PKCS7_NOVERIFY;
258 BIO *bio_indata = NULL;
260 PKCS7 *pkcs7_p7s = NULL;
263 bio_p7s = BIO_new_file(p7s_file_path, INMODE);
265 EM_DEBUG_EXCEPTION("File open failed");
266 err = EMAIL_ERROR_SYSTEM_FAILURE;
270 /* Open input data file */
271 bio_indata = BIO_new_file(mime_entity, INMODE);
273 EM_DEBUG_EXCEPTION("File open failed");
274 err = EMAIL_ERROR_SYSTEM_FAILURE;
278 /* Load the p7s file */
279 pkcs7_p7s = d2i_PKCS7_bio(bio_p7s, NULL);
281 EM_DEBUG_EXCEPTION("d2i_PKCS7_bio failed");
282 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
286 if (!PKCS7_verify(pkcs7_p7s, NULL, NULL, bio_indata, NULL, flags)) {
287 EM_DEBUG_EXCEPTION("PKCS7_verify failed");
298 PKCS7_free(pkcs7_p7s);
304 BIO_free(bio_indata);
307 *validity = t_validity;