summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAKalinich-Luxoft <AKalinich@luxoft.com>2018-05-25 15:02:52 +0300
committerAKalinich-Luxoft <AKalinich@luxoft.com>2018-06-15 17:09:14 +0300
commit671c6b5966ee58343ce87f31f35e9d3df1fe269c (patch)
treefc7472e027bc2bc998a545d6779f5970de3692fb
parent68def28d6268218818f60ee7dbfc8aa915a32a3c (diff)
downloadsdl_core-671c6b5966ee58343ce87f31f35e9d3df1fe269c.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 Conflicts: src/components/security_manager/include/security_manager/crypto_manager_impl.h src/components/security_manager/src/crypto_manager_impl.cc
-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.cc88
2 files changed, 83 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 d7f5fa132a..95bb90f8ff 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
@@ -154,6 +154,14 @@ class CryptoManagerImpl : public CryptoManager {
bool AreForceProtectionSettingsCorrect() const;
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);
+
int pull_number_from_buf(char* buf, int* idx);
void asn1_time_to_tm(ASN1_TIME* time);
@@ -185,6 +193,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 1ee62c6ce6..77aaaf9af1 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()) {
@@ -379,6 +379,8 @@ bool CryptoManagerImpl::set_certificate(const std::string& cert_data) {
X509* cert = NULL;
PEM_read_bio_X509(bio_cert, &cert, 0, 0);
+ asn1_time_to_tm(X509_get_notAfter(cert));
+
EVP_PKEY* pkey = NULL;
if (1 == BIO_reset(bio_cert)) {
PEM_read_bio_PrivateKey(bio_cert, &pkey, 0, 0);
@@ -393,35 +395,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);
}
int CryptoManagerImpl::pull_number_from_buf(char* buf, int* idx) {
@@ -548,4 +525,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