1 /* Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License
16 * @file certificate-stack.cpp
17 * @author Barlomiej Grzelewski (b.grzelewski@samsung.com)
19 * @brief Certificate Stack Implmentation.
21 #include <openssl/x509.h>
25 #include <dpl/log/log.h>
27 #include <certificate-store.h>
28 #include <certificate-config.h>
29 #include <ckm/ckm-error.h>
30 #include <ckm/ckm-type.h>
31 #include <openssl_utils.h>
35 CertificateStore::CertificateStore() : m_store(X509_STORE_new())
38 LogError("Failed to create store");
39 throw std::runtime_error("Failed to create store");
43 CertificateStore::~CertificateStore()
45 X509_STORE_free(m_store);
48 int CertificateStore::verifyCertificate(
49 const CertificateImpl &cert,
50 const CertificateImplVector &untrustedVector,
51 const CertificateImplVector &trustedVector,
52 bool useTrustedSystemCertificates,
54 CertificateImplVector &chainVector)
57 LogDebug("Certificate for verfication ptr: " << (void*)cert.getX509());
58 LogDebug("Verfication with " << untrustedVector.size() << " untrusted certificates" <<
59 trustedVector.size() << "trusted certificates" << " and system certificates set to: "
60 << useTrustedSystemCertificates);
62 X509_STORE_CTX_PTR csc= create_x509_store_ctx();
64 LogError("failed to create csc");
65 return CKM_API_ERROR_UNKNOWN;
68 if (useTrustedSystemCertificates) {
69 ret = addSystemCertificateDirs();
70 if (ret != CKM_API_SUCCESS)
73 ret = addSystemCertificateFiles();
74 if (ret != CKM_API_SUCCESS)
78 ret = addCustomTrustedCertificates(trustedVector);
79 if (ret != CKM_API_SUCCESS)
82 // create stack of untrusted certificates
83 X509_STACK_PTR untrusted = create_x509_stack();
84 if (!untrustedVector.empty()) {
85 for (auto &e : untrustedVector) {
86 // we don't want to free certificates because we wont create copies
87 sk_X509_push(untrusted.get(), e.getX509());
91 if (0 == X509_STORE_CTX_init(csc.get(), m_store, cert.getX509(), untrusted.get())) {
92 LogError("failed to X509_STORE_CTX_init");
93 return CKM_API_ERROR_UNKNOWN;
97 X509_VERIFY_PARAM_set_flags(csc->param, X509_V_FLAG_X509_STRICT);
100 int result = X509_verify_cert(csc.get()); // 1 == ok; 0 == fail; -1 == error
102 LogDebug("Openssl verification result: " << result);
105 STACK_OF(X509) *chain = X509_STORE_CTX_get_chain(csc.get());
106 for (int i = 0; i < sk_X509_num(chain); ++i) {
107 X509* icert = (X509*)sk_X509_value(chain, i);
108 chainVector.push_back(CertificateImpl(icert));
114 ret = X509_STORE_CTX_get_error(csc.get());
115 LogError("verify error[" << ret << "]: " << X509_verify_cert_error_string(ret));
116 return CKM_API_ERROR_VERIFICATION_FAILED;
118 return CKM_API_SUCCESS;
120 return CKM_API_ERROR_UNKNOWN;
124 int CertificateStore::addSystemCertificateDirs()
126 const auto& dirs = CertificateConfig::getSystemCertificateDirs();
128 return CKM_API_SUCCESS;
130 // add system certificate directories
131 auto dir_lookup = X509_STORE_add_lookup(m_store, X509_LOOKUP_hash_dir());
133 LogError("Error in X509_STORE_add_lookup");
134 return CKM_API_ERROR_UNKNOWN;
136 for(const auto& i: dirs) {
137 if (!X509_LOOKUP_add_dir(dir_lookup, i.c_str(), X509_FILETYPE_PEM)) {
138 LogError("Error in X509_LOOKUP_add_dir");
139 return CKM_API_ERROR_UNKNOWN;
142 return CKM_API_SUCCESS;
145 int CertificateStore::addSystemCertificateFiles()
147 const auto& files = CertificateConfig::getSystemCertificateFiles();
149 return CKM_API_SUCCESS;
151 // add system certificate files
152 auto file_lookup = X509_STORE_add_lookup(m_store, X509_LOOKUP_file());
154 LogError("Error in X509_STORE_add_lookup");
155 return CKM_API_ERROR_UNKNOWN;
158 for(const auto& i:files) {
159 if (!X509_LOOKUP_load_file(file_lookup, i.c_str(), X509_FILETYPE_PEM)) {
160 LogError("Error in X509_LOOKUP_load_file");
161 return CKM_API_ERROR_UNKNOWN;
164 return CKM_API_SUCCESS;
167 int CertificateStore::addCustomTrustedCertificates(const CertificateImplVector &trustedVector)
169 // add trusted certificates to store
170 for (const auto& i:trustedVector) {
171 if(1 != X509_STORE_add_cert(m_store, i.getX509())) {
172 LogError("failed to add certificate to the store");
173 return CKM_API_ERROR_UNKNOWN;
176 return CKM_API_SUCCESS;