summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAKalinich-Luxoft <AKalinich@luxoft.com>2018-05-25 13:18:50 +0300
committerAndrii Kalinich <AKalinich@luxoft.com>2018-06-18 21:01:02 +0300
commit5a364fb188e09e4fe15892a535b7e6c98f4edd9d (patch)
treeb84f0b02bb658f75db4f722aa38c2566a6e85a7a
parent9651cdc35c3e62040d4fac996a8638b6eebe4015 (diff)
downloadsdl_core-5a364fb188e09e4fe15892a535b7e6c98f4edd9d.tar.gz
Fix nonfunctional CertificatePath and KeyPath parameters in INI
Currently, SDL Core ignores both the CertificatePath and KeyPath keywords that would allow the system integrator to specify certificates for their environment, instead SDL Core only processes the certificate provided via the policy table. This fix makes these keywords functional. 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 loading certificate and private key data from the files specified by CertificatePath and KeyPath keywords - CryptoManager component implementation was updated. Now this component also read certificate data from files (if they are present and accessible) on its own initialization
-rw-r--r--src/components/include/security_manager/security_manager_settings.h2
-rw-r--r--src/components/security_manager/include/security_manager/crypto_manager_impl.h24
-rw-r--r--src/components/security_manager/include/security_manager/crypto_manager_settings_impl.h8
-rw-r--r--src/components/security_manager/src/crypto_manager_impl.cc95
4 files changed, 128 insertions, 1 deletions
diff --git a/src/components/include/security_manager/security_manager_settings.h b/src/components/include/security_manager/security_manager_settings.h
index f8eaadce3e..0bbe0f4f96 100644
--- a/src/components/include/security_manager/security_manager_settings.h
+++ b/src/components/include/security_manager/security_manager_settings.h
@@ -54,6 +54,8 @@ class CryptoManagerSettings {
virtual const std::string& certificate_data() const = 0;
virtual const std::string& ciphers_list() const = 0;
virtual const std::string& ca_cert_path() const = 0;
+ virtual const std::string& module_cert_path() const = 0;
+ virtual const std::string& module_key_path() const = 0;
virtual size_t update_before_hours() const = 0;
virtual size_t maximum_payload_size() const = 0;
virtual const std::vector<int>& force_protected_service() const = 0;
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 be0d102a36..f4a13198da 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
@@ -153,6 +153,30 @@ class CryptoManagerImpl : public CryptoManager {
private:
bool AreForceProtectionSettingsCorrect() const;
bool set_certificate(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
+ * @return true if certificate and private key were updated successfully,
+ * otherwise returns false
+ */
+ bool UpdateModuleCertificateData(X509* certificate, EVP_PKEY* key);
+
+ /**
+ * @brief Loads X509 certificate from file specified in CryptoManagerSettings
+ * @return returns pointer to the loaded X509 certificate in case of success
+ * otherwise returns NULL
+ */
+ X509* LoadModuleCertificateFromFile();
+
+ /**
+ * @brief Loads private key from file specified in CryptoManagerSettings
+ * @return returns pointer to the loaded private key in case of success
+ * otherwise returns NULL
+ */
+ EVP_PKEY* LoadModulePrivateKeyFromFile();
+
const utils::SharedPtr<const CryptoManagerSettings> settings_;
SSL_CTX* context_;
static uint32_t instance_count_;
diff --git a/src/components/security_manager/include/security_manager/crypto_manager_settings_impl.h b/src/components/security_manager/include/security_manager/crypto_manager_settings_impl.h
index 295a76680f..f20d3e4034 100644
--- a/src/components/security_manager/include/security_manager/crypto_manager_settings_impl.h
+++ b/src/components/security_manager/include/security_manager/crypto_manager_settings_impl.h
@@ -60,6 +60,14 @@ class CryptoManagerSettingsImpl : public CryptoManagerSettings {
return profile_.ca_cert_path();
}
+ const std::string& module_cert_path() const OVERRIDE {
+ return profile_.cert_path();
+ }
+
+ const std::string& module_key_path() const OVERRIDE {
+ return profile_.key_path();
+ }
+
size_t update_before_hours() const OVERRIDE {
return profile_.update_before_hours();
}
diff --git a/src/components/security_manager/src/crypto_manager_impl.cc b/src/components/security_manager/src/crypto_manager_impl.cc
index f5908f8043..cf92c2d40c 100644
--- a/src/components/security_manager/src/crypto_manager_impl.cc
+++ b/src/components/security_manager/src/crypto_manager_impl.cc
@@ -254,6 +254,14 @@ bool CryptoManagerImpl::Init() {
<< '"');
}
+ LOG4CXX_DEBUG(logger_, "Setting up module certificate and private key");
+ X509* module_certificate = LoadModuleCertificateFromFile();
+ EVP_PKEY* module_key = LoadModulePrivateKeyFromFile();
+
+ if (!UpdateModuleCertificateData(module_certificate, module_key)) {
+ LOG4CXX_WARN(logger_, "Failed to update module key and certificate");
+ }
+
guard.Dismiss();
const int verify_mode =
@@ -273,7 +281,15 @@ bool CryptoManagerImpl::OnCertificateUpdated(const std::string& data) {
return false;
}
- return set_certificate(data);
+ if (!set_certificate(data)) {
+ LOG4CXX_ERROR(logger_, "Failed to save certificate data");
+ return false;
+ }
+
+ X509* module_certificate = LoadModuleCertificateFromFile();
+ EVP_PKEY* module_key = LoadModulePrivateKeyFromFile();
+
+ return UpdateModuleCertificateData(module_certificate, module_key);
}
SSLContext* CryptoManagerImpl::CreateSSLContext() {
@@ -394,4 +410,81 @@ bool CryptoManagerImpl::set_certificate(const std::string& cert_data) {
return true;
}
+bool CryptoManagerImpl::UpdateModuleCertificateData(X509* certificate,
+ EVP_PKEY* key) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (NULL != certificate) {
+ if (!SSL_CTX_use_certificate(context_, certificate)) {
+ LOG4CXX_WARN(logger_, "Could not use certificate: " << LastError());
+ return false;
+ }
+ }
+
+ if (NULL != key) {
+ if (!SSL_CTX_use_PrivateKey(context_, key)) {
+ LOG4CXX_ERROR(logger_, "Could not use key: " << LastError());
+ return false;
+ }
+
+ if (!SSL_CTX_check_private_key(context_)) {
+ LOG4CXX_ERROR(logger_, "Private key is invalid: " << LastError());
+ return false;
+ }
+ }
+
+ LOG4CXX_DEBUG(logger_, "Certificate and key are successfully updated");
+ return true;
+}
+
+X509* CryptoManagerImpl::LoadModuleCertificateFromFile() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ const std::string cert_path = get_settings().module_cert_path();
+ BIO* bio_cert = BIO_new_file(cert_path.c_str(), "r");
+ if (NULL == bio_cert) {
+ LOG4CXX_WARN(logger_,
+ "Failed to open " << cert_path << " file: " << LastError());
+ return NULL;
+ }
+
+ utils::ScopeGuard bio_guard = utils::MakeGuard(BIO_free, bio_cert);
+ UNUSED(bio_guard);
+
+ X509* module_certificate = NULL;
+ if (0 == PEM_read_bio_X509(bio_cert, &module_certificate, NULL, NULL)) {
+ LOG4CXX_ERROR(logger_,
+ "Failed to read certificate data from file: " << LastError());
+ return NULL;
+ }
+ LOG4CXX_DEBUG(logger_,
+ "Module certificate was loaded: " << module_certificate);
+
+ return module_certificate;
+}
+
+EVP_PKEY* CryptoManagerImpl::LoadModulePrivateKeyFromFile() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ const std::string key_path = get_settings().module_key_path();
+ BIO* bio_key = BIO_new_file(key_path.c_str(), "r");
+ if (NULL == bio_key) {
+ LOG4CXX_WARN(logger_,
+ "Failed to open " << key_path << " file: " << LastError());
+ return NULL;
+ }
+
+ utils::ScopeGuard bio_guard = utils::MakeGuard(BIO_free, bio_key);
+ UNUSED(bio_guard);
+
+ EVP_PKEY* module_key = NULL;
+ if (0 == PEM_read_bio_PrivateKey(bio_key, &module_key, NULL, NULL)) {
+ LOG4CXX_ERROR(logger_,
+ "Failed to read private key data from file: " << LastError());
+ return NULL;
+ }
+ LOG4CXX_DEBUG(logger_, "Module private key was loaded: " << module_key);
+
+ return module_key;
+}
+
} // namespace security_manager