summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAKalinich-Luxoft <AKalinich@luxoft.com>2018-05-25 15:02:52 +0300
committerAndrii Kalinich <AKalinich@luxoft.com>2018-06-18 21:14:26 +0300
commit8d2379ca0b62c97118293e24d9ae097f1a556c6a (patch)
tree13b351f0bffb5bf5e325a7b79847b9d2b5eceddf
parent9967a6a03ddb4fa5844952349c6dd579621e2731 (diff)
downloadsdl_core-8d2379ca0b62c97118293e24d9ae097f1a556c6a.tar.gz
Fix cert processing and module saving after policy table update
SDL Core should update the module certificate in the local file system when a policy table update occurs. Currently SDL core is retrieving its certificate directly out of the policy table. This fix provides functionality for saving module certificate to the file system. Following changes were done: - Added getters for CertificatePath and KeyPath parameters in SecurityManagerSettings class to provide another components an access to these properties - Added methods for saving certificate and private key data to the files specified by CertificatePath and KeyPath keywords - CryptoManager component implementation was updated. Now this component also saves certificate data to files (if write permission allowed) after PTU
-rw-r--r--src/components/security_manager/include/security_manager/crypto_manager_impl.h26
-rw-r--r--src/components/security_manager/src/crypto_manager_impl.cc86
2 files changed, 81 insertions, 31 deletions
diff --git a/src/components/security_manager/include/security_manager/crypto_manager_impl.h b/src/components/security_manager/include/security_manager/crypto_manager_impl.h
index cba1a1d1d0..770dfa102d 100644
--- a/src/components/security_manager/include/security_manager/crypto_manager_impl.h
+++ b/src/components/security_manager/include/security_manager/crypto_manager_impl.h
@@ -155,6 +155,14 @@ class CryptoManagerImpl : public CryptoManager {
bool set_certificate(const std::string& cert_data);
/**
+ * @brief Saves new certificate data on the file system
+ * @param cert_data certificate data in PEM format
+ * @return true if new certificate data was successfully saved on the file
+ * system, otherwise returns false
+ */
+ bool SaveCertificateData(const std::string& cert_data);
+
+ /**
* @brief Updates certificate and private key for the current SSL context
* @param certificate new certificate to update
* @param key new private key to update
@@ -200,6 +208,24 @@ class CryptoManagerImpl : public CryptoManager {
*/
EVP_PKEY* LoadModulePrivateKeyFromFile();
+ /**
+ * @brief Saves new X509 certificate data to file specified in
+ * CryptoManagerSettings
+ * @param certificate new X509 certificate data
+ * @return true if certificate data was saved to the file system otherwise
+ * returns false
+ */
+ bool SaveModuleCertificateToFile(X509* certificate) const;
+
+ /**
+ * @brief Saves new private key data to file specified in
+ * CryptoManagerSettings
+ * @param key new private key data
+ * @return true if private key data was saved to the file system otherwise
+ * returns false
+ */
+ bool SaveModuleKeyToFile(EVP_PKEY* key) const;
+
const utils::SharedPtr<const CryptoManagerSettings> settings_;
SSL_CTX* context_;
static uint32_t instance_count_;
diff --git a/src/components/security_manager/src/crypto_manager_impl.cc b/src/components/security_manager/src/crypto_manager_impl.cc
index 34727fedf9..48acd61614 100644
--- a/src/components/security_manager/src/crypto_manager_impl.cc
+++ b/src/components/security_manager/src/crypto_manager_impl.cc
@@ -221,7 +221,7 @@ bool CryptoManagerImpl::Init() {
// Disable SSL2 as deprecated
SSL_CTX_set_options(context_, SSL_OP_NO_SSLv2);
- set_certificate(get_settings().certificate_data());
+ SaveCertificateData(get_settings().certificate_data());
if (get_settings().ciphers_list().empty()) {
LOG4CXX_WARN(logger_, "Empty ciphers list");
@@ -288,7 +288,7 @@ bool CryptoManagerImpl::OnCertificateUpdated(const std::string& data) {
return false;
}
- if (!set_certificate(data)) {
+ if (!SaveCertificateData(data)) {
LOG4CXX_ERROR(logger_, "Failed to save certificate data");
return false;
}
@@ -362,7 +362,7 @@ const CryptoManagerSettings& CryptoManagerImpl::get_settings() const {
return *settings_;
}
-bool CryptoManagerImpl::set_certificate(const std::string& cert_data) {
+bool CryptoManagerImpl::SaveCertificateData(const std::string& cert_data) {
LOG4CXX_AUTO_TRACE(logger_);
if (cert_data.empty()) {
@@ -393,35 +393,10 @@ bool CryptoManagerImpl::set_certificate(const std::string& cert_data) {
return false;
}
- if (!SSL_CTX_use_certificate(context_, cert)) {
- LOG4CXX_WARN(logger_, "Could not use certificate: " << LastError());
- return false;
- }
-
- if (!SSL_CTX_use_PrivateKey(context_, pkey)) {
- LOG4CXX_ERROR(logger_, "Could not use key: " << LastError());
- return false;
- }
-
- if (!SSL_CTX_check_private_key(context_)) {
- LOG4CXX_ERROR(logger_, "Could not use certificate: " << LastError());
- return false;
- }
-
- X509_STORE* store = SSL_CTX_get_cert_store(context_);
- if (store) {
- X509* extra_cert = NULL;
- while ((extra_cert = PEM_read_bio_X509(bio_cert, NULL, 0, 0))) {
- if (extra_cert != cert) {
- LOG4CXX_DEBUG(logger_,
- "Added new certificate to store: " << extra_cert);
- X509_STORE_add_cert(store, extra_cert);
- }
- }
- }
+ utils::ScopeGuard key_guard = utils::MakeGuard(EVP_PKEY_free, pkey);
+ UNUSED(key_guard);
- LOG4CXX_DEBUG(logger_, "Certificate and key successfully updated");
- return true;
+ return SaveModuleCertificateToFile(cert) && SaveModuleKeyToFile(pkey);
}
bool CryptoManagerImpl::UpdateModuleCertificateData(X509* certificate,
@@ -501,4 +476,53 @@ EVP_PKEY* CryptoManagerImpl::LoadModulePrivateKeyFromFile() {
return module_key;
}
+bool CryptoManagerImpl::SaveModuleCertificateToFile(X509* certificate) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ if (NULL == certificate) {
+ LOG4CXX_WARN(logger_, "Empty certificate. Saving will be skipped");
+ return false;
+ }
+
+ const std::string cert_path = get_settings().module_cert_path();
+ BIO* bio_cert = BIO_new_file(cert_path.c_str(), "w");
+ if (NULL == bio_cert) {
+ LOG4CXX_ERROR(logger_,
+ "Failed to open " << cert_path << " file: " << LastError());
+ return false;
+ }
+
+ if (0 == PEM_write_bio_X509(bio_cert, certificate)) {
+ LOG4CXX_ERROR(logger_,
+ "Failed to write certificate to file: " << LastError());
+ return false;
+ }
+
+ return true;
+}
+
+bool CryptoManagerImpl::SaveModuleKeyToFile(EVP_PKEY* key) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ if (NULL == key) {
+ LOG4CXX_WARN(logger_, "Empty private key. Saving will be skipped");
+ return false;
+ }
+
+ const std::string key_path = get_settings().module_key_path();
+ BIO* bio_key = BIO_new_file(key_path.c_str(), "w");
+ if (NULL == bio_key) {
+ LOG4CXX_ERROR(logger_,
+ "Failed to open " << key_path << " file: " << LastError());
+ return false;
+ }
+
+ if (0 == PEM_write_bio_PrivateKey(bio_key, key, NULL, NULL, 0, NULL, NULL)) {
+ LOG4CXX_ERROR(logger_, "Failed to write key to file: " << LastError());
+ return false;
+ }
+
+ return true;
+}
+
} // namespace security_manager