From 5e68dedcc1c743e70d1676fe2a0c1dc388d330b6 Mon Sep 17 00:00:00 2001 From: Piotr Sikora Date: Wed, 20 Dec 2017 18:57:25 -0800 Subject: [PATCH 1/9] tls: inline delivery of TLS certificates and private keys. File-based BoringSSL APIs are no longer used and everything is processed as if it was delivered inline in order to provide consistent behavior. Additionally, DataSource files are now read during configuration parsing, which means that the configuration is considered invalid if it refers to non-existing files. Fixes #1357. Signed-off-by: Piotr Sikora --- RAW_RELEASE_NOTES.md | 1 + configs/BUILD | 7 +- configs/configgen.sh | 16 ++- configs/envoy_double_proxy.template.json | 10 +- configs/envoy_front_proxy.template.json | 6 +- include/envoy/ssl/context_config.h | 27 ++++- source/common/ssl/context_config_impl.cc | 63 +++++++---- source/common/ssl/context_config_impl.h | 29 ++++- source/common/ssl/context_impl.cc | 121 ++++++++++++++++---- test/common/ssl/ssl_socket_test.cc | 138 +++++++++++++++++++++++ test/config_test/config_test.cc | 6 +- 11 files changed, 353 insertions(+), 71 deletions(-) diff --git a/RAW_RELEASE_NOTES.md b/RAW_RELEASE_NOTES.md index 5b235dd1b5939..be58ad0e96cce 100644 --- a/RAW_RELEASE_NOTES.md +++ b/RAW_RELEASE_NOTES.md @@ -8,6 +8,7 @@ will make it substantially easier for the releaser to "linkify" all of the relea final version. ## 1.6.0 +* Added support for inline delivery of TLS certificates and private keys. * Added DOWNSTREAM_REMOTE_ADDRESS, DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT, and DOWNSTREAM_LOCAL_ADDRESS access log formatters. DOWNSTREAM_ADDRESS access log formatter has been deprecated. diff --git a/configs/BUILD b/configs/BUILD index 4ef4d27a9daad..b4ebc516c4405 100644 --- a/configs/BUILD +++ b/configs/BUILD @@ -21,9 +21,12 @@ envoy_py_test_binary( genrule( name = "example_configs", - srcs = ["//examples:configs"], + srcs = [ + "//examples:configs", + "//test/config/integration/certs", + ], outs = ["example_configs.tar"], - cmd = "$(location configgen.sh) $(location configgen) $(@D) $(locations //examples:configs)", + cmd = "$(location configgen.sh) $(location configgen) $(@D) $(locations //examples:configs) $(locations //test/config/integration/certs)", tools = [ "configgen.sh", ":configgen", diff --git a/configs/configgen.sh b/configs/configgen.sh index 71d1134a4d697..4fa1aa31a9f28 100755 --- a/configs/configgen.sh +++ b/configs/configgen.sh @@ -7,9 +7,19 @@ shift OUT_DIR="$1" shift -mkdir -p "$OUT_DIR" +mkdir -p "$OUT_DIR/certs" "$CONFIGGEN" "$OUT_DIR" -cp $* "$OUT_DIR" + +for FILE in $*; do + case "$FILE" in + *.pem) + cp "$FILE" "$OUT_DIR/certs" + ;; + *) + cp "$FILE" "$OUT_DIR" + ;; + esac +done # tar is having issues with -C for some reason so just cd into OUT_DIR. -(cd "$OUT_DIR"; tar -cvf example_configs.tar *.json *.yaml) +(cd "$OUT_DIR"; tar -cvf example_configs.tar *.json *.yaml certs/*.pem) diff --git a/configs/envoy_double_proxy.template.json b/configs/envoy_double_proxy.template.json index 345d463eabbef..7f67784be80f3 100644 --- a/configs/envoy_double_proxy.template.json +++ b/configs/envoy_double_proxy.template.json @@ -5,8 +5,8 @@ "ssl_context": { "alpn_protocols": "h2,http/1.1", "alt_alpn_protocols": "http/1.1", - "cert_chain_file": "/etc/envoy/cert.pem", - "private_key_file": "/etc/envoy/key.pem" + "cert_chain_file": "certs/servercert.pem", + "private_key_file": "certs/serverkey.pem" }, {% endif -%} {% if proxy_proto -%} @@ -128,8 +128,8 @@ up with a better solution just limit the requests so we can cycle and get better spread. #} "ssl_context": { - "cert_chain_file": "/etc/envoy/envoy-double-proxy.pem", - "private_key_file": "/etc/envoy/envoy-double-proxy.key", + "cert_chain_file": "certs/clientcert.pem", + "private_key_file": "certs/clientkey.pem", "verify_subject_alt_name": ["front-proxy.yourcompany.net"] }, "hosts": [{"url": "tcp://front-proxy.yourcompany.net:9400"}] @@ -138,7 +138,7 @@ "name": "lightstep_saas", "features": "http2", "ssl_context": { - "ca_cert_file": "/etc/ssl/certs/ca-certificates.crt", + "ca_cert_file": "certs/cacert.pem", "verify_subject_alt_name": ["collector-grpc.lightstep.com"] }, "connect_timeout_ms": 1000, diff --git a/configs/envoy_front_proxy.template.json b/configs/envoy_front_proxy.template.json index 9b3d56df3e86f..85ea1b02e9219 100644 --- a/configs/envoy_front_proxy.template.json +++ b/configs/envoy_front_proxy.template.json @@ -8,13 +8,13 @@ "alpn_protocols": "h2,http/1.1", "alt_alpn_protocols": "http/1.1", {% if kwargs.get('pin_double_proxy_client', False) -%} - "ca_cert_file": "/etc/envoy/envoy-ca.pem", + "ca_cert_file": "certs/cacert.pem", {# This should be the hash of the /etc/envoy/envoy-double-proxy.pem cert used in the double proxy configuration. #} "verify_certificate_hash": "fill me in", {% endif -%} - "cert_chain_file": "/etc/envoy/cert.pem", - "private_key_file": "/etc/envoy/key.pem" + "cert_chain_file": "certs/servercert.pem", + "private_key_file": "certs/serverkey.pem" }, {% endif -%} {% if kwargs['proxy_proto'] -%} diff --git a/include/envoy/ssl/context_config.h b/include/envoy/ssl/context_config.h index edabaf5772c48..aa1843c8045fd 100644 --- a/include/envoy/ssl/context_config.h +++ b/include/envoy/ssl/context_config.h @@ -39,19 +39,34 @@ class ContextConfig { virtual const std::string& ecdhCurves() const PURE; /** - * @return The CA certificate file to use for peer validation. + * @return The CA certificate to use for peer validation. */ - virtual const std::string& caCertFile() const PURE; + virtual const std::string& caCert() const PURE; /** - * @return The certificate chain file used to identify the local side. + * @return Path of the CA certificate to use for peer validation. */ - virtual const std::string& certChainFile() const PURE; + virtual const std::string& caCertPath() const PURE; /** - * @return The private key chain file used to identify the local side. + * @return The certificate chain used to identify the local side. */ - virtual const std::string& privateKeyFile() const PURE; + virtual const std::string& certChain() const PURE; + + /** + * @return Path of the certificate chain used to identify the local side. + */ + virtual const std::string& certChainPath() const PURE; + + /** + * @return The private key used to identify the local side. + */ + virtual const std::string& privateKey() const PURE; + + /** + * @return Path of the private key used to identify the local side. + */ + virtual const std::string& privateKeyPath() const PURE; /** * @return The subject alt names to be verified, if enabled. Otherwise, "" diff --git a/source/common/ssl/context_config_impl.cc b/source/common/ssl/context_config_impl.cc index 3b2263b12c60a..c273343e285a8 100644 --- a/source/common/ssl/context_config_impl.cc +++ b/source/common/ssl/context_config_impl.cc @@ -41,13 +41,27 @@ ContextConfigImpl::ContextConfigImpl(const envoy::api::v2::CommonTlsContext& con RepeatedPtrUtil::join(config.tls_params().cipher_suites(), ":"), DEFAULT_CIPHER_SUITES)), ecdh_curves_(StringUtil::nonEmptyStringOrDefault( RepeatedPtrUtil::join(config.tls_params().ecdh_curves(), ":"), DEFAULT_ECDH_CURVES)), - ca_cert_file_(config.validation_context().trusted_ca().filename()), - cert_chain_file_(config.tls_certificates().empty() - ? "" - : config.tls_certificates()[0].certificate_chain().filename()), - private_key_file_(config.tls_certificates().empty() - ? "" - : config.tls_certificates()[0].private_key().filename()), + ca_cert_(readDataSource(config.validation_context().trusted_ca(), true)), + ca_cert_path_(config.validation_context().trusted_ca().specifier_case() == + envoy::api::v2::DataSource::kFilename + ? config.validation_context().trusted_ca().filename() + : ""), + cert_chain_(config.tls_certificates().empty() + ? "" + : readDataSource(config.tls_certificates()[0].certificate_chain(), true)), + cert_chain_path_((!config.tls_certificates().empty() && + config.tls_certificates()[0].certificate_chain().specifier_case() == + envoy::api::v2::DataSource::kFilename) + ? config.tls_certificates()[0].certificate_chain().filename() + : ""), + private_key_(config.tls_certificates().empty() + ? "" + : readDataSource(config.tls_certificates()[0].private_key(), true)), + private_key_path_((!config.tls_certificates().empty() && + config.tls_certificates()[0].private_key().specifier_case() == + envoy::api::v2::DataSource::kFilename) + ? config.tls_certificates()[0].private_key().filename() + : ""), verify_subject_alt_name_list_(config.validation_context().verify_subject_alt_name().begin(), config.validation_context().verify_subject_alt_name().end()), verify_certificate_hash_(config.validation_context().verify_certificate_hash().empty() @@ -61,6 +75,22 @@ ContextConfigImpl::ContextConfigImpl(const envoy::api::v2::CommonTlsContext& con ASSERT(config.validation_context().verify_certificate_hash().size() <= 1); } +const std::string ContextConfigImpl::readDataSource(const envoy::api::v2::DataSource& source, + bool allow_empty) { + switch (source.specifier_case()) { + case envoy::api::v2::DataSource::kFilename: + return Filesystem::fileReadToEnd(source.filename()); + case envoy::api::v2::DataSource::kInline: + return source.inline_(); + default: + if (!allow_empty) { + throw EnvoyException( + fmt::format("Unexpected DataSource::specifier_case(): {}", source.specifier_case())); + } + return ""; + } +} + unsigned ContextConfigImpl::tlsVersionFromProto(const envoy::api::v2::TlsParameters_TlsProtocol& version, unsigned default_version) { @@ -105,19 +135,7 @@ ServerContextConfigImpl::ServerContextConfigImpl(const envoy::api::v2::Downstrea switch (config.session_ticket_keys_type_case()) { case envoy::api::v2::DownstreamTlsContext::kSessionTicketKeys: for (const auto& datasource : config.session_ticket_keys().keys()) { - switch (datasource.specifier_case()) { - case envoy::api::v2::DataSource::kFilename: { - validateAndAppendKey(ret, Filesystem::fileReadToEnd(datasource.filename())); - break; - } - case envoy::api::v2::DataSource::kInline: { - validateAndAppendKey(ret, datasource.inline_()); - break; - } - default: - throw EnvoyException(fmt::format("Unexpected DataSource::specifier_case(): {}", - datasource.specifier_case())); - } + validateAndAppendKey(ret, readDataSource(datasource, false)); } break; case envoy::api::v2::DownstreamTlsContext::kSessionTicketKeysSdsSecretConfig: @@ -135,12 +153,7 @@ ServerContextConfigImpl::ServerContextConfigImpl(const envoy::api::v2::Downstrea // TODO(PiotrSikora): Support multiple TLS certificates. // TODO(mattklein123): All of the ASSERTs in this file need to be converted to exceptions with // proper error handling. - // TODO(htuch): Support inline cert material delivery. ASSERT(config.common_tls_context().tls_certificates().size() == 1); - ASSERT(config.common_tls_context().tls_certificates()[0].certificate_chain().specifier_case() == - envoy::api::v2::DataSource::kFilename); - ASSERT(config.common_tls_context().tls_certificates()[0].private_key().specifier_case() == - envoy::api::v2::DataSource::kFilename); } ServerContextConfigImpl::ServerContextConfigImpl(const Json::Object& config) diff --git a/source/common/ssl/context_config_impl.h b/source/common/ssl/context_config_impl.h index fbf557847ee38..c8bb9a52051c0 100644 --- a/source/common/ssl/context_config_impl.h +++ b/source/common/ssl/context_config_impl.h @@ -12,6 +12,8 @@ namespace Envoy { namespace Ssl { +static const std::string INLINE_STRING = ""; + class ContextConfigImpl : public virtual Ssl::ContextConfig { public: // Ssl::ContextConfig @@ -19,9 +21,18 @@ class ContextConfigImpl : public virtual Ssl::ContextConfig { const std::string& altAlpnProtocols() const override { return alt_alpn_protocols_; } const std::string& cipherSuites() const override { return cipher_suites_; } const std::string& ecdhCurves() const override { return ecdh_curves_; } - const std::string& caCertFile() const override { return ca_cert_file_; } - const std::string& certChainFile() const override { return cert_chain_file_; } - const std::string& privateKeyFile() const override { return private_key_file_; } + const std::string& caCert() const override { return ca_cert_; } + const std::string& caCertPath() const override { + return (ca_cert_path_.empty() && !ca_cert_.empty()) ? INLINE_STRING : ca_cert_path_; + } + const std::string& certChain() const override { return cert_chain_; } + const std::string& certChainPath() const override { + return (cert_chain_path_.empty() && !cert_chain_.empty()) ? INLINE_STRING : cert_chain_path_; + } + const std::string& privateKey() const override { return private_key_; } + const std::string& privateKeyPath() const override { + return (private_key_path_.empty() && !private_key_.empty()) ? INLINE_STRING : private_key_path_; + } const std::vector& verifySubjectAltNameList() const override { return verify_subject_alt_name_list_; }; @@ -32,6 +43,9 @@ class ContextConfigImpl : public virtual Ssl::ContextConfig { protected: ContextConfigImpl(const envoy::api::v2::CommonTlsContext& config); + static const std::string readDataSource(const envoy::api::v2::DataSource& source, + bool allow_empty); + private: static unsigned tlsVersionFromProto(const envoy::api::v2::TlsParameters_TlsProtocol& version, unsigned default_version); @@ -43,9 +57,12 @@ class ContextConfigImpl : public virtual Ssl::ContextConfig { const std::string alt_alpn_protocols_; const std::string cipher_suites_; const std::string ecdh_curves_; - const std::string ca_cert_file_; - const std::string cert_chain_file_; - const std::string private_key_file_; + const std::string ca_cert_; + const std::string ca_cert_path_; + const std::string cert_chain_; + const std::string cert_chain_path_; + const std::string private_key_; + const std::string private_key_path_; const std::vector verify_subject_alt_name_list_; const std::string verify_certificate_hash_; const unsigned min_protocol_version_; diff --git a/source/common/ssl/context_impl.cc b/source/common/ssl/context_impl.cc index bc5e49627a61b..af6fd40617872 100644 --- a/source/common/ssl/context_impl.cc +++ b/source/common/ssl/context_impl.cc @@ -54,14 +54,33 @@ ContextImpl::ContextImpl(ContextManagerImpl& parent, Stats::Scope& scope, int verify_mode = SSL_VERIFY_NONE; - if (!config.caCertFile().empty()) { - ca_cert_ = loadCert(config.caCertFile()); - ca_file_path_ = config.caCertFile(); - // set CA certificate - int rc = SSL_CTX_load_verify_locations(ctx_.get(), config.caCertFile().c_str(), nullptr); - if (0 == rc) { + if (!config.caCert().empty()) { + ca_file_path_ = config.caCertPath(); + bssl::UniquePtr bio( + BIO_new_mem_buf(const_cast(config.caCert().data()), config.caCert().size())); + RELEASE_ASSERT(bio != nullptr); + // Based on BoringSSL's X509_load_cert_crl_file(). + bssl::UniquePtr list( + PEM_X509_INFO_read_bio(bio.get(), nullptr, nullptr, nullptr)); + if (list == nullptr) { throw EnvoyException( - fmt::format("Failed to load verify locations file {}", config.caCertFile())); + fmt::format("Failed to load trusted CA certificates from {}", config.caCertPath())); + } + for (const X509_INFO* item : list.get()) { + if (item->x509) { + X509_STORE_add_cert(SSL_CTX_get_cert_store(ctx_.get()), item->x509); + if (ca_cert_ == nullptr) { + X509_up_ref(item->x509); + ca_cert_.reset(item->x509); + } + } + if (item->crl) { + X509_STORE_add_crl(SSL_CTX_get_cert_store(ctx_.get()), item->crl); + } + } + if (ca_cert_ == nullptr) { + throw EnvoyException( + fmt::format("Failed to load trusted CA certificates from {}", config.caCertPath())); } verify_mode = SSL_VERIFY_PEER; } @@ -84,19 +103,50 @@ ContextImpl::ContextImpl(ContextManagerImpl& parent, Stats::Scope& scope, SSL_CTX_set_cert_verify_callback(ctx_.get(), ContextImpl::verifyCallback, this); } - if (!config.certChainFile().empty()) { - cert_chain_ = loadCert(config.certChainFile()); - cert_chain_file_path_ = config.certChainFile(); - int rc = SSL_CTX_use_certificate_chain_file(ctx_.get(), config.certChainFile().c_str()); - if (0 == rc) { + if (config.certChain().empty() != config.privateKey().empty()) { + throw EnvoyException(fmt::format("Failed to load incomplete certificate from {}, {}", + config.certChainPath(), config.privateKeyPath())); + } + + if (!config.certChain().empty()) { + // Load certificate chain. + cert_chain_file_path_ = config.certChainPath(); + bssl::UniquePtr bio( + BIO_new_mem_buf(const_cast(config.certChain().data()), config.certChain().size())); + RELEASE_ASSERT(bio != nullptr); + cert_chain_.reset(PEM_read_bio_X509_AUX(bio.get(), nullptr, nullptr, nullptr)); + if (cert_chain_ == nullptr || !SSL_CTX_use_certificate(ctx_.get(), cert_chain_.get())) { + throw EnvoyException( + fmt::format("Failed to load certificate chain from {}", config.certChainPath())); + } + // Read rest of the certificate chain. + for (;;) { + bssl::UniquePtr cert(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr)); + if (cert == nullptr) { + break; + } + if (!SSL_CTX_add_extra_chain_cert(ctx_.get(), cert.get())) { + throw EnvoyException( + fmt::format("Failed to load certificate chain from {}", config.certChainPath())); + } + } + // Check for EOF. + uint32_t err = ERR_peek_last_error(); + if (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE) { + ERR_clear_error(); + } else { throw EnvoyException( - fmt::format("Failed to load certificate chain file {}", config.certChainFile())); + fmt::format("Failed to load certificate chain from {}", config.certChainPath())); } - rc = SSL_CTX_use_PrivateKey_file(ctx_.get(), config.privateKeyFile().c_str(), SSL_FILETYPE_PEM); - if (0 == rc) { + // Load private key. + bio.reset( + BIO_new_mem_buf(const_cast(config.privateKey().data()), config.privateKey().size())); + RELEASE_ASSERT(bio != nullptr); + bssl::UniquePtr pkey(PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr)); + if (pkey == nullptr || !SSL_CTX_use_PrivateKey(ctx_.get(), pkey.get())) { throw EnvoyException( - fmt::format("Failed to load private key file {}", config.privateKeyFile())); + fmt::format("Failed to load private key from {}", config.privateKeyPath())); } } @@ -375,10 +425,41 @@ ServerContextImpl::ServerContextImpl(ContextManagerImpl& parent, const std::stri return dynamic_cast(context_impl)->processClientHello(client_hello); }); - if (!config.caCertFile().empty()) { - bssl::UniquePtr list(SSL_load_client_CA_file(config.caCertFile().c_str())); - if (nullptr == list) { - throw EnvoyException(fmt::format("Failed to load client CA file {}", config.caCertFile())); + if (!config.caCert().empty()) { + bssl::UniquePtr bio( + BIO_new_mem_buf(const_cast(config.caCert().data()), config.caCert().size())); + RELEASE_ASSERT(bio != nullptr); + // Based on BoringSSL's SSL_add_file_cert_subjects_to_stack(). + bssl::UniquePtr list(sk_X509_NAME_new( + [](const X509_NAME** a, const X509_NAME** b) -> int { return X509_NAME_cmp(*a, *b); })); + RELEASE_ASSERT(list != nullptr); + for (;;) { + bssl::UniquePtr cert(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr)); + if (cert == nullptr) { + break; + } + X509_NAME* name = X509_get_subject_name(cert.get()); + if (name == nullptr) { + throw EnvoyException(fmt::format("Failed to load trusted client CA certificates from {}", + config.caCertPath())); + } + // Check for duplicates. + if (sk_X509_NAME_find(list.get(), nullptr, name)) { + continue; + } + bssl::UniquePtr name_dup(X509_NAME_dup(name)); + if (name_dup == nullptr || !sk_X509_NAME_push(list.get(), name_dup.release())) { + throw EnvoyException(fmt::format("Failed to load trusted client CA certificates from {}", + config.caCertPath())); + } + } + // Check for EOF. + uint32_t err = ERR_peek_last_error(); + if (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE) { + ERR_clear_error(); + } else { + throw EnvoyException(fmt::format("Failed to load trusted client CA certificates from {}", + config.caCertPath())); } SSL_CTX_set_client_CA_list(ctx_.get(), list.release()); diff --git a/test/common/ssl/ssl_socket_test.cc b/test/common/ssl/ssl_socket_test.cc index 410716cb0b9e7..1067a676210ae 100644 --- a/test/common/ssl/ssl_socket_test.cc +++ b/test/common/ssl/ssl_socket_test.cc @@ -249,6 +249,144 @@ TEST_P(SslSocketTest, GetCertDigest) { true, GetParam()); } +TEST_P(SslSocketTest, GetCertDigestInline) { + envoy::api::v2::Listener listener; + envoy::api::v2::FilterChain* filter_chain = listener.add_filter_chains(); + envoy::api::v2::TlsCertificate* server_cert = + filter_chain->mutable_tls_context()->mutable_common_tls_context()->add_tls_certificates(); + + // From test/common/ssl/test_data/san_dns_cert.pem. + server_cert->mutable_certificate_chain()->set_inline_( + "-----BEGIN CERTIFICATE-----\n" + "MIIDDDCCAnWgAwIBAgIJAPOCjrJP13nQMA0GCSqGSIb3DQEBCwUAMHYxCzAJBgNV\n" + "BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNp\n" + "c2NvMQ0wCwYDVQQKEwRMeWZ0MRkwFwYDVQQLExBMeWZ0IEVuZ2luZWVyaW5nMRAw\n" + "DgYDVQQDEwdUZXN0IENBMB4XDTE3MDcwOTAxMzkzMloXDTE5MDcwOTAxMzkzMlow\n" + "ejELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh\n" + "biBGcmFuY2lzY28xDTALBgNVBAoTBEx5ZnQxGTAXBgNVBAsTEEx5ZnQgRW5naW5l\n" + "ZXJpbmcxFDASBgNVBAMTC1Rlc3QgU2VydmVyMIGfMA0GCSqGSIb3DQEBAQUAA4GN\n" + "ADCBiQKBgQDARNUJMFkWF0E6mbdz/nkydVC4TU2SgR95vhJhWpG6xKkCNoXkJxNz\n" + "XOmFUUIXQyq7FnIWACYuMrE2KXnomeCGP9A6M21lumNseYSLX3/b+ao4E6gimm1/\n" + "Gp8C3FaoAs8Ep7VE+o2DMIfTIPJhFf6RBFPundGhEm8/gv+QObVhKQIDAQABo4Gd\n" + "MIGaMAwGA1UdEwEB/wQCMAAwCwYDVR0PBAQDAgXgMB0GA1UdJQQWMBQGCCsGAQUF\n" + "BwMCBggrBgEFBQcDATAeBgNVHREEFzAVghNzZXJ2ZXIxLmV4YW1wbGUuY29tMB0G\n" + "A1UdDgQWBBRCcUr8mIigWlR61OX/gmDY5vBV6jAfBgNVHSMEGDAWgBQ7eKRRTxaE\n" + "kxxIKHoMrSuWQcp9eTANBgkqhkiG9w0BAQsFAAOBgQAtn05e8U41heun5L7MKflv\n" + "tJM7w0whavdS8hLe63CxnS98Ap973mSiShKG+OxSJ0ClMWIZPy+KyC+T8yGIaynj\n" + "wEEuoSGRWmhzcMMnZWxqQyD95Fsx6mtdnq/DJxiYzmH76fALe/538j8pTcoygSGD\n" + "NWw1EW8TEwlFyuvCrlWQcg==\n" + "-----END CERTIFICATE-----"); + + // From test/common/ssl/test_data/san_dns_key.pem. + server_cert->mutable_private_key()->set_inline_( + "-----BEGIN RSA PRIVATE KEY-----\n" + "MIICXQIBAAKBgQDARNUJMFkWF0E6mbdz/nkydVC4TU2SgR95vhJhWpG6xKkCNoXk\n" + "JxNzXOmFUUIXQyq7FnIWACYuMrE2KXnomeCGP9A6M21lumNseYSLX3/b+ao4E6gi\n" + "mm1/Gp8C3FaoAs8Ep7VE+o2DMIfTIPJhFf6RBFPundGhEm8/gv+QObVhKQIDAQAB\n" + "AoGBAJM64kukC0QAUMHX/gRD5HkAHuzSvUknuXuXUincmeWEPMtmBwdb6OgZSPT+\n" + "8XYwx+L14Cz6tkIALXWFM0YrtyKfVdELRRs8dw5nenzK3wOeo/N/7XL4kwim4kV3\n" + "q817RO6NUN76vHOsvQMFsPlEfCZpOTIGJEJBI7eFLP0djOMlAkEA/yWEPfQoER/i\n" + "X6uNyXrU51A6gxyZg7rPNP0cxxRhDedtsJPNY6Tlu90v9SiTgQLUTp7BINH24t9a\n" + "MST1tmax+wJBAMDpeRy52q+sqLXI1C2oHPuXrXzeyp9pynV/9tsYL9+qoyP2XcEZ\n" + "DaI0tfXDJXOdYIaDnSfB50eqQUnaTmQjtCsCQGUFGaLd9K8zDJIMforzUzByl3gp\n" + "7q41XK0COk6oRvUWWFu9aWi2dS84mDBc7Gn8EMtAF/9CopmZDUC//XlGl9kCQQCr\n" + "6yWw8PywFHohzwEwUyLJIKpOnyoKGTiBsHGpXYvEk4hiEzwISzB4PutuQuRMfZM5\n" + "LW/Pr6FSn6shivjTi3ITAkACMTBczBQ+chMBcTXDqyqwccQOIhupxani9wfZhsrm\n" + "ZXbTTxnUZioQ2l/7IWa+K2O2NrWWT7b3KpCAob0bJsQz\n" + "-----END RSA PRIVATE KEY-----"); + + // From test/common/ssl/test_data/ca_certificates.pem. + filter_chain->mutable_tls_context() + ->mutable_common_tls_context() + ->mutable_validation_context() + ->mutable_trusted_ca() + ->set_inline_("-----BEGIN CERTIFICATE-----\n" + "MIICzTCCAjagAwIBAgIJAPAEjHA3MX2BMA0GCSqGSIb3DQEBCwUAMHYxCzAJBgNV\n" + "BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNp\n" + "c2NvMQ0wCwYDVQQKEwRMeWZ0MRkwFwYDVQQLExBMeWZ0IEVuZ2luZWVyaW5nMRAw\n" + "DgYDVQQDEwdGYWtlIENBMB4XDTE3MDcwOTAxMzkzMloXDTI3MDcwNzAxMzkzMlow\n" + "djELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh\n" + "biBGcmFuY2lzY28xDTALBgNVBAoTBEx5ZnQxGTAXBgNVBAsTEEx5ZnQgRW5naW5l\n" + "ZXJpbmcxEDAOBgNVBAMTB0Zha2UgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ\n" + "AoGBAK/89R7j0kwhGh7NDAiuhlVmN1Hh73sGRzDBgON/ZfmJSgkvZIwQ4+hu0wZ6\n" + "wjN0am1iIKyp8O1OkmKurcfCRQM2QGiIUI7v7rSa0GzqENoEsQGXVk8/yhwD8Ys9\n" + "IPLTWXLVyh49yh5FCs6nt2/LrIuZX/K2cZQx+VuLCcg5sTllAgMBAAGjYzBhMA8G\n" + "A1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRRsE37S/H/\n" + "lCd1pWH4sCn9qrON3TAfBgNVHSMEGDAWgBRRsE37S/H/lCd1pWH4sCn9qrON3TAN\n" + "BgkqhkiG9w0BAQsFAAOBgQAvFbQm1PrqeWlZssPDPfI5dlo2KEL9VedIlThqDU4z\n" + "MStNR/Tfw2A0WtjOyjm2R0viqLu8JdDe8umUqO9DkRhZOaUtLgQEkaQn75z8WQPk\n" + "Sj+kenx0v3GMrPZMAsELiPG5PcSk8l5prDgU7VkzNvoCtypCsB7RQRyvZs52Qih3\n" + "Ug==\n" + "-----END CERTIFICATE-----\n" + "-----BEGIN CERTIFICATE-----\n" + "MIICzTCCAjagAwIBAgIJAOrzsOodDleaMA0GCSqGSIb3DQEBCwUAMHYxCzAJBgNV\n" + "BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNp\n" + "c2NvMQ0wCwYDVQQKEwRMeWZ0MRkwFwYDVQQLExBMeWZ0IEVuZ2luZWVyaW5nMRAw\n" + "DgYDVQQDEwdUZXN0IENBMB4XDTE3MDcwOTAxMzkzMloXDTI3MDcwNzAxMzkzMlow\n" + "djELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh\n" + "biBGcmFuY2lzY28xDTALBgNVBAoTBEx5ZnQxGTAXBgNVBAsTEEx5ZnQgRW5naW5l\n" + "ZXJpbmcxEDAOBgNVBAMTB1Rlc3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ\n" + "AoGBAJuJh8N5TheTHLKOxsLSAfiIu9VDeKPsV98KRJJaYCMoaof3j9wBs65HzIat\n" + "AunuV4DVZZ2c/x7/v741oWadYd3yqL7XSzQaeBvhXi+wv3g17FYrdxaowG7cfmsh\n" + "gCp7/9TRW0bRGL6Qp6od/u62L8dprdHXxnck/+sZMupam9YrAgMBAAGjYzBhMA8G\n" + "A1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQ7eKRRTxaE\n" + "kxxIKHoMrSuWQcp9eTAfBgNVHSMEGDAWgBQ7eKRRTxaEkxxIKHoMrSuWQcp9eTAN\n" + "BgkqhkiG9w0BAQsFAAOBgQCN00/2k9k8HNeJ8eYuFH10jnc+td7+OaYWpRSEKCS7\n" + "ux3KAu0UFt90mojEMClt4Y6uP4oXTWbRzMzAgQHldHU8Gkj8tYnv7mToX7Bh/xdc\n" + "19epzjCmo/4Q6+16GZZvltiFjkkHSZEVI5ggljy1QdMIPRegsKKmX9mjZSCSSXD6\n" + "SA==\n" + "-----END CERTIFICATE-----"); + + envoy::api::v2::UpstreamTlsContext client_ctx; + envoy::api::v2::TlsCertificate* client_cert = + client_ctx.mutable_common_tls_context()->add_tls_certificates(); + + // From test/common/ssl/test_data/san_uri_cert.pem. + client_cert->mutable_certificate_chain()->set_inline_( + "-----BEGIN CERTIFICATE-----\n" + "MIIDFDCCAn2gAwIBAgIJAN6Kky/8alfaMA0GCSqGSIb3DQEBCwUAMHYxCzAJBgNV\n" + "BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNp\n" + "c2NvMQ0wCwYDVQQKEwRMeWZ0MRkwFwYDVQQLExBMeWZ0IEVuZ2luZWVyaW5nMRAw\n" + "DgYDVQQDEwdUZXN0IENBMB4XDTE3MDcwOTAxMzkzMloXDTE5MDcwOTAxMzkzMlow\n" + "ejELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh\n" + "biBGcmFuY2lzY28xDTALBgNVBAoTBEx5ZnQxGTAXBgNVBAsTEEx5ZnQgRW5naW5l\n" + "ZXJpbmcxFDASBgNVBAMTC1Rlc3QgU2VydmVyMIGfMA0GCSqGSIb3DQEBAQUAA4GN\n" + "ADCBiQKBgQDQNSdVcQBlmLBHoyMtMJrYRMI4HkuCYqubvBD9gfZbt+bux5Lh2CRT\n" + "RVB9fUTh/bQ9fzZ+XpZu2OLG/otHi20Yu5XPgXL5+OSzCdzMqujGs8Ft9ugZI2UL\n" + "TufqMfesbs7y8cJg2y+UpQZlXlJ2iImMkqdomOsrNvzFzT3/LRncywIDAQABo4Gl\n" + "MIGiMAwGA1UdEwEB/wQCMAAwCwYDVR0PBAQDAgXgMB0GA1UdJQQWMBQGCCsGAQUF\n" + "BwMCBggrBgEFBQcDATAmBgNVHREEHzAdhhtzcGlmZmU6Ly9seWZ0LmNvbS90ZXN0\n" + "LXRlYW0wHQYDVR0OBBYEFCmCEC8ABzXj8S4E++Whd37lIhg5MB8GA1UdIwQYMBaA\n" + "FDt4pFFPFoSTHEgoegytK5ZByn15MA0GCSqGSIb3DQEBCwUAA4GBAF6p8V73RNLS\n" + "jWcS/NUuRFWNqJ0pGc06wsb7JnVnSn12zPrpzwTQOPHZYY+KZC8TtgpnLgLobWVu\n" + "mlDkUA5/25A1O+smL2nquUaix/I3X71U3MKo59JzrxNV3mlBSOmv9K1r/jpxZ96d\n" + "mMXJ1d7L5pUWxa3q0ANg+mywtpGMvqHL\n" + "-----END CERTIFICATE-----"); + + // From test/common/ssl/test_data/san_uri_key.pem. + client_cert->mutable_private_key()->set_inline_( + "-----BEGIN RSA PRIVATE KEY-----\n" + "MIICWwIBAAKBgQDQNSdVcQBlmLBHoyMtMJrYRMI4HkuCYqubvBD9gfZbt+bux5Lh\n" + "2CRTRVB9fUTh/bQ9fzZ+XpZu2OLG/otHi20Yu5XPgXL5+OSzCdzMqujGs8Ft9ugZ\n" + "I2ULTufqMfesbs7y8cJg2y+UpQZlXlJ2iImMkqdomOsrNvzFzT3/LRncywIDAQAB\n" + "AoGAUczQS00+LqwydbKuW07BRz6cX5fnaq6BZYoZ0r+AnsA9xoo6NujIPL76xJK2\n" + "wWL/sTmNm1BmId6sGipfZhhtH5kELxddygGYotTYfL9NHxf0FA3uPGnGVIEQphwa\n" + "orAe5NVpORUzZwYQdxohXR25+DnDb4cM7TktNb32P0hO2KECQQDqqRHdYzh/EPyz\n" + "7LEUsBPD28ijb+sFfSce+YFYVUuJBtN6zHnnpnbkuQK7EbRGVEB2XrpFj/3AFktz\n" + "tHymGI1NAkEA4yRCPSC5VEH9jJa6gpij7t8LPJ5gOh2EvrvzFVyN49E4hE2H1kKP\n" + "1kKs8TKbsNFgHhOxwsmTnOV0ZHlZ0THmdwJAJyDqCbBxyz5Z5Oai4IA7y3zqh9Yx\n" + "qkikLVYNa11NqxuoR+Gwsh/f02PGQMtC9Dc4SISjKtZHya/uBO0jm86cQQJAE10c\n" + "9H8crY0uo1SaM9X1a8DCAXny9CFeFrCJKZIJWpmUetrtMJveDUMD4VASK8G9svK0\n" + "3ck3d1GsWYBq4sWhQwJAKP1jLt3nwQEuSS88Yi2dMC3iPCWMljatC3u6976etDg7\n" + "AoETSNx+UIqKSg6LsNYqs4omsDPnZ2j+4m2fvHaVJg==\n" + "-----END RSA PRIVATE KEY-----"); + + // ssl.handshake logged by both: client & server. + testUtilV2(listener, client_ctx, "", true, "", + "1406294e80c818158697d65d2aaca16748ff132442ab0e2f28bc1109f1d47a2e", + "spiffe://lyft.com/test-team", "", "ssl.handshake", 2, GetParam()); +} + TEST_P(SslSocketTest, GetCertDigestServerCertWithoutCommonName) { std::string client_ctx_json = R"EOF( { diff --git a/test/config_test/config_test.cc b/test/config_test/config_test.cc index bb3fa3048ad5a..fff7d4a7a8606 100644 --- a/test/config_test/config_test.cc +++ b/test/config_test/config_test.cc @@ -1,3 +1,5 @@ +#include + #include #include @@ -75,7 +77,9 @@ class ConfigTest { uint32_t run(const std::string& directory) { uint32_t num_tested = 0; - for (const std::string& filename : TestUtility::listFiles(directory, true)) { + // Change working directory, otherwise we won't be able to read files using relative paths. + RELEASE_ASSERT(::chdir(directory.c_str()) == 0); + for (const std::string& filename : TestUtility::listFiles(directory, false)) { ConfigTest config(filename); num_tested++; } From 0241759e472629490a50e434ae712c16bb5af7b4 Mon Sep 17 00:00:00 2001 From: Piotr Sikora Date: Wed, 20 Dec 2017 21:28:39 -0800 Subject: [PATCH 2/9] review: fix few more examples (for macOS). Signed-off-by: Piotr Sikora --- configs/envoy_front_proxy.template.json | 2 +- configs/envoy_service_to_service.template.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/configs/envoy_front_proxy.template.json b/configs/envoy_front_proxy.template.json index 85ea1b02e9219..6e6e45ef6a46c 100644 --- a/configs/envoy_front_proxy.template.json +++ b/configs/envoy_front_proxy.template.json @@ -144,7 +144,7 @@ "name": "lightstep_saas", "features": "http2", "ssl_context": { - "ca_cert_file": "/etc/ssl/certs/ca-certificates.crt", + "ca_cert_file": "certs/cacert.pem", "verify_subject_alt_name": ["collector-grpc.lightstep.com"] }, "connect_timeout_ms": 1000, diff --git a/configs/envoy_service_to_service.template.json b/configs/envoy_service_to_service.template.json index 1bf1bdcc71405..ebfee83c9bdcd 100644 --- a/configs/envoy_service_to_service.template.json +++ b/configs/envoy_service_to_service.template.json @@ -362,7 +362,7 @@ "name": "egress_{{ host['name'] }}", {% if host.get('ssl', False) -%} "ssl_context": { - "ca_cert_file": "/etc/ssl/certs/ca-certificates.crt" + "ca_cert_file": "certs/cacert.pem" {% if host.get('sni', False) -%} ,"sni": "{{ host['sni'] }}" {% endif -%} @@ -446,7 +446,7 @@ "name": "lightstep_saas", "features": "http2", "ssl_context": { - "ca_cert_file": "/etc/ssl/certs/ca-certificates.crt", + "ca_cert_file": "certs/cacert.pem", "verify_subject_alt_name": ["collector-grpc.lightstep.com"] }, "connect_timeout_ms": 1000, From 909e25b6575ec61fdbce0aad348238ff30fd8bc9 Mon Sep 17 00:00:00 2001 From: Piotr Sikora Date: Mon, 15 Jan 2018 18:48:03 -0800 Subject: [PATCH 3/9] Add tests (and a fix!) for certificates with intermediate CA. Signed-off-by: Piotr Sikora --- source/common/ssl/context_impl.cc | 2 + test/common/ssl/ssl_socket_test.cc | 54 +++++++++++++++++++ test/common/ssl/test_data/README.md | 13 +++-- test/common/ssl/test_data/certs.sh | 15 +++++- .../ssl/test_data/intermediate_ca_cert.cfg | 29 ++++++++++ .../ssl/test_data/intermediate_ca_cert.pem | 18 +++++++ .../ssl/test_data/intermediate_ca_key.pem | 15 ++++++ test/common/ssl/test_data/san_dns_cert3.pem | 19 +++++++ test/common/ssl/test_data/san_dns_chain3.pem | 37 +++++++++++++ test/common/ssl/test_data/san_dns_key3.pem | 15 ++++++ 10 files changed, 212 insertions(+), 5 deletions(-) create mode 100644 test/common/ssl/test_data/intermediate_ca_cert.cfg create mode 100644 test/common/ssl/test_data/intermediate_ca_cert.pem create mode 100644 test/common/ssl/test_data/intermediate_ca_key.pem create mode 100644 test/common/ssl/test_data/san_dns_cert3.pem create mode 100644 test/common/ssl/test_data/san_dns_chain3.pem create mode 100644 test/common/ssl/test_data/san_dns_key3.pem diff --git a/source/common/ssl/context_impl.cc b/source/common/ssl/context_impl.cc index af6fd40617872..7c3a29dd182b3 100644 --- a/source/common/ssl/context_impl.cc +++ b/source/common/ssl/context_impl.cc @@ -129,6 +129,8 @@ ContextImpl::ContextImpl(ContextManagerImpl& parent, Stats::Scope& scope, throw EnvoyException( fmt::format("Failed to load certificate chain from {}", config.certChainPath())); } + // SSL_CTX_add_extra_chain_cert() takes ownership. + cert.release(); } // Check for EOF. uint32_t err = ERR_peek_last_error(); diff --git a/test/common/ssl/ssl_socket_test.cc b/test/common/ssl/ssl_socket_test.cc index 6b9cb657a7395..aba6072fdb769 100644 --- a/test/common/ssl/ssl_socket_test.cc +++ b/test/common/ssl/ssl_socket_test.cc @@ -402,6 +402,28 @@ TEST_P(SslSocketTest, GetCertDigestInline) { "spiffe://lyft.com/test-team", "", "ssl.handshake", 2, GetParam()); } +TEST_P(SslSocketTest, GetCertDigestServerCertWithIntermediateCA) { + std::string client_ctx_json = R"EOF( + { + "cert_chain_file": "{{ test_rundir }}/test/common/ssl/test_data/no_san_cert.pem", + "private_key_file": "{{ test_rundir }}/test/common/ssl/test_data/no_san_key.pem", + "ca_cert_file": "{{ test_rundir }}/test/common/ssl/test_data/ca_cert.pem" + } + )EOF"; + + std::string server_ctx_json = R"EOF( + { + "cert_chain_file": "{{ test_rundir }}/test/common/ssl/test_data/san_dns_chain3.pem", + "private_key_file": "{{ test_rundir }}/test/common/ssl/test_data/san_dns_key3.pem", + "ca_cert_file": "{{ test_rundir }}/test/common/ssl/test_data/ca_cert.pem" + } + )EOF"; + + testUtil(client_ctx_json, server_ctx_json, + "4444fbca965d916475f04fb4dd234dd556adb028ceb4300fa8ad6f2983c6aaa3", "", "", "", "", + "ssl.handshake", true, GetParam()); +} + TEST_P(SslSocketTest, GetCertDigestServerCertWithoutCommonName) { std::string client_ctx_json = R"EOF( { @@ -996,6 +1018,38 @@ TEST_P(SslSocketTest, TicketSessionResumptionDifferentServerCert) { GetParam()); } +// Sessions cannot be resumed because the server certificates are different, CN/SANs are identical, +// but the issuer is different. +TEST_P(SslSocketTest, TicketSessionResumptionDifferentServerCertIntermediateCA) { + std::string server_ctx_json1 = R"EOF( + { + "cert_chain_file": "{{ test_rundir }}/test/common/ssl/test_data/san_dns_cert.pem", + "private_key_file": "{{ test_rundir }}/test/common/ssl/test_data/san_dns_key.pem", + "session_ticket_key_paths": [ + "{{ test_rundir }}/test/common/ssl/test_data/ticket_key_a" + ] + } + )EOF"; + + std::string server_ctx_json2 = R"EOF( + { + "cert_chain_file": "{{ test_rundir }}/test/common/ssl/test_data/san_dns_chain3.pem", + "private_key_file": "{{ test_rundir }}/test/common/ssl/test_data/san_dns_key3.pem", + "session_ticket_key_paths": [ + "{{ test_rundir }}/test/common/ssl/test_data/ticket_key_a" + ] + } + )EOF"; + + std::string client_ctx_json = R"EOF( + { + } + )EOF"; + + testTicketSessionResumption(server_ctx_json1, server_ctx_json2, client_ctx_json, false, + GetParam()); +} + // Sessions cannot be resumed because the server certificates are different and the SANs // are not identical TEST_P(SslSocketTest, TicketSessionResumptionDifferentServerCertDifferentSAN) { diff --git a/test/common/ssl/test_data/README.md b/test/common/ssl/test_data/README.md index 6ac2c16ff40c8..b434d17da3141 100644 --- a/test/common/ssl/test_data/README.md +++ b/test/common/ssl/test_data/README.md @@ -3,9 +3,12 @@ There are 6 identities: - **CA**: Certificate Authority for **No SAN**, **SAN With URI** and **SAN With DNS**. It has the self-signed certificate *ca_cert.pem*. *ca_key.pem* is its private key. --- **Fake CA**: Fake Certificate Authority used to validate verification logic. -- It has the self-signed certificate *fake_ca_cert.pem"*. *fake_ca_key.pem" is -- its private key. +- **Intermediate CA**: Intermediate Certificate Authority, signed by the **CA**. + It has the certificate *intermediate_ca_cert.pem". *intermediate_ca_key.pem* + is its private key. +- **Fake CA**: Fake Certificate Authority used to validate verification logic. + It has the self-signed certificate *fake_ca_cert.pem"*. *fake_ca_key.pem" is + its private key. - **No SAN**: It has the certificate *no_san_cert.pem*, signed by the **CA**. The certificate does not have SAN field. *no_san_key.pem* is its private key. - **SAN With URI**: It has the certificate *san_uri_cert.pem*, which is signed @@ -14,7 +17,9 @@ There are 6 identities: - **SAN With DNS**: It has the certificate *san_dns_cert.pem*, which is signed by the **CA** using the config *san_dns_cert.cfg*. The certificate has SAN field of DNS type. *san_dns_key.pem* is its private key. A second certificate - and key, using the same config, is *san_dns_cert2*. + and key, using the same config, is *san_dns_cert2*. A third certificate and key, + using the same config, but signed by the **Intermediate CA** is *san_dns_cert3*, + its certificate chain is *san_dns_chain3.pem*. - **SAN With Multiple DNS**: Same as *SAN With DNS* except there are multiple SANs (including wildcard domain). It has certificate *san_multiple_dns_cert.pem*, *san_multiple_dns_key.pem* is its private key. diff --git a/test/common/ssl/test_data/certs.sh b/test/common/ssl/test_data/certs.sh index 969857d7e4004..6d76ef8aea52c 100755 --- a/test/common/ssl/test_data/certs.sh +++ b/test/common/ssl/test_data/certs.sh @@ -4,10 +4,12 @@ set -e # Uncomment the following lines if you want to regenerate the private keys. # openssl genrsa -out ca_key.pem 1024 +# openssl genrsa -out intermediate_ca_key.pem 1024 # openssl genrsa -out fake_ca_key.pem 1024 # openssl genrsa -out no_san_key.pem 1024 # openssl genrsa -out san_dns_key.pem 1024 # openssl genrsa -out san_dns_key2.pem 1024 +# openssl genrsa -out san_dns_key3.pem 1024 # openssl genrsa -out san_multiple_dns_key.pem 1024 # openssl genrsa -out san_uri_key.pem 1024 # openssl genrsa -out selfsigned_key.pem 1024 @@ -16,6 +18,10 @@ set -e openssl req -new -key ca_key.pem -out ca_cert.csr -config ca_cert.cfg -batch -sha256 openssl x509 -req -days 3650 -in ca_cert.csr -signkey ca_key.pem -out ca_cert.pem -extensions v3_ca -extfile ca_cert.cfg +# Generate intermediate_ca_cert.pem. +openssl req -new -key intermediate_ca_key.pem -out intermediate_ca_cert.csr -config intermediate_ca_cert.cfg -batch -sha256 +openssl x509 -req -days 3650 -in intermediate_ca_cert.csr -sha256 -CA ca_cert.pem -CAkey ca_key.pem -CAcreateserial -out intermediate_ca_cert.pem -extensions v3_ca -extfile intermediate_ca_cert.cfg + # Generate fake_ca_cert.pem. openssl req -new -key fake_ca_key.pem -out fake_ca_cert.csr -config fake_ca_cert.cfg -batch -sha256 openssl x509 -req -days 3650 -in fake_ca_cert.csr -signkey fake_ca_key.pem -out fake_ca_cert.pem -extensions v3_ca -extfile fake_ca_cert.cfg @@ -31,10 +37,17 @@ openssl x509 -req -days 730 -in no_san_cert.csr -sha256 -CA ca_cert.pem -CAkey c openssl req -new -key san_dns_key.pem -out san_dns_cert.csr -config san_dns_cert.cfg -batch -sha256 openssl x509 -req -days 730 -in san_dns_cert.csr -sha256 -CA ca_cert.pem -CAkey ca_key.pem -CAcreateserial -out san_dns_cert.pem -extensions v3_ca -extfile san_dns_cert.cfg -# Generate san_dns_cert2.pem. +# Generate san_dns_cert2.pem (duplicate of san_dns_cert.pem, but with a different private key). openssl req -new -key san_dns_key2.pem -out san_dns_cert2.csr -config san_dns_cert.cfg -batch -sha256 openssl x509 -req -days 730 -in san_dns_cert2.csr -sha256 -CA ca_cert.pem -CAkey ca_key.pem -CAcreateserial -out san_dns_cert2.pem -extensions v3_ca -extfile san_dns_cert.cfg +# Generate san_dns_cert3.pem (signed by intermediate_ca_cert.pem). +openssl req -new -key san_dns_key3.pem -out san_dns_cert3.csr -config san_dns_cert.cfg -batch -sha256 +openssl x509 -req -days 730 -in san_dns_cert3.csr -sha256 -CA intermediate_ca_cert.pem -CAkey intermediate_ca_key.pem -CAcreateserial -out san_dns_cert3.pem -extensions v3_ca -extfile san_dns_cert.cfg + +# Concatenate san_dns_cert3.pem and Test Intermediate CA (intermediate_ca_cert.pem) to create valid certificate chain. +cat san_dns_cert3.pem intermediate_ca_cert.pem > san_dns_chain3.pem + # Generate san_multiple_dns_cert.pem. openssl req -new -key san_multiple_dns_key.pem -out san_multiple_dns_cert.csr -config san_multiple_dns_cert.cfg -batch -sha256 openssl x509 -req -days 730 -in san_multiple_dns_cert.csr -sha256 -CA ca_cert.pem -CAkey ca_key.pem -CAcreateserial -out san_multiple_dns_cert.pem -extensions v3_ca -extfile san_multiple_dns_cert.cfg diff --git a/test/common/ssl/test_data/intermediate_ca_cert.cfg b/test/common/ssl/test_data/intermediate_ca_cert.cfg new file mode 100644 index 0000000000000..b107e442c1822 --- /dev/null +++ b/test/common/ssl/test_data/intermediate_ca_cert.cfg @@ -0,0 +1,29 @@ +[req] +distinguished_name = req_distinguished_name +req_extensions = v3_req + +[req_distinguished_name] +countryName = US +countryName_default = US +stateOrProvinceName = California +stateOrProvinceName_default = California +localityName = San Francisco +localityName_default = San Francisco +organizationName = Lyft +organizationName_default = Lyft +organizationalUnitName = Lyft Engineering +organizationalUnitName_default = Lyft Engineering +commonName = Test Intermediate CA +commonName_default = Test Intermediate CA +commonName_max = 64 + +[v3_req] +basicConstraints = CA:TRUE, pathlen:0 +keyUsage = critical, cRLSign, keyCertSign +subjectKeyIdentifier = hash + +[v3_ca] +basicConstraints = critical, CA:TRUE, pathlen:0 +keyUsage = critical, cRLSign, keyCertSign +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always diff --git a/test/common/ssl/test_data/intermediate_ca_cert.pem b/test/common/ssl/test_data/intermediate_ca_cert.pem new file mode 100644 index 0000000000000..d1dc57c014b37 --- /dev/null +++ b/test/common/ssl/test_data/intermediate_ca_cert.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC3jCCAkegAwIBAgIJAJvUixVO/5pTMA0GCSqGSIb3DQEBCwUAMHYxCzAJBgNV +BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNp +c2NvMQ0wCwYDVQQKEwRMeWZ0MRkwFwYDVQQLExBMeWZ0IEVuZ2luZWVyaW5nMRAw +DgYDVQQDEwdUZXN0IENBMB4XDTE4MDExNTIyNDAyN1oXDTI4MDExMzIyNDAyN1ow +gYMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1T +YW4gRnJhbmNpc2NvMQ0wCwYDVQQKDARMeWZ0MRkwFwYDVQQLDBBMeWZ0IEVuZ2lu +ZWVyaW5nMR0wGwYDVQQDDBRUZXN0IEludGVybWVkaWF0ZSBDQTCBnzANBgkqhkiG +9w0BAQEFAAOBjQAwgYkCgYEAxd1kOhV+/2n+rJWKvrtkyyqkWgBXXhH15G9cusaR +zJtwxsvtPRYZ9nTc+A6GDFgZ0TS1sq/WJXfs3guMpFObXU+tSlezxHVRpWPTXKff +hblqtZMPKW5q5LmOHxKi8GUxwDnEeAiZmzstGCYkRKn+GmLYe26vFGBw4MvM89Vm +ecMCAwEAAaNmMGQwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYw +HQYDVR0OBBYEFIuDOLnI5iZPpH230VFAuWeNYuWdMB8GA1UdIwQYMBaAFDt4pFFP +FoSTHEgoegytK5ZByn15MA0GCSqGSIb3DQEBCwUAA4GBAGO77sBFzn63pM2Oy4XS ++FEcFj/lB4vBh4r8jtzdf5EMaKUeXY9i57MTryPTJZRFXW6BuQ/B3hiOW2fwkCdL +eHd0MwGv95cn1PCWZh1IidVrtrDeu0oLxhRk5mcflaaLBuGADUD3Y1ms2sl90Ean +6C+0EHH2O6Emesx9IhPZRx4H +-----END CERTIFICATE----- diff --git a/test/common/ssl/test_data/intermediate_ca_key.pem b/test/common/ssl/test_data/intermediate_ca_key.pem new file mode 100644 index 0000000000000..4a2593d9ecbb9 --- /dev/null +++ b/test/common/ssl/test_data/intermediate_ca_key.pem @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQDF3WQ6FX7/af6slYq+u2TLKqRaAFdeEfXkb1y6xpHMm3DGy+09 +Fhn2dNz4DoYMWBnRNLWyr9Yld+zeC4ykU5tdT61KV7PEdVGlY9Ncp9+FuWq1kw8p +bmrkuY4fEqLwZTHAOcR4CJmbOy0YJiREqf4aYth7bq8UYHDgy8zz1WZ5wwIDAQAB +AoGAB91l930VQDfJXLjQ/AXc2sqGH+G1l1KlcIAQsofkEbr3/57pfi0buRUqF14U +a/cwh4VN151vqKucqbLR01JTcY8lfPtIBoSd3A0eXxZo6gZKQZcnj8aF1HGdonV9 +B06yfU9Hm3U40R9ZEPbZNfBzsNm+HHki1jd3ZvdvMQl961ECQQDvD/4M9RrveQK8 +A/H+EKf+pZq85tk5oTWLF5ZDItcOQ9VG5LnFKU2e8wNZkkgfT7p812veHsIw8Hg8 +55k65JipAkEA0+Isq701NAveNfgUy2rIMBRsKnXbczrMnpWUyaeGvm4pq1b5PmZY +As4MjXZLY7QLcJJ7o+Sark+GQKfJ+jqmiwJAMGfWkx0WJSMlkJhj6YPJ4F/74wAD +QA4KX22ZOWLWlMbbao1pqChi1SpzpTFfdSeZpSmhZ8pmm641Sm/CsRAUcQJAYSjB +my70Cp22k8DiqDSa/5Ed2IqaysgXtFCbHa04WHJjoTIMsNR1XzPlBalNALc617AU +Ch913qCQy20lbR0f6QJBAMoCSTXEsbPh3awPWMzNR71Yq4nnDk/1jFZX6JerUHEz +ylI4pXCRNs4vGjAF9q24HLXreapziANtWovEXJkoQAI= +-----END RSA PRIVATE KEY----- diff --git a/test/common/ssl/test_data/san_dns_cert3.pem b/test/common/ssl/test_data/san_dns_cert3.pem new file mode 100644 index 0000000000000..f8d6956a594af --- /dev/null +++ b/test/common/ssl/test_data/san_dns_cert3.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDGjCCAoOgAwIBAgIJALE/9j8tvBGNMA0GCSqGSIb3DQEBCwUAMIGDMQswCQYD +VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5j +aXNjbzENMAsGA1UECgwETHlmdDEZMBcGA1UECwwQTHlmdCBFbmdpbmVlcmluZzEd +MBsGA1UEAwwUVGVzdCBJbnRlcm1lZGlhdGUgQ0EwHhcNMTgwMTE1MjI0MDI3WhcN +MjAwMTE1MjI0MDI3WjB6MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5p +YTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwETHlmdDEZMBcGA1UE +CwwQTHlmdCBFbmdpbmVlcmluZzEUMBIGA1UEAwwLVGVzdCBTZXJ2ZXIwgZ8wDQYJ +KoZIhvcNAQEBBQADgY0AMIGJAoGBALGG70n/nfIB64LH6jraqxpJ3EUO+gL/KkHG +4+/hQMMZpehPdcHa7vj1efBgaaddtjRZ3GLSSF968O19EbMwjQl1Azwn3Ql8SddQ +hyW30/Q/jgY54MnDBGgb5xhb7tdfjGvZ+lKapu9FypTcrre/wXSwBSsmm2me0CCN +AZKddyMzAgMBAAGjgZ0wgZowDAYDVR0TAQH/BAIwADALBgNVHQ8EBAMCBeAwHQYD +VR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMB4GA1UdEQQXMBWCE3NlcnZlcjEu +ZXhhbXBsZS5jb20wHQYDVR0OBBYEFBZcRXhGXlFghYQ9/R6yF7XTHzkxMB8GA1Ud +IwQYMBaAFIuDOLnI5iZPpH230VFAuWeNYuWdMA0GCSqGSIb3DQEBCwUAA4GBAFZg +6ZznS3KuEus6ZJsLJH7J0BMKmpdj5hM0M++TBnP8LVy73ETc95Y2sxvB/B2c7f2v +wjz4nGd5O3kkiVlMrQ44GPUKrO3/Ltix+MT3ixuF7Z7vLFKwkIG2d0RXJVVb1MOM +w1bmtABHf8sVAFF6RZtjshWSaZYvIhiG1FedV4Vw +-----END CERTIFICATE----- diff --git a/test/common/ssl/test_data/san_dns_chain3.pem b/test/common/ssl/test_data/san_dns_chain3.pem new file mode 100644 index 0000000000000..7f61a41163960 --- /dev/null +++ b/test/common/ssl/test_data/san_dns_chain3.pem @@ -0,0 +1,37 @@ +-----BEGIN CERTIFICATE----- +MIIDGjCCAoOgAwIBAgIJALE/9j8tvBGNMA0GCSqGSIb3DQEBCwUAMIGDMQswCQYD +VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5j +aXNjbzENMAsGA1UECgwETHlmdDEZMBcGA1UECwwQTHlmdCBFbmdpbmVlcmluZzEd +MBsGA1UEAwwUVGVzdCBJbnRlcm1lZGlhdGUgQ0EwHhcNMTgwMTE1MjI0MDI3WhcN +MjAwMTE1MjI0MDI3WjB6MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5p +YTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwETHlmdDEZMBcGA1UE +CwwQTHlmdCBFbmdpbmVlcmluZzEUMBIGA1UEAwwLVGVzdCBTZXJ2ZXIwgZ8wDQYJ +KoZIhvcNAQEBBQADgY0AMIGJAoGBALGG70n/nfIB64LH6jraqxpJ3EUO+gL/KkHG +4+/hQMMZpehPdcHa7vj1efBgaaddtjRZ3GLSSF968O19EbMwjQl1Azwn3Ql8SddQ +hyW30/Q/jgY54MnDBGgb5xhb7tdfjGvZ+lKapu9FypTcrre/wXSwBSsmm2me0CCN +AZKddyMzAgMBAAGjgZ0wgZowDAYDVR0TAQH/BAIwADALBgNVHQ8EBAMCBeAwHQYD +VR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMB4GA1UdEQQXMBWCE3NlcnZlcjEu +ZXhhbXBsZS5jb20wHQYDVR0OBBYEFBZcRXhGXlFghYQ9/R6yF7XTHzkxMB8GA1Ud +IwQYMBaAFIuDOLnI5iZPpH230VFAuWeNYuWdMA0GCSqGSIb3DQEBCwUAA4GBAFZg +6ZznS3KuEus6ZJsLJH7J0BMKmpdj5hM0M++TBnP8LVy73ETc95Y2sxvB/B2c7f2v +wjz4nGd5O3kkiVlMrQ44GPUKrO3/Ltix+MT3ixuF7Z7vLFKwkIG2d0RXJVVb1MOM +w1bmtABHf8sVAFF6RZtjshWSaZYvIhiG1FedV4Vw +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIC3jCCAkegAwIBAgIJAJvUixVO/5pTMA0GCSqGSIb3DQEBCwUAMHYxCzAJBgNV +BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNp +c2NvMQ0wCwYDVQQKEwRMeWZ0MRkwFwYDVQQLExBMeWZ0IEVuZ2luZWVyaW5nMRAw +DgYDVQQDEwdUZXN0IENBMB4XDTE4MDExNTIyNDAyN1oXDTI4MDExMzIyNDAyN1ow +gYMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1T +YW4gRnJhbmNpc2NvMQ0wCwYDVQQKDARMeWZ0MRkwFwYDVQQLDBBMeWZ0IEVuZ2lu +ZWVyaW5nMR0wGwYDVQQDDBRUZXN0IEludGVybWVkaWF0ZSBDQTCBnzANBgkqhkiG +9w0BAQEFAAOBjQAwgYkCgYEAxd1kOhV+/2n+rJWKvrtkyyqkWgBXXhH15G9cusaR +zJtwxsvtPRYZ9nTc+A6GDFgZ0TS1sq/WJXfs3guMpFObXU+tSlezxHVRpWPTXKff +hblqtZMPKW5q5LmOHxKi8GUxwDnEeAiZmzstGCYkRKn+GmLYe26vFGBw4MvM89Vm +ecMCAwEAAaNmMGQwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYw +HQYDVR0OBBYEFIuDOLnI5iZPpH230VFAuWeNYuWdMB8GA1UdIwQYMBaAFDt4pFFP +FoSTHEgoegytK5ZByn15MA0GCSqGSIb3DQEBCwUAA4GBAGO77sBFzn63pM2Oy4XS ++FEcFj/lB4vBh4r8jtzdf5EMaKUeXY9i57MTryPTJZRFXW6BuQ/B3hiOW2fwkCdL +eHd0MwGv95cn1PCWZh1IidVrtrDeu0oLxhRk5mcflaaLBuGADUD3Y1ms2sl90Ean +6C+0EHH2O6Emesx9IhPZRx4H +-----END CERTIFICATE----- diff --git a/test/common/ssl/test_data/san_dns_key3.pem b/test/common/ssl/test_data/san_dns_key3.pem new file mode 100644 index 0000000000000..b0da70902f062 --- /dev/null +++ b/test/common/ssl/test_data/san_dns_key3.pem @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXgIBAAKBgQCxhu9J/53yAeuCx+o62qsaSdxFDvoC/ypBxuPv4UDDGaXoT3XB +2u749XnwYGmnXbY0Wdxi0khfevDtfRGzMI0JdQM8J90JfEnXUIclt9P0P44GOeDJ +wwRoG+cYW+7XX4xr2fpSmqbvRcqU3K63v8F0sAUrJptpntAgjQGSnXcjMwIDAQAB +AoGAJk4kQcZLEVYCuDRkwRA/zStUwP3rSkw+lPTSaAcljzNwjgDfOtX/rG5jQk+7 +XGanEwK0wAn5nciMReIvuIdoVt7zEtFygZ7D3yKh+Ywu0AYC8TaiszAaL0efMnAW +MtpgyrAoMB4bFON3oyNVZM161+cdrU0PrEDqh+GHl8abpokCQQDfn2jE3WmS/a36 +2Dt/e3yjNE/4xDshAcHkNmF+jpcB66bls5ZU5Yv07RUVExQ30fw3v+ADMxmNYg2f +qpAF2getAkEAyzr9GwgdKeruErwlLhMOG327zTcZlHZXU5Q378/S3bKi3c/voGCb +exKjxRBZTzSw5hfrOzbCEpMLcwZaoBiyXwJBAJAH2XAq98vQDpXpXfEPNUjc8cFV +iowI2LxHdmYQKxz2jemW0PXfX1Siuxh20GffnOa/c+Y7rHKOvB2hut+5/YUCQQCF +nBx2vxjdTBSEwKj455IoxLrJKeZpUnwK+LDluo35Ls4gYeo6WAkgGpsMnbj5d7yt +KSB/Z3qj14R5dL3z7wilAkEAp78JPrvWP5zc3YOmmr9s8IQ3almspwnlh1mdcgoX +4rHe3U4jRZwE6fw8W9G4QsFRlez1Re6g8T7yoFXiZETGqQ== +-----END RSA PRIVATE KEY----- From 99fec859ee2b4915f9fc47e03c4a9951396f4cef Mon Sep 17 00:00:00 2001 From: Piotr Sikora Date: Mon, 15 Jan 2018 18:48:32 -0800 Subject: [PATCH 4/9] Add YAML tests. Signed-off-by: Piotr Sikora --- test/server/listener_manager_impl_test.cc | 128 ++++++++++++++++++++++ 1 file changed, 128 insertions(+) diff --git a/test/server/listener_manager_impl_test.cc b/test/server/listener_manager_impl_test.cc index 42decc20025c2..9969e35b39162 100644 --- a/test/server/listener_manager_impl_test.cc +++ b/test/server/listener_manager_impl_test.cc @@ -1042,5 +1042,133 @@ TEST_F(ListenerManagerImplWithRealFiltersTest, SniWithTwoDifferentFilterChains) "chains is currently not supported"); } +TEST_F(ListenerManagerImplWithRealFiltersTest, TlsCertificateInline) { + const std::string yaml = R"EOF( + address: + socket_address: { address: 127.0.0.1, port_value: 1234 } + filter_chains: + - tls_context: + common_tls_context: + tls_certificates: + - certificate_chain: { inline_string: "-----BEGIN CERTIFICATE-----\nMIIDGjCCAoOgAwIBAgIJALE/9j8tvBGNMA0GCSqGSIb3DQEBCwUAMIGDMQswCQYD\nVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5j\naXNjbzENMAsGA1UECgwETHlmdDEZMBcGA1UECwwQTHlmdCBFbmdpbmVlcmluZzEd\nMBsGA1UEAwwUVGVzdCBJbnRlcm1lZGlhdGUgQ0EwHhcNMTgwMTE1MjI0MDI3WhcN\nMjAwMTE1MjI0MDI3WjB6MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5p\nYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwETHlmdDEZMBcGA1UE\nCwwQTHlmdCBFbmdpbmVlcmluZzEUMBIGA1UEAwwLVGVzdCBTZXJ2ZXIwgZ8wDQYJ\nKoZIhvcNAQEBBQADgY0AMIGJAoGBALGG70n/nfIB64LH6jraqxpJ3EUO+gL/KkHG\n4+/hQMMZpehPdcHa7vj1efBgaaddtjRZ3GLSSF968O19EbMwjQl1Azwn3Ql8SddQ\nhyW30/Q/jgY54MnDBGgb5xhb7tdfjGvZ+lKapu9FypTcrre/wXSwBSsmm2me0CCN\nAZKddyMzAgMBAAGjgZ0wgZowDAYDVR0TAQH/BAIwADALBgNVHQ8EBAMCBeAwHQYD\nVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMB4GA1UdEQQXMBWCE3NlcnZlcjEu\nZXhhbXBsZS5jb20wHQYDVR0OBBYEFBZcRXhGXlFghYQ9/R6yF7XTHzkxMB8GA1Ud\nIwQYMBaAFIuDOLnI5iZPpH230VFAuWeNYuWdMA0GCSqGSIb3DQEBCwUAA4GBAFZg\n6ZznS3KuEus6ZJsLJH7J0BMKmpdj5hM0M++TBnP8LVy73ETc95Y2sxvB/B2c7f2v\nwjz4nGd5O3kkiVlMrQ44GPUKrO3/Ltix+MT3ixuF7Z7vLFKwkIG2d0RXJVVb1MOM\nw1bmtABHf8sVAFF6RZtjshWSaZYvIhiG1FedV4Vw\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIIC3jCCAkegAwIBAgIJAJvUixVO/5pTMA0GCSqGSIb3DQEBCwUAMHYxCzAJBgNV\nBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNp\nc2NvMQ0wCwYDVQQKEwRMeWZ0MRkwFwYDVQQLExBMeWZ0IEVuZ2luZWVyaW5nMRAw\nDgYDVQQDEwdUZXN0IENBMB4XDTE4MDExNTIyNDAyN1oXDTI4MDExMzIyNDAyN1ow\ngYMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1T\nYW4gRnJhbmNpc2NvMQ0wCwYDVQQKDARMeWZ0MRkwFwYDVQQLDBBMeWZ0IEVuZ2lu\nZWVyaW5nMR0wGwYDVQQDDBRUZXN0IEludGVybWVkaWF0ZSBDQTCBnzANBgkqhkiG\n9w0BAQEFAAOBjQAwgYkCgYEAxd1kOhV+/2n+rJWKvrtkyyqkWgBXXhH15G9cusaR\nzJtwxsvtPRYZ9nTc+A6GDFgZ0TS1sq/WJXfs3guMpFObXU+tSlezxHVRpWPTXKff\nhblqtZMPKW5q5LmOHxKi8GUxwDnEeAiZmzstGCYkRKn+GmLYe26vFGBw4MvM89Vm\necMCAwEAAaNmMGQwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYw\nHQYDVR0OBBYEFIuDOLnI5iZPpH230VFAuWeNYuWdMB8GA1UdIwQYMBaAFDt4pFFP\nFoSTHEgoegytK5ZByn15MA0GCSqGSIb3DQEBCwUAA4GBAGO77sBFzn63pM2Oy4XS\n+FEcFj/lB4vBh4r8jtzdf5EMaKUeXY9i57MTryPTJZRFXW6BuQ/B3hiOW2fwkCdL\neHd0MwGv95cn1PCWZh1IidVrtrDeu0oLxhRk5mcflaaLBuGADUD3Y1ms2sl90Ean\n6C+0EHH2O6Emesx9IhPZRx4H\n-----END CERTIFICATE-----" } + private_key: { inline_string: "-----BEGIN RSA PRIVATE KEY-----\nMIICXgIBAAKBgQCxhu9J/53yAeuCx+o62qsaSdxFDvoC/ypBxuPv4UDDGaXoT3XB\n2u749XnwYGmnXbY0Wdxi0khfevDtfRGzMI0JdQM8J90JfEnXUIclt9P0P44GOeDJ\nwwRoG+cYW+7XX4xr2fpSmqbvRcqU3K63v8F0sAUrJptpntAgjQGSnXcjMwIDAQAB\nAoGAJk4kQcZLEVYCuDRkwRA/zStUwP3rSkw+lPTSaAcljzNwjgDfOtX/rG5jQk+7\nXGanEwK0wAn5nciMReIvuIdoVt7zEtFygZ7D3yKh+Ywu0AYC8TaiszAaL0efMnAW\nMtpgyrAoMB4bFON3oyNVZM161+cdrU0PrEDqh+GHl8abpokCQQDfn2jE3WmS/a36\n2Dt/e3yjNE/4xDshAcHkNmF+jpcB66bls5ZU5Yv07RUVExQ30fw3v+ADMxmNYg2f\nqpAF2getAkEAyzr9GwgdKeruErwlLhMOG327zTcZlHZXU5Q378/S3bKi3c/voGCb\nexKjxRBZTzSw5hfrOzbCEpMLcwZaoBiyXwJBAJAH2XAq98vQDpXpXfEPNUjc8cFV\niowI2LxHdmYQKxz2jemW0PXfX1Siuxh20GffnOa/c+Y7rHKOvB2hut+5/YUCQQCF\nnBx2vxjdTBSEwKj455IoxLrJKeZpUnwK+LDluo35Ls4gYeo6WAkgGpsMnbj5d7yt\nKSB/Z3qj14R5dL3z7wilAkEAp78JPrvWP5zc3YOmmr9s8IQ3almspwnlh1mdcgoX\n4rHe3U4jRZwE6fw8W9G4QsFRlez1Re6g8T7yoFXiZETGqQ==\n-----END RSA PRIVATE KEY-----" } + validation_context: + trusted_ca: { inline_string: "-----BEGIN CERTIFICATE-----\nMIICzTCCAjagAwIBAgIJAOrzsOodDleaMA0GCSqGSIb3DQEBCwUAMHYxCzAJBgNV\nBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNp\nc2NvMQ0wCwYDVQQKEwRMeWZ0MRkwFwYDVQQLExBMeWZ0IEVuZ2luZWVyaW5nMRAw\nDgYDVQQDEwdUZXN0IENBMB4XDTE3MDcwOTAxMzkzMloXDTI3MDcwNzAxMzkzMlow\ndjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh\nbiBGcmFuY2lzY28xDTALBgNVBAoTBEx5ZnQxGTAXBgNVBAsTEEx5ZnQgRW5naW5l\nZXJpbmcxEDAOBgNVBAMTB1Rlc3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ\nAoGBAJuJh8N5TheTHLKOxsLSAfiIu9VDeKPsV98KRJJaYCMoaof3j9wBs65HzIat\nAunuV4DVZZ2c/x7/v741oWadYd3yqL7XSzQaeBvhXi+wv3g17FYrdxaowG7cfmsh\ngCp7/9TRW0bRGL6Qp6od/u62L8dprdHXxnck/+sZMupam9YrAgMBAAGjYzBhMA8G\nA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQ7eKRRTxaE\nkxxIKHoMrSuWQcp9eTAfBgNVHSMEGDAWgBQ7eKRRTxaEkxxIKHoMrSuWQcp9eTAN\nBgkqhkiG9w0BAQsFAAOBgQCN00/2k9k8HNeJ8eYuFH10jnc+td7+OaYWpRSEKCS7\nux3KAu0UFt90mojEMClt4Y6uP4oXTWbRzMzAgQHldHU8Gkj8tYnv7mToX7Bh/xdc\n19epzjCmo/4Q6+16GZZvltiFjkkHSZEVI5ggljy1QdMIPRegsKKmX9mjZSCSSXD6\nSA==\n-----END CERTIFICATE-----" } + )EOF"; + + EXPECT_CALL(server_.random_, uuid()); + EXPECT_CALL(listener_factory_, createListenSocket(_, true)); + manager_->addOrUpdateListener(parseListenerFromV2Yaml(yaml), true); + EXPECT_EQ(1U, manager_->listeners().size()); +} + +TEST_F(ListenerManagerImplWithRealFiltersTest, TlsCertificateChainInlinePrivateKeyFilename) { + const std::string yaml = TestEnvironment::substitute(R"EOF( + address: + socket_address: { address: 127.0.0.1, port_value: 1234 } + filter_chains: + - tls_context: + common_tls_context: + tls_certificates: + - certificate_chain: { inline_string: "-----BEGIN CERTIFICATE-----\nMIIDGjCCAoOgAwIBAgIJALE/9j8tvBGNMA0GCSqGSIb3DQEBCwUAMIGDMQswCQYD\nVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5j\naXNjbzENMAsGA1UECgwETHlmdDEZMBcGA1UECwwQTHlmdCBFbmdpbmVlcmluZzEd\nMBsGA1UEAwwUVGVzdCBJbnRlcm1lZGlhdGUgQ0EwHhcNMTgwMTE1MjI0MDI3WhcN\nMjAwMTE1MjI0MDI3WjB6MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5p\nYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwETHlmdDEZMBcGA1UE\nCwwQTHlmdCBFbmdpbmVlcmluZzEUMBIGA1UEAwwLVGVzdCBTZXJ2ZXIwgZ8wDQYJ\nKoZIhvcNAQEBBQADgY0AMIGJAoGBALGG70n/nfIB64LH6jraqxpJ3EUO+gL/KkHG\n4+/hQMMZpehPdcHa7vj1efBgaaddtjRZ3GLSSF968O19EbMwjQl1Azwn3Ql8SddQ\nhyW30/Q/jgY54MnDBGgb5xhb7tdfjGvZ+lKapu9FypTcrre/wXSwBSsmm2me0CCN\nAZKddyMzAgMBAAGjgZ0wgZowDAYDVR0TAQH/BAIwADALBgNVHQ8EBAMCBeAwHQYD\nVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMB4GA1UdEQQXMBWCE3NlcnZlcjEu\nZXhhbXBsZS5jb20wHQYDVR0OBBYEFBZcRXhGXlFghYQ9/R6yF7XTHzkxMB8GA1Ud\nIwQYMBaAFIuDOLnI5iZPpH230VFAuWeNYuWdMA0GCSqGSIb3DQEBCwUAA4GBAFZg\n6ZznS3KuEus6ZJsLJH7J0BMKmpdj5hM0M++TBnP8LVy73ETc95Y2sxvB/B2c7f2v\nwjz4nGd5O3kkiVlMrQ44GPUKrO3/Ltix+MT3ixuF7Z7vLFKwkIG2d0RXJVVb1MOM\nw1bmtABHf8sVAFF6RZtjshWSaZYvIhiG1FedV4Vw\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIIC3jCCAkegAwIBAgIJAJvUixVO/5pTMA0GCSqGSIb3DQEBCwUAMHYxCzAJBgNV\nBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNp\nc2NvMQ0wCwYDVQQKEwRMeWZ0MRkwFwYDVQQLExBMeWZ0IEVuZ2luZWVyaW5nMRAw\nDgYDVQQDEwdUZXN0IENBMB4XDTE4MDExNTIyNDAyN1oXDTI4MDExMzIyNDAyN1ow\ngYMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1T\nYW4gRnJhbmNpc2NvMQ0wCwYDVQQKDARMeWZ0MRkwFwYDVQQLDBBMeWZ0IEVuZ2lu\nZWVyaW5nMR0wGwYDVQQDDBRUZXN0IEludGVybWVkaWF0ZSBDQTCBnzANBgkqhkiG\n9w0BAQEFAAOBjQAwgYkCgYEAxd1kOhV+/2n+rJWKvrtkyyqkWgBXXhH15G9cusaR\nzJtwxsvtPRYZ9nTc+A6GDFgZ0TS1sq/WJXfs3guMpFObXU+tSlezxHVRpWPTXKff\nhblqtZMPKW5q5LmOHxKi8GUxwDnEeAiZmzstGCYkRKn+GmLYe26vFGBw4MvM89Vm\necMCAwEAAaNmMGQwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYw\nHQYDVR0OBBYEFIuDOLnI5iZPpH230VFAuWeNYuWdMB8GA1UdIwQYMBaAFDt4pFFP\nFoSTHEgoegytK5ZByn15MA0GCSqGSIb3DQEBCwUAA4GBAGO77sBFzn63pM2Oy4XS\n+FEcFj/lB4vBh4r8jtzdf5EMaKUeXY9i57MTryPTJZRFXW6BuQ/B3hiOW2fwkCdL\neHd0MwGv95cn1PCWZh1IidVrtrDeu0oLxhRk5mcflaaLBuGADUD3Y1ms2sl90Ean\n6C+0EHH2O6Emesx9IhPZRx4H\n-----END CERTIFICATE-----" } + private_key: { filename: "{{ test_rundir }}/test/common/ssl/test_data/san_dns_key3.pem" } + )EOF", + Network::Address::IpVersion::v4); + + EXPECT_CALL(server_.random_, uuid()); + EXPECT_CALL(listener_factory_, createListenSocket(_, true)); + manager_->addOrUpdateListener(parseListenerFromV2Yaml(yaml), true); + EXPECT_EQ(1U, manager_->listeners().size()); +} + +TEST_F(ListenerManagerImplWithRealFiltersTest, TlsCertificateIncomplete) { + const std::string yaml = TestEnvironment::substitute(R"EOF( + address: + socket_address: { address: 127.0.0.1, port_value: 1234 } + filter_chains: + - tls_context: + common_tls_context: + tls_certificates: + - certificate_chain: { filename: "{{ test_rundir }}/test/common/ssl/test_data/san_dns_chain3.pem" } + )EOF", + Network::Address::IpVersion::v4); + + EXPECT_THROW_WITH_MESSAGE( + manager_->addOrUpdateListener(parseListenerFromV2Yaml(yaml), true), EnvoyException, + TestEnvironment::substitute("Failed to load incomplete certificate from {{ test_rundir }}" + "/test/common/ssl/test_data/san_dns_chain3.pem, ", + Network::Address::IpVersion::v4)); +} + +TEST_F(ListenerManagerImplWithRealFiltersTest, TlsCertificateInvalidCertificateChain) { + const std::string yaml = TestEnvironment::substitute(R"EOF( + address: + socket_address: { address: 127.0.0.1, port_value: 1234 } + filter_chains: + - tls_context: + common_tls_context: + tls_certificates: + - certificate_chain: { inline_string: "invalid" } + private_key: { filename: "{{ test_rundir }}/test/common/ssl/test_data/san_dns_key3.pem" } + )EOF", + Network::Address::IpVersion::v4); + + EXPECT_THROW_WITH_MESSAGE(manager_->addOrUpdateListener(parseListenerFromV2Yaml(yaml), true), + EnvoyException, "Failed to load certificate chain from "); +} + +TEST_F(ListenerManagerImplWithRealFiltersTest, TlsCertificateInvalidIntermediateCA) { + const std::string yaml = TestEnvironment::substitute(R"EOF( + address: + socket_address: { address: 127.0.0.1, port_value: 1234 } + filter_chains: + - tls_context: + common_tls_context: + tls_certificates: + - certificate_chain: { inline_string: "-----BEGIN CERTIFICATE-----\nMIIDGjCCAoOgAwIBAgIJALE/9j8tvBGNMA0GCSqGSIb3DQEBCwUAMIGDMQswCQYD\nVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5j\naXNjbzENMAsGA1UECgwETHlmdDEZMBcGA1UECwwQTHlmdCBFbmdpbmVlcmluZzEd\nMBsGA1UEAwwUVGVzdCBJbnRlcm1lZGlhdGUgQ0EwHhcNMTgwMTE1MjI0MDI3WhcN\nMjAwMTE1MjI0MDI3WjB6MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5p\nYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwETHlmdDEZMBcGA1UE\nCwwQTHlmdCBFbmdpbmVlcmluZzEUMBIGA1UEAwwLVGVzdCBTZXJ2ZXIwgZ8wDQYJ\nKoZIhvcNAQEBBQADgY0AMIGJAoGBALGG70n/nfIB64LH6jraqxpJ3EUO+gL/KkHG\n4+/hQMMZpehPdcHa7vj1efBgaaddtjRZ3GLSSF968O19EbMwjQl1Azwn3Ql8SddQ\nhyW30/Q/jgY54MnDBGgb5xhb7tdfjGvZ+lKapu9FypTcrre/wXSwBSsmm2me0CCN\nAZKddyMzAgMBAAGjgZ0wgZowDAYDVR0TAQH/BAIwADALBgNVHQ8EBAMCBeAwHQYD\nVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMB4GA1UdEQQXMBWCE3NlcnZlcjEu\nZXhhbXBsZS5jb20wHQYDVR0OBBYEFBZcRXhGXlFghYQ9/R6yF7XTHzkxMB8GA1Ud\nIwQYMBaAFIuDOLnI5iZPpH230VFAuWeNYuWdMA0GCSqGSIb3DQEBCwUAA4GBAFZg\n6ZznS3KuEus6ZJsLJH7J0BMKmpdj5hM0M++TBnP8LVy73ETc95Y2sxvB/B2c7f2v\nwjz4nGd5O3kkiVlMrQ44GPUKrO3/Ltix+MT3ixuF7Z7vLFKwkIG2d0RXJVVb1MOM\nw1bmtABHf8sVAFF6RZtjshWSaZYvIhiG1FedV4Vw\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\ninvalid" } + private_key: { filename: "{{ test_rundir }}/test/common/ssl/test_data/san_dns_key3.pem" } + )EOF", + Network::Address::IpVersion::v4); + + EXPECT_THROW_WITH_MESSAGE(manager_->addOrUpdateListener(parseListenerFromV2Yaml(yaml), true), + EnvoyException, "Failed to load certificate chain from "); +} + +TEST_F(ListenerManagerImplWithRealFiltersTest, TlsCertificateInvalidPrivateKey) { + const std::string yaml = TestEnvironment::substitute(R"EOF( + address: + socket_address: { address: 127.0.0.1, port_value: 1234 } + filter_chains: + - tls_context: + common_tls_context: + tls_certificates: + - certificate_chain: { filename: "{{ test_rundir }}/test/common/ssl/test_data/san_dns_chain3.pem" } + private_key: { inline_string: "invalid" } + )EOF", + Network::Address::IpVersion::v4); + + EXPECT_THROW_WITH_MESSAGE(manager_->addOrUpdateListener(parseListenerFromV2Yaml(yaml), true), + EnvoyException, "Failed to load private key from "); +} + +TEST_F(ListenerManagerImplWithRealFiltersTest, TlsCertificateInvalidTrustedCA) { + const std::string yaml = TestEnvironment::substitute(R"EOF( + address: + socket_address: { address: 127.0.0.1, port_value: 1234 } + filter_chains: + - tls_context: + common_tls_context: + tls_certificates: + - certificate_chain: { filename: "{{ test_rundir }}/test/common/ssl/test_data/san_dns_chain3.pem" } + private_key: { filename: "{{ test_rundir }}/test/common/ssl/test_data/san_dns_key3.pem" } + validation_context: + trusted_ca: { inline_string: "invalid" } + )EOF", + Network::Address::IpVersion::v4); + + EXPECT_THROW_WITH_MESSAGE(manager_->addOrUpdateListener(parseListenerFromV2Yaml(yaml), true), + EnvoyException, "Failed to load trusted CA certificates from "); +} + } // namespace Server } // namespace Envoy From 5a84fae415aab7a2e068277de077e9d52f7f0868 Mon Sep 17 00:00:00 2001 From: Piotr Sikora Date: Mon, 15 Jan 2018 18:49:01 -0800 Subject: [PATCH 5/9] Remove trailing whitespace. Signed-off-by: Piotr Sikora --- configs/configgen.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/configgen.sh b/configs/configgen.sh index 4fa1aa31a9f28..703d09b2c5494 100755 --- a/configs/configgen.sh +++ b/configs/configgen.sh @@ -12,7 +12,7 @@ mkdir -p "$OUT_DIR/certs" for FILE in $*; do case "$FILE" in - *.pem) + *.pem) cp "$FILE" "$OUT_DIR/certs" ;; *) From 3ca4f44b9d76ddf08219ca1b93d6189778fe144e Mon Sep 17 00:00:00 2001 From: Piotr Sikora Date: Mon, 15 Jan 2018 20:17:11 -0800 Subject: [PATCH 6/9] Fix format. Signed-off-by: Piotr Sikora --- test/common/ssl/ssl_socket_test.cc | 70 +++++++++++++++--------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/test/common/ssl/ssl_socket_test.cc b/test/common/ssl/ssl_socket_test.cc index aba6072fdb769..d5d2f9de471ad 100644 --- a/test/common/ssl/ssl_socket_test.cc +++ b/test/common/ssl/ssl_socket_test.cc @@ -316,41 +316,41 @@ TEST_P(SslSocketTest, GetCertDigestInline) { ->mutable_validation_context() ->mutable_trusted_ca() ->set_inline_bytes("-----BEGIN CERTIFICATE-----\n" - "MIICzTCCAjagAwIBAgIJAPAEjHA3MX2BMA0GCSqGSIb3DQEBCwUAMHYxCzAJBgNV\n" - "BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNp\n" - "c2NvMQ0wCwYDVQQKEwRMeWZ0MRkwFwYDVQQLExBMeWZ0IEVuZ2luZWVyaW5nMRAw\n" - "DgYDVQQDEwdGYWtlIENBMB4XDTE3MDcwOTAxMzkzMloXDTI3MDcwNzAxMzkzMlow\n" - "djELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh\n" - "biBGcmFuY2lzY28xDTALBgNVBAoTBEx5ZnQxGTAXBgNVBAsTEEx5ZnQgRW5naW5l\n" - "ZXJpbmcxEDAOBgNVBAMTB0Zha2UgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ\n" - "AoGBAK/89R7j0kwhGh7NDAiuhlVmN1Hh73sGRzDBgON/ZfmJSgkvZIwQ4+hu0wZ6\n" - "wjN0am1iIKyp8O1OkmKurcfCRQM2QGiIUI7v7rSa0GzqENoEsQGXVk8/yhwD8Ys9\n" - "IPLTWXLVyh49yh5FCs6nt2/LrIuZX/K2cZQx+VuLCcg5sTllAgMBAAGjYzBhMA8G\n" - "A1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRRsE37S/H/\n" - "lCd1pWH4sCn9qrON3TAfBgNVHSMEGDAWgBRRsE37S/H/lCd1pWH4sCn9qrON3TAN\n" - "BgkqhkiG9w0BAQsFAAOBgQAvFbQm1PrqeWlZssPDPfI5dlo2KEL9VedIlThqDU4z\n" - "MStNR/Tfw2A0WtjOyjm2R0viqLu8JdDe8umUqO9DkRhZOaUtLgQEkaQn75z8WQPk\n" - "Sj+kenx0v3GMrPZMAsELiPG5PcSk8l5prDgU7VkzNvoCtypCsB7RQRyvZs52Qih3\n" - "Ug==\n" - "-----END CERTIFICATE-----\n" - "-----BEGIN CERTIFICATE-----\n" - "MIICzTCCAjagAwIBAgIJAOrzsOodDleaMA0GCSqGSIb3DQEBCwUAMHYxCzAJBgNV\n" - "BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNp\n" - "c2NvMQ0wCwYDVQQKEwRMeWZ0MRkwFwYDVQQLExBMeWZ0IEVuZ2luZWVyaW5nMRAw\n" - "DgYDVQQDEwdUZXN0IENBMB4XDTE3MDcwOTAxMzkzMloXDTI3MDcwNzAxMzkzMlow\n" - "djELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh\n" - "biBGcmFuY2lzY28xDTALBgNVBAoTBEx5ZnQxGTAXBgNVBAsTEEx5ZnQgRW5naW5l\n" - "ZXJpbmcxEDAOBgNVBAMTB1Rlc3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ\n" - "AoGBAJuJh8N5TheTHLKOxsLSAfiIu9VDeKPsV98KRJJaYCMoaof3j9wBs65HzIat\n" - "AunuV4DVZZ2c/x7/v741oWadYd3yqL7XSzQaeBvhXi+wv3g17FYrdxaowG7cfmsh\n" - "gCp7/9TRW0bRGL6Qp6od/u62L8dprdHXxnck/+sZMupam9YrAgMBAAGjYzBhMA8G\n" - "A1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQ7eKRRTxaE\n" - "kxxIKHoMrSuWQcp9eTAfBgNVHSMEGDAWgBQ7eKRRTxaEkxxIKHoMrSuWQcp9eTAN\n" - "BgkqhkiG9w0BAQsFAAOBgQCN00/2k9k8HNeJ8eYuFH10jnc+td7+OaYWpRSEKCS7\n" - "ux3KAu0UFt90mojEMClt4Y6uP4oXTWbRzMzAgQHldHU8Gkj8tYnv7mToX7Bh/xdc\n" - "19epzjCmo/4Q6+16GZZvltiFjkkHSZEVI5ggljy1QdMIPRegsKKmX9mjZSCSSXD6\n" - "SA==\n" - "-----END CERTIFICATE-----"); + "MIICzTCCAjagAwIBAgIJAPAEjHA3MX2BMA0GCSqGSIb3DQEBCwUAMHYxCzAJBgNV\n" + "BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNp\n" + "c2NvMQ0wCwYDVQQKEwRMeWZ0MRkwFwYDVQQLExBMeWZ0IEVuZ2luZWVyaW5nMRAw\n" + "DgYDVQQDEwdGYWtlIENBMB4XDTE3MDcwOTAxMzkzMloXDTI3MDcwNzAxMzkzMlow\n" + "djELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh\n" + "biBGcmFuY2lzY28xDTALBgNVBAoTBEx5ZnQxGTAXBgNVBAsTEEx5ZnQgRW5naW5l\n" + "ZXJpbmcxEDAOBgNVBAMTB0Zha2UgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ\n" + "AoGBAK/89R7j0kwhGh7NDAiuhlVmN1Hh73sGRzDBgON/ZfmJSgkvZIwQ4+hu0wZ6\n" + "wjN0am1iIKyp8O1OkmKurcfCRQM2QGiIUI7v7rSa0GzqENoEsQGXVk8/yhwD8Ys9\n" + "IPLTWXLVyh49yh5FCs6nt2/LrIuZX/K2cZQx+VuLCcg5sTllAgMBAAGjYzBhMA8G\n" + "A1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRRsE37S/H/\n" + "lCd1pWH4sCn9qrON3TAfBgNVHSMEGDAWgBRRsE37S/H/lCd1pWH4sCn9qrON3TAN\n" + "BgkqhkiG9w0BAQsFAAOBgQAvFbQm1PrqeWlZssPDPfI5dlo2KEL9VedIlThqDU4z\n" + "MStNR/Tfw2A0WtjOyjm2R0viqLu8JdDe8umUqO9DkRhZOaUtLgQEkaQn75z8WQPk\n" + "Sj+kenx0v3GMrPZMAsELiPG5PcSk8l5prDgU7VkzNvoCtypCsB7RQRyvZs52Qih3\n" + "Ug==\n" + "-----END CERTIFICATE-----\n" + "-----BEGIN CERTIFICATE-----\n" + "MIICzTCCAjagAwIBAgIJAOrzsOodDleaMA0GCSqGSIb3DQEBCwUAMHYxCzAJBgNV\n" + "BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNp\n" + "c2NvMQ0wCwYDVQQKEwRMeWZ0MRkwFwYDVQQLExBMeWZ0IEVuZ2luZWVyaW5nMRAw\n" + "DgYDVQQDEwdUZXN0IENBMB4XDTE3MDcwOTAxMzkzMloXDTI3MDcwNzAxMzkzMlow\n" + "djELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh\n" + "biBGcmFuY2lzY28xDTALBgNVBAoTBEx5ZnQxGTAXBgNVBAsTEEx5ZnQgRW5naW5l\n" + "ZXJpbmcxEDAOBgNVBAMTB1Rlc3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ\n" + "AoGBAJuJh8N5TheTHLKOxsLSAfiIu9VDeKPsV98KRJJaYCMoaof3j9wBs65HzIat\n" + "AunuV4DVZZ2c/x7/v741oWadYd3yqL7XSzQaeBvhXi+wv3g17FYrdxaowG7cfmsh\n" + "gCp7/9TRW0bRGL6Qp6od/u62L8dprdHXxnck/+sZMupam9YrAgMBAAGjYzBhMA8G\n" + "A1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQ7eKRRTxaE\n" + "kxxIKHoMrSuWQcp9eTAfBgNVHSMEGDAWgBQ7eKRRTxaEkxxIKHoMrSuWQcp9eTAN\n" + "BgkqhkiG9w0BAQsFAAOBgQCN00/2k9k8HNeJ8eYuFH10jnc+td7+OaYWpRSEKCS7\n" + "ux3KAu0UFt90mojEMClt4Y6uP4oXTWbRzMzAgQHldHU8Gkj8tYnv7mToX7Bh/xdc\n" + "19epzjCmo/4Q6+16GZZvltiFjkkHSZEVI5ggljy1QdMIPRegsKKmX9mjZSCSSXD6\n" + "SA==\n" + "-----END CERTIFICATE-----"); envoy::api::v2::UpstreamTlsContext client_ctx; envoy::api::v2::TlsCertificate* client_cert = From fa821e73f6f83e58c786b71a632b497e6e000945 Mon Sep 17 00:00:00 2001 From: Piotr Sikora Date: Mon, 15 Jan 2018 22:10:01 -0800 Subject: [PATCH 7/9] Fix "bazel.coverage" by returning to the original working directory. Signed-off-by: Piotr Sikora --- test/config_test/config_test.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/config_test/config_test.cc b/test/config_test/config_test.cc index fff7d4a7a8606..7de7607f71093 100644 --- a/test/config_test/config_test.cc +++ b/test/config_test/config_test.cc @@ -76,13 +76,17 @@ class ConfigTest { }; uint32_t run(const std::string& directory) { - uint32_t num_tested = 0; // Change working directory, otherwise we won't be able to read files using relative paths. + char cwd[PATH_MAX]; + RELEASE_ASSERT(::getcwd(cwd, PATH_MAX) != nullptr); RELEASE_ASSERT(::chdir(directory.c_str()) == 0); + uint32_t num_tested = 0; for (const std::string& filename : TestUtility::listFiles(directory, false)) { ConfigTest config(filename); num_tested++; } + // Return to the original working directory, otherwise "bazel.coverage" breaks (...but why?). + RELEASE_ASSERT(::chdir(cwd) == 0); return num_tested; } From e200503227df481fe0df6d6e9d79da6d6e324106 Mon Sep 17 00:00:00 2001 From: Piotr Sikora Date: Tue, 16 Jan 2018 15:46:02 -0800 Subject: [PATCH 8/9] review: Address ggreenway@'s comments. Signed-off-by: Piotr Sikora --- include/envoy/ssl/context_config.h | 9 ++++++--- source/common/ssl/context_config_impl.cc | 25 +++++++++++------------- source/common/ssl/context_config_impl.h | 1 + source/common/ssl/context_impl.cc | 2 +- 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/include/envoy/ssl/context_config.h b/include/envoy/ssl/context_config.h index aa1843c8045fd..016b7c11db58d 100644 --- a/include/envoy/ssl/context_config.h +++ b/include/envoy/ssl/context_config.h @@ -44,7 +44,8 @@ class ContextConfig { virtual const std::string& caCert() const PURE; /** - * @return Path of the CA certificate to use for peer validation. + * @return Path of the CA certificate to use for peer validation or an empty string + * if the CA certificate was inlined. */ virtual const std::string& caCertPath() const PURE; @@ -54,7 +55,8 @@ class ContextConfig { virtual const std::string& certChain() const PURE; /** - * @return Path of the certificate chain used to identify the local side. + * @return Path of the certificate chain used to identify the local side or an empty string + * if the certificate chain was inlined. */ virtual const std::string& certChainPath() const PURE; @@ -64,7 +66,8 @@ class ContextConfig { virtual const std::string& privateKey() const PURE; /** - * @return Path of the private key used to identify the local side. + * @return Path of the private key used to identify the local side or an empty string + * if the private key was inlined. */ virtual const std::string& privateKeyPath() const PURE; diff --git a/source/common/ssl/context_config_impl.cc b/source/common/ssl/context_config_impl.cc index 0eb86e32f48c1..9414002913228 100644 --- a/source/common/ssl/context_config_impl.cc +++ b/source/common/ssl/context_config_impl.cc @@ -42,26 +42,19 @@ ContextConfigImpl::ContextConfigImpl(const envoy::api::v2::CommonTlsContext& con ecdh_curves_(StringUtil::nonEmptyStringOrDefault( RepeatedPtrUtil::join(config.tls_params().ecdh_curves(), ":"), DEFAULT_ECDH_CURVES)), ca_cert_(readDataSource(config.validation_context().trusted_ca(), true)), - ca_cert_path_(config.validation_context().trusted_ca().specifier_case() == - envoy::api::v2::DataSource::kFilename - ? config.validation_context().trusted_ca().filename() - : ""), + ca_cert_path_(getDataSourcePath(config.validation_context().trusted_ca())), cert_chain_(config.tls_certificates().empty() ? "" : readDataSource(config.tls_certificates()[0].certificate_chain(), true)), - cert_chain_path_((!config.tls_certificates().empty() && - config.tls_certificates()[0].certificate_chain().specifier_case() == - envoy::api::v2::DataSource::kFilename) - ? config.tls_certificates()[0].certificate_chain().filename() - : ""), + cert_chain_path_(config.tls_certificates().empty() + ? "" + : getDataSourcePath(config.tls_certificates()[0].certificate_chain())), private_key_(config.tls_certificates().empty() ? "" : readDataSource(config.tls_certificates()[0].private_key(), true)), - private_key_path_((!config.tls_certificates().empty() && - config.tls_certificates()[0].private_key().specifier_case() == - envoy::api::v2::DataSource::kFilename) - ? config.tls_certificates()[0].private_key().filename() - : ""), + private_key_path_(config.tls_certificates().empty() + ? "" + : getDataSourcePath(config.tls_certificates()[0].private_key())), verify_subject_alt_name_list_(config.validation_context().verify_subject_alt_name().begin(), config.validation_context().verify_subject_alt_name().end()), verify_certificate_hash_(config.validation_context().verify_certificate_hash().empty() @@ -93,6 +86,10 @@ const std::string ContextConfigImpl::readDataSource(const envoy::api::v2::DataSo } } +const std::string ContextConfigImpl::getDataSourcePath(const envoy::api::v2::DataSource& source) { + return source.specifier_case() == envoy::api::v2::DataSource::kFilename ? source.filename() : ""; +} + unsigned ContextConfigImpl::tlsVersionFromProto(const envoy::api::v2::TlsParameters_TlsProtocol& version, unsigned default_version) { diff --git a/source/common/ssl/context_config_impl.h b/source/common/ssl/context_config_impl.h index c8bb9a52051c0..83212fa722e33 100644 --- a/source/common/ssl/context_config_impl.h +++ b/source/common/ssl/context_config_impl.h @@ -45,6 +45,7 @@ class ContextConfigImpl : public virtual Ssl::ContextConfig { static const std::string readDataSource(const envoy::api::v2::DataSource& source, bool allow_empty); + static const std::string getDataSourcePath(const envoy::api::v2::DataSource& source); private: static unsigned tlsVersionFromProto(const envoy::api::v2::TlsParameters_TlsProtocol& version, diff --git a/source/common/ssl/context_impl.cc b/source/common/ssl/context_impl.cc index 7c3a29dd182b3..ea020a25eb85b 100644 --- a/source/common/ssl/context_impl.cc +++ b/source/common/ssl/context_impl.cc @@ -120,7 +120,7 @@ ContextImpl::ContextImpl(ContextManagerImpl& parent, Stats::Scope& scope, fmt::format("Failed to load certificate chain from {}", config.certChainPath())); } // Read rest of the certificate chain. - for (;;) { + while (true) { bssl::UniquePtr cert(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr)); if (cert == nullptr) { break; From 65c1dbbc5e8c3d49e949972412880dd061224993 Mon Sep 17 00:00:00 2001 From: Piotr Sikora Date: Tue, 16 Jan 2018 16:32:34 -0800 Subject: [PATCH 9/9] review: fix comments. Signed-off-by: Piotr Sikora --- include/envoy/ssl/context_config.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/envoy/ssl/context_config.h b/include/envoy/ssl/context_config.h index 016b7c11db58d..83df4dc70360e 100644 --- a/include/envoy/ssl/context_config.h +++ b/include/envoy/ssl/context_config.h @@ -44,7 +44,7 @@ class ContextConfig { virtual const std::string& caCert() const PURE; /** - * @return Path of the CA certificate to use for peer validation or an empty string + * @return Path of the CA certificate to use for peer validation or "" * if the CA certificate was inlined. */ virtual const std::string& caCertPath() const PURE; @@ -55,7 +55,7 @@ class ContextConfig { virtual const std::string& certChain() const PURE; /** - * @return Path of the certificate chain used to identify the local side or an empty string + * @return Path of the certificate chain used to identify the local side or "" * if the certificate chain was inlined. */ virtual const std::string& certChainPath() const PURE; @@ -66,7 +66,7 @@ class ContextConfig { virtual const std::string& privateKey() const PURE; /** - * @return Path of the private key used to identify the local side or an empty string + * @return Path of the private key used to identify the local side or "" * if the private key was inlined. */ virtual const std::string& privateKeyPath() const PURE;