diff options
Diffstat (limited to 'vespalib/src/tests/net/tls/auto_reloading_tls_crypto_engine/auto_reloading_tls_crypto_engine_test.cpp')
-rw-r--r-- | vespalib/src/tests/net/tls/auto_reloading_tls_crypto_engine/auto_reloading_tls_crypto_engine_test.cpp | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/vespalib/src/tests/net/tls/auto_reloading_tls_crypto_engine/auto_reloading_tls_crypto_engine_test.cpp b/vespalib/src/tests/net/tls/auto_reloading_tls_crypto_engine/auto_reloading_tls_crypto_engine_test.cpp new file mode 100644 index 00000000000..7926f71e812 --- /dev/null +++ b/vespalib/src/tests/net/tls/auto_reloading_tls_crypto_engine/auto_reloading_tls_crypto_engine_test.cpp @@ -0,0 +1,87 @@ +// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include <vespa/vespalib/io/fileutil.h> +#include <vespa/vespalib/net/tls/auto_reloading_tls_crypto_engine.h> +#include <vespa/vespalib/net/tls/transport_security_options.h> +#include <vespa/vespalib/net/tls/transport_security_options_reading.h> +#include <vespa/vespalib/net/tls/impl/openssl_tls_context_impl.h> +#include <vespa/vespalib/testkit/test_kit.h> + +#include <chrono> + +#include <openssl/ssl.h> + +using namespace vespalib; +using namespace vespalib::net::tls; +using namespace std::chrono_literals; + +constexpr const char* cert1_pem = R"(-----BEGIN CERTIFICATE----- +MIIBszCCAVgCCQCXsYrXQWS0bzAKBggqhkjOPQQDAjBkMQswCQYDVQQGEwJVUzEU +MBIGA1UEBwwLTG9vbmV5VmlsbGUxDTALBgNVBAoMBEFDTUUxFTATBgNVBAsMDEFD +TUUgdGVzdCBDQTEZMBcGA1UEAwwQYWNtZS5leGFtcGxlLmNvbTAeFw0xODExMzAx +NDA0MzdaFw00NjA0MTcxNDA0MzdaMF4xCzAJBgNVBAYTAlVTMRQwEgYDVQQHDAtM +b29uZXlWaWxsZTEeMBwGA1UECgwVV2lsZS4gRS4gQ295b3RlLCBMdGQuMRkwFwYD +VQQDDBB3aWxlLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE +cQN3UOKg30+h1EYgAxQukAYgzbx7VmcrOBheD7AaJoTUnaRn9xQ6j0t4eKNa6x/1 +K7luNL+AfaJiCQLrbalVoDAKBggqhkjOPQQDAgNJADBGAiEAyzvCt9qJCtY/7Qi1 +2Jzb1BTvAPOszeBFRzovMatQSUICIQDuT6cyV3yigoxLZbn5In3Sx+qUPFPCMI8O +X5yKMXNkmQ== +-----END CERTIFICATE-----)"; + +constexpr const char* cert2_pem = R"(-----BEGIN CERTIFICATE----- +MIIBsjCCAVgCCQCXsYrXQWS0cDAKBggqhkjOPQQDAjBkMQswCQYDVQQGEwJVUzEU +MBIGA1UEBwwLTG9vbmV5VmlsbGUxDTALBgNVBAoMBEFDTUUxFTATBgNVBAsMDEFD +TUUgdGVzdCBDQTEZMBcGA1UEAwwQYWNtZS5leGFtcGxlLmNvbTAeFw0xODExMzAx +NDA0MzdaFw00NjA0MTcxNDA0MzdaMF4xCzAJBgNVBAYTAlVTMRQwEgYDVQQHDAtM +b29uZXlWaWxsZTEeMBwGA1UECgwVV2lsZS4gRS4gQ295b3RlLCBMdGQuMRkwFwYD +VQQDDBB3aWxlLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE +cQN3UOKg30+h1EYgAxQukAYgzbx7VmcrOBheD7AaJoTUnaRn9xQ6j0t4eKNa6x/1 +K7luNL+AfaJiCQLrbalVoDAKBggqhkjOPQQDAgNIADBFAiEAluT52NkVdGBRZJxo +PhL9XBnJJfzvG5GKXIK/iZgFuYkCIFLp+SIQ5Nc1+NzrU2ii/mkzCgC4N/nOWu9H +88OP2wnm +-----END CERTIFICATE-----)"; + +void write_file(vespalib::stringref path, vespalib::stringref data) { + File f(path); + f.open(File::CREATE | File::TRUNC); + f.write(data.data(), data.size(), 0); +} + +struct Fixture { + std::unique_ptr<AutoReloadingTlsCryptoEngine> engine; + explicit Fixture(AutoReloadingTlsCryptoEngine::TimeInterval reload_interval) { + write_file("test_cert.pem", cert1_pem); + // Must be done after file has been written + engine = std::make_unique<AutoReloadingTlsCryptoEngine>("test_config.json", reload_interval); + } + + ~Fixture() { + engine.reset(); + if (fileExists("test_cert.pem")) { + unlink("test_cert.pem"); // just crash the test if this throws + } + } + + vespalib::string current_cert_chain() const { + auto impl = engine->acquire_current_engine(); + auto& ctx_impl = dynamic_cast<impl::OpenSslTlsContextImpl&>(*impl->tls_context()); + return ctx_impl.transport_security_options().cert_chain_pem(); + } +}; + +TEST_FF("Config reloading transitively loads updated files", Fixture(50ms), TimeBomb(60)) { + auto current_certs = f1.current_cert_chain(); + ASSERT_EQUAL(cert1_pem, current_certs); + + write_file("test_cert.pem.tmp", cert2_pem); + rename("test_cert.pem.tmp", "test_cert.pem", false, false); // We expect this to be an atomic rename under the hood + + current_certs = f1.current_cert_chain(); + while (current_certs != cert2_pem) { + std::this_thread::sleep_for(10ms); + current_certs = f1.current_cert_chain(); + } + // If the config is never reloaded, test will go boom. +} + +TEST_MAIN() { TEST_RUN_ALL(); } |