ClickHouse/src/Server/CertificateReloader.cpp

106 lines
2.6 KiB
C++
Raw Normal View History

2021-07-06 23:15:30 +00:00
#include "CertificateReloader.h"
#if USE_SSL
namespace DB
{
2021-07-06 23:15:30 +00:00
int cert_reloader_dispatch_set_cert(SSL * ssl, [[maybe_unused]] void * arg)
{
2021-07-06 23:15:30 +00:00
return CertificateReloader::instance().setCertificate(ssl);
}
2021-07-06 23:15:30 +00:00
int CertificateReloader::setCertificate(SSL * ssl)
{
2021-07-06 22:19:26 +00:00
std::shared_lock lock(mutex);
SSL_use_certificate(ssl, const_cast<X509 *>(cert->certificate()));
SSL_use_RSAPrivateKey(ssl, key->impl()->getRSA());
int err = SSL_check_private_key(ssl);
if (err != 1)
{
std::string msg = Poco::Net::Utility::getLastError();
LOG_ERROR(log, "Unusable keypair {}", msg);
return -1;
}
return 1;
}
2021-07-06 23:15:30 +00:00
void CertificateReloader::init(const Poco::Util::AbstractConfiguration & config)
{
LOG_DEBUG(log, "Initializing config reloader.");
auto & ssl_manager = Poco::Net::SSLManager::instance();
const auto ssl_ctx_ptr = ssl_manager.defaultServerContext();
auto ctx = ssl_ctx_ptr->sslContext();
SSL_CTX_set_cert_cb(ctx, cert_reloader_dispatch_set_cert, nullptr);
reload(config);
}
2021-07-06 23:15:30 +00:00
void CertificateReloader::reload(const Poco::Util::AbstractConfiguration & config)
{
LOG_DEBUG(log, "Handling cert reload.");
const auto cert_file_ = config.getString("openSSL.server.certificateFile", "");
const auto key_file_ = config.getString("openSSL.server.privateKeyFile", "");
bool changed = false;
changed |= setKeyFile(key_file_);
2021-07-06 23:15:30 +00:00
changed |= setCertificateFile(cert_file_);
if (changed)
{
LOG_INFO(log, "Reloading cert({}), key({})", cert_file, key_file);
{
2021-07-06 22:19:26 +00:00
std::unique_lock lock(mutex);
2021-07-06 22:20:14 +00:00
key = std::make_unique<Poco::Crypto::RSAKey>("", key_file);
cert = std::make_unique<Poco::Crypto::X509Certificate>(cert_file);
}
LOG_INFO(log, "Reloaded cert {}", cert_file);
}
}
2021-07-06 23:15:30 +00:00
bool CertificateReloader::setKeyFile(const std::string key_file_)
{
if (key_file_.empty())
return false;
stat_t st;
int res = stat(key_file_.c_str(), &st);
if (res == -1)
return false;
if (st.st_mtime != key_file_st.st_mtime || key_file != key_file_)
{
key_file = key_file_;
key_file_st = st;
return true;
}
return false;
}
2021-07-06 23:15:30 +00:00
bool CertificateReloader::setCertificateFile(const std::string cert_file_)
{
if (cert_file_.empty())
return false;
stat_t st;
int res = stat(cert_file_.c_str(), &st);
if (res == -1)
return false;
if (st.st_mtime != cert_file_st.st_mtime || cert_file != cert_file_)
{
cert_file = cert_file_;
cert_file_st = st;
return true;
}
return false;
}
}
2021-07-06 23:15:30 +00:00
#endif