[tls] Backport of #34861 to v1.56.x. (#35795)

Co-authored-by: Luwei Ge <lwge@google.com>
This commit is contained in:
Matthew Stevenson 2024-02-05 11:04:00 -08:00 committed by GitHub
parent 04dd012962
commit eece0c034a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 140 additions and 2 deletions

2
grpc.def generated
View File

@ -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

View File

@ -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
*

View File

@ -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 {

View File

@ -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);
}

View File

@ -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() !=

View File

@ -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);

View File

@ -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

View File

@ -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");

View File

@ -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

View File

@ -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.
//

View File

@ -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

View File

@ -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