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>
37 #include <cert-svc/ccert.h>
38 #include <cert-svc/cstring.h>
39 #include <cert-svc/cpkcs12.h>
40 #include <cert-svc/cinstance.h>
41 #include <cert-svc/cprimitives.h>
43 #include "email-core-cert.h"
44 #include "email-core-mail.h"
45 #include "email-core-utils.h"
46 #include "email-utilities.h"
47 #include "email-storage.h"
48 #include "email-debug-log.h"
51 #define WRITE_MODE "w"
60 INTERNAL_FUNC int emcore_load_PFX_file(char *certificate, EVP_PKEY **pri_key, X509 **cert,
61 STACK_OF(X509) **ca, int *err_code)
63 EM_DEBUG_FUNC_BEGIN_SEC("certificate : [%s]", certificate);
64 int err = EMAIL_ERROR_NONE;
67 char *private_key = NULL;
69 /* Variable for certificate */
72 // STACK_OF(X509) *t_ca = NULL;
74 /* Variable for private key */
75 EVP_PKEY *t_pri_key = NULL;
77 CertSvcString csstring;
78 CertSvcInstance cert_instance;
79 CertSvcCertificate csc_cert;
80 CertSvcCertificateList certificate_list;
81 CertSvcStoreCertList* certList = NULL;
82 CertSvcStoreCertList* tempList = NULL;
86 if (certificate == NULL) {
87 EM_DEBUG_EXCEPTION("Invalid parameter");
88 err = EMAIL_ERROR_INVALID_PARAM;
92 EM_DEBUG_LOG("emcore_load_PFX_file - certificate passed : %s", certificate);
95 err = certsvc_instance_new(&cert_instance);
96 if (err != CERTSVC_SUCCESS) {
97 EM_DEBUG_EXCEPTION("certsvc_instance_new failed : [%d]", err);
98 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
102 /* Make the pfxID string */
103 err = certsvc_string_new(cert_instance, certificate, EM_SAFE_STRLEN(certificate), &csstring);
104 if (err != CERTSVC_SUCCESS) {
105 EM_DEBUG_EXCEPTION("certsvc_string_new failed : [%d]", err);
106 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
110 if (certsvc_pkcs12_get_end_user_certificate_list_from_store(
114 &length) != CERTSVC_SUCCESS) {
115 EM_DEBUG_EXCEPTION("certsvc_string_new failed : [%d]", err);
116 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
118 certsvc_pkcs12_free_certificate_list_loaded_from_store(cert_instance, &certList);
124 if (strcmp(tempList->title, certificate) == 0
125 || strcmp(tempList->gname, certificate) == 0) {
126 alias = strdup(tempList->gname);
130 tempList = tempList->next;
133 certsvc_pkcs12_free_certificate_list_loaded_from_store(cert_instance, &certList);
135 EM_DEBUG_EXCEPTION("Failed to strdup");
136 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
140 /* Make the pfxID string */
141 err = certsvc_string_new(cert_instance, alias, EM_SAFE_STRLEN(alias), &csstring);
142 if (err != CERTSVC_SUCCESS) {
143 EM_DEBUG_EXCEPTION("certsvc_string_new failed : [%d]", err);
144 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
148 err = certsvc_pkcs12_load_certificate_list_from_store(cert_instance, EMAIL_STORE, csstring, &certificate_list);
149 if (err != CERTSVC_SUCCESS) {
150 certsvc_string_free(csstring);
151 err = certsvc_string_new(cert_instance, certificate, EM_SAFE_STRLEN(certificate), &csstring);
152 if (err != CERTSVC_SUCCESS) {
153 EM_DEBUG_EXCEPTION("certsvc_string_new failed : [%d]", err);
154 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
158 /* Load the certificate list of pkcs12 type */
159 err = certsvc_pkcs12_load_certificate_list_from_store(cert_instance, EMAIL_STORE, csstring, &certificate_list);
160 if (err != CERTSVC_SUCCESS) {
161 EM_DEBUG_EXCEPTION("certsvc_pkcs12_load_certificate_list_from_store failed : [%d]", err);
162 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
168 /* Get a certificate */
169 err = certsvc_certificate_list_get_one(certificate_list, 0, &csc_cert);
170 if (err != CERTSVC_SUCCESS) {
171 EM_DEBUG_EXCEPTION("certsvc_certificate_list_get_one failed : [%d]", err);
172 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
176 /* Convert from char to X509 */
177 err = certsvc_certificate_dup_x509(csc_cert, &t_cert);
178 if (t_cert == NULL || err != CERTSVC_SUCCESS) {
179 EM_DEBUG_EXCEPTION("certsvc_certificate_dup_x509 failed");
180 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
184 /* Get the private key */
185 err = certsvc_pkcs12_private_key_dup_from_store(cert_instance, EMAIL_STORE, csstring, &private_key, &key_size);
186 if (err != CERTSVC_SUCCESS) {
187 EM_DEBUG_EXCEPTION("certsvc_pkcs12_private_key_dup_from_store failed : [%d]", err);
188 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
192 EM_DEBUG_LOG_DEV("key_size : [%u], private_key : [%s]", key_size, private_key);
194 /* Convert char to pkey */
195 bio_mem = BIO_new(BIO_s_mem());
196 if (bio_mem == NULL) {
197 EM_DEBUG_EXCEPTION("malloc failed");
198 err = EMAIL_ERROR_OUT_OF_MEMORY;
202 if (BIO_write(bio_mem, private_key, (int)key_size) <= 0) {
203 EM_DEBUG_EXCEPTION("BIO_write failed");
204 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
208 t_pri_key = PEM_read_bio_PrivateKey(bio_mem, NULL, 0, NULL);
209 if (t_pri_key == NULL) {
210 EM_DEBUG_EXCEPTION("PEM_read_bio_PrivateKey failed");
211 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
227 *pri_key = t_pri_key;
230 EVP_PKEY_free(t_pri_key);
234 EM_SAFE_FREE(private_key);
242 certsvc_instance_free(cert_instance);
247 INTERNAL_FUNC int emcore_verify_signature(char *p7s_file_path, char *mime_entity, int *validity, int *err_code)
249 EM_DEBUG_FUNC_BEGIN_SEC("path : [%s], mime_entity : [%s]", p7s_file_path, mime_entity);
251 int err = EMAIL_ERROR_NONE;
253 int flags = PKCS7_NOVERIFY;
257 BIO *bio_indata = NULL;
259 PKCS7 *pkcs7_p7s = NULL;
262 bio_p7s = BIO_new_file(p7s_file_path, INMODE);
264 EM_DEBUG_EXCEPTION("File open failed");
265 err = EMAIL_ERROR_SYSTEM_FAILURE;
269 /* Open input data file */
270 bio_indata = BIO_new_file(mime_entity, INMODE);
272 EM_DEBUG_EXCEPTION("File open failed");
273 err = EMAIL_ERROR_SYSTEM_FAILURE;
277 /* Load the p7s file */
278 pkcs7_p7s = d2i_PKCS7_bio(bio_p7s, NULL);
280 EM_DEBUG_EXCEPTION("d2i_PKCS7_bio failed");
281 err = EMAIL_ERROR_LOAD_CERTIFICATE_FAILURE;
285 if (!PKCS7_verify(pkcs7_p7s, NULL, NULL, bio_indata, NULL, flags)) {
286 EM_DEBUG_EXCEPTION("PKCS7_verify failed");
297 PKCS7_free(pkcs7_p7s);
303 BIO_free(bio_indata);
306 *validity = t_validity;