Introduce ApiListener#RenewCert()

This commit is contained in:
Alexander A. Klimov 2022-03-29 16:36:13 +02:00
parent 9be2eb8e5e
commit 6d470a3ca5
3 changed files with 29 additions and 18 deletions

View File

@ -179,6 +179,30 @@ void ApiListener::OnConfigLoaded()
UpdateSSLContext();
}
std::shared_ptr<X509> ApiListener::RenewCert(const std::shared_ptr<X509>& cert)
{
std::shared_ptr<EVP_PKEY> pubkey (X509_get_pubkey(cert.get()), EVP_PKEY_free);
auto subject (X509_get_subject_name(cert.get()));
auto cacert (GetX509Certificate(GetDefaultCaPath()));
auto newcert (CreateCertIcingaCA(pubkey.get(), subject));
/* verify that the new cert matches the CA we're using for the ApiListener;
* this ensures that the CA we have in /var/lib/icinga2/ca matches the one
* we're using for cluster connections (there's no point in sending a client
* a certificate it wouldn't be able to use to connect to us anyway) */
try {
if (!VerifyCertificate(cacert, newcert, GetCrlPath())) {
Log(LogWarning, "ApiListener")
<< "The CA in '" << GetDefaultCaPath() << "' does not match the CA which Icinga uses "
<< "for its own cluster connections. This is most likely a configuration problem.";
return nullptr;
}
} catch (const std::exception&) { } /* Swallow the exception on purpose, cacert will never be a non-CA certificate. */
return newcert;
}
void ApiListener::UpdateSSLContext()
{
m_SSLContext = SetupSslContext(GetDefaultCertPath(), GetDefaultKeyPath(), GetDefaultCaPath(), GetCrlPath(), GetCipherList(), GetTlsProtocolmin(), GetDebugInfo());

View File

@ -89,6 +89,7 @@ public:
static String GetCaDir();
static String GetCertificateRequestsDir();
std::shared_ptr<X509> RenewCert(const std::shared_ptr<X509>& cert);
void UpdateSSLContext();
static ApiListener::Ptr GetInstance();

View File

@ -146,8 +146,6 @@ Value RequestCertificateHandler(const MessageOrigin::Ptr& origin, const Dictiona
}
std::shared_ptr<X509> newcert;
std::shared_ptr<EVP_PKEY> pubkey;
X509_NAME *subject;
Dictionary::Ptr message;
String ticket;
@ -198,23 +196,11 @@ Value RequestCertificateHandler(const MessageOrigin::Ptr& origin, const Dictiona
}
}
pubkey = std::shared_ptr<EVP_PKEY>(X509_get_pubkey(cert.get()), EVP_PKEY_free);
subject = X509_get_subject_name(cert.get());
newcert = listener->RenewCert(cert);
newcert = CreateCertIcingaCA(pubkey.get(), subject);
/* verify that the new cert matches the CA we're using for the ApiListener;
* this ensures that the CA we have in /var/lib/icinga2/ca matches the one
* we're using for cluster connections (there's no point in sending a client
* a certificate it wouldn't be able to use to connect to us anyway) */
try {
if (!VerifyCertificate(cacert, newcert, listener->GetCrlPath())) {
Log(LogWarning, "JsonRpcConnection")
<< "The CA in '" << listener->GetDefaultCaPath() << "' does not match the CA which Icinga uses "
<< "for its own cluster connections. This is most likely a configuration problem.";
goto delayed_request;
}
} catch (const std::exception&) { } /* Swallow the exception on purpose, cacert will never be a non-CA certificate. */
if (!newcert) {
goto delayed_request;
}
/* Send the signed certificate update. */
Log(LogInformation, "JsonRpcConnection")