aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Stevenson <52979934+matthewstevenson88@users.noreply.github.com>2024-02-05 11:04:00 -0800
committerGitHub <noreply@github.com>2024-02-05 11:04:00 -0800
commiteece0c034a83d98cbe8111fd74f7e98ade4e8d31 (patch)
tree51e34e116d6873e2a7ebd43bf17f099f46e8489f
parent04dd01296203bbb59ee5fe49969c13844de24eb0 (diff)
downloadgrpc-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.def2
-rw-r--r--include/grpc/grpc_security.h18
-rw-r--r--include/grpcpp/security/tls_credentials_options.h9
-rw-r--r--src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc12
-rw-r--r--src/core/lib/security/credentials/tls/tls_credentials.cc14
-rw-r--r--src/cpp/common/tls_credentials_options.cc12
-rw-r--r--src/cpp/server/secure_server_credentials.cc9
-rw-r--r--src/ruby/ext/grpc/rb_grpc_imports.generated.c4
-rw-r--r--src/ruby/ext/grpc/rb_grpc_imports.generated.h6
-rw-r--r--test/core/security/grpc_tls_credentials_options_test.cc18
-rw-r--r--test/cpp/client/credentials_test.cc18
-rw-r--r--test/cpp/server/credentials_test.cc20
12 files changed, 140 insertions, 2 deletions
diff --git a/grpc.def b/grpc.def
index 1a82b377c6..eb4b668653 100644
--- a/grpc.def
+++ b/grpc.def
@@ -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