Merge pull request #61671 from GrigoryPervakov/master

Reload certificate chain during certificate reload
This commit is contained in:
Nikita Taranov 2024-03-27 21:19:32 +01:00 committed by GitHub
commit 7b17b14aa0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 116 additions and 10 deletions

View File

@ -22,7 +22,6 @@ int callSetCertificate(SSL * ssl, [[maybe_unused]] void * arg)
}
/// This is callback for OpenSSL. It will be called on every connection to obtain a certificate and private key.
int CertificateReloader::setCertificate(SSL * ssl)
{
@ -30,17 +29,37 @@ int CertificateReloader::setCertificate(SSL * ssl)
if (!current)
return -1;
SSL_use_certificate(ssl, const_cast<X509 *>(current->cert.certificate()));
SSL_use_PrivateKey(ssl, const_cast<EVP_PKEY *>(static_cast<const EVP_PKEY *>(current->key)));
if (current->certs_chain.empty())
return -1;
int err = SSL_check_private_key(ssl);
if (err != 1)
if (auto err = SSL_clear_chain_certs(ssl); err != 1)
{
std::string msg = Poco::Net::Utility::getLastError();
LOG_ERROR(log, "Unusable key-pair {}", msg);
LOG_ERROR(log, "Clear certificates {}", Poco::Net::Utility::getLastError());
return -1;
}
if (auto err = SSL_use_certificate(ssl, const_cast<X509 *>(current->certs_chain[0].certificate())); err != 1)
{
LOG_ERROR(log, "Use certificate {}", Poco::Net::Utility::getLastError());
return -1;
}
for (auto cert = current->certs_chain.begin() + 1; cert != current->certs_chain.end(); cert++)
{
if (auto err = SSL_add1_chain_cert(ssl, const_cast<X509 *>(cert->certificate())); err != 1)
{
LOG_ERROR(log, "Add certificate to chain {}", Poco::Net::Utility::getLastError());
return -1;
}
}
if (auto err = SSL_use_PrivateKey(ssl, const_cast<EVP_PKEY *>(static_cast<const EVP_PKEY *>(current->key))); err != 1)
{
LOG_ERROR(log, "Use private key {}", Poco::Net::Utility::getLastError());
return -1;
}
if (auto err = SSL_check_private_key(ssl); err != 1)
{
LOG_ERROR(log, "Unusable key-pair {}", Poco::Net::Utility::getLastError());
return -1;
}
return 1;
}
@ -100,7 +119,7 @@ void CertificateReloader::tryLoad(const Poco::Util::AbstractConfiguration & conf
CertificateReloader::Data::Data(std::string cert_path, std::string key_path, std::string pass_phrase)
: cert(cert_path), key(/* public key */ "", /* private key */ key_path, pass_phrase)
: certs_chain(Poco::Crypto::X509Certificate::readPEM(cert_path)), key(/* public key */ "", /* private key */ key_path, pass_phrase)
{
}

View File

@ -70,7 +70,7 @@ private:
struct Data
{
Poco::Crypto::X509Certificate cert;
Poco::Crypto::X509Certificate::List certs_chain;
Poco::Crypto::EVPPKey key;
Data(std::string cert_path, std::string key_path, std::string pass_phrase);

View File

@ -0,0 +1,43 @@
-----BEGIN CERTIFICATE-----
MIIDkzCCAnugAwIBAgIUSChEeHqJus9jzKmD/L3Tw0x4OwcwDQYJKoZIhvcNAQEL
BQAwQTEaMBgGA1UEAwwRZGVtby5tbG9wc2h1Yi5jb20xCzAJBgNVBAYTAlVTMRYw
FAYDVQQHDA1TYW4gRnJhbnNpc2NvMCAXDTI0MDMyMDE5MTE1OVoYDzIxMjQwMjI1
MTkxMTU5WjBxMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG
A1UEBwwNU2FuIEZyYW5zaXNjbzEPMA0GA1UECgwGRm9vQmFyMRAwDgYDVQQLDAdG
b28gQmFyMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IB
DwAwggEKAoIBAQDM//0s6AX988J86HzxX95irGa9cJIfY24UDBXVkO3gREiwj1Uf
bpvpxCcwADMuFdggsJlppWa3q+PNJ/eoVwdl3gG0WXaZp1rcuv6ltxdQAUtgfMAb
5p7HwsO7rCTGJBwa62Jg+E79j+V8rZWfaJRfNtY0p7eauWIrqLA0Gyse+lRayPHI
hsR9+0qedF+qziFpbNxpW8DHrpIrLb8LEao1BCYQ44koBXjkrXeR6OidXw/gek8+
9M2GLxy6ubQ7hrcYwVWpFOKLLZLmyYDgescM6AIU904o1bN0yJ5rM7a1+f150qp6
ttZlya0sJH0lm3gzEsqb6Fbh+Dw/9Lsp66sDAgMBAAGjUTBPMB8GA1UdIwQYMBaA
FMjyDUyXujACeQa2G+4I8ic5HVBiMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgTwMBQG
A1UdEQQNMAuCCWxvY2FsaG9zdDANBgkqhkiG9w0BAQsFAAOCAQEABEWEaVDqv9Za
bFpD/JEMIFVqe5ANKAnbbff0/vFJQ7yFmsL8/G4bbdd8uidRgE4WgoeNUscCnfk+
kjb1vFjvY4/cBYITn41Pz5I7lQMH+BaR5gHb1oJVlJavQ2vsaeMuyDJaNmumejmU
YnoKZRwwb6SCXujS2MKgKl+jL5OkZk60i+nJhIXfxwMNmlvtqADSU5Z3VMagq8hj
DnEsxTz8PptuVaLVT4kcZm9gZpDEW2KPMZhNCv/g7EzQv8r3WnFGqumMGBO82ZE0
mUh/Chrhss/meVK0FqTTBjOlex7R0GiJBCDfZGYTWIVdND4ICdZ1OpGWid5CXbfQ
sWBrbBaEyw==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDYzCCAkugAwIBAgIUR0PldYYSk3DAifgb600kvqjaCAIwDQYJKoZIhvcNAQEL
BQAwQTEaMBgGA1UEAwwRZGVtby5tbG9wc2h1Yi5jb20xCzAJBgNVBAYTAlVTMRYw
FAYDVQQHDA1TYW4gRnJhbnNpc2NvMB4XDTI0MDMyMDE5MTEzMVoXDTI1MDMxMTE5
MTEzMVowQTEaMBgGA1UEAwwRZGVtby5tbG9wc2h1Yi5jb20xCzAJBgNVBAYTAlVT
MRYwFAYDVQQHDA1TYW4gRnJhbnNpc2NvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEAqL3k6Pexu1KR8fc84fRmu0hYon7+xOPmtFSzspeN+DJNe5oDO6x0
RzTQkgtDoxTcq32O290r3uURnDmnvNubz5yTpM1Zcz/kuSNpHLJh4yyZsXRsB21v
lb3bhjqyn6rkfoQzIMekt7clPQS0dWdU2T+lwn6XBVShOyB/W7ysP309ofQGXV+T
VFyU+lgZc2WjK6611QDCpTXgRc/UKUfU5460BnTCylP6jzBOWBZb8FX6dYBzS4U2
yISvOXagxJVruoWjscc35ln6HBQ8bu/fI8Q0n1/ROlm785Bsd/LpVw465kklwQwS
FY3FQkiedD1fyszXO4Yq5PARw54AGKbAyQIDAQABo1MwUTAdBgNVHQ4EFgQUyPIN
TJe6MAJ5BrYb7gjyJzkdUGIwHwYDVR0jBBgwFoAUyPINTJe6MAJ5BrYb7gjyJzkd
UGIwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAYyl27sxwrjz5
qcqwbLYv2eFIR6VZzvHfknSK1ht1jzMkXxvAOjETbYwqwWquWwMHOD2X4q5d57nu
qYAE9YE27HFzknPQkDdzwJ0u4dKi28PK8tM6dqDK46LSal/MEUxXGuzW3TRyJXrl
lPi+Wh6gZRRiANJ+giEwvQ+8k6eURHrhtL7yZqT+swi+jP4h6S4mmHmsaOj4VoP/
NCFoRZud5SCd7RZV+fzNfxhLHI9I2c2gFycBDZOEdlrIZHM6EoaDb3i9kDVbnZqG
Zj/+k/NwCKg5UiDap6Z7Xj7w0chSppg3DMcsxGeQ9vQcMtydNu5fSK4CozNqxObb
hGBJrQylAw==
-----END CERTIFICATE-----

View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAzP/9LOgF/fPCfOh88V/eYqxmvXCSH2NuFAwV1ZDt4ERIsI9V
H26b6cQnMAAzLhXYILCZaaVmt6vjzSf3qFcHZd4BtFl2mada3Lr+pbcXUAFLYHzA
G+aex8LDu6wkxiQcGutiYPhO/Y/lfK2Vn2iUXzbWNKe3mrliK6iwNBsrHvpUWsjx
yIbEfftKnnRfqs4haWzcaVvAx66SKy2/CxGqNQQmEOOJKAV45K13kejonV8P4HpP
PvTNhi8curm0O4a3GMFVqRTiiy2S5smA4HrHDOgCFPdOKNWzdMieazO2tfn9edKq
erbWZcmtLCR9JZt4MxLKm+hW4fg8P/S7KeurAwIDAQABAoIBAQDIT6LtzFJ+kT+L
mgjsOocs19UUavj9XsTjJeP36UPnDhIRJB1DN2t2Astf5fIcqA+l8aoWRx6Vfop7
nwAqJ8/8w+/acEipX5Qzdyz4dG19Kaajw4JcQP8JptBng4/zZLlpvHNG2ZslvQO6
zksTlrbUStsIXJHVyCubCZwTbjC2dJlc97705DZAk/8L7FkljmyJws2xwQZlxdQG
FZ+8IrAqpWJC55EPfKo6+QsKEc9hh4N/MQW483V5yCuw9dLShcEMDGuxcHGFHif8
BrwImih0rIwj9tTDY9pw6aJ5+80tVStNLDk+1eQRME6Fy/c7RG/sm/lj+P0YOI7F
jH4wyXVRAoGBAOc+rFNpM/CgRZD4VXQ+gV1+PLdaqUUU3UXAPfNWkrMIr0u4+tmg
OMMkXaM7B/ps7o5+Rcj+tO1VAvl6m7uM376szC3Ex8JA0XBDmJrJKfEQCHkzvkdf
wywVBeAR4f3D2+9Meh1XSNRqGU+Anb48neTyVYzPNIoK8ZmtZID49GfVAoGBAOLy
EX1TT1xwE/VwDy5BeJQzyZ+xwevie/960RIYooLeb31NLhOcX142b8U7XRMtiqdd
wfsT5SbjnrATBponKZELO7LwE+Z4djo2+O6JZjYB5/t/Z6r7qfOaTTlJEl8VJKo4
F+qAsqKo0Q9EpkRUeNdcOjDzkuEikw9IlhS0VEt3AoGAWLHoRQH4AxZmOGmX1UNY
OTT/MtCaVj3fdS58VIZjNDpjiibESI601txu8fnlYH9BrPPv7l0LpnBR+MC3VON+
ulLq6a8tc2uLKYUz1kLMTIL6zQo0tImdgZ36p+wUA1KJXCq4N+LPs3GSjbTmTB5R
7Yuplp2vKDd0XZ5tCy7yB5UCgYEA3ppoE1DTSC1bNmSLT2jCuEOv4ic+unw1+lti
lWh6hvldzD8XEf9RAB1PNtvKqNQD67SoX/mczK956OVQlYYSXIXzMcoRCwBfnyxq
sbct/Y2TGXpXmjwt8JcKZkVJcuBPTXOl6cwA7FHAdkR0/hMJUNzS608PZCtAqj4d
kANtp3MCgYEA3plv6RYYDZsUdJmIcdIvr/LxWTSqYf37LQM//k+OXo+zWMxgnUNv
AEqDlNWP+bw3yJlU1bQS2o1Z+hKzDgqDZtaVVVDgdVsUaDSW0EsJpedWXoGqJdrw
yxhB7RYi1tQsXHbR1iyT5hH0ZlV7s0XIKRU4U8MP05av099+++YKhks=
-----END RSA PRIVATE KEY-----

View File

@ -13,6 +13,8 @@ node = cluster.add_instance(
"configs/second.key",
"configs/ECcert.crt",
"configs/ECcert.key",
"configs/WithChain.crt",
"configs/WithChain.key",
"configs/WithPassPhrase.crt",
"configs/WithPassPhrase.key",
"configs/cert.xml",
@ -158,3 +160,18 @@ def test_cert_with_pass_phrase():
check_certificate_switch(
"first", "WithPassPhrase", pass_phrase_second=pass_phrase_for_cert
)
def test_chain_reload():
"""Check cert chain reload"""
check_certificate_switch("first", "WithChain")
assert (
node.exec_in_container(
[
"bash",
"-c",
"openssl s_client -showcerts -servername localhost -connect localhost:8443 </dev/null 2>/dev/null | grep 'BEGIN CERTIFICATE' | wc -l",
]
)
== "2\n"
)