From 11361809bb3a091c08a0b561f21e3c605fb29066 Mon Sep 17 00:00:00 2001 From: Brian Neradt Date: Fri, 1 Oct 2021 17:21:41 +0000 Subject: [PATCH] TSSslSecretSet: Update SSL_CTX TLS Secrets TSSslSecretSet previously updated the in-memory certificate data stored in SSLSecret, but did not update the stored SSL_CTX certificates. As a result, any newly created SSL contexts would get the updated secret while the previously stored contexts would still use the old secrets. This patch updates TSSslSecretSet to also update the secrets for stored SSL_CTX objects. This also fixes the related SSLSecret debug logging which had formatting issues, rendering their output unreadable. --- iocore/net/SSLConfig.cc | 3 +++ iocore/net/SSLSecret.cc | 8 +++++--- iocore/net/SSLUtils.cc | 7 +++++++ src/traffic_server/InkAPI.cc | 6 +++++- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/iocore/net/SSLConfig.cc b/iocore/net/SSLConfig.cc index cecbb4592ed..152d9feb4d4 100644 --- a/iocore/net/SSLConfig.cc +++ b/iocore/net/SSLConfig.cc @@ -573,6 +573,9 @@ SSLCertificateConfig::acquire() void SSLCertificateConfig::release(SSLCertLookup *lookup) { + if (lookup == nullptr) { + return; + } configProcessor.release(configid, lookup); } diff --git a/iocore/net/SSLSecret.cc b/iocore/net/SSLSecret.cc index 945e444a0e0..3135d5681fb 100644 --- a/iocore/net/SSLSecret.cc +++ b/iocore/net/SSLSecret.cc @@ -82,7 +82,7 @@ SSLSecret::setSecret(const std::string &name, const char *data, int data_len) return false; } iter->second.assign(data, data_len); - Debug("secret_ssl", "Set secret=%10.s... to %*.s", name.c_str(), static_cast(iter->second.size()), iter->second.data()); + Debug("ssl_secret", "Set secret for %s to %.*s", name.c_str(), static_cast(iter->second.size()), iter->second.data()); return true; } @@ -102,9 +102,10 @@ SSLSecret::getSecret(const std::string &name, std::string_view &data) const { const std::string *data_item = this->getSecretItem(name); if (data_item) { - Debug("secret_ssl", "Get secret=%10.s... %s(%zd)", name.c_str(), data_item->data(), data_item->length()); + Debug("ssl_secret", "Get secret for %s: %.*s", name.c_str(), static_cast(data_item->length()), data_item->data()); data = *data_item; } else { + Debug("ssl_secret", "Get secret for %s: not found", name.c_str()); data = std::string_view{}; } return data_item != nullptr; @@ -113,11 +114,12 @@ SSLSecret::getSecret(const std::string &name, std::string_view &data) const bool SSLSecret::getOrLoadSecret(const std::string &name1, const std::string &name2, std::string_view &data1, std::string_view &data2) { + Debug("ssl_secret", "lookup up secrets for %s and %s", name1.c_str(), name2.c_str()); std::scoped_lock lock(secret_map_mutex); bool found_secret1 = this->getSecret(name1, data1); bool found_secret2 = name2.empty() || this->getSecret(name2, data2); - // If we can't find either secret, load the both again + // If we can't find either secret, load them both again if (!found_secret1 || !found_secret2) { // Make sure each name has an entry if (!found_secret1) { diff --git a/iocore/net/SSLUtils.cc b/iocore/net/SSLUtils.cc index 43b463564f8..d6b87e3c674 100644 --- a/iocore/net/SSLUtils.cc +++ b/iocore/net/SSLUtils.cc @@ -1747,6 +1747,13 @@ SSLMultiCertConfigLoader::update_ssl_ctx(const std::string &secret_name) bool retval = true; SSLCertificateConfig::scoped_config lookup; + if (!lookup) { + // SSLCertificateConfig is still being configured, thus there are no SSL + // contexts to update. This situation can happen during startup if a + // registered hook updates certs before SSLCertContext configuration is + // complete. + return retval; + } std::set policies; lookup->getPolicies(secret_name, policies); diff --git a/src/traffic_server/InkAPI.cc b/src/traffic_server/InkAPI.cc index 9f4b1ddef0a..c3f0cd7a564 100644 --- a/src/traffic_server/InkAPI.cc +++ b/src/traffic_server/InkAPI.cc @@ -9511,15 +9511,19 @@ TSSslSecretSet(const char *secret_name, int secret_name_length, const char *secr SSLConfigParams *load_params = SSLConfig::load_acquire(); SSLConfigParams *params = SSLConfig::acquire(); if (load_params != nullptr) { // Update the current data structure + Debug("ssl.cert_update", "Setting secrets in SSLConfig load for: %.*s", secret_name_length, secret_name); if (!load_params->secrets.setSecret(std::string(secret_name, secret_name_length), secret_data, secret_data_len)) { retval = TS_ERROR; } - SSLConfig::load_release(params); + load_params->updateCTX(std::string(secret_name, secret_name_length)); + SSLConfig::load_release(load_params); } if (params != nullptr) { + Debug("ssl.cert_update", "Setting secrets in SSLConfig for: %.*s", secret_name_length, secret_name); if (!params->secrets.setSecret(std::string(secret_name, secret_name_length), secret_data, secret_data_len)) { retval = TS_ERROR; } + params->updateCTX(std::string(secret_name, secret_name_length)); SSLConfig::release(params); } return retval;