Add TLS 1.2 testing.

pull/23165/head
Matthew Stevenson 5 years ago
parent df6f8c0729
commit 32c0846d45
  1. 3
      include/grpc/grpc_security_constants.h
  2. 20
      src/core/lib/security/credentials/ssl/ssl_credentials.cc
  3. 10
      src/core/lib/security/credentials/ssl/ssl_credentials.h
  4. 4
      src/core/lib/security/security_connector/ssl/ssl_security_connector.cc
  5. 5
      src/core/lib/security/security_connector/ssl/ssl_security_connector.h
  6. 50
      src/core/tsi/ssl_transport_security.cc
  7. 16
      src/core/tsi/ssl_transport_security.h
  8. 1
      test/core/end2end/end2end_tests.h
  9. 50
      test/core/end2end/fixtures/h2_oauth2.cc
  10. 50
      test/core/end2end/fixtures/h2_ssl.cc
  11. 50
      test/core/end2end/fixtures/h2_ssl_cred_reload.cc
  12. 10
      test/core/end2end/tests/filter_call_init_fails.cc
  13. 73
      test/core/tsi/ssl_transport_security_test.cc

@ -139,6 +139,9 @@ typedef enum {
*/
typedef enum { UDS = 0, LOCAL_TCP } grpc_local_connect_type;
/** The TLS versions that are supported by the SSL stack. **/
typedef enum { TLS1_2, TLS1_3 } grpc_tls_version;
#ifdef __cplusplus
}
#endif

@ -117,6 +117,16 @@ void grpc_ssl_credentials::build_config(
}
}
void grpc_ssl_credentials::set_min_tls_version(
grpc_tls_version min_tls_version) {
config_.min_tls_version = min_tls_version;
}
void grpc_ssl_credentials::set_max_tls_version(
grpc_tls_version max_tls_version) {
config_.max_tls_version = max_tls_version;
}
/* Deprecated in favor of grpc_ssl_credentials_create_ex. Will be removed
* once all of its call sites are migrated to grpc_ssl_credentials_create_ex. */
grpc_channel_credentials* grpc_ssl_credentials_create(
@ -213,6 +223,16 @@ void grpc_ssl_server_credentials::build_config(
config_.num_key_cert_pairs = num_key_cert_pairs;
}
void grpc_ssl_server_credentials::set_min_tls_version(
grpc_tls_version min_tls_version) {
config_.min_tls_version = min_tls_version;
}
void grpc_ssl_server_credentials::set_max_tls_version(
grpc_tls_version max_tls_version) {
config_.max_tls_version = max_tls_version;
}
grpc_ssl_server_certificate_config* grpc_ssl_server_certificate_config_create(
const char* pem_root_certs,
const grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs,

@ -38,6 +38,11 @@ class grpc_ssl_credentials : public grpc_channel_credentials {
const char* target, const grpc_channel_args* args,
grpc_channel_args** new_args) override;
// TODO(mattstev): Plumb to wrapped languages. Until then, setting the TLS
// version should be done for testing purposes only.
void set_min_tls_version(grpc_tls_version min_tls_version);
void set_max_tls_version(grpc_tls_version max_tls_version);
private:
void build_config(const char* pem_root_certs,
grpc_ssl_pem_key_cert_pair* pem_key_cert_pair,
@ -77,6 +82,11 @@ class grpc_ssl_server_credentials final : public grpc_server_credentials {
config);
}
// TODO(mattstev): Plumb to wrapped languages. Until then, setting the TLS
// version should be done for testing purposes only.
void set_min_tls_version(grpc_tls_version min_tls_version);
void set_max_tls_version(grpc_tls_version max_tls_version);
const grpc_ssl_server_config& config() const { return config_; }
private:

@ -107,6 +107,8 @@ class grpc_ssl_channel_security_connector final
}
options.cipher_suites = grpc_get_ssl_cipher_suites();
options.session_cache = ssl_session_cache;
options.min_tls_version = config->min_tls_version;
options.max_tls_version = config->max_tls_version;
const tsi_result result =
tsi_create_ssl_client_handshaker_factory_with_options(
&options, &client_handshaker_factory_);
@ -251,6 +253,8 @@ class grpc_ssl_server_security_connector
options.cipher_suites = grpc_get_ssl_cipher_suites();
options.alpn_protocols = alpn_protocol_strings;
options.num_alpn_protocols = static_cast<uint16_t>(num_alpn_protocols);
options.min_tls_version = server_credentials->config().min_tls_version;
options.max_tls_version = server_credentials->config().max_tls_version;
const tsi_result result =
tsi_create_ssl_server_handshaker_factory_with_options(
&options, &server_handshaker_factory_);

@ -33,7 +33,10 @@ struct grpc_ssl_config {
tsi_ssl_pem_key_cert_pair* pem_key_cert_pair;
char* pem_root_certs;
verify_peer_options verify_options;
grpc_tls_version min_tls_version = grpc_tls_version::TLS1_2;
grpc_tls_version max_tls_version = grpc_tls_version::TLS1_3;
};
/* Creates an SSL channel_security_connector.
- request_metadata_creds is the credentials object which metadata
will be sent with each request. This parameter can be NULL.
@ -62,6 +65,8 @@ struct grpc_ssl_server_config {
char* pem_root_certs = nullptr;
grpc_ssl_client_certificate_request_type client_certificate_request =
GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE;
grpc_tls_version min_tls_version = grpc_tls_version::TLS1_2;
grpc_tls_version max_tls_version = grpc_tls_version::TLS1_3;
};
/* Creates an SSL server_security_connector.
- config is the SSL config to be used for the SSL channel establishment.

@ -888,6 +888,43 @@ static int NullVerifyCallback(int /*preverify_ok*/, X509_STORE_CTX* /*ctx*/) {
return 1;
}
// Sets the min and max TLS version of |ssl_context| to |min_tls_version| and
// |max_tls_version|, respectively.
static tsi_result tsi_set_min_and_max_tls_versions(
SSL_CTX* ssl_context, grpc_tls_version min_tls_version,
grpc_tls_version max_tls_version) {
if (ssl_context == nullptr) {
gpr_log(GPR_INFO,
"Invalid nullptr argument to |tsi_set_min_and_max_tls_versions|.");
return TSI_INVALID_ARGUMENT;
}
// Set the min TLS version of the SSL context.
switch (min_tls_version) {
case grpc_tls_version::TLS1_2:
SSL_CTX_set_min_proto_version(ssl_context, TLS1_2_VERSION);
break;
case grpc_tls_version::TLS1_3:
SSL_CTX_set_min_proto_version(ssl_context, TLS1_3_VERSION);
break;
default:
gpr_log(GPR_INFO, "TLS version is not supported.");
return TSI_FAILED_PRECONDITION;
}
// Set the max TLS version of the SSL context.
switch (max_tls_version) {
case grpc_tls_version::TLS1_2:
SSL_CTX_set_max_proto_version(ssl_context, TLS1_2_VERSION);
break;
case grpc_tls_version::TLS1_3:
SSL_CTX_set_max_proto_version(ssl_context, TLS1_3_VERSION);
break;
default:
gpr_log(GPR_INFO, "TLS version is not supported.");
return TSI_FAILED_PRECONDITION;
}
return TSI_OK;
}
/* --- tsi_ssl_root_certs_store methods implementation. ---*/
tsi_ssl_root_certs_store* tsi_ssl_root_certs_store_create(
@ -1843,10 +1880,10 @@ tsi_result tsi_create_ssl_client_handshaker_factory_with_options(
}
#if OPENSSL_VERSION_NUMBER >= 0x10100000
// TODO(mattstev): Allow user to set min/max TLS version.
// https://github.com/grpc/grpc/issues/22403
ssl_context = SSL_CTX_new(TLS_method());
SSL_CTX_set_min_proto_version(ssl_context, TLS1_2_VERSION);
result = tsi_set_min_and_max_tls_versions(
ssl_context, options->min_tls_version, options->max_tls_version);
if (result != TSI_OK) return result;
#else
ssl_context = SSL_CTX_new(TLSv1_2_method());
#endif
@ -2010,10 +2047,11 @@ tsi_result tsi_create_ssl_server_handshaker_factory_with_options(
for (i = 0; i < options->num_key_cert_pairs; i++) {
do {
#if OPENSSL_VERSION_NUMBER >= 0x10100000
// TODO(mattstev): Allow user to set min/max TLS version.
// https://github.com/grpc/grpc/issues/22403
impl->ssl_contexts[i] = SSL_CTX_new(TLS_method());
SSL_CTX_set_min_proto_version(impl->ssl_contexts[i], TLS1_2_VERSION);
result = tsi_set_min_and_max_tls_versions(impl->ssl_contexts[i],
options->min_tls_version,
options->max_tls_version);
if (result != TSI_OK) return result;
#else
impl->ssl_contexts[i] = SSL_CTX_new(TLSv1_2_method());
#endif

@ -21,6 +21,7 @@
#include <grpc/support/port_platform.h>
#include <grpc/grpc_security_constants.h>
#include "absl/strings/string_view.h"
#include "src/core/tsi/transport_security_interface.h"
@ -152,6 +153,10 @@ struct tsi_ssl_client_handshaker_options {
/* skip server certificate verification. */
bool skip_server_certificate_verification;
/* The min and max TLS versions that will be negotiated by the handshaker. */
grpc_tls_version min_tls_version;
grpc_tls_version max_tls_version;
tsi_ssl_client_handshaker_options()
: pem_key_cert_pair(nullptr),
pem_root_certs(nullptr),
@ -160,7 +165,9 @@ struct tsi_ssl_client_handshaker_options {
alpn_protocols(nullptr),
num_alpn_protocols(0),
session_cache(nullptr),
skip_server_certificate_verification(false) {}
skip_server_certificate_verification(false),
min_tls_version(grpc_tls_version::TLS1_2),
max_tls_version(grpc_tls_version::TLS1_3) {}
};
/* Creates a client handshaker factory.
@ -276,6 +283,9 @@ struct tsi_ssl_server_handshaker_options {
const char* session_ticket_key;
/* session_ticket_key_size is a size of session ticket encryption key. */
size_t session_ticket_key_size;
/* The min and max TLS versions that will be negotiated by the handshaker. */
grpc_tls_version min_tls_version;
grpc_tls_version max_tls_version;
tsi_ssl_server_handshaker_options()
: pem_key_cert_pairs(nullptr),
@ -286,7 +296,9 @@ struct tsi_ssl_server_handshaker_options {
alpn_protocols(nullptr),
num_alpn_protocols(0),
session_ticket_key(nullptr),
session_ticket_key_size(0) {}
session_ticket_key_size(0),
min_tls_version(grpc_tls_version::TLS1_2),
max_tls_version(grpc_tls_version::TLS1_3) {}
};
/* Creates a server handshaker factory.

@ -35,6 +35,7 @@ typedef struct grpc_end2end_test_config grpc_end2end_test_config;
#define FEATURE_MASK_DOES_NOT_SUPPORT_NETWORK_STATUS_CHANGE 128
#define FEATURE_MASK_SUPPORTS_WORKAROUNDS 256
#define FEATURE_MASK_DOES_NOT_SUPPORT_SEND_CALL_CREDENTIALS 512
#define FEATURE_MASK_DOES_NOT_SUPPORT_CLIENT_HANDSHAKE_COMPLETE_FIRST 1024
#define FAIL_AUTH_CHECK_SERVER_ARG_NAME "fail_auth_check"

@ -26,6 +26,7 @@
#include "src/core/lib/iomgr/iomgr.h"
#include "src/core/lib/iomgr/load_file.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/credentials/ssl/ssl_credentials.h"
#include "test/core/end2end/end2end_tests.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
@ -40,6 +41,7 @@ static const char* client_identity = "Brainy Smurf";
struct fullstack_secure_fixture_data {
std::string localaddr;
grpc_tls_version tls_version;
};
static const grpc_metadata* find_metadata(const grpc_metadata* md,
@ -93,18 +95,32 @@ static void process_oauth2_failure(void* state, grpc_auth_context* /*ctx*/,
}
static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack(
grpc_channel_args* /*client_args*/, grpc_channel_args* /*server_args*/) {
grpc_channel_args* /*client_args*/, grpc_channel_args* /*server_args*/,
grpc_tls_version tls_version) {
grpc_end2end_test_fixture f;
int port = grpc_pick_unused_port_or_die();
fullstack_secure_fixture_data* ffd = new fullstack_secure_fixture_data();
memset(&f, 0, sizeof(f));
ffd->localaddr = grpc_core::JoinHostPort("localhost", port);
ffd->tls_version = tls_version;
f.fixture_data = ffd;
f.cq = grpc_completion_queue_create_for_next(nullptr);
f.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr);
return f;
}
static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack_tls1_2(
grpc_channel_args* client_args, grpc_channel_args* server_args) {
return chttp2_create_fixture_secure_fullstack(client_args, server_args,
grpc_tls_version::TLS1_2);
}
static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack_tls1_3(
grpc_channel_args* client_args, grpc_channel_args* server_args) {
return chttp2_create_fixture_secure_fullstack(client_args, server_args,
grpc_tls_version::TLS1_3);
}
static void chttp2_init_client_secure_fullstack(
grpc_end2end_test_fixture* f, grpc_channel_args* client_args,
grpc_channel_credentials* creds) {
@ -148,6 +164,15 @@ static void chttp2_init_client_simple_ssl_with_oauth2_secure_fullstack(
reinterpret_cast<const char*> GRPC_SLICE_START_PTR(ca_slice);
grpc_channel_credentials* ssl_creds =
grpc_ssl_credentials_create(test_root_cert, nullptr, nullptr, nullptr);
if (f != nullptr && ssl_creds != nullptr) {
// Set the min and max TLS version.
grpc_ssl_credentials* creds =
reinterpret_cast<grpc_ssl_credentials*>(ssl_creds);
fullstack_secure_fixture_data* ffd =
static_cast<fullstack_secure_fixture_data*>(f->fixture_data);
creds->set_min_tls_version(ffd->tls_version);
creds->set_max_tls_version(ffd->tls_version);
}
grpc_call_credentials* oauth2_creds = grpc_md_only_test_credentials_create(
"authorization", oauth2_md, true /* is_async */);
grpc_channel_credentials* ssl_oauth2_creds =
@ -213,6 +238,15 @@ static void chttp2_init_server_simple_ssl_secure_fullstack(
grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {server_key, server_cert};
grpc_server_credentials* ssl_creds = grpc_ssl_server_credentials_create(
nullptr, &pem_key_cert_pair, 1, 0, nullptr);
if (f != nullptr && ssl_creds != nullptr) {
// Set the min and max TLS version.
grpc_ssl_server_credentials* creds =
reinterpret_cast<grpc_ssl_server_credentials*>(ssl_creds);
fullstack_secure_fixture_data* ffd =
static_cast<fullstack_secure_fixture_data*>(f->fixture_data);
creds->set_min_tls_version(ffd->tls_version);
creds->set_max_tls_version(ffd->tls_version);
}
grpc_server_credentials_set_auth_metadata_processor(
ssl_creds, test_processor_create(fail_server_auth_check(server_args)));
chttp2_init_server_secure_fullstack(f, server_args, ssl_creds);
@ -223,12 +257,22 @@ static void chttp2_init_server_simple_ssl_secure_fullstack(
/* All test configurations */
static grpc_end2end_test_config configs[] = {
{"chttp2/simple_ssl_with_oauth2_fullstack",
{"chttp2/simple_ssl_with_oauth2_fullstack_tls1_2",
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
"foo.test.google.fr", chttp2_create_fixture_secure_fullstack,
"foo.test.google.fr", chttp2_create_fixture_secure_fullstack_tls1_2,
chttp2_init_client_simple_ssl_with_oauth2_secure_fullstack,
chttp2_init_server_simple_ssl_secure_fullstack,
chttp2_tear_down_secure_fullstack},
{"chttp2/simple_ssl_with_oauth2_fullstack_tls1_3",
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER |
FEATURE_MASK_DOES_NOT_SUPPORT_CLIENT_HANDSHAKE_COMPLETE_FIRST,
"foo.test.google.fr", chttp2_create_fixture_secure_fullstack_tls1_3,
chttp2_init_client_simple_ssl_with_oauth2_secure_fullstack,
chttp2_init_server_simple_ssl_secure_fullstack,
chttp2_tear_down_secure_fullstack},

@ -27,6 +27,7 @@
#include "src/core/lib/gprpp/host_port.h"
#include "src/core/lib/iomgr/load_file.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/credentials/ssl/ssl_credentials.h"
#include "src/core/lib/security/security_connector/ssl_utils_config.h"
#include "test/core/end2end/end2end_tests.h"
#include "test/core/util/port.h"
@ -38,16 +39,19 @@
struct fullstack_secure_fixture_data {
std::string localaddr;
grpc_tls_version tls_version;
};
static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack(
grpc_channel_args* /*client_args*/, grpc_channel_args* /*server_args*/) {
grpc_channel_args* /*client_args*/, grpc_channel_args* /*server_args*/,
grpc_tls_version tls_version) {
grpc_end2end_test_fixture f;
int port = grpc_pick_unused_port_or_die();
fullstack_secure_fixture_data* ffd = new fullstack_secure_fixture_data();
memset(&f, 0, sizeof(f));
ffd->localaddr = grpc_core::JoinHostPort("localhost", port);
ffd->tls_version = tls_version;
f.fixture_data = ffd;
f.cq = grpc_completion_queue_create_for_next(nullptr);
@ -56,6 +60,18 @@ static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack(
return f;
}
static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack_tls1_2(
grpc_channel_args* client_args, grpc_channel_args* server_args) {
return chttp2_create_fixture_secure_fullstack(client_args, server_args,
grpc_tls_version::TLS1_2);
}
static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack_tls1_3(
grpc_channel_args* client_args, grpc_channel_args* server_args) {
return chttp2_create_fixture_secure_fullstack(client_args, server_args,
grpc_tls_version::TLS1_3);
}
static void process_auth_failure(void* state, grpc_auth_context* /*ctx*/,
const grpc_metadata* /*md*/,
size_t /*md_count*/,
@ -102,6 +118,15 @@ static void chttp2_init_client_simple_ssl_secure_fullstack(
grpc_end2end_test_fixture* f, grpc_channel_args* client_args) {
grpc_channel_credentials* ssl_creds =
grpc_ssl_credentials_create(nullptr, nullptr, nullptr, nullptr);
if (f != nullptr && ssl_creds != nullptr) {
// Set the min and max TLS version.
grpc_ssl_credentials* creds =
reinterpret_cast<grpc_ssl_credentials*>(ssl_creds);
fullstack_secure_fixture_data* ffd =
static_cast<fullstack_secure_fixture_data*>(f->fixture_data);
creds->set_min_tls_version(ffd->tls_version);
creds->set_max_tls_version(ffd->tls_version);
}
grpc_arg ssl_name_override = {
GRPC_ARG_STRING,
const_cast<char*>(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG),
@ -138,6 +163,15 @@ static void chttp2_init_server_simple_ssl_secure_fullstack(
grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {server_key, server_cert};
grpc_server_credentials* ssl_creds = grpc_ssl_server_credentials_create(
nullptr, &pem_key_cert_pair, 1, 0, nullptr);
if (f != nullptr && ssl_creds != nullptr) {
// Set the min and max TLS version.
grpc_ssl_server_credentials* creds =
reinterpret_cast<grpc_ssl_server_credentials*>(ssl_creds);
fullstack_secure_fixture_data* ffd =
static_cast<fullstack_secure_fixture_data*>(f->fixture_data);
creds->set_min_tls_version(ffd->tls_version);
creds->set_max_tls_version(ffd->tls_version);
}
grpc_slice_unref(cert_slice);
grpc_slice_unref(key_slice);
if (fail_server_auth_check(server_args)) {
@ -151,12 +185,22 @@ static void chttp2_init_server_simple_ssl_secure_fullstack(
/* All test configurations */
static grpc_end2end_test_config configs[] = {
{"chttp2/simple_ssl_fullstack",
{"chttp2/simple_ssl_fullstack_tls1_2",
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
"foo.test.google.fr", chttp2_create_fixture_secure_fullstack,
"foo.test.google.fr", chttp2_create_fixture_secure_fullstack_tls1_2,
chttp2_init_client_simple_ssl_secure_fullstack,
chttp2_init_server_simple_ssl_secure_fullstack,
chttp2_tear_down_secure_fullstack},
{"chttp2/simple_ssl_fullstack_tls1_3",
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER |
FEATURE_MASK_DOES_NOT_SUPPORT_CLIENT_HANDSHAKE_COMPLETE_FIRST,
"foo.test.google.fr", chttp2_create_fixture_secure_fullstack_tls1_3,
chttp2_init_client_simple_ssl_secure_fullstack,
chttp2_init_server_simple_ssl_secure_fullstack,
chttp2_tear_down_secure_fullstack},

@ -27,6 +27,7 @@
#include "src/core/lib/gprpp/host_port.h"
#include "src/core/lib/iomgr/load_file.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/credentials/ssl/ssl_credentials.h"
#include "src/core/lib/security/security_connector/ssl_utils_config.h"
#include "test/core/end2end/end2end_tests.h"
#include "test/core/util/port.h"
@ -38,6 +39,7 @@
struct fullstack_secure_fixture_data {
std::string localaddr;
grpc_tls_version tls_version;
bool server_credential_reloaded = false;
};
@ -77,12 +79,14 @@ ssl_server_certificate_config_callback(
}
static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack(
grpc_channel_args* /*client_args*/, grpc_channel_args* /*server_args*/) {
grpc_channel_args* /*client_args*/, grpc_channel_args* /*server_args*/,
grpc_tls_version tls_version) {
grpc_end2end_test_fixture f;
int port = grpc_pick_unused_port_or_die();
fullstack_secure_fixture_data* ffd = new fullstack_secure_fixture_data();
memset(&f, 0, sizeof(f));
ffd->localaddr = grpc_core::JoinHostPort("localhost", port);
ffd->tls_version = tls_version;
f.fixture_data = ffd;
f.cq = grpc_completion_queue_create_for_next(nullptr);
@ -91,6 +95,18 @@ static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack(
return f;
}
static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack_tls1_2(
grpc_channel_args* client_args, grpc_channel_args* server_args) {
return chttp2_create_fixture_secure_fullstack(client_args, server_args,
grpc_tls_version::TLS1_2);
}
static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack_tls1_3(
grpc_channel_args* client_args, grpc_channel_args* server_args) {
return chttp2_create_fixture_secure_fullstack(client_args, server_args,
grpc_tls_version::TLS1_3);
}
static void process_auth_failure(void* state, grpc_auth_context* /*ctx*/,
const grpc_metadata* /*md*/,
size_t /*md_count*/,
@ -138,6 +154,15 @@ static void chttp2_init_client_simple_ssl_secure_fullstack(
grpc_end2end_test_fixture* f, grpc_channel_args* client_args) {
grpc_channel_credentials* ssl_creds =
grpc_ssl_credentials_create(nullptr, nullptr, nullptr, nullptr);
if (f != nullptr && ssl_creds != nullptr) {
// Set the min and max TLS version.
grpc_ssl_credentials* creds =
reinterpret_cast<grpc_ssl_credentials*>(ssl_creds);
fullstack_secure_fixture_data* ffd =
static_cast<fullstack_secure_fixture_data*>(f->fixture_data);
creds->set_min_tls_version(ffd->tls_version);
creds->set_max_tls_version(ffd->tls_version);
}
grpc_arg ssl_name_override = {
GRPC_ARG_STRING,
const_cast<char*>(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG),
@ -168,6 +193,15 @@ static void chttp2_init_server_simple_ssl_secure_fullstack(
ssl_server_certificate_config_callback, f->fixture_data);
grpc_server_credentials* ssl_creds =
grpc_ssl_server_credentials_create_with_options(options);
if (f != nullptr && ssl_creds != nullptr) {
// Set the min and max TLS version.
grpc_ssl_server_credentials* creds =
reinterpret_cast<grpc_ssl_server_credentials*>(ssl_creds);
fullstack_secure_fixture_data* ffd =
static_cast<fullstack_secure_fixture_data*>(f->fixture_data);
creds->set_min_tls_version(ffd->tls_version);
creds->set_max_tls_version(ffd->tls_version);
}
if (fail_server_auth_check(server_args)) {
grpc_auth_metadata_processor processor = {process_auth_failure, nullptr,
nullptr};
@ -179,12 +213,22 @@ static void chttp2_init_server_simple_ssl_secure_fullstack(
/* All test configurations */
static grpc_end2end_test_config configs[] = {
{"chttp2/simple_ssl_fullstack",
{"chttp2/simple_ssl_fullstack_tls1_2",
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
"foo.test.google.fr", chttp2_create_fixture_secure_fullstack,
"foo.test.google.fr", chttp2_create_fixture_secure_fullstack_tls1_2,
chttp2_init_client_simple_ssl_secure_fullstack,
chttp2_init_server_simple_ssl_secure_fullstack,
chttp2_tear_down_secure_fullstack},
{"chttp2/simple_ssl_fullstack_tls1_3",
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER |
FEATURE_MASK_DOES_NOT_SUPPORT_CLIENT_HANDSHAKE_COMPLETE_FIRST,
"foo.test.google.fr", chttp2_create_fixture_secure_fullstack_tls1_3,
chttp2_init_client_simple_ssl_secure_fullstack,
chttp2_init_server_simple_ssl_secure_fullstack,
chttp2_tear_down_secure_fullstack},

@ -508,7 +508,15 @@ void filter_call_init_fails(grpc_end2end_test_config config) {
g_enable_client_channel_filter = true;
test_client_channel_filter(config);
g_enable_client_channel_filter = false;
if (config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL) {
// If the client handshake completes before the server handshake and the
// client is able to send application data before the server handshake
// completes, then testing the CLIENT_SUBCHANNEL filter will cause the server
// to hang waiting for the final handshake message from the client. This
// handshake message will never arrive because it would have been sent with
// the first application data message, which failed because of the filter.
if ((config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL) &&
!(config.feature_mask &
FEATURE_MASK_DOES_NOT_SUPPORT_CLIENT_HANDSHAKE_COMPLETE_FIRST)) {
gpr_log(GPR_INFO, "Testing CLIENT_SUBCHANNEL filter.");
g_enable_client_subchannel_filter = true;
test_client_subchannel_filter(config);

@ -55,6 +55,9 @@ const size_t kSessionTicketEncryptionKeySize = 80;
const size_t kSessionTicketEncryptionKeySize = 48;
#endif
// Indicates the TLS version used for the test.
static grpc_tls_version test_tls_version = grpc_tls_version::TLS1_3;
typedef enum AlpnMode {
NO_ALPN,
ALPN_CLIENT_NO_SERVER,
@ -127,6 +130,8 @@ static void ssl_test_setup_handshakers(tsi_test_fixture* fixture) {
if (ssl_fixture->session_cache != nullptr) {
client_options.session_cache = ssl_fixture->session_cache;
}
client_options.min_tls_version = test_tls_version;
client_options.max_tls_version = test_tls_version;
GPR_ASSERT(tsi_create_ssl_client_handshaker_factory_with_options(
&client_options, &ssl_fixture->client_handshaker_factory) ==
TSI_OK);
@ -159,6 +164,8 @@ static void ssl_test_setup_handshakers(tsi_test_fixture* fixture) {
}
server_options.session_ticket_key = ssl_fixture->session_ticket_key;
server_options.session_ticket_key_size = ssl_fixture->session_ticket_key_size;
server_options.min_tls_version = test_tls_version;
server_options.max_tls_version = test_tls_version;
GPR_ASSERT(tsi_create_ssl_server_handshaker_factory_with_options(
&server_options, &ssl_fixture->server_handshaker_factory) ==
TSI_OK);
@ -317,13 +324,17 @@ static void ssl_test_check_handshaker_peers(tsi_test_fixture* fixture) {
GPR_ASSERT(ssl_fixture->key_cert_lib != nullptr);
ssl_key_cert_lib* key_cert_lib = ssl_fixture->key_cert_lib;
tsi_peer peer;
// In TLS 1.3, the client-side handshake succeeds even if the client sends a
// bad certificate. In such a case, the server would fail the TLS handshake
// and send an alert to the client as the first application data message. In
// TLS 1.2, the client-side handshake will fail if the client sends a bad
// certificate.
bool expect_server_success =
!(key_cert_lib->use_bad_server_cert ||
(key_cert_lib->use_bad_client_cert && ssl_fixture->force_client_auth));
// In TLS 1.3, the client-side handshake succeeds even if the client sends a
// bad certificate. In such a case, the server would fail the TLS handshake
// and send an alert to the client as the first application data message.
bool expect_client_success = !key_cert_lib->use_bad_server_cert;
bool expect_client_success = test_tls_version == grpc_tls_version::TLS1_2
? expect_server_success
: !key_cert_lib->use_bad_server_cert;
if (expect_client_success) {
GPR_ASSERT(tsi_handshaker_result_extract_peer(
ssl_fixture->base.client_result, &peer) == TSI_OK);
@ -954,31 +965,39 @@ void ssl_tsi_test_extract_cert_chain() {
int main(int argc, char** argv) {
grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
ssl_tsi_test_do_handshake_tiny_handshake_buffer();
ssl_tsi_test_do_handshake_small_handshake_buffer();
ssl_tsi_test_do_handshake();
ssl_tsi_test_do_handshake_with_root_store();
ssl_tsi_test_do_handshake_with_client_authentication();
ssl_tsi_test_do_handshake_with_client_authentication_and_root_store();
ssl_tsi_test_do_handshake_with_server_name_indication_exact_domain();
ssl_tsi_test_do_handshake_with_server_name_indication_wild_star_domain();
ssl_tsi_test_do_handshake_with_wrong_server_name_indication();
ssl_tsi_test_do_handshake_with_bad_server_cert();
ssl_tsi_test_do_handshake_with_bad_client_cert();
const size_t number_tls_versions = 2;
const grpc_tls_version tls_versions[] = {grpc_tls_version::TLS1_2,
grpc_tls_version::TLS1_3};
for (size_t i = 0; i < number_tls_versions; i++) {
// Set the TLS version to be used in the tests.
test_tls_version = tls_versions[i];
// Run all the tests using that TLS version for both the client and server.
ssl_tsi_test_do_handshake_tiny_handshake_buffer();
ssl_tsi_test_do_handshake_small_handshake_buffer();
ssl_tsi_test_do_handshake();
ssl_tsi_test_do_handshake_with_root_store();
ssl_tsi_test_do_handshake_with_client_authentication();
ssl_tsi_test_do_handshake_with_client_authentication_and_root_store();
ssl_tsi_test_do_handshake_with_server_name_indication_exact_domain();
ssl_tsi_test_do_handshake_with_server_name_indication_wild_star_domain();
ssl_tsi_test_do_handshake_with_wrong_server_name_indication();
ssl_tsi_test_do_handshake_with_bad_server_cert();
ssl_tsi_test_do_handshake_with_bad_client_cert();
#ifdef OPENSSL_IS_BORINGSSL
// BoringSSL and OpenSSL have different behaviors on mismatched ALPN.
ssl_tsi_test_do_handshake_alpn_client_no_server();
ssl_tsi_test_do_handshake_alpn_client_server_mismatch();
// BoringSSL and OpenSSL have different behaviors on mismatched ALPN.
ssl_tsi_test_do_handshake_alpn_client_no_server();
ssl_tsi_test_do_handshake_alpn_client_server_mismatch();
#endif
ssl_tsi_test_do_handshake_alpn_server_no_client();
ssl_tsi_test_do_handshake_alpn_client_server_ok();
ssl_tsi_test_do_handshake_session_cache();
ssl_tsi_test_do_round_trip_for_all_configs();
ssl_tsi_test_do_round_trip_odd_buffer_size();
ssl_tsi_test_handshaker_factory_internals();
ssl_tsi_test_duplicate_root_certificates();
ssl_tsi_test_extract_x509_subject_names();
ssl_tsi_test_extract_cert_chain();
ssl_tsi_test_do_handshake_alpn_server_no_client();
ssl_tsi_test_do_handshake_alpn_client_server_ok();
ssl_tsi_test_do_handshake_session_cache();
ssl_tsi_test_do_round_trip_for_all_configs();
ssl_tsi_test_do_round_trip_odd_buffer_size();
ssl_tsi_test_handshaker_factory_internals();
ssl_tsi_test_duplicate_root_certificates();
ssl_tsi_test_extract_x509_subject_names();
ssl_tsi_test_extract_cert_chain();
}
grpc_shutdown();
return 0;
}

Loading…
Cancel
Save