diff options
author | Matthew Stevenson <52979934+matthewstevenson88@users.noreply.github.com> | 2024-02-05 11:04:00 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-05 11:04:00 -0800 |
commit | eece0c034a83d98cbe8111fd74f7e98ade4e8d31 (patch) | |
tree | 51e34e116d6873e2a7ebd43bf17f099f46e8489f | |
parent | 04dd01296203bbb59ee5fe49969c13844de24eb0 (diff) | |
download | grpc-grpc-eece0c034a83d98cbe8111fd74f7e98ade4e8d31.tar.gz |
[tls] Backport of #34861 to v1.56.x. (#35795)
Co-authored-by: Luwei Ge <lwge@google.com>
-rw-r--r-- | grpc.def | 2 | ||||
-rw-r--r-- | include/grpc/grpc_security.h | 18 | ||||
-rw-r--r-- | include/grpcpp/security/tls_credentials_options.h | 9 | ||||
-rw-r--r-- | src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc | 12 | ||||
-rw-r--r-- | src/core/lib/security/credentials/tls/tls_credentials.cc | 14 | ||||
-rw-r--r-- | src/cpp/common/tls_credentials_options.cc | 12 | ||||
-rw-r--r-- | src/cpp/server/secure_server_credentials.cc | 9 | ||||
-rw-r--r-- | src/ruby/ext/grpc/rb_grpc_imports.generated.c | 4 | ||||
-rw-r--r-- | src/ruby/ext/grpc/rb_grpc_imports.generated.h | 6 | ||||
-rw-r--r-- | test/core/security/grpc_tls_credentials_options_test.cc | 18 | ||||
-rw-r--r-- | test/cpp/client/credentials_test.cc | 18 | ||||
-rw-r--r-- | test/cpp/server/credentials_test.cc | 20 |
12 files changed, 140 insertions, 2 deletions
@@ -157,6 +157,8 @@ EXPORTS grpc_tls_certificate_provider_file_watcher_create grpc_tls_certificate_provider_release grpc_tls_credentials_options_create + grpc_tls_credentials_options_set_min_tls_version + grpc_tls_credentials_options_set_max_tls_version grpc_tls_credentials_options_set_certificate_provider grpc_tls_credentials_options_watch_root_certs grpc_tls_credentials_options_set_root_cert_name diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h index 986683d405..54bfa4d55d 100644 --- a/include/grpc/grpc_security.h +++ b/include/grpc/grpc_security.h @@ -818,6 +818,24 @@ GRPCAPI grpc_tls_credentials_options* grpc_tls_credentials_options_create(void); /** * EXPERIMENTAL API - Subject to change * + * Sets the minimum TLS version that will be negotiated during the TLS + * handshake. If not set, the underlying SSL library will set it to TLS v1.2. + */ +GRPCAPI void grpc_tls_credentials_options_set_min_tls_version( + grpc_tls_credentials_options* options, grpc_tls_version min_tls_version); + +/** + * EXPERIMENTAL API - Subject to change + * + * Sets the maximum TLS version that will be negotiated during the TLS + * handshake. If not set, the underlying SSL library will set it to TLS v1.3. + */ +GRPCAPI void grpc_tls_credentials_options_set_max_tls_version( + grpc_tls_credentials_options* options, grpc_tls_version max_tls_version); + +/** + * EXPERIMENTAL API - Subject to change + * * Sets the credential provider in the options. * The |options| will implicitly take a new ref to the |provider|. */ diff --git a/include/grpcpp/security/tls_credentials_options.h b/include/grpcpp/security/tls_credentials_options.h index da5620f805..b2136515c2 100644 --- a/include/grpcpp/security/tls_credentials_options.h +++ b/include/grpcpp/security/tls_credentials_options.h @@ -104,6 +104,15 @@ class TlsCredentialsOptions { // version > 1.1. void set_crl_directory(const std::string& path); + // Sets the minimum TLS version that will be negotiated during the TLS + // handshake. If not set, the underlying SSL library will use TLS v1.2. + // @param tls_version: The minimum TLS version. + void set_min_tls_version(grpc_tls_version tls_version); + // Sets the maximum TLS version that will be negotiated during the TLS + // handshake. If not set, the underlying SSL library will use TLS v1.3. + // @param tls_version: The maximum TLS version. + void set_max_tls_version(grpc_tls_version tls_version); + // ----- Getters for member fields ---- // Get the internal c options. This function shall be used only internally. grpc_tls_credentials_options* c_credentials_options() const { diff --git a/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc b/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc index 2f951b5754..f496f9edcb 100644 --- a/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc +++ b/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc @@ -128,3 +128,15 @@ void grpc_tls_credentials_options_set_send_client_ca_list( } options->set_send_client_ca_list(send_client_ca_list); } + +void grpc_tls_credentials_options_set_min_tls_version( + grpc_tls_credentials_options* options, grpc_tls_version min_tls_version) { + GPR_ASSERT(options != nullptr); + options->set_min_tls_version(min_tls_version); +} + +void grpc_tls_credentials_options_set_max_tls_version( + grpc_tls_credentials_options* options, grpc_tls_version max_tls_version) { + GPR_ASSERT(options != nullptr); + options->set_max_tls_version(max_tls_version); +} diff --git a/src/core/lib/security/credentials/tls/tls_credentials.cc b/src/core/lib/security/credentials/tls/tls_credentials.cc index 10b5134b5e..7d068db54a 100644 --- a/src/core/lib/security/credentials/tls/tls_credentials.cc +++ b/src/core/lib/security/credentials/tls/tls_credentials.cc @@ -45,6 +45,20 @@ bool CredentialOptionSanityCheck(grpc_tls_credentials_options* options, gpr_log(GPR_ERROR, "TLS credentials options is nullptr."); return false; } + // In this case, there will be non-retriable handshake errors. + if (options->min_tls_version() == grpc_tls_version::TLS1_3 && + options->max_tls_version() == grpc_tls_version::TLS1_2) { + gpr_log(GPR_ERROR, "TLS min version must not be higher than max version."); + return false; + } + if (options->max_tls_version() > grpc_tls_version::TLS1_3) { + gpr_log(GPR_ERROR, "TLS max version must not be higher than v1.3."); + return false; + } + if (options->min_tls_version() < grpc_tls_version::TLS1_2) { + gpr_log(GPR_ERROR, "TLS min version must not be lower than v1.2."); + return false; + } // In the following conditions, there won't be any issues, but it might // indicate callers are doing something wrong with the API. if (is_client && options->cert_request_type() != diff --git a/src/cpp/common/tls_credentials_options.cc b/src/cpp/common/tls_credentials_options.cc index 6a515055c1..8e3a5c8fa9 100644 --- a/src/cpp/common/tls_credentials_options.cc +++ b/src/cpp/common/tls_credentials_options.cc @@ -84,6 +84,18 @@ void TlsCredentialsOptions::set_certificate_verifier( } } +void TlsCredentialsOptions::set_min_tls_version(grpc_tls_version tls_version) { + grpc_tls_credentials_options* options = c_credentials_options(); + GPR_ASSERT(options != nullptr); + grpc_tls_credentials_options_set_min_tls_version(options, tls_version); +} + +void TlsCredentialsOptions::set_max_tls_version(grpc_tls_version tls_version) { + grpc_tls_credentials_options* options = c_credentials_options(); + GPR_ASSERT(options != nullptr); + grpc_tls_credentials_options_set_max_tls_version(options, tls_version); +} + void TlsCredentialsOptions::set_check_call_host(bool check_call_host) { grpc_tls_credentials_options* options = c_credentials_options(); GPR_ASSERT(options != nullptr); diff --git a/src/cpp/server/secure_server_credentials.cc b/src/cpp/server/secure_server_credentials.cc index 8874700410..793bd62c68 100644 --- a/src/cpp/server/secure_server_credentials.cc +++ b/src/cpp/server/secure_server_credentials.cc @@ -152,8 +152,13 @@ std::shared_ptr<ServerCredentials> LocalServerCredentials( std::shared_ptr<ServerCredentials> TlsServerCredentials( const grpc::experimental::TlsServerCredentialsOptions& options) { - return std::shared_ptr<ServerCredentials>(new SecureServerCredentials( - grpc_tls_server_credentials_create(options.c_credentials_options()))); + grpc_server_credentials* c_creds = + grpc_tls_server_credentials_create(options.c_credentials_options()); + if (c_creds == nullptr) { + return nullptr; + } + return std::shared_ptr<ServerCredentials>( + new SecureServerCredentials(c_creds)); } } // namespace experimental diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c index 36bd6808a0..7133bb761e 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c @@ -180,6 +180,8 @@ grpc_tls_certificate_provider_static_data_create_type grpc_tls_certificate_provi grpc_tls_certificate_provider_file_watcher_create_type grpc_tls_certificate_provider_file_watcher_create_import; grpc_tls_certificate_provider_release_type grpc_tls_certificate_provider_release_import; grpc_tls_credentials_options_create_type grpc_tls_credentials_options_create_import; +grpc_tls_credentials_options_set_min_tls_version_type grpc_tls_credentials_options_set_min_tls_version_import; +grpc_tls_credentials_options_set_max_tls_version_type grpc_tls_credentials_options_set_max_tls_version_import; grpc_tls_credentials_options_set_certificate_provider_type grpc_tls_credentials_options_set_certificate_provider_import; grpc_tls_credentials_options_watch_root_certs_type grpc_tls_credentials_options_watch_root_certs_import; grpc_tls_credentials_options_set_root_cert_name_type grpc_tls_credentials_options_set_root_cert_name_import; @@ -467,6 +469,8 @@ void grpc_rb_load_imports(HMODULE library) { grpc_tls_certificate_provider_file_watcher_create_import = (grpc_tls_certificate_provider_file_watcher_create_type) GetProcAddress(library, "grpc_tls_certificate_provider_file_watcher_create"); grpc_tls_certificate_provider_release_import = (grpc_tls_certificate_provider_release_type) GetProcAddress(library, "grpc_tls_certificate_provider_release"); grpc_tls_credentials_options_create_import = (grpc_tls_credentials_options_create_type) GetProcAddress(library, "grpc_tls_credentials_options_create"); + grpc_tls_credentials_options_set_min_tls_version_import = (grpc_tls_credentials_options_set_min_tls_version_type) GetProcAddress(library, "grpc_tls_credentials_options_set_min_tls_version"); + grpc_tls_credentials_options_set_max_tls_version_import = (grpc_tls_credentials_options_set_max_tls_version_type) GetProcAddress(library, "grpc_tls_credentials_options_set_max_tls_version"); grpc_tls_credentials_options_set_certificate_provider_import = (grpc_tls_credentials_options_set_certificate_provider_type) GetProcAddress(library, "grpc_tls_credentials_options_set_certificate_provider"); grpc_tls_credentials_options_watch_root_certs_import = (grpc_tls_credentials_options_watch_root_certs_type) GetProcAddress(library, "grpc_tls_credentials_options_watch_root_certs"); grpc_tls_credentials_options_set_root_cert_name_import = (grpc_tls_credentials_options_set_root_cert_name_type) GetProcAddress(library, "grpc_tls_credentials_options_set_root_cert_name"); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index cce517daad..43931e54d6 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -515,6 +515,12 @@ extern grpc_tls_certificate_provider_release_type grpc_tls_certificate_provider_ typedef grpc_tls_credentials_options*(*grpc_tls_credentials_options_create_type)(void); extern grpc_tls_credentials_options_create_type grpc_tls_credentials_options_create_import; #define grpc_tls_credentials_options_create grpc_tls_credentials_options_create_import +typedef void(*grpc_tls_credentials_options_set_min_tls_version_type)(grpc_tls_credentials_options* options, grpc_tls_version min_tls_version); +extern grpc_tls_credentials_options_set_min_tls_version_type grpc_tls_credentials_options_set_min_tls_version_import; +#define grpc_tls_credentials_options_set_min_tls_version grpc_tls_credentials_options_set_min_tls_version_import +typedef void(*grpc_tls_credentials_options_set_max_tls_version_type)(grpc_tls_credentials_options* options, grpc_tls_version max_tls_version); +extern grpc_tls_credentials_options_set_max_tls_version_type grpc_tls_credentials_options_set_max_tls_version_import; +#define grpc_tls_credentials_options_set_max_tls_version grpc_tls_credentials_options_set_max_tls_version_import typedef void(*grpc_tls_credentials_options_set_certificate_provider_type)(grpc_tls_credentials_options* options, grpc_tls_certificate_provider* provider); extern grpc_tls_credentials_options_set_certificate_provider_type grpc_tls_credentials_options_set_certificate_provider_import; #define grpc_tls_credentials_options_set_certificate_provider grpc_tls_credentials_options_set_certificate_provider_import diff --git a/test/core/security/grpc_tls_credentials_options_test.cc b/test/core/security/grpc_tls_credentials_options_test.cc index 3ab8ca671e..33f979284e 100644 --- a/test/core/security/grpc_tls_credentials_options_test.cc +++ b/test/core/security/grpc_tls_credentials_options_test.cc @@ -66,6 +66,24 @@ class GrpcTlsCredentialsOptionsTest : public ::testing::Test { HostNameCertificateVerifier hostname_certificate_verifier_; }; +TEST_F(GrpcTlsCredentialsOptionsTest, BadTlsVersionsForChannelCredentials) { + auto options = grpc_tls_credentials_options_create(); + options->set_max_tls_version(grpc_tls_version::TLS1_2); + options->set_min_tls_version(grpc_tls_version::TLS1_3); + auto credentials = grpc_tls_credentials_create(options); + EXPECT_EQ(credentials, nullptr); + delete options; +} + +TEST_F(GrpcTlsCredentialsOptionsTest, BadTlsVersionsForServerCredentials) { + auto server_options = grpc_tls_credentials_options_create(); + server_options->set_max_tls_version(grpc_tls_version::TLS1_2); + server_options->set_min_tls_version(grpc_tls_version::TLS1_3); + auto server_credentials = grpc_tls_server_credentials_create(server_options); + EXPECT_EQ(server_credentials, nullptr); + delete server_options; +} + // // Tests for Default Root Certs. // diff --git a/test/cpp/client/credentials_test.cc b/test/cpp/client/credentials_test.cc index bd4137c9e2..a296790a00 100644 --- a/test/cpp/client/credentials_test.cc +++ b/test/cpp/client/credentials_test.cc @@ -30,6 +30,7 @@ #include "src/core/lib/gpr/tmpfile.h" #include "src/core/lib/gprpp/env.h" +#include "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h" #include "src/cpp/client/secure_credentials.h" #include "test/cpp/util/tls_test_utils.h" @@ -397,6 +398,23 @@ TEST(CredentialsTest, TlsChannelCredentialsWithCrlDirectory) { GPR_ASSERT(channel_credentials.get() != nullptr); } +TEST(CredentialsTest, TlsChannelCredentialsWithGoodMinAndMaxTlsVersions) { + grpc::experimental::TlsChannelCredentialsOptions options; + options.set_min_tls_version(grpc_tls_version::TLS1_2); + options.set_max_tls_version(grpc_tls_version::TLS1_3); + auto channel_credentials = grpc::experimental::TlsCredentials(options); + EXPECT_NE(channel_credentials, nullptr); +} + +TEST(CredentialsTest, TlsChannelCredentialsWithBadMinAndMaxTlsVersions) { + grpc::experimental::TlsChannelCredentialsOptions options; + options.set_min_tls_version(grpc_tls_version::TLS1_3); + options.set_max_tls_version(grpc_tls_version::TLS1_2); + auto channel_credentials = grpc::experimental::TlsCredentials(options); + EXPECT_EQ(channel_credentials, nullptr); + delete options.c_credentials_options(); +} + } // namespace } // namespace testing } // namespace grpc diff --git a/test/cpp/server/credentials_test.cc b/test/cpp/server/credentials_test.cc index 97db8d5be1..8e7e437965 100644 --- a/test/cpp/server/credentials_test.cc +++ b/test/cpp/server/credentials_test.cc @@ -24,6 +24,7 @@ #include <grpcpp/security/server_credentials.h> #include <grpcpp/security/tls_credentials_options.h> +#include "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h" #include "src/cpp/client/secure_credentials.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -176,6 +177,25 @@ TEST(CredentialsTest, TlsServerCredentialsWithAsyncExternalVerifier) { GPR_ASSERT(server_credentials.get() != nullptr); } +TEST(CredentialsTest, TlsServerCredentialsWithGoodMinMaxTlsVersions) { + grpc::experimental::TlsServerCredentialsOptions options( + /*certificate_provider=*/nullptr); + options.set_min_tls_version(grpc_tls_version::TLS1_2); + options.set_max_tls_version(grpc_tls_version::TLS1_3); + auto server_credentials = grpc::experimental::TlsServerCredentials(options); + EXPECT_NE(server_credentials, nullptr); +} + +TEST(CredentialsTest, TlsServerCredentialsWithBadMinMaxTlsVersions) { + grpc::experimental::TlsServerCredentialsOptions options( + /*certificate_provider=*/nullptr); + options.set_min_tls_version(grpc_tls_version::TLS1_3); + options.set_max_tls_version(grpc_tls_version::TLS1_2); + auto server_credentials = grpc::experimental::TlsServerCredentials(options); + EXPECT_EQ(server_credentials, nullptr); + delete options.c_credentials_options(); +} + } // namespace } // namespace testing } // namespace grpc |