[tls] Add set min/max TLS version APIs to TLS credentials APIs. (#34861)

Address #28382. This is a recreation of #31368 except e2e tests are not handled here (yet).

Closes #34861

COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/34861 from rockspore:tls_version f9a1215ac1
PiperOrigin-RevId: 589847110
pull/35273/head^2
Luwei Ge 12 months ago committed by Copybara-Service
parent 71367424d6
commit dd12460018
  1. 2
      grpc.def
  2. 18
      include/grpc/grpc_security.h
  3. 9
      include/grpcpp/security/tls_credentials_options.h
  4. 12
      src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc
  5. 16
      src/core/lib/security/credentials/tls/tls_credentials.cc
  6. 12
      src/cpp/common/tls_credentials_options.cc
  7. 4
      src/ruby/ext/grpc/rb_grpc_imports.generated.c
  8. 6
      src/ruby/ext/grpc/rb_grpc_imports.generated.h
  9. 16
      test/core/security/grpc_tls_credentials_options_test.cc
  10. 16
      test/cpp/client/credentials_test.cc
  11. 18
      test/cpp/server/credentials_test.cc

2
grpc.def generated

@ -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_copy
grpc_tls_credentials_options_destroy
grpc_tls_credentials_options_set_certificate_provider

@ -815,6 +815,24 @@ GRPCAPI void grpc_tls_certificate_provider_release(
*/
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
*

@ -109,6 +109,15 @@ class TlsCredentialsOptions {
void set_crl_provider(std::shared_ptr<CrlProvider> crl_provider);
// 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 ----
// Returns a deep copy of the internal c options. The caller takes ownership
// of the returned pointer. This function shall be used only internally.

@ -149,3 +149,15 @@ void grpc_tls_credentials_options_set_crl_provider(
GPR_ASSERT(options != nullptr);
options->set_crl_provider(provider);
}
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);
}

@ -46,6 +46,22 @@ 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() > options->max_tls_version()) {
gpr_log(GPR_ERROR, "TLS min version must not be higher than max version.");
grpc_tls_credentials_options_destroy(options);
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.");
grpc_tls_credentials_options_destroy(options);
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.");
grpc_tls_credentials_options_destroy(options);
return false;
}
if (!options->crl_directory().empty() && options->crl_provider() != nullptr) {
gpr_log(GPR_ERROR,
"Setting crl_directory and crl_provider not supported. Using the "

@ -95,6 +95,18 @@ void TlsCredentialsOptions::set_certificate_verifier(
}
}
void TlsCredentialsOptions::set_min_tls_version(grpc_tls_version tls_version) {
grpc_tls_credentials_options* options = mutable_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 = mutable_c_credentials_options();
GPR_ASSERT(options != nullptr);
grpc_tls_credentials_options_set_max_tls_version(options, tls_version);
}
grpc_tls_credentials_options* TlsCredentialsOptions::c_credentials_options()
const {
return grpc_tls_credentials_options_copy(c_credentials_options_);

@ -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_copy_type grpc_tls_credentials_options_copy_import;
grpc_tls_credentials_options_destroy_type grpc_tls_credentials_options_destroy_import;
grpc_tls_credentials_options_set_certificate_provider_type grpc_tls_credentials_options_set_certificate_provider_import;
@ -469,6 +471,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_copy_import = (grpc_tls_credentials_options_copy_type) GetProcAddress(library, "grpc_tls_credentials_options_copy");
grpc_tls_credentials_options_destroy_import = (grpc_tls_credentials_options_destroy_type) GetProcAddress(library, "grpc_tls_credentials_options_destroy");
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");

@ -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 grpc_tls_credentials_options*(*grpc_tls_credentials_options_copy_type)(grpc_tls_credentials_options* options);
extern grpc_tls_credentials_options_copy_type grpc_tls_credentials_options_copy_import;
#define grpc_tls_credentials_options_copy grpc_tls_credentials_options_copy_import

@ -67,6 +67,22 @@ 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);
}
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);
}
//
// Tests for Default Root Certs.
//

@ -500,6 +500,22 @@ TEST(CredentialsTest, MultipleChannelCredentialsOneCrlProviderDoesNotLeak) {
EXPECT_NE(channel_creds_2, 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);
}
} // namespace
} // namespace testing
} // namespace grpc

@ -277,6 +277,24 @@ TEST(CredentialsTest, MultipleServerCredentialsOneCrlProviderDoesNotLeak) {
EXPECT_NE(server_creds_2, 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);
}
} // namespace
} // namespace testing
} // namespace grpc

Loading…
Cancel
Save