diff --git a/changelogs/current.yaml b/changelogs/current.yaml index 4c5d21d968f4..56aa1d8d55e2 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -13,6 +13,9 @@ removed_config_or_runtime: # *Normally occurs at the end of the* :ref:`deprecation period ` new_features: +- area: tls + change: | + Added support for P-384 and P-521 curves for TLS server certificates. - area: stats ads change: | Fixed metric for ADS disconnection counters, extracting the tag from `grpc.ads_cluster.*` counter stats. diff --git a/docs/root/intro/arch_overview/security/ssl.rst b/docs/root/intro/arch_overview/security/ssl.rst index b44b109af693..465716cc23d3 100644 --- a/docs/root/intro/arch_overview/security/ssl.rst +++ b/docs/root/intro/arch_overview/security/ssl.rst @@ -114,7 +114,7 @@ Certificate selection --------------------- :ref:`DownstreamTlsContexts ` support multiple TLS -certificates. These may be a mix of RSA and P-256 ECDSA certificates for multiple server name patterns. +certificates. These may be a mix of RSA and ECDSA certificates for multiple server name patterns. Certificate config/loading rules: @@ -122,7 +122,7 @@ Certificate config/loading rules: * FQDN like "test.example.com" and wildcard like "\*.example.com" are valid at the same time, which will be loaded as two different server name patterns. * If multiple certificates of a particular type (RSA or ECDSA) are specified for the same name or name pattern, the first one loaded is used for that name. -* Non-P-256 server ECDSA certificates are rejected. +* Non-P-256, P-384 or P-521 server ECDSA certificates are rejected. * Static and SDS certificates may not be mixed in a given :ref:`DownstreamTlsContext `. @@ -144,7 +144,7 @@ Certificate selection rules: is false or true. * Full scan execuates OCSP and key type checking on each cert which is the same as described above in exact SNI matching. It falls back to the first cert in the whole list if there is no cert selected. -* Currently only two kinds of key type are supported, RSA or ECDSA. If the client supports P-256 ECDSA, the P-256 ECDSA certificate +* Currently only two kinds of key type are supported, RSA or ECDSA. If the client supports P-256, P-384 or P-521 ECDSA, the P-256, P-384 or P-521 ECDSA certificate is preferred over RSA. The certificate that it falls back to might result in a failed handshake. For instance, a client only supports RSA certificates and the certificate only support ECDSA. * The final selected certificate must adhere to the OCSP policy. If no such certificate is found, the connection is refused. diff --git a/envoy/ssl/handshaker.h b/envoy/ssl/handshaker.h index 30b6b07d1403..22a7ec65ecc3 100644 --- a/envoy/ssl/handshaker.h +++ b/envoy/ssl/handshaker.h @@ -9,6 +9,7 @@ #include "envoy/server/options.h" #include "envoy/singleton/manager.h" +#include "absl/container/inlined_vector.h" #include "openssl/ssl.h" namespace Envoy { @@ -26,6 +27,11 @@ struct TlsContext; class ServerContextConfig; +using CurveNID = int; +// Currently this type only ever holds 3 values: P-256, P-384, and P-521, so optimize by using +// `InlinedVector`. +using CurveNIDVector = absl::InlinedVector; + class HandshakeCallbacks { public: virtual ~HandshakeCallbacks() = default; @@ -231,8 +237,8 @@ class TlsCertificateSelector { * @return context will have the same lifetime as ``ServerContextImpl``. */ virtual std::pair - findTlsContext(absl::string_view sni, bool client_ecdsa_capable, bool client_ocsp_capable, - bool* cert_matched_sni) PURE; + findTlsContext(absl::string_view sni, const CurveNIDVector& client_ecdsa_capabilities, + bool client_ocsp_capable, bool* cert_matched_sni) PURE; }; using TlsCertificateSelectorPtr = std::unique_ptr; diff --git a/source/common/quic/quic_server_transport_socket_factory.cc b/source/common/quic/quic_server_transport_socket_factory.cc index f7ee3199c84c..7d7f9dd416a3 100644 --- a/source/common/quic/quic_server_transport_socket_factory.cc +++ b/source/common/quic/quic_server_transport_socket_factory.cc @@ -171,8 +171,9 @@ QuicServerTransportSocketFactory::getTlsCertificateAndKey(absl::string_view sni, } auto ctx = std::dynamic_pointer_cast(ssl_ctx); - auto [tls_context, ocsp_staple_action] = ctx->findTlsContext( - sni, true /* TODO: ecdsa_capable */, false /* TODO: ocsp_capable */, cert_matched_sni); + auto [tls_context, ocsp_staple_action] = + ctx->findTlsContext(sni, Ssl::CurveNIDVector{NID_X9_62_prime256v1} /* TODO: ecdsa_capable */, + false /* TODO: ocsp_capable */, cert_matched_sni); // Thread safety note: accessing the tls_context requires holding a shared_ptr to the ``ssl_ctx``. // Both of these members are themselves reference counted, so it is safe to use them after diff --git a/source/common/quic/quic_server_transport_socket_factory.h b/source/common/quic/quic_server_transport_socket_factory.h index b753a88b04e8..270d658709a5 100644 --- a/source/common/quic/quic_server_transport_socket_factory.h +++ b/source/common/quic/quic_server_transport_socket_factory.h @@ -4,6 +4,7 @@ #include "envoy/network/transport_socket.h" #include "envoy/server/transport_socket_config.h" #include "envoy/ssl/context_config.h" +#include "envoy/ssl/handshaker.h" #include "source/common/common/assert.h" #include "source/common/network/transport_socket_options_impl.h" diff --git a/source/common/tls/context_impl.cc b/source/common/tls/context_impl.cc index fed9720a46a3..865cbe8a2167 100644 --- a/source/common/tls/context_impl.cc +++ b/source/common/tls/context_impl.cc @@ -218,23 +218,24 @@ ContextImpl::ContextImpl(Stats::Scope& scope, const Envoy::Ssl::ContextConfig& c bssl::UniquePtr public_key(X509_get_pubkey(ctx.cert_chain_.get())); const int pkey_id = EVP_PKEY_id(public_key.get()); - ctx.is_ecdsa_ = pkey_id == EVP_PKEY_EC; switch (pkey_id) { case EVP_PKEY_EC: { - // We only support P-256 ECDSA today. + // We only support P-256, P-384 or P-521 ECDSA today. const EC_KEY* ecdsa_public_key = EVP_PKEY_get0_EC_KEY(public_key.get()); // Since we checked the key type above, this should be valid. ASSERT(ecdsa_public_key != nullptr); const EC_GROUP* ecdsa_group = EC_KEY_get0_group(ecdsa_public_key); + const int ec_group_curve_name = EC_GROUP_get_curve_name(ecdsa_group); if (ecdsa_group == nullptr || - EC_GROUP_get_curve_name(ecdsa_group) != NID_X9_62_prime256v1) { + (ec_group_curve_name != NID_X9_62_prime256v1 && ec_group_curve_name != NID_secp384r1 && + ec_group_curve_name != NID_secp521r1)) { creation_status = absl::InvalidArgumentError( - fmt::format("Failed to load certificate chain from {}, only P-256 " - "ECDSA certificates are supported", + fmt::format("Failed to load certificate chain from {}, only P-256, " + "P-384 or P-521 ECDSA certificates are supported", ctx.cert_chain_file_path_)); return; } - ctx.is_ecdsa_ = true; + ctx.ec_group_curve_name_ = ec_group_curve_name; } break; case EVP_PKEY_RSA: { // We require RSA certificates with 2048-bit or larger keys. diff --git a/source/common/tls/context_impl.h b/source/common/tls/context_impl.h index 080f1ecb11a8..846cf1922de4 100644 --- a/source/common/tls/context_impl.h +++ b/source/common/tls/context_impl.h @@ -38,6 +38,8 @@ namespace Envoy { namespace Ssl { +const int EC_CURVE_INVALID_NID = -1; + struct TlsContext { // Each certificate specified for the context has its own SSL_CTX. `SSL_CTXs` // are identical with the exception of certificate material, and can be @@ -47,7 +49,9 @@ struct TlsContext { bssl::UniquePtr cert_chain_; std::string cert_chain_file_path_; std::unique_ptr ocsp_response_; - bool is_ecdsa_{}; + // We initialize the curve name variable to EC_CURVE_INVALID_NID which is used as a sentinel value + // for "not an ECDSA context". + CurveNID ec_group_curve_name_ = EC_CURVE_INVALID_NID; bool is_must_staple_{}; Ssl::PrivateKeyMethodProviderSharedPtr private_key_method_provider_{}; diff --git a/source/common/tls/default_tls_certificate_selector.cc b/source/common/tls/default_tls_certificate_selector.cc index 61dac47be2e5..d889e22a925f 100644 --- a/source/common/tls/default_tls_certificate_selector.cc +++ b/source/common/tls/default_tls_certificate_selector.cc @@ -89,11 +89,12 @@ DefaultTlsCertificateSelector::selectTlsContext(const SSL_CLIENT_HELLO& ssl_clie Ssl::CertificateSelectionCallbackPtr) { absl::string_view sni = absl::NullSafeStringView(SSL_get_servername(ssl_client_hello.ssl, TLSEXT_NAMETYPE_host_name)); - const bool client_ecdsa_capable = server_ctx_.isClientEcdsaCapable(ssl_client_hello); + const Ssl::CurveNIDVector client_ecdsa_capabilities = + server_ctx_.getClientEcdsaCapabilities(ssl_client_hello); const bool client_ocsp_capable = server_ctx_.isClientOcspCapable(ssl_client_hello); auto [selected_ctx, ocsp_staple_action] = - findTlsContext(sni, client_ecdsa_capable, client_ocsp_capable, nullptr); + findTlsContext(sni, client_ecdsa_capabilities, client_ocsp_capable, nullptr); auto stats = server_ctx_.stats(); if (client_ocsp_capable) { @@ -162,7 +163,8 @@ Ssl::OcspStapleAction DefaultTlsCertificateSelector::ocspStapleAction(const Ssl: } std::pair -DefaultTlsCertificateSelector::findTlsContext(absl::string_view sni, bool client_ecdsa_capable, +DefaultTlsCertificateSelector::findTlsContext(absl::string_view sni, + const Ssl::CurveNIDVector& client_ecdsa_capabilities, bool client_ocsp_capable, bool* cert_matched_sni) { bool unused = false; if (cert_matched_sni == nullptr) { @@ -176,20 +178,36 @@ DefaultTlsCertificateSelector::findTlsContext(absl::string_view sni, bool client const Ssl::TlsContext* candidate_ctx = nullptr; Ssl::OcspStapleAction ocsp_staple_action; + // If the capabilities list vector is not empty, then the client is ECDSA-capable. + const bool client_ecdsa_capable = !client_ecdsa_capabilities.empty(); + auto selected = [&](const Ssl::TlsContext& ctx) -> bool { auto action = ocspStapleAction(ctx, client_ocsp_capable); if (action == Ssl::OcspStapleAction::Fail) { // The selected ctx must adhere to OCSP policy return false; } + // If the client is ECDSA-capable and the context is ECDSA, we check if it is capable of + // handling the curves in the cert in a given TlsContext. If the client is not ECDSA-capable, + // we will not std::find anything here and move on. If the context is RSA, we will not find + // the value of `EC_CURVE_INVALID_NID` in an vector of ECDSA capabilities. + // If we have a matching curve NID in our client capabilities, return `true`. + if (std::find(client_ecdsa_capabilities.begin(), client_ecdsa_capabilities.end(), + ctx.ec_group_curve_name_) != client_ecdsa_capabilities.end()) { + selected_ctx = &ctx; + ocsp_staple_action = action; + return true; + } - if (client_ecdsa_capable == ctx.is_ecdsa_) { + // If the client is not ECDSA-capable and the `ctx` is non-ECDSA, then select this `ctx`. + if (!client_ecdsa_capable && ctx.ec_group_curve_name_ == Ssl::EC_CURVE_INVALID_NID) { selected_ctx = &ctx; ocsp_staple_action = action; return true; } - if (client_ecdsa_capable && !ctx.is_ecdsa_ && candidate_ctx == nullptr) { + if (client_ecdsa_capable && ctx.ec_group_curve_name_ == Ssl::EC_CURVE_INVALID_NID && + candidate_ctx == nullptr) { // ECDSA cert is preferred if client is ECDSA capable, so RSA cert is marked as a candidate, // searching will continue until exhausting all certs or find a exact match. candidate_ctx = &ctx; diff --git a/source/common/tls/default_tls_certificate_selector.h b/source/common/tls/default_tls_certificate_selector.h index 6a462c55301a..1fdb290020ba 100644 --- a/source/common/tls/default_tls_certificate_selector.h +++ b/source/common/tls/default_tls_certificate_selector.h @@ -31,8 +31,8 @@ class DefaultTlsCertificateSelector : public Ssl::TlsCertificateSelector, // Finds the best matching context. The returned context will have the same lifetime as // ``ServerContextImpl``. std::pair - findTlsContext(absl::string_view sni, bool client_ecdsa_capable, bool client_ocsp_capable, - bool* cert_matched_sni) override; + findTlsContext(absl::string_view sni, const Ssl::CurveNIDVector& client_ecdsa_capabilities, + bool client_ocsp_capable, bool* cert_matched_sni) override; private: // Currently, at most one certificate of a given key type may be specified for each exact diff --git a/source/common/tls/server_context_impl.cc b/source/common/tls/server_context_impl.cc index 7b76f958f138..d2375c204eca 100644 --- a/source/common/tls/server_context_impl.cc +++ b/source/common/tls/server_context_impl.cc @@ -40,28 +40,34 @@ #include "openssl/rand.h" namespace Envoy { -namespace { -bool cbsContainsU16(CBS& cbs, uint16_t n) { +namespace Extensions { +namespace TransportSockets { +namespace Tls { + +Ssl::CurveNIDVector getClientCurveNIDSupported(CBS& cbs) { + Ssl::CurveNIDVector cnsv{}; while (CBS_len(&cbs) > 0) { uint16_t v; if (!CBS_get_u16(&cbs, &v)) { - return false; + break; } - if (v == n) { - return true; + // Check for values that refer to the `sigalgs` used in TLSv1.3 negotiation (left) + // or their equivalent curve expressed in TLSv1.2 `TLSEXT_TYPE_supported_groups` + // present in ClientHello (right). + if (v == SSL_SIGN_ECDSA_SECP256R1_SHA256 || v == SSL_CURVE_SECP256R1) { + cnsv.push_back(NID_X9_62_prime256v1); + } + if (v == SSL_SIGN_ECDSA_SECP384R1_SHA384 || v == SSL_CURVE_SECP384R1) { + cnsv.push_back(NID_secp384r1); + } + if (v == SSL_SIGN_ECDSA_SECP521R1_SHA512 || v == SSL_CURVE_SECP521R1) { + cnsv.push_back(NID_secp521r1); } } - - return false; + return cnsv; } -} // namespace - -namespace Extensions { -namespace TransportSockets { -namespace Tls { - int ServerContextImpl::alpnSelectCallback(const unsigned char** out, unsigned char* outlen, const unsigned char* in, unsigned int inlen) { // Currently this uses the standard selection algorithm in priority order. @@ -376,7 +382,10 @@ int ServerContextImpl::sessionTicketProcess(SSL*, uint8_t* key_name, uint8_t* iv } } -bool ServerContextImpl::isClientEcdsaCapable(const SSL_CLIENT_HELLO& ssl_client_hello) const { +// Returns a list of client capabilities for ECDSA curves as NIDs. An empty vector indicates +// a client that is unable to handle ECDSA. +Ssl::CurveNIDVector +ServerContextImpl::getClientEcdsaCapabilities(const SSL_CLIENT_HELLO& ssl_client_hello) const { CBS client_hello; CBS_init(&client_hello, ssl_client_hello.client_hello, ssl_client_hello.client_hello_len); @@ -399,14 +408,12 @@ bool ServerContextImpl::isClientEcdsaCapable(const SSL_CLIENT_HELLO& ssl_client_ CBS_init(&signature_algorithms_ext, signature_algorithms_data, signature_algorithms_len); if (!CBS_get_u16_length_prefixed(&signature_algorithms_ext, &signature_algorithms) || CBS_len(&signature_algorithms_ext) != 0) { - return false; - } - if (cbsContainsU16(signature_algorithms, SSL_SIGN_ECDSA_SECP256R1_SHA256)) { - return true; + return Ssl::CurveNIDVector{}; } + return getClientCurveNIDSupported(signature_algorithms); } - return false; + return Ssl::CurveNIDVector{}; } } @@ -416,15 +423,16 @@ bool ServerContextImpl::isClientEcdsaCapable(const SSL_CLIENT_HELLO& ssl_client_ size_t curvelist_len; if (!SSL_early_callback_ctx_extension_get(&ssl_client_hello, TLSEXT_TYPE_supported_groups, &curvelist_data, &curvelist_len)) { - return false; + return Ssl::CurveNIDVector{}; } CBS curvelist; CBS_init(&curvelist, curvelist_data, curvelist_len); - // We only support P256 ECDSA curves today. - if (!cbsContainsU16(curvelist, SSL_CURVE_SECP256R1)) { - return false; + Ssl::CurveNIDVector client_capabilities = getClientCurveNIDSupported(curvelist); + // if we haven't got any curves in common with the client, return empty CurveNIDVector. + if (client_capabilities.empty()) { + return Ssl::CurveNIDVector{}; } // The client must have offered an ECDSA ciphersuite that we like. @@ -434,16 +442,16 @@ bool ServerContextImpl::isClientEcdsaCapable(const SSL_CLIENT_HELLO& ssl_client_ while (CBS_len(&cipher_suites) > 0) { uint16_t cipher_id; if (!CBS_get_u16(&cipher_suites, &cipher_id)) { - return false; + return Ssl::CurveNIDVector{}; } // All tls_context_ share the same set of enabled ciphers, so we can just look at the base // context. if (tls_contexts_[0].isCipherEnabled(cipher_id, client_version)) { - return true; + return client_capabilities; } } - return false; + return Ssl::CurveNIDVector{}; } bool ServerContextImpl::isClientOcspCapable(const SSL_CLIENT_HELLO& ssl_client_hello) const { @@ -458,10 +466,11 @@ bool ServerContextImpl::isClientOcspCapable(const SSL_CLIENT_HELLO& ssl_client_h } std::pair -ServerContextImpl::findTlsContext(absl::string_view sni, bool client_ecdsa_capable, +ServerContextImpl::findTlsContext(absl::string_view sni, + const Ssl::CurveNIDVector& client_ecdsa_capabilities, bool client_ocsp_capable, bool* cert_matched_sni) { - return tls_certificate_selector_->findTlsContext(sni, client_ecdsa_capable, client_ocsp_capable, - cert_matched_sni); + return tls_certificate_selector_->findTlsContext(sni, client_ecdsa_capabilities, + client_ocsp_capable, cert_matched_sni); } enum ssl_select_cert_result_t diff --git a/source/common/tls/server_context_impl.h b/source/common/tls/server_context_impl.h index ed3c359a17f3..5d1db8b97aec 100644 --- a/source/common/tls/server_context_impl.h +++ b/source/common/tls/server_context_impl.h @@ -12,6 +12,7 @@ #include "envoy/network/transport_socket.h" #include "envoy/ssl/context.h" #include "envoy/ssl/context_config.h" +#include "envoy/ssl/handshaker.h" #include "envoy/ssl/private_key/private_key.h" #include "envoy/ssl/ssl_socket_extended_info.h" #include "envoy/stats/scope.h" @@ -35,10 +36,13 @@ #endif namespace Envoy { + namespace Extensions { namespace TransportSockets { namespace Tls { +Ssl::CurveNIDVector getClientCurveNIDSupported(CBS& cbs); + class ServerContextImpl : public ContextImpl, public Envoy::Ssl::ServerContext, public Envoy::Ssl::TlsCertificateSelectorContext { @@ -60,11 +64,11 @@ class ServerContextImpl : public ContextImpl, // Finds the best matching context. The returned context will have the same lifetime as // this ``ServerContextImpl``. - std::pair findTlsContext(absl::string_view sni, - bool client_ecdsa_capable, - bool client_ocsp_capable, - bool* cert_matched_sni); - bool isClientEcdsaCapable(const SSL_CLIENT_HELLO& ssl_client_hello) const; + std::pair + findTlsContext(absl::string_view sni, const Ssl::CurveNIDVector& client_ecdsa_capable, + bool client_ocsp_capable, bool* cert_matched_sni); + + Ssl::CurveNIDVector getClientEcdsaCapabilities(const SSL_CLIENT_HELLO& ssl_client_hello) const; bool isClientOcspCapable(const SSL_CLIENT_HELLO& ssl_client_hello) const; private: diff --git a/test/common/quic/envoy_quic_proof_source_test.cc b/test/common/quic/envoy_quic_proof_source_test.cc index c831f9b71334..beb9c50770d8 100644 --- a/test/common/quic/envoy_quic_proof_source_test.cc +++ b/test/common/quic/envoy_quic_proof_source_test.cc @@ -195,6 +195,7 @@ class EnvoyQuicProofSourceTest : public ::testing::Test { auto factory = Extensions::TransportSockets::Tls::TlsCertificateSelectorConfigFactoryImpl:: getDefaultTlsCertificateSelectorConfigFactory(); ASSERT_TRUE(factory); + ASSERT_EQ("envoy.tls.certificate_selectors.default", factory->name()); const ProtobufWkt::Any any; absl::Status creation_status = absl::OkStatus(); auto tls_certificate_selector_factory_cb = factory->createTlsCertificateSelectorFactory( diff --git a/test/common/tls/BUILD b/test/common/tls/BUILD index 69b1bc9e6074..1e354158cc8d 100644 --- a/test/common/tls/BUILD +++ b/test/common/tls/BUILD @@ -283,6 +283,14 @@ envoy_cc_test( ], ) +envoy_cc_test( + name = "server_context_impl_test", + srcs = ["server_context_impl_test.cc"], + deps = [ + "//source/common/tls:server_context_lib", + ], +) + envoy_cc_benchmark_binary( name = "tls_throughput_benchmark", srcs = ["tls_throughput_benchmark.cc"], diff --git a/test/common/tls/cert_selector/async_cert_selector.h b/test/common/tls/cert_selector/async_cert_selector.h index b525c32179d3..425f68bc64aa 100644 --- a/test/common/tls/cert_selector/async_cert_selector.h +++ b/test/common/tls/cert_selector/async_cert_selector.h @@ -29,8 +29,8 @@ class AsyncTlsCertificateSelector : public Ssl::TlsCertificateSelector, Ssl::CertificateSelectionCallbackPtr cb) override; // It's only for quic. - std::pair findTlsContext(absl::string_view, bool, - bool, bool*) override { + std::pair + findTlsContext(absl::string_view, const Ssl::CurveNIDVector&, bool, bool*) override { PANIC("unreachable"); }; diff --git a/test/common/tls/context_impl_test.cc b/test/common/tls/context_impl_test.cc index f1c4b926e1ca..1ad54a85b213 100644 --- a/test/common/tls/context_impl_test.cc +++ b/test/common/tls/context_impl_test.cc @@ -1412,8 +1412,8 @@ TEST_F(ClientContextConfigImplTest, P256EcdsaCert) { auto cleanup = cleanUpHelper(*context_or); } -// Validate that non-P256 ECDSA certs are rejected. -TEST_F(ClientContextConfigImplTest, NonP256EcdsaCert) { +// Validate that P384 ECDSA certs load. +TEST_F(ClientContextConfigImplTest, P384EcdsaCert) { envoy::extensions::transport_sockets::tls::v3::UpstreamTlsContext tls_context; const std::string tls_certificate_yaml = R"EOF( certificate_chain: @@ -1425,16 +1425,13 @@ TEST_F(ClientContextConfigImplTest, NonP256EcdsaCert) { *tls_context.mutable_common_tls_context()->add_tls_certificates()); auto client_context_config = *ClientContextConfigImpl::create(tls_context, factory_context_); Stats::IsolatedStoreImpl store; - EXPECT_THAT(manager_.createSslClientContext(*store.rootScope(), *client_context_config) - .status() - .message(), - testing::ContainsRegex( - "Failed to load certificate chain from .*selfsigned_ecdsa_p384_cert.pem, " - "only P-256 ECDSA certificates are supported")); + auto context_or = manager_.createSslClientContext(*store.rootScope(), *client_context_config); + EXPECT_TRUE(context_or.ok()); + auto cleanup = cleanUpHelper(*context_or); } -// Validate that non-P256 ECDSA certs are rejected loaded from `pkcs12`. -TEST_F(ClientContextConfigImplTest, NonP256EcdsaPkcs12) { +// Validate that P384 ECDSA certs are loaded from `pkcs12`. +TEST_F(ClientContextConfigImplTest, P384EcdsaPkcs12) { envoy::extensions::transport_sockets::tls::v3::UpstreamTlsContext tls_context; const std::string tls_certificate_yaml = R"EOF( pkcs12: @@ -1444,12 +1441,44 @@ TEST_F(ClientContextConfigImplTest, NonP256EcdsaPkcs12) { *tls_context.mutable_common_tls_context()->add_tls_certificates()); auto client_context_config = *ClientContextConfigImpl::create(tls_context, factory_context_); Stats::IsolatedStoreImpl store; +} + +TEST_F(ClientContextConfigImplTest, P521EcdsaCert) { + envoy::extensions::transport_sockets::tls::v3::UpstreamTlsContext tls_context; + const std::string tls_certificate_yaml = R"EOF( + certificate_chain: + filename: "{{ test_rundir }}/test/common/tls/test_data/selfsigned_ecdsa_p521_cert.pem" + private_key: + filename: "{{ test_rundir }}/test/common/tls/test_data/selfsigned_ecdsa_p521_key.pem" + )EOF"; + TestUtility::loadFromYaml(TestEnvironment::substitute(tls_certificate_yaml), + *tls_context.mutable_common_tls_context()->add_tls_certificates()); + auto client_context_config = *ClientContextConfigImpl::create(tls_context, factory_context_); + Stats::IsolatedStoreImpl store; + auto context_or = manager_.createSslClientContext(*store.rootScope(), *client_context_config); + EXPECT_TRUE(context_or.ok()); + auto cleanup = cleanUpHelper(*context_or); +} + +// Validate that a P-224 key will cause an error. +TEST_F(ClientContextConfigImplTest, UnsupportedCurveEcdsaCert) { + envoy::extensions::transport_sockets::tls::v3::UpstreamTlsContext tls_context; + const std::string tls_certificate_yaml = R"EOF( + certificate_chain: + filename: "{{ test_rundir }}/test/common/tls/test_data/selfsigned_secp224r1_cert.pem" + private_key: + filename: "{{ test_rundir }}/test/common/tls/test_data/selfsigned_secp224r1_key.pem" + )EOF"; + TestUtility::loadFromYaml(TestEnvironment::substitute(tls_certificate_yaml), + *tls_context.mutable_common_tls_context()->add_tls_certificates()); + auto client_context_config = *ClientContextConfigImpl::create(tls_context, factory_context_); + Stats::IsolatedStoreImpl store; EXPECT_THAT(manager_.createSslClientContext(*store.rootScope(), *client_context_config) .status() .message(), testing::ContainsRegex( - "Failed to load certificate chain from .*selfsigned_ecdsa_p384_certkey.p12, " - "only P-256 ECDSA certificates are supported")); + "Failed to load certificate chain from .*selfsigned_secp224r1_cert.pem, " + "only P-256, P-384 or P-521 ECDSA certificates are supported")); } // Multiple TLS certificates are not yet supported. diff --git a/test/common/tls/integration/ssl_integration_test.cc b/test/common/tls/integration/ssl_integration_test.cc index d2718ea31c06..6ff427ff4416 100644 --- a/test/common/tls/integration/ssl_integration_test.cc +++ b/test/common/tls/integration/ssl_integration_test.cc @@ -703,6 +703,59 @@ class SslCertficateIntegrationTest return options.setSigningAlgorithms({"ecdsa_secp256r1_sha256"}); } else { return options.setCipherSuites({"ECDHE-ECDSA-AES128-GCM-SHA256"}); + ; + } + } + + ClientSslTransportOptions ecdsaP384OnlyClientOptions() { + auto options = ClientSslTransportOptions(); + if (tls_version_ == envoy::extensions::transport_sockets::tls::v3::TlsParameters::TLSv1_3) { + return options.setSigningAlgorithms({"ecdsa_secp384r1_sha384", "rsa_pss_rsae_sha256"}); + } else { + return options + .setCipherSuites({"ECDHE-RSA-AES128-GCM-SHA256", "ECDHE-ECDSA-AES128-GCM-SHA256"}) + .setSigningAlgorithms({"rsa_pss_rsae_sha256", "ecdsa_secp384r1_sha384"}) + .setCurves({"P-384"}); + } + } + + ClientSslTransportOptions ecdsaP256P384OnlyClientOptions() { + auto options = ClientSslTransportOptions(); + if (tls_version_ == envoy::extensions::transport_sockets::tls::v3::TlsParameters::TLSv1_3) { + return options.setSigningAlgorithms( + {"ecdsa_secp256r1_sha256", "ecdsa_secp384r1_sha384", "rsa_pss_rsae_sha256"}); + } else { + return options + .setCipherSuites({"ECDHE-RSA-AES128-GCM-SHA256", "ECDHE-ECDSA-AES128-GCM-SHA256"}) + .setSigningAlgorithms( + {"rsa_pss_rsae_sha256", "ecdsa_secp256r1_sha256", "ecdsa_secp384r1_sha384"}) + .setCurves({"P-256", "P-384"}); + } + } + + ClientSslTransportOptions ecdsaP256P521OnlyClientOptions() { + auto options = ClientSslTransportOptions(); + if (tls_version_ == envoy::extensions::transport_sockets::tls::v3::TlsParameters::TLSv1_3) { + return options.setSigningAlgorithms( + {"ecdsa_secp256r1_sha256", "ecdsa_secp521r1_sha512", "rsa_pss_rsae_sha256"}); + } else { + return options + .setCipherSuites({"ECDHE-RSA-AES128-GCM-SHA256", "ECDHE-ECDSA-AES128-GCM-SHA256"}) + .setSigningAlgorithms( + {"rsa_pss_rsae_sha256", "ecdsa_secp256r1_sha256", "ecdsa_secp521r1_sha512"}) + .setCurves({"P-256", "P-521"}); + } + } + + ClientSslTransportOptions ecdsaAllCurvesClientOptions() { + auto options = ClientSslTransportOptions().setClientEcdsaCert(true); + if (tls_version_ == envoy::extensions::transport_sockets::tls::v3::TlsParameters::TLSv1_3) { + return options.setSigningAlgorithms({"ecdsa_secp256r1_sha256", "ecdsa_secp384r1_sha384", + "ecdsa_secp521r1_sha512", "rsa_pss_rsae_sha256"}); + } else { + return options + .setCipherSuites({"ECDHE-ECDSA-AES128-GCM-SHA256", "ECDHE-ECDSA-AES128-GCM-SHA256"}) + .setCurves({"P-256", "P-384", "P-521"}); } } @@ -879,6 +932,82 @@ TEST_P(SslCertficateIntegrationTest, ServerRsaEcdsaClientEcdsaOnly) { checkStats(); } +// Server has RSA and ECDSA P-256 certificates, client only supports +// P-384 curve. We fall back to RSA certificate. +TEST_P(SslCertficateIntegrationTest, ServerRsaServerEcdsaP256EcdsaClientEcdsaP384Only) { + server_rsa_cert_ = true; + server_ecdsa_cert_ = true; + // We have to set the server curves to allow for ECDH negotiation where client + // doesn't support P-256 + server_curves_.push_back("P-256"); + server_curves_.push_back("P-384"); + ConnectionCreationFunction creator = [&]() -> Network::ClientConnectionPtr { + return makeSslClientConnection(ecdsaP384OnlyClientOptions()); + }; + testRouterRequestAndResponseWithBody(1024, 512, false, false, &creator); + checkStats(); +} + +// Server has RSA and ECDSA P-384 certificates, client only supports +// and P-256 and P-521 curves. We fall back to RSA certificate. +TEST_P(SslCertficateIntegrationTest, ServerRsaServerEcdsaP384EcdsaClientEcdsaP256P521Only) { + server_rsa_cert_ = true; + server_ecdsa_cert_ = true; + server_ecdsa_cert_name_ = "server_ecdsa_p384"; + ConnectionCreationFunction creator = [&]() -> Network::ClientConnectionPtr { + return makeSslClientConnection(ecdsaP256P521OnlyClientOptions()); + }; + testRouterRequestAndResponseWithBody(1024, 512, false, false, &creator); + checkStats(); +} + +// Server has RSA and ECDSA P-256 certificates, client only supports +// and P-256 and P-384 curves. We fall back to RSA certificate. +TEST_P(SslCertficateIntegrationTest, ServerRsaServerEcdsaP521EcdsaClientEcdsaP256P384Only) { + server_rsa_cert_ = true; + server_ecdsa_cert_ = true; + server_ecdsa_cert_name_ = "server_ecdsa_p521"; + ConnectionCreationFunction creator = [&]() -> Network::ClientConnectionPtr { + return makeSslClientConnection(ecdsaP256P384OnlyClientOptions()); + }; + testRouterRequestAndResponseWithBody(1024, 512, false, false, &creator); + checkStats(); +} + +// Server has RSA and ECDSA P-384 certificates, client supports all curves. +// We use the ECDSA certificate. +TEST_P(SslCertficateIntegrationTest, ServerRsaServerEcdsaP384EcdsaClientAllCurves) { + server_rsa_cert_ = true; + server_ecdsa_cert_ = true; + server_ecdsa_cert_name_ = "server_ecdsa_p384"; + client_ecdsa_cert_ = true; + ConnectionCreationFunction creator = [&]() -> Network::ClientConnectionPtr { + return makeSslClientConnection(ecdsaAllCurvesClientOptions()); + }; + testRouterRequestAndResponseWithBody(1024, 512, false, false, &creator); + for (const Stats::CounterSharedPtr& counter : test_server_->counters()) { + // Useful for debugging when the test is failing. + if (counter->name().find("ssl") != std::string::npos) { + ENVOY_LOG_MISC(critical, "Found ssl metric: {}", counter->name()); + } + } + checkStats(); +} + +// Server has RSA and ECDSA P-521 certificates, client supports all curves. +// We use the ECDSA certificate. +TEST_P(SslCertficateIntegrationTest, ServerRsaServerEcdsaP521EcdsaClientAllCurves) { + server_rsa_cert_ = true; + server_ecdsa_cert_ = true; + server_ecdsa_cert_name_ = "server_ecdsa_p521"; + client_ecdsa_cert_ = true; + ConnectionCreationFunction creator = [&]() -> Network::ClientConnectionPtr { + return makeSslClientConnection(ecdsaAllCurvesClientOptions()); + }; + testRouterRequestAndResponseWithBody(1024, 512, false, false, &creator); + checkStats(); +} + // Server has an RSA certificate with an OCSP response works. TEST_P(SslCertficateIntegrationTest, ServerRsaOnlyOcspResponse) { server_rsa_cert_ = true; diff --git a/test/common/tls/integration/ssl_integration_test_base.cc b/test/common/tls/integration/ssl_integration_test_base.cc index 53ae8d35027b..c153bd4facfe 100644 --- a/test/common/tls/integration/ssl_integration_test_base.cc +++ b/test/common/tls/integration/ssl_integration_test_base.cc @@ -8,6 +8,7 @@ void SslIntegrationTestBase::initialize() { .setRsaCert(server_rsa_cert_) .setRsaCertOcspStaple(server_rsa_cert_ocsp_staple_) .setEcdsaCert(server_ecdsa_cert_) + .setEcdsaCertName(server_ecdsa_cert_name_) .setEcdsaCertOcspStaple(server_ecdsa_cert_ocsp_staple_) .setOcspStapleRequired(ocsp_staple_required_) .setPreferClientCiphers(prefer_client_ciphers_) diff --git a/test/common/tls/integration/ssl_integration_test_base.h b/test/common/tls/integration/ssl_integration_test_base.h index 4eb3fb99fb5f..d2bd7b45f87e 100644 --- a/test/common/tls/integration/ssl_integration_test_base.h +++ b/test/common/tls/integration/ssl_integration_test_base.h @@ -35,6 +35,7 @@ class SslIntegrationTestBase : public HttpIntegrationTest { bool server_rsa_cert_{true}; bool server_rsa_cert_ocsp_staple_{false}; bool server_ecdsa_cert_{false}; + std::string server_ecdsa_cert_name_{"server_ecdsa"}; bool server_ecdsa_cert_ocsp_staple_{false}; bool ocsp_staple_required_{false}; bool prefer_client_ciphers_{false}; diff --git a/test/common/tls/server_context_impl_test.cc b/test/common/tls/server_context_impl_test.cc new file mode 100644 index 000000000000..7a45e6428444 --- /dev/null +++ b/test/common/tls/server_context_impl_test.cc @@ -0,0 +1,21 @@ +#include "source/common/tls/server_context_impl.h" + +#include "gtest/gtest.h" + +namespace Envoy { +namespace Extensions { +namespace TransportSockets { +namespace Tls { +TEST(ServerContextImplTest, OneByteCBSParameterReturnsEmptyCurveNIDVector) { + // A one-byte CBS will result in `CBS_get_u16` returning false + // giving us coverage for the break in `getClientCurveNIDSupported`. + const uint8_t* data = reinterpret_cast("a"); + CBS cbs; + CBS_init(&cbs, data, 1); + Ssl::CurveNIDVector nullCbs = getClientCurveNIDSupported(cbs); + EXPECT_EQ(0, nullCbs.size()); +} +} // namespace Tls +} // namespace TransportSockets +} // namespace Extensions +} // namespace Envoy diff --git a/test/common/tls/test_data/README.md b/test/common/tls/test_data/README.md index 57c7b5a114d0..01f782e586a2 100644 --- a/test/common/tls/test_data/README.md +++ b/test/common/tls/test_data/README.md @@ -54,7 +54,10 @@ There are 15 identities: using the config *selfsigned_cert.cfg*. *selfsigned_ecdsa_p256_key.pem* is its private key. - **Self-signed ECDSA P-384**: The self-signed certificate *selfsigned_ecdsa_p384_cert.pem*, - using the config *selfsigned_cert.cfg*. *selfsigned_ecdsa_p256_key.pem* is + using the config *selfsigned_cert.cfg*. *selfsigned_ecdsa_p384_key.pem* is + its private key. +- **Self-signed ECDSA P-521**: The self-signed certificate *selfsigned_ecdsa_p521_cert.pem*, + using the config *selfsigned_cert.cfg*. *selfsigned_ecdsa_p521_key.pem* is its private key. - **Expired**: A self-signed, expired certificate *expired_cert.pem*, using the config *selfsigned_cert.cfg*. *expired_key.pem* is its private diff --git a/test/common/tls/test_data/certs.sh b/test/common/tls/test_data/certs.sh index 1150f94c9574..75a8898d304d 100755 --- a/test/common/tls/test_data/certs.sh +++ b/test/common/tls/test_data/certs.sh @@ -316,9 +316,21 @@ generate_ecdsa_key selfsigned_ecdsa_p384 secp384r1 generate_selfsigned_x509_cert selfsigned_ecdsa_p384 rm -f selfsigned_ecdsa_p384_cert.cfg +# Generate selfsigned_ecdsa_p521_cert.pem. +cp -f selfsigned_cert.cfg selfsigned_ecdsa_p521_cert.cfg +generate_ecdsa_key selfsigned_ecdsa_p521 secp521r1 +generate_selfsigned_x509_cert selfsigned_ecdsa_p521 +rm -f selfsigned_ecdsa_p521_cert.cfg + # Generate selfsigned_ecdsa_p384_certkey.p12 with no password. openssl pkcs12 -export -out selfsigned_ecdsa_p384_certkey.p12 -inkey selfsigned_ecdsa_p384_key.pem -in selfsigned_ecdsa_p384_cert.pem -keypbe NONE -certpbe NONE -nomaciter -passout pass: +# Generate selfsigned_secp224r1_cert.pem +cp -f selfsigned_cert.cfg selfsigned_secp224r1_cert.cfg +generate_ecdsa_key selfsigned_secp224r1 secp224r1 +generate_selfsigned_x509_cert selfsigned_secp224r1 +rm -f selfsigned_secp224r1_cert.cfg + # Generate long_validity_cert.pem as a self-signed, with expiry that exceeds 32bit time_t. cp -f selfsigned_cert.cfg long_validity_cert.cfg generate_rsa_key long_validity diff --git a/test/common/tls/test_data/selfsigned_ecdsa_p521_cert.pem b/test/common/tls/test_data/selfsigned_ecdsa_p521_cert.pem new file mode 100644 index 000000000000..88bd1b18a9e8 --- /dev/null +++ b/test/common/tls/test_data/selfsigned_ecdsa_p521_cert.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDHDCCAn2gAwIBAgIUfFEHcYA6qzTSMJKdKpDbr8j7lHgwCgYIKoZIzj0EAwIw +ejELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNh +biBGcmFuY2lzY28xDTALBgNVBAoMBEx5ZnQxGTAXBgNVBAsMEEx5ZnQgRW5naW5l +ZXJpbmcxFDASBgNVBAMMC1Rlc3QgU2VydmVyMB4XDTI0MDkyNzE3NDI1OFoXDTI2 +MDkyNzE3NDI1OFowejELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWEx +FjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xDTALBgNVBAoMBEx5ZnQxGTAXBgNVBAsM +EEx5ZnQgRW5naW5lZXJpbmcxFDASBgNVBAMMC1Rlc3QgU2VydmVyMIGbMBAGByqG +SM49AgEGBSuBBAAjA4GGAAQAWMQGu6Rr2C1Ydc015kP2EwOz/xLh7yikFk8edJyc +WA9WwyXPGWFtpYl4LAlFH/kIHDnOsYnM/DJngqF1fOb8sngB1dEL+93YRvINvjmG +iBQ9qHg+/kEJLW5NOx53Dc1a4oia3Ey7b2/Gkm8A+CzN2CLbMzLHTesfgSSIP7D7 +YNWlNAujgZ0wgZowDAYDVR0TAQH/BAIwADALBgNVHQ8EBAMCBeAwHQYDVR0lBBYw +FAYIKwYBBQUHAwIGCCsGAQUFBwMBMB4GA1UdEQQXMBWCE3NlcnZlcjEuZXhhbXBs +ZS5jb20wHQYDVR0OBBYEFLwTH64c7Glg6D61fFVfM+DHhYq7MB8GA1UdIwQYMBaA +FLwTH64c7Glg6D61fFVfM+DHhYq7MAoGCCqGSM49BAMCA4GMADCBiAJCAfuwJBMT +L9CAMp2CVxgkmNk19Ku6idjQ59mXB/UOdpDU4SSvhlZBNgXZNHehe1syTa35clGr +OV8T5KE80Yui8C2ZAkIBooI1HiRQ+Vrzs5WyJ/F6pVLqT9iIw/p0mIhoCtfTUsi4 +RWQXJfm3OWqnYHhHba5riEQsUoTJV9bb4RdAUQrDlJc= +-----END CERTIFICATE----- diff --git a/test/common/tls/test_data/selfsigned_ecdsa_p521_cert_info.h b/test/common/tls/test_data/selfsigned_ecdsa_p521_cert_info.h new file mode 100644 index 000000000000..88afa94779c5 --- /dev/null +++ b/test/common/tls/test_data/selfsigned_ecdsa_p521_cert_info.h @@ -0,0 +1,14 @@ +#pragma once + +// NOLINT(namespace-envoy) +// This file is auto-generated by certs.sh. +constexpr char TEST_SELFSIGNED_ECDSA_P521_CERT_256_HASH[] = + "d893db88874c259f607cdd819a0b12a4852898ae7f80f9cf67c0f244e67f5b0d"; +constexpr char TEST_SELFSIGNED_ECDSA_P521_CERT_1_HASH[] = + "6f60b7fa1ee64a9dcf90a34f851bd39281b653a0"; +constexpr char TEST_SELFSIGNED_ECDSA_P521_CERT_SPKI[] = + "WWdJYW4tEaF/LBVKVcQSNO1vwerCpB2p7dw6GPksFlE="; +constexpr char TEST_SELFSIGNED_ECDSA_P521_CERT_SERIAL[] = + "7c510771803aab34d230929d2a90dbafc8fb9478"; +constexpr char TEST_SELFSIGNED_ECDSA_P521_CERT_NOT_BEFORE[] = "Sep 27 17:42:58 2024 GMT"; +constexpr char TEST_SELFSIGNED_ECDSA_P521_CERT_NOT_AFTER[] = "Sep 27 17:42:58 2026 GMT"; diff --git a/test/common/tls/test_data/selfsigned_ecdsa_p521_key.pem b/test/common/tls/test_data/selfsigned_ecdsa_p521_key.pem new file mode 100644 index 000000000000..5938fd0b086b --- /dev/null +++ b/test/common/tls/test_data/selfsigned_ecdsa_p521_key.pem @@ -0,0 +1,10 @@ +-----BEGIN EC PARAMETERS----- +BgUrgQQAIw== +-----END EC PARAMETERS----- +-----BEGIN EC PRIVATE KEY----- +MIHcAgEBBEIBvfR0YP6beGkBRT+6pwru4XdQYiVp6wHgYT4kVlmrJTk9QYRFtkLs +Tc+jEB6y7akyGuaAcwj1ZZe06YE4t8eyXCqgBwYFK4EEACOhgYkDgYYABABYxAa7 +pGvYLVh1zTXmQ/YTA7P/EuHvKKQWTx50nJxYD1bDJc8ZYW2liXgsCUUf+QgcOc6x +icz8MmeCoXV85vyyeAHV0Qv73dhG8g2+OYaIFD2oeD7+QQktbk07HncNzVriiJrc +TLtvb8aSbwD4LM3YItszMsdN6x+BJIg/sPtg1aU0Cw== +-----END EC PRIVATE KEY----- diff --git a/test/common/tls/test_data/selfsigned_secp224r1_cert.pem b/test/common/tls/test_data/selfsigned_secp224r1_cert.pem new file mode 100644 index 000000000000..a4fb9e80f0e6 --- /dev/null +++ b/test/common/tls/test_data/selfsigned_secp224r1_cert.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICgDCCAi+gAwIBAgIUWG9qf/85uxL73Ag8DrE4Vu7qz8swCgYIKoZIzj0EAwIw +ejELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNh +biBGcmFuY2lzY28xDTALBgNVBAoMBEx5ZnQxGTAXBgNVBAsMEEx5ZnQgRW5naW5l +ZXJpbmcxFDASBgNVBAMMC1Rlc3QgU2VydmVyMB4XDTI0MTAxMTE2NTQ1NloXDTI2 +MTAxMTE2NTQ1NlowejELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWEx +FjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xDTALBgNVBAoMBEx5ZnQxGTAXBgNVBAsM +EEx5ZnQgRW5naW5lZXJpbmcxFDASBgNVBAMMC1Rlc3QgU2VydmVyME4wEAYHKoZI +zj0CAQYFK4EEACEDOgAEydINy1wMkX+iUrBhiz+TOzg8LlWNOKWonz6z4LcXSPyu +QB+8+Pm3KP6ii+v+RURoYciXc/nzLaijgZ0wgZowDAYDVR0TAQH/BAIwADALBgNV +HQ8EBAMCBeAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMB4GA1UdEQQX +MBWCE3NlcnZlcjEuZXhhbXBsZS5jb20wHQYDVR0OBBYEFI/efwpZyM58ItUFvoQH +gALWDqVKMB8GA1UdIwQYMBaAFI/efwpZyM58ItUFvoQHgALWDqVKMAoGCCqGSM49 +BAMCAz8AMDwCHGWm6WCwjN/KEGPIWq9yGU+L8wANyV2xi2/TDvsCHErFlQ1Y0jMR +G1sY3TdUhOBHZUe2nKvP2qYNpBs= +-----END CERTIFICATE----- diff --git a/test/common/tls/test_data/selfsigned_secp224r1_cert_info.h b/test/common/tls/test_data/selfsigned_secp224r1_cert_info.h new file mode 100644 index 000000000000..af786cc4d497 --- /dev/null +++ b/test/common/tls/test_data/selfsigned_secp224r1_cert_info.h @@ -0,0 +1,12 @@ +#pragma once + +// NOLINT(namespace-envoy) +// This file is auto-generated by certs.sh. +constexpr char TEST_SELFSIGNED_SECP224R1_CERT_256_HASH[] = + "9485a4046c5841c99f43e5597ebe92aa393c16156a4e7f001cf8a8fa2afbe76c"; +constexpr char TEST_SELFSIGNED_SECP224R1_CERT_1_HASH[] = "ab2bdb606f51666c9937e6e7bb93d832b929f085"; +constexpr char TEST_SELFSIGNED_SECP224R1_CERT_SPKI[] = + "03hDOkVOrYNHQLk0emTI7a+qW2itJkpvaGcwiuQhYMw="; +constexpr char TEST_SELFSIGNED_SECP224R1_CERT_SERIAL[] = "586f6a7fff39bb12fbdc083c0eb13856eeeacfcb"; +constexpr char TEST_SELFSIGNED_SECP224R1_CERT_NOT_BEFORE[] = "Oct 11 16:54:56 2024 GMT"; +constexpr char TEST_SELFSIGNED_SECP224R1_CERT_NOT_AFTER[] = "Oct 11 16:54:56 2026 GMT"; diff --git a/test/common/tls/test_data/selfsigned_secp224r1_key.pem b/test/common/tls/test_data/selfsigned_secp224r1_key.pem new file mode 100644 index 000000000000..232a1d028f47 --- /dev/null +++ b/test/common/tls/test_data/selfsigned_secp224r1_key.pem @@ -0,0 +1,8 @@ +-----BEGIN EC PARAMETERS----- +BgUrgQQAIQ== +-----END EC PARAMETERS----- +-----BEGIN EC PRIVATE KEY----- +MGgCAQEEHIwwI7H3kg94rkdqyT4a0KwGMxuImz8kcdlVgVGgBwYFK4EEACGhPAM6 +AATJ0g3LXAyRf6JSsGGLP5M7ODwuVY04paifPrPgtxdI/K5AH7z4+bco/qKL6/5F +RGhhyJdz+fMtqA== +-----END EC PRIVATE KEY----- diff --git a/test/common/tls/tls_certificate_selector_test.cc b/test/common/tls/tls_certificate_selector_test.cc index bc78f264f7e4..8dd36697c900 100644 --- a/test/common/tls/tls_certificate_selector_test.cc +++ b/test/common/tls/tls_certificate_selector_test.cc @@ -107,8 +107,8 @@ class TestTlsCertificateSelector : public virtual Ssl::TlsCertificateSelector { return {mod_, nullptr, false}; }; - std::pair findTlsContext(absl::string_view, bool, - bool, bool*) override { + std::pair + findTlsContext(absl::string_view, const Ssl::CurveNIDVector&, bool, bool*) override { PANIC("unreachable"); }; diff --git a/test/config/integration/certs/certs.sh b/test/config/integration/certs/certs.sh index 9fa7534f0f4d..daf9b43e4091 100755 --- a/test/config/integration/certs/certs.sh +++ b/test/config/integration/certs/certs.sh @@ -22,9 +22,9 @@ generate_rsa_key() { openssl genrsa -out "${1}key.pem" 2048 } -# $1= +# $1= $2= generate_ecdsa_key() { - openssl ecparam -name secp256r1 -genkey -out "${1}key.pem" + openssl ecparam -name "${2}" -genkey -out "${1}key.pem" } # $1= $2= $3=[days] @@ -92,12 +92,24 @@ generate_info_header server generate_rsa_key server2 ca generate_x509_cert server2 ca generate_info_header server2 -# Generate ECDSA cert for the server. +# Generate ECDSA P-256 cert for the server. cp -f servercert.cfg server_ecdsacert.cfg -generate_ecdsa_key server_ecdsa ca +generate_ecdsa_key server_ecdsa secp256r1 generate_x509_cert server_ecdsa ca generate_ocsp_response server_ecdsa ca rm -f server_ecdsacert.cfg +# Generate ECDSA P-384 cert for the server. +cp -f servercert.cfg server_ecdsa_p384cert.cfg +generate_ecdsa_key server_ecdsa_p384 secp384r1 +generate_x509_cert server_ecdsa_p384 ca +generate_ocsp_response server_ecdsa_p384 ca +rm -f server_ecdsa_p384cert.cfg +# Generate ECDSA P-521 cert for the server. +cp -f servercert.cfg server_ecdsa_p521cert.cfg +generate_ecdsa_key server_ecdsa_p521 secp521r1 +generate_x509_cert server_ecdsa_p521 ca +generate_ocsp_response server_ecdsa_p521 ca +rm -f server_ecdsa_p521cert.cfg # Generate cert for the client. generate_rsa_key client generate_x509_cert client ca @@ -106,7 +118,7 @@ generate_rsa_key client2 ca generate_x509_cert client2 intermediate_ca_2 # Generate ECDSA cert for the client. cp -f clientcert.cfg client_ecdsacert.cfg -generate_ecdsa_key client_ecdsa ca +generate_ecdsa_key client_ecdsa secp256r1 generate_x509_cert client_ecdsa ca rm -f client_ecdsacert.cfg diff --git a/test/config/integration/certs/server_ecdsa_ocsp_resp.der b/test/config/integration/certs/server_ecdsa_ocsp_resp.der index 1fa146ca5652..f49fcf12da91 100644 Binary files a/test/config/integration/certs/server_ecdsa_ocsp_resp.der and b/test/config/integration/certs/server_ecdsa_ocsp_resp.der differ diff --git a/test/config/integration/certs/server_ecdsa_p384_ocsp_resp.der b/test/config/integration/certs/server_ecdsa_p384_ocsp_resp.der new file mode 100644 index 000000000000..4b991e47a5bf Binary files /dev/null and b/test/config/integration/certs/server_ecdsa_p384_ocsp_resp.der differ diff --git a/test/config/integration/certs/server_ecdsa_p384cert.pem b/test/config/integration/certs/server_ecdsa_p384cert.pem new file mode 100644 index 000000000000..58eb5422bb0e --- /dev/null +++ b/test/config/integration/certs/server_ecdsa_p384cert.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID1zCCAr+gAwIBAgIUY0ZFQRbKvRiOlg1zCSg1Y/HmqW8wDQYJKoZIhvcNAQEL +BQAwdjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM +DVNhbiBGcmFuY2lzY28xDTALBgNVBAoMBEx5ZnQxGTAXBgNVBAsMEEx5ZnQgRW5n +aW5lZXJpbmcxEDAOBgNVBAMMB1Rlc3QgQ0EwHhcNMjQxMDA5MjAyNTA1WhcNMjYx +MDA5MjAyNTA1WjCBpjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWEx +FjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xDTALBgNVBAoMBEx5ZnQxGTAXBgNVBAsM +EEx5ZnQgRW5naW5lZXJpbmcxGjAYBgNVBAMMEVRlc3QgQmFja2VuZCBUZWFtMSQw +IgYJKoZIhvcNAQkBFhViYWNrZW5kLXRlYW1AbHlmdC5jb20wdjAQBgcqhkjOPQIB +BgUrgQQAIgNiAAQVmVjUOspBdukEYcbuQrI3hwkpqbX6UFDGQUzKGTeWDFZyDVXS +qU+5QIFnZUVsguVfh6lDD8y9KEJuSH0N5QZJweIIe/6Qqd8lrpDCZigcWHpUh8ty +tJRN1YO6YvNXsw2jgdkwgdYwDAYDVR0TAQH/BAIwADALBgNVHQ8EBAMCBeAwHQYD +VR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMFoGA1UdEQRTMFGGHnNwaWZmZTov +L2x5ZnQuY29tL2JhY2tlbmQtdGVhbYYXaHR0cDovL2JhY2tlbmQubHlmdC5jb22C +CGx5ZnQuY29tggx3d3cubHlmdC5jb20wHQYDVR0OBBYEFPXR29l75CezAaahDeo5 +luPxj3MRMB8GA1UdIwQYMBaAFBn+c0Qg6qbDyfGRTNk1jzuKuSOAMA0GCSqGSIb3 +DQEBCwUAA4IBAQBeKl1b7Ni8fSbzvPMexs6GF4iwYLEEfIhnFxof74xCMF37R2S9 +4gKyUmsukByz2KxUk17A3Z7JisuG4bHyqATXEWpt1WtqWpXMQJg2EICOfWgiT3+J +kpaCbuq7JkciTxjCzLK8t5emJhn5Vc3isHT2ZBmVtGLSigDERqclS8SRK6cEtJc2 +zXdLKUU5hrD1GL5dHxd9/nwTEkJaSueQ3lnJwnk0ls6hD3ZHREKSmCmLiM/UCdSM +DtXzVJ5tIUM3dUsY7hCU2hFlFB6AyyRO+jN7vQVVtmstALjyWEou09XiPyPLFx9/ +2L2QOU2kgB76wIrX/rwjJ8LI9ZWCNAzBCrkz +-----END CERTIFICATE----- diff --git a/test/config/integration/certs/server_ecdsa_p384cert_hash.h b/test/config/integration/certs/server_ecdsa_p384cert_hash.h new file mode 100644 index 000000000000..4e8b602a5465 --- /dev/null +++ b/test/config/integration/certs/server_ecdsa_p384cert_hash.h @@ -0,0 +1,6 @@ +#pragma once + +// NOLINT(namespace-envoy) +constexpr char TEST_SERVER_ECDSA_P384_CERT_HASH[] = + "02:65:B8:5E:38:43:46:F2:6B:AA:B1:20:F9:7E:5B:8B:F1:3C:31:2D:3C:E0:CE:19:0C:45:A1:16:BC:77:89:" + "B3"; diff --git a/test/config/integration/certs/server_ecdsa_p384key.pem b/test/config/integration/certs/server_ecdsa_p384key.pem new file mode 100644 index 000000000000..a1911995f552 --- /dev/null +++ b/test/config/integration/certs/server_ecdsa_p384key.pem @@ -0,0 +1,9 @@ +-----BEGIN EC PARAMETERS----- +BgUrgQQAIg== +-----END EC PARAMETERS----- +-----BEGIN EC PRIVATE KEY----- +MIGkAgEBBDBNf8JQP8beK5egk/bWzR8CwiA7zsPQpHtOlVHDIr6J8WRix7YqKDil +dGHyRR0vVZygBwYFK4EEACKhZANiAAQVmVjUOspBdukEYcbuQrI3hwkpqbX6UFDG +QUzKGTeWDFZyDVXSqU+5QIFnZUVsguVfh6lDD8y9KEJuSH0N5QZJweIIe/6Qqd8l +rpDCZigcWHpUh8tytJRN1YO6YvNXsw0= +-----END EC PRIVATE KEY----- diff --git a/test/config/integration/certs/server_ecdsa_p521_ocsp_resp.der b/test/config/integration/certs/server_ecdsa_p521_ocsp_resp.der new file mode 100644 index 000000000000..116a8f5bbafd Binary files /dev/null and b/test/config/integration/certs/server_ecdsa_p521_ocsp_resp.der differ diff --git a/test/config/integration/certs/server_ecdsa_p521cert.pem b/test/config/integration/certs/server_ecdsa_p521cert.pem new file mode 100644 index 000000000000..e6f982bcdcd0 --- /dev/null +++ b/test/config/integration/certs/server_ecdsa_p521cert.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIID/TCCAuWgAwIBAgIUY0ZFQRbKvRiOlg1zCSg1Y/HmqXAwDQYJKoZIhvcNAQEL +BQAwdjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM +DVNhbiBGcmFuY2lzY28xDTALBgNVBAoMBEx5ZnQxGTAXBgNVBAsMEEx5ZnQgRW5n +aW5lZXJpbmcxEDAOBgNVBAMMB1Rlc3QgQ0EwHhcNMjQxMDA5MjAyNTA1WhcNMjYx +MDA5MjAyNTA1WjCBpjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWEx +FjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xDTALBgNVBAoMBEx5ZnQxGTAXBgNVBAsM +EEx5ZnQgRW5naW5lZXJpbmcxGjAYBgNVBAMMEVRlc3QgQmFja2VuZCBUZWFtMSQw +IgYJKoZIhvcNAQkBFhViYWNrZW5kLXRlYW1AbHlmdC5jb20wgZswEAYHKoZIzj0C +AQYFK4EEACMDgYYABAHrn8Egg2vwIhSfU9A+7rzJMPfng4fRABFbjCmU7+Qh+zYz +uOO2nR9ROVgE48+srCac/9GXT/U5UthO2gLWXZm2JwA63OU9p5QrReTuNKpJyHUo +dnBOFU4zyQUAo0hLc50IDZttC85xbDPuDicpIfssflR79SYfGJXR6WFr5Szw+I9v +A6OB2TCB1jAMBgNVHRMBAf8EAjAAMAsGA1UdDwQEAwIF4DAdBgNVHSUEFjAUBggr +BgEFBQcDAgYIKwYBBQUHAwEwWgYDVR0RBFMwUYYec3BpZmZlOi8vbHlmdC5jb20v +YmFja2VuZC10ZWFthhdodHRwOi8vYmFja2VuZC5seWZ0LmNvbYIIbHlmdC5jb22C +DHd3dy5seWZ0LmNvbTAdBgNVHQ4EFgQUoDKSCtS1Fbt6NkcXOIGbl0OLYk0wHwYD +VR0jBBgwFoAUGf5zRCDqpsPJ8ZFM2TWPO4q5I4AwDQYJKoZIhvcNAQELBQADggEB +ADJ73Kl3dOUKXiggg479WtUITpaZHK19FjlPpBpVxX7gdFmrA+Ekij1PCBRwcReF +4Y2UxFXNYnMNa/lB6ObTONvLTZkL5NOa5RQJ2PkIop6Xh1vMwWuDI+r1NfOk1fiH +1pFpHoZWdKgk+yYhx2QRAEL9GEoDzwr6qOlSbhgluyheqMo4X3oC+WDljYSU6WvB +Dwnej4NOCYkb7P1GoV0p0FExiYltBbeY5AQ3Ckwg+URv24jOLcX2csGOcRUKeUQS +HvfEqRWFLfOYvHbCT+gt9XfXNHMqCegtPB9d2EtQpQGcFXDiKtm/NdOzFccsPLWz +qU+wrTKKdccqNGZPWsCTKCg= +-----END CERTIFICATE----- diff --git a/test/config/integration/certs/server_ecdsa_p521cert_hash.h b/test/config/integration/certs/server_ecdsa_p521cert_hash.h new file mode 100644 index 000000000000..1d468ffc1a85 --- /dev/null +++ b/test/config/integration/certs/server_ecdsa_p521cert_hash.h @@ -0,0 +1,6 @@ +#pragma once + +// NOLINT(namespace-envoy) +constexpr char TEST_SERVER_ECDSA_P521_CERT_HASH[] = + "9F:3F:C3:0E:44:66:68:1A:69:44:E2:51:07:8C:66:5F:68:BD:21:7A:14:D6:2E:E8:0E:67:0E:4B:FE:8F:D0:" + "49"; diff --git a/test/config/integration/certs/server_ecdsa_p521key.pem b/test/config/integration/certs/server_ecdsa_p521key.pem new file mode 100644 index 000000000000..9711af7d0ccd --- /dev/null +++ b/test/config/integration/certs/server_ecdsa_p521key.pem @@ -0,0 +1,10 @@ +-----BEGIN EC PARAMETERS----- +BgUrgQQAIw== +-----END EC PARAMETERS----- +-----BEGIN EC PRIVATE KEY----- +MIHcAgEBBEIBAODJ5t2rORe2FOL4P0TU62ZF0meN+3+yYhDaHuThNDajHyu1VemT +Irz7emVfIuf2NrMqQx4DU1KSeJ/8NE1B2yugBwYFK4EEACOhgYkDgYYABAHrn8Eg +g2vwIhSfU9A+7rzJMPfng4fRABFbjCmU7+Qh+zYzuOO2nR9ROVgE48+srCac/9GX +T/U5UthO2gLWXZm2JwA63OU9p5QrReTuNKpJyHUodnBOFU4zyQUAo0hLc50IDZtt +C85xbDPuDicpIfssflR79SYfGJXR6WFr5Szw+I9vAw== +-----END EC PRIVATE KEY----- diff --git a/test/config/integration/certs/server_ecdsacert.pem b/test/config/integration/certs/server_ecdsacert.pem index b90bb2a6811a..d45e46a9154a 100644 --- a/test/config/integration/certs/server_ecdsacert.pem +++ b/test/config/integration/certs/server_ecdsacert.pem @@ -1,22 +1,22 @@ -----BEGIN CERTIFICATE----- -MIIDujCCAqKgAwIBAgIUQRkh3sY/JN5+tu5NX3Tbyx0Y8mEwDQYJKoZIhvcNAQEL +MIIDujCCAqKgAwIBAgIUY0ZFQRbKvRiOlg1zCSg1Y/HmqW4wDQYJKoZIhvcNAQEL BQAwdjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM DVNhbiBGcmFuY2lzY28xDTALBgNVBAoMBEx5ZnQxGTAXBgNVBAsMEEx5ZnQgRW5n -aW5lZXJpbmcxEDAOBgNVBAMMB1Rlc3QgQ0EwHhcNMjQwNDA4MTA0MjUzWhcNMjYw -NDA4MTA0MjUzWjCBpjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWEx +aW5lZXJpbmcxEDAOBgNVBAMMB1Rlc3QgQ0EwHhcNMjQxMDA5MjAyNTA1WhcNMjYx +MDA5MjAyNTA1WjCBpjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWEx FjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xDTALBgNVBAoMBEx5ZnQxGTAXBgNVBAsM EEx5ZnQgRW5naW5lZXJpbmcxGjAYBgNVBAMMEVRlc3QgQmFja2VuZCBUZWFtMSQw IgYJKoZIhvcNAQkBFhViYWNrZW5kLXRlYW1AbHlmdC5jb20wWTATBgcqhkjOPQIB -BggqhkjOPQMBBwNCAASZAJu8tonSTQar0CFAVoZAE+xzlTVQ0dZBy1z4gpYjdHXD -pP+iYTSAxEkYQ/cNPEgWmOHxlsGi9lU4nC2VaR4do4HZMIHWMAwGA1UdEwEB/wQC +BggqhkjOPQMBBwNCAAQnOGmNnqJFlMJ1BO3IG68PnczdKmX30Mb443IzEXlEDFfZ +B8b7YW/ZHcEta9FrxsRJB2rZjHOePhvafcCFfNoao4HZMIHWMAwGA1UdEwEB/wQC MAAwCwYDVR0PBAQDAgXgMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATBa BgNVHREEUzBRhh5zcGlmZmU6Ly9seWZ0LmNvbS9iYWNrZW5kLXRlYW2GF2h0dHA6 Ly9iYWNrZW5kLmx5ZnQuY29tgghseWZ0LmNvbYIMd3d3Lmx5ZnQuY29tMB0GA1Ud -DgQWBBQ17aPI8F2y8t3/EU0fhApQBvXB0jAfBgNVHSMEGDAWgBQZ/nNEIOqmw8nx -kUzZNY87irkjgDANBgkqhkiG9w0BAQsFAAOCAQEAUmYVxNXhTaxGxXLAOAJfYxoA -JlbuCN7WynHHXRgijKoHCwQIKtHHUdcGXlHroc+1bR/O2T7HVCTclJtshepO1pGb -K1hu2DR0IaXOBom7nxOBBNqDhNDGf2T6ebe0b3WoUGuCDy7kVtoB1TbstNruefov -gc8MyF27/R7Cux/rifzI70h4hrTQG2OOmRXzVHuP/VtDAUYeXyIHZQxHvJy3Q46G -LuOt49A+9JrrlCvsi5d5BzzmNUNXURLHpON3U2ZmREhOOXEsSqirfAWVlTCWW9jR -ORJBtnmx0p6wiH13uWzf6RD+Q18dmDIjN2JNCpLKVNDG5Vw2H8LP3UfFQp/QPQ== +DgQWBBRVmyinHuizVE9eaHQxFM7sfGIDjDAfBgNVHSMEGDAWgBQZ/nNEIOqmw8nx +kUzZNY87irkjgDANBgkqhkiG9w0BAQsFAAOCAQEAlFfvhCP+NPYJnWoRuByLv5i1 +b4YnmJtk831miyPZinimDRRbRAQ8nEMwrbed0jSsi+lILiwPIBc8o5mjlxDbTxth +eECjdAWjrUg1MoEAu6+SGOqxhrLByJoClMYGQizOQrwiBdnQ2eSXeEFqQVR07QOD ++JxS0R1nr8sRSjj/Nl3STQ4Pz9WOX+iFDpbvFI0bmhajEqnKnyZDMe3FLqFxThM7 +zs8UhzjhcPkMu8REqJcRYnokf0JHSuv7O+fp7eJBrFosRYcReK0srJY/B0hZQpjI +Fj5oI4o2DyblzI5tvVrcmSd5XQZ+cjchU4nAaE1t5YSj9JZzsmrrmYGJv4m6VA== -----END CERTIFICATE----- diff --git a/test/config/integration/certs/server_ecdsacert_hash.h b/test/config/integration/certs/server_ecdsacert_hash.h index 6c7a2ed96ee7..d73271ca4827 100644 --- a/test/config/integration/certs/server_ecdsacert_hash.h +++ b/test/config/integration/certs/server_ecdsacert_hash.h @@ -1,5 +1,5 @@ #pragma once // NOLINT(namespace-envoy) -constexpr char TEST_SERVER_ECDSA_CERT_HASH[] = "DD:95:84:89:9D:51:BD:93:EC:EC:B0:AA:B1:DC:8A:3C:5C:" - "21:8C:D5:2D:F0:49:94:1F:52:60:2D:8B:7F:0E:10"; +constexpr char TEST_SERVER_ECDSA_CERT_HASH[] = "8C:A4:3B:F4:D2:E1:95:26:F8:30:39:72:54:B6:72:5B:B4:" + "73:4F:69:82:11:97:D5:A8:94:D3:F1:75:57:C5:B0"; diff --git a/test/config/integration/certs/server_ecdsakey.pem b/test/config/integration/certs/server_ecdsakey.pem index 3eee0f2bdb3b..d80971cdbb6f 100644 --- a/test/config/integration/certs/server_ecdsakey.pem +++ b/test/config/integration/certs/server_ecdsakey.pem @@ -2,7 +2,7 @@ BggqhkjOPQMBBw== -----END EC PARAMETERS----- -----BEGIN EC PRIVATE KEY----- -MHcCAQEEIHP5Jy9x/fs0IGKT5cDtDI7Yu2cbVaq/xQoQnDAp8voXoAoGCCqGSM49 -AwEHoUQDQgAEmQCbvLaJ0k0Gq9AhQFaGQBPsc5U1UNHWQctc+IKWI3R1w6T/omE0 -gMRJGEP3DTxIFpjh8ZbBovZVOJwtlWkeHQ== +MHcCAQEEIIdXxuTr8uKo+eIbMIBKCzoBcCxJptlxJBQ4RdQC+hqXoAoGCCqGSM49 +AwEHoUQDQgAEJzhpjZ6iRZTCdQTtyBuvD53M3Spl99DG+ONyMxF5RAxX2QfG+2Fv +2R3BLWvRa8bESQdq2Yxznj4b2n3AhXzaGg== -----END EC PRIVATE KEY----- diff --git a/test/config/utility.cc b/test/config/utility.cc index 668d4f290882..c982d5ce6a1c 100644 --- a/test/config/utility.cc +++ b/test/config/utility.cc @@ -1523,13 +1523,13 @@ void ConfigHelper::initializeTls( } if (options.ecdsa_cert_) { auto* tls_certificate = common_tls_context.add_tls_certificates(); - tls_certificate->mutable_certificate_chain()->set_filename( - TestEnvironment::runfilesPath("test/config/integration/certs/server_ecdsacert.pem")); - tls_certificate->mutable_private_key()->set_filename( - TestEnvironment::runfilesPath("test/config/integration/certs/server_ecdsakey.pem")); + tls_certificate->mutable_certificate_chain()->set_filename(TestEnvironment::runfilesPath( + "test/config/integration/certs/" + options.ecdsa_cert_name_ + "cert.pem")); + tls_certificate->mutable_private_key()->set_filename(TestEnvironment::runfilesPath( + "test/config/integration/certs/" + options.ecdsa_cert_name_ + "key.pem")); if (options.ecdsa_cert_ocsp_staple_) { tls_certificate->mutable_ocsp_staple()->set_filename(TestEnvironment::runfilesPath( - "test/config/integration/certs/server_ecdsa_ocsp_resp.der")); + "test/config/integration/certs/" + options.ecdsa_cert_name_ + "_ocsp_resp.der")); } } diff --git a/test/config/utility.h b/test/config/utility.h index 9410d2e84ec7..b808e7c8ddc4 100644 --- a/test/config/utility.h +++ b/test/config/utility.h @@ -58,6 +58,11 @@ class ConfigHelper { return *this; } + ServerSslOptions& setEcdsaCertName(const std::string& ecdsa_cert_name) { + ecdsa_cert_name_ = ecdsa_cert_name; + return *this; + } + ServerSslOptions& setEcdsaCertOcspStaple(bool ecdsa_cert_ocsp_staple) { ecdsa_cert_ocsp_staple_ = ecdsa_cert_ocsp_staple; return *this; @@ -144,6 +149,7 @@ class ConfigHelper { bool rsa_cert_{true}; bool rsa_cert_ocsp_staple_{true}; bool ecdsa_cert_{false}; + std::string ecdsa_cert_name_{"server_ecdsa"}; bool ecdsa_cert_ocsp_staple_{false}; bool prefer_client_ciphers_{false}; bool ocsp_staple_required_{false}; diff --git a/test/integration/ssl_utility.cc b/test/integration/ssl_utility.cc index 2ff475cb56b0..082edc9e0f78 100644 --- a/test/integration/ssl_utility.cc +++ b/test/integration/ssl_utility.cc @@ -92,6 +92,9 @@ void initializeUpstreamTlsContextConfig( for (const std::string& algorithm : options.sigalgs_) { common_context->mutable_tls_params()->add_signature_algorithms(algorithm); } + for (const std::string& curve : options.curves_) { + common_context->mutable_tls_params()->add_ecdh_curves(curve); + } if (!options.sni_.empty()) { tls_context.set_sni(options.sni_); } diff --git a/test/integration/ssl_utility.h b/test/integration/ssl_utility.h index e6ebdd2b55d9..cb09c25221c5 100644 --- a/test/integration/ssl_utility.h +++ b/test/integration/ssl_utility.h @@ -38,6 +38,11 @@ struct ClientSslTransportOptions { return *this; } + ClientSslTransportOptions& setCurves(const std::vector& curves) { + curves_ = curves; + return *this; + } + ClientSslTransportOptions& setSni(absl::string_view sni) { sni_ = std::string(sni); return *this; @@ -70,6 +75,7 @@ struct ClientSslTransportOptions { std::vector cipher_suites_{}; std::string san_; std::vector sigalgs_; + std::vector curves_; std::string sni_; envoy::extensions::transport_sockets::tls::v3::TlsParameters::TlsProtocol tls_version_{ envoy::extensions::transport_sockets::tls::v3::TlsParameters::TLS_AUTO};