xDS Security: Use new way to fetch certificate provider plugin instance config (#27264)

* xDS Security: Use new way to fetch certificate provider plugin instance
config

* Reviewer comments

* Additional fields to NACK

* Move NACKing tests for tls_certificates and tls_certificate_sds_securet_configs to client-side
pull/27300/head
Yash Tibrewal 4 years ago committed by GitHub
parent f26c107651
commit 1a009cf4e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 20
      src/core/ext/filters/client_channel/lb_policy/xds/cds.cc
  2. 408
      src/core/ext/xds/xds_api.cc
  3. 41
      src/core/ext/xds/xds_api.h
  4. 12
      src/core/ext/xds/xds_server_config_fetcher.cc
  5. 80
      src/proto/grpc/testing/xds/v3/tls.proto
  6. 335
      test/cpp/end2end/xds_end2end_test.cc

@ -572,11 +572,11 @@ grpc_error_handle CdsLb::UpdateXdsCertificateProvider(
}
// Configure root cert.
absl::string_view root_provider_instance_name =
cluster_data.common_tls_context.combined_validation_context
.validation_context_certificate_provider_instance.instance_name;
cluster_data.common_tls_context.certificate_validation_context
.ca_certificate_provider_instance.instance_name;
absl::string_view root_provider_cert_name =
cluster_data.common_tls_context.combined_validation_context
.validation_context_certificate_provider_instance.certificate_name;
cluster_data.common_tls_context.certificate_validation_context
.ca_certificate_provider_instance.certificate_name;
RefCountedPtr<XdsCertificateProvider> new_root_provider;
if (!root_provider_instance_name.empty()) {
new_root_provider =
@ -612,11 +612,11 @@ grpc_error_handle CdsLb::UpdateXdsCertificateProvider(
: root_certificate_provider_->distributor());
// Configure identity cert.
absl::string_view identity_provider_instance_name =
cluster_data.common_tls_context
.tls_certificate_certificate_provider_instance.instance_name;
cluster_data.common_tls_context.tls_certificate_provider_instance
.instance_name;
absl::string_view identity_provider_cert_name =
cluster_data.common_tls_context
.tls_certificate_certificate_provider_instance.certificate_name;
cluster_data.common_tls_context.tls_certificate_provider_instance
.certificate_name;
RefCountedPtr<XdsCertificateProvider> new_identity_provider;
if (!identity_provider_instance_name.empty()) {
new_identity_provider =
@ -653,8 +653,8 @@ grpc_error_handle CdsLb::UpdateXdsCertificateProvider(
: identity_certificate_provider_->distributor());
// Configure SAN matchers.
const std::vector<StringMatcher>& match_subject_alt_names =
cluster_data.common_tls_context.combined_validation_context
.default_validation_context.match_subject_alt_names;
cluster_data.common_tls_context.certificate_validation_context
.match_subject_alt_names;
xds_certificate_provider_->UpdateSubjectAlternativeNameMatchers(
cluster_name, match_subject_alt_names);
return GRPC_ERROR_NONE;

@ -438,11 +438,11 @@ bool XdsApi::CommonTlsContext::CertificateValidationContext::Empty() const {
}
//
// XdsApi::CommonTlsContext::CertificateValidationContext
// XdsApi::CommonTlsContext::CertificateProviderPluginInstance
//
std::string XdsApi::CommonTlsContext::CertificateProviderInstance::ToString()
const {
std::string
XdsApi::CommonTlsContext::CertificateProviderPluginInstance::ToString() const {
absl::InlinedVector<std::string, 2> contents;
if (!instance_name.empty()) {
contents.push_back(absl::StrFormat("instance_name=%s", instance_name));
@ -454,34 +454,9 @@ std::string XdsApi::CommonTlsContext::CertificateProviderInstance::ToString()
return absl::StrCat("{", absl::StrJoin(contents, ", "), "}");
}
bool XdsApi::CommonTlsContext::CertificateProviderInstance::Empty() const {
return instance_name.empty() && certificate_name.empty();
}
//
// XdsApi::CommonTlsContext::CombinedCertificateValidationContext
//
std::string
XdsApi::CommonTlsContext::CombinedCertificateValidationContext::ToString()
const {
absl::InlinedVector<std::string, 2> contents;
if (!default_validation_context.Empty()) {
contents.push_back(absl::StrFormat("default_validation_context=%s",
default_validation_context.ToString()));
}
if (!validation_context_certificate_provider_instance.Empty()) {
contents.push_back(absl::StrFormat(
"validation_context_certificate_provider_instance=%s",
validation_context_certificate_provider_instance.ToString()));
}
return absl::StrCat("{", absl::StrJoin(contents, ", "), "}");
}
bool XdsApi::CommonTlsContext::CombinedCertificateValidationContext::Empty()
bool XdsApi::CommonTlsContext::CertificateProviderPluginInstance::Empty()
const {
return default_validation_context.Empty() &&
validation_context_certificate_provider_instance.Empty();
return instance_name.empty() && certificate_name.empty();
}
//
@ -490,21 +465,22 @@ bool XdsApi::CommonTlsContext::CombinedCertificateValidationContext::Empty()
std::string XdsApi::CommonTlsContext::ToString() const {
absl::InlinedVector<std::string, 2> contents;
if (!tls_certificate_certificate_provider_instance.Empty()) {
contents.push_back(absl::StrFormat(
"tls_certificate_certificate_provider_instance=%s",
tls_certificate_certificate_provider_instance.ToString()));
if (!tls_certificate_provider_instance.Empty()) {
contents.push_back(
absl::StrFormat("tls_certificate_provider_instance=%s",
tls_certificate_provider_instance.ToString()));
}
if (!combined_validation_context.Empty()) {
contents.push_back(absl::StrFormat("combined_validation_context=%s",
combined_validation_context.ToString()));
if (!certificate_validation_context.Empty()) {
contents.push_back(
absl::StrFormat("certificate_validation_context=%s",
certificate_validation_context.ToString()));
}
return absl::StrCat("{", absl::StrJoin(contents, ", "), "}");
}
bool XdsApi::CommonTlsContext::Empty() const {
return tls_certificate_certificate_provider_instance.Empty() &&
combined_validation_context.Empty();
return tls_certificate_provider_instance.Empty() &&
certificate_validation_context.Empty();
}
//
@ -1946,13 +1922,18 @@ grpc_error_handle RouteConfigParse(
return GRPC_ERROR_NONE;
}
// CertificateProviderInstance is deprecated but we are still supporting it for
// backward compatibility reasons. Note that we still parse the data into the
// same CertificateProviderPluginInstance struct since the fields are the same.
// TODO(yashykt): Remove this once we stop supporting the old way of fetching
// certificate provider instances.
grpc_error_handle CertificateProviderInstanceParse(
const EncodingContext& context,
const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance*
certificate_provider_instance_proto,
XdsApi::CommonTlsContext::CertificateProviderInstance*
certificate_provider_instance) {
*certificate_provider_instance = {
XdsApi::CommonTlsContext::CertificateProviderPluginInstance*
certificate_provider_plugin_instance) {
*certificate_provider_plugin_instance = {
UpbStringToStdString(
envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance_instance_name(
certificate_provider_instance_proto)),
@ -1960,22 +1941,160 @@ grpc_error_handle CertificateProviderInstanceParse(
envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance_certificate_name(
certificate_provider_instance_proto))};
if (context.certificate_provider_definition_map->find(
certificate_provider_instance->instance_name) ==
certificate_provider_plugin_instance->instance_name) ==
context.certificate_provider_definition_map->end()) {
return GRPC_ERROR_CREATE_FROM_COPIED_STRING(
absl::StrCat("Unrecognized certificate provider instance name: ",
certificate_provider_instance->instance_name)
certificate_provider_plugin_instance->instance_name)
.c_str());
}
return GRPC_ERROR_NONE;
}
grpc_error_handle CertificateProviderPluginInstanceParse(
const EncodingContext& context,
const envoy_extensions_transport_sockets_tls_v3_CertificateProviderPluginInstance*
certificate_provider_plugin_instance_proto,
XdsApi::CommonTlsContext::CertificateProviderPluginInstance*
certificate_provider_plugin_instance) {
*certificate_provider_plugin_instance = {
UpbStringToStdString(
envoy_extensions_transport_sockets_tls_v3_CertificateProviderPluginInstance_instance_name(
certificate_provider_plugin_instance_proto)),
UpbStringToStdString(
envoy_extensions_transport_sockets_tls_v3_CertificateProviderPluginInstance_certificate_name(
certificate_provider_plugin_instance_proto))};
if (context.certificate_provider_definition_map->find(
certificate_provider_plugin_instance->instance_name) ==
context.certificate_provider_definition_map->end()) {
return GRPC_ERROR_CREATE_FROM_COPIED_STRING(
absl::StrCat("Unrecognized certificate provider instance name: ",
certificate_provider_plugin_instance->instance_name)
.c_str());
}
return GRPC_ERROR_NONE;
}
grpc_error_handle CertificateValidationContextParse(
const EncodingContext& context,
const envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext*
certificate_validation_context_proto,
XdsApi::CommonTlsContext::CertificateValidationContext*
certificate_validation_context) {
std::vector<grpc_error_handle> errors;
size_t len = 0;
auto* subject_alt_names_matchers =
envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_match_subject_alt_names(
certificate_validation_context_proto, &len);
for (size_t i = 0; i < len; ++i) {
StringMatcher::Type type;
std::string matcher;
if (envoy_type_matcher_v3_StringMatcher_has_exact(
subject_alt_names_matchers[i])) {
type = StringMatcher::Type::kExact;
matcher = UpbStringToStdString(envoy_type_matcher_v3_StringMatcher_exact(
subject_alt_names_matchers[i]));
} else if (envoy_type_matcher_v3_StringMatcher_has_prefix(
subject_alt_names_matchers[i])) {
type = StringMatcher::Type::kPrefix;
matcher = UpbStringToStdString(envoy_type_matcher_v3_StringMatcher_prefix(
subject_alt_names_matchers[i]));
} else if (envoy_type_matcher_v3_StringMatcher_has_suffix(
subject_alt_names_matchers[i])) {
type = StringMatcher::Type::kSuffix;
matcher = UpbStringToStdString(envoy_type_matcher_v3_StringMatcher_suffix(
subject_alt_names_matchers[i]));
} else if (envoy_type_matcher_v3_StringMatcher_has_contains(
subject_alt_names_matchers[i])) {
type = StringMatcher::Type::kContains;
matcher =
UpbStringToStdString(envoy_type_matcher_v3_StringMatcher_contains(
subject_alt_names_matchers[i]));
} else if (envoy_type_matcher_v3_StringMatcher_has_safe_regex(
subject_alt_names_matchers[i])) {
type = StringMatcher::Type::kSafeRegex;
auto* regex_matcher = envoy_type_matcher_v3_StringMatcher_safe_regex(
subject_alt_names_matchers[i]);
matcher = UpbStringToStdString(
envoy_type_matcher_v3_RegexMatcher_regex(regex_matcher));
} else {
errors.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Invalid StringMatcher specified"));
continue;
}
bool ignore_case = envoy_type_matcher_v3_StringMatcher_ignore_case(
subject_alt_names_matchers[i]);
absl::StatusOr<StringMatcher> string_matcher =
StringMatcher::Create(type, matcher,
/*case_sensitive=*/!ignore_case);
if (!string_matcher.ok()) {
errors.push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING(
absl::StrCat("string matcher: ", string_matcher.status().message())
.c_str()));
continue;
}
if (type == StringMatcher::Type::kSafeRegex && ignore_case) {
errors.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"StringMatcher: ignore_case has no effect for SAFE_REGEX."));
continue;
}
certificate_validation_context->match_subject_alt_names.push_back(
std::move(string_matcher.value()));
}
auto* ca_certificate_provider_instance =
envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_ca_certificate_provider_instance(
certificate_validation_context_proto);
if (ca_certificate_provider_instance != nullptr) {
grpc_error_handle error = CertificateProviderPluginInstanceParse(
context, ca_certificate_provider_instance,
&certificate_validation_context->ca_certificate_provider_instance);
if (error != GRPC_ERROR_NONE) errors.push_back(error);
}
if (envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_verify_certificate_spki(
certificate_validation_context_proto, nullptr) != nullptr) {
errors.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"CertificateValidationContext: verify_certificate_spki "
"unsupported"));
}
if (envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_verify_certificate_hash(
certificate_validation_context_proto, nullptr) != nullptr) {
errors.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"CertificateValidationContext: verify_certificate_hash "
"unsupported"));
}
auto* require_signed_certificate_timestamp =
envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_require_signed_certificate_timestamp(
certificate_validation_context_proto);
if (require_signed_certificate_timestamp != nullptr &&
google_protobuf_BoolValue_value(require_signed_certificate_timestamp)) {
errors.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"CertificateValidationContext: "
"require_signed_certificate_timestamp unsupported"));
}
if (envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_has_crl(
certificate_validation_context_proto)) {
errors.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"CertificateValidationContext: crl unsupported"));
}
if (envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_has_custom_validator_config(
certificate_validation_context_proto)) {
errors.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"CertificateValidationContext: custom_validator_config "
"unsupported"));
}
return GRPC_ERROR_CREATE_FROM_VECTOR(
"Error parsing CertificateValidationContext", &errors);
}
grpc_error_handle CommonTlsContextParse(
const EncodingContext& context,
const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext*
common_tls_context_proto,
XdsApi::CommonTlsContext* common_tls_context) {
std::vector<grpc_error_handle> errors;
// The validation context is derived from the oneof in
// 'validation_context_type'. 'validation_context_sds_secret_config' is not
// supported.
auto* combined_validation_context =
envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_combined_validation_context(
common_tls_context_proto);
@ -1984,123 +2103,89 @@ grpc_error_handle CommonTlsContextParse(
envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_default_validation_context(
combined_validation_context);
if (default_validation_context != nullptr) {
size_t len = 0;
auto* subject_alt_names_matchers =
envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_match_subject_alt_names(
default_validation_context, &len);
for (size_t i = 0; i < len; ++i) {
StringMatcher::Type type;
std::string matcher;
if (envoy_type_matcher_v3_StringMatcher_has_exact(
subject_alt_names_matchers[i])) {
type = StringMatcher::Type::kExact;
matcher =
UpbStringToStdString(envoy_type_matcher_v3_StringMatcher_exact(
subject_alt_names_matchers[i]));
} else if (envoy_type_matcher_v3_StringMatcher_has_prefix(
subject_alt_names_matchers[i])) {
type = StringMatcher::Type::kPrefix;
matcher =
UpbStringToStdString(envoy_type_matcher_v3_StringMatcher_prefix(
subject_alt_names_matchers[i]));
} else if (envoy_type_matcher_v3_StringMatcher_has_suffix(
subject_alt_names_matchers[i])) {
type = StringMatcher::Type::kSuffix;
matcher =
UpbStringToStdString(envoy_type_matcher_v3_StringMatcher_suffix(
subject_alt_names_matchers[i]));
} else if (envoy_type_matcher_v3_StringMatcher_has_contains(
subject_alt_names_matchers[i])) {
type = StringMatcher::Type::kContains;
matcher =
UpbStringToStdString(envoy_type_matcher_v3_StringMatcher_contains(
subject_alt_names_matchers[i]));
} else if (envoy_type_matcher_v3_StringMatcher_has_safe_regex(
subject_alt_names_matchers[i])) {
type = StringMatcher::Type::kSafeRegex;
auto* regex_matcher = envoy_type_matcher_v3_StringMatcher_safe_regex(
subject_alt_names_matchers[i]);
matcher = UpbStringToStdString(
envoy_type_matcher_v3_RegexMatcher_regex(regex_matcher));
} else {
errors.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Invalid StringMatcher specified"));
continue;
}
bool ignore_case = envoy_type_matcher_v3_StringMatcher_ignore_case(
subject_alt_names_matchers[i]);
absl::StatusOr<StringMatcher> string_matcher =
StringMatcher::Create(type, matcher,
/*case_sensitive=*/!ignore_case);
if (!string_matcher.ok()) {
errors.push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING(
absl::StrCat("string matcher: ",
string_matcher.status().message())
.c_str()));
continue;
}
if (type == StringMatcher::Type::kSafeRegex && ignore_case) {
errors.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"StringMatcher: ignore_case has no effect for SAFE_REGEX."));
continue;
}
common_tls_context->combined_validation_context
.default_validation_context.match_subject_alt_names.push_back(
std::move(string_matcher.value()));
}
if (envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_verify_certificate_spki(
default_validation_context, nullptr) != nullptr) {
errors.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"CertificateValidationContext: verify_certificate_spki "
"unsupported"));
}
if (envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_verify_certificate_hash(
default_validation_context, nullptr) != nullptr) {
errors.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"CertificateValidationContext: verify_certificate_hash "
"unsupported"));
}
auto* require_signed_certificate_timestamp =
envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_require_signed_certificate_timestamp(
default_validation_context);
if (require_signed_certificate_timestamp != nullptr &&
google_protobuf_BoolValue_value(
require_signed_certificate_timestamp)) {
errors.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"CertificateValidationContext: "
"require_signed_certificate_timestamp unsupported"));
}
if (envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_has_crl(
default_validation_context)) {
errors.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"CertificateValidationContext: crl unsupported"));
}
if (envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_has_custom_validator_config(
default_validation_context)) {
errors.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"CertificateValidationContext: custom_validator_config "
"unsupported"));
}
grpc_error_handle error = CertificateValidationContextParse(
context, default_validation_context,
&common_tls_context->certificate_validation_context);
if (error != GRPC_ERROR_NONE) errors.push_back(error);
}
// If after parsing default_validation_context,
// common_tls_context->certificate_validation_context.ca_certificate_provider_instance
// is empty, fall back onto
// 'validation_context_certificate_provider_instance' inside
// 'combined_validation_context'. Note that this way of fetching root
// certificates is deprecated and will be removed in the future.
// TODO(yashykt): Remove this once it's no longer needed.
auto* validation_context_certificate_provider_instance =
envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_validation_context_certificate_provider_instance(
combined_validation_context);
if (validation_context_certificate_provider_instance != nullptr) {
if (common_tls_context->certificate_validation_context
.ca_certificate_provider_instance.Empty() &&
validation_context_certificate_provider_instance != nullptr) {
grpc_error_handle error = CertificateProviderInstanceParse(
context, validation_context_certificate_provider_instance,
&common_tls_context->combined_validation_context
.validation_context_certificate_provider_instance);
&common_tls_context->certificate_validation_context
.ca_certificate_provider_instance);
if (error != GRPC_ERROR_NONE) errors.push_back(error);
}
} else {
auto* validation_context =
envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_validation_context(
common_tls_context_proto);
if (validation_context != nullptr) {
grpc_error_handle error = CertificateValidationContextParse(
context, validation_context,
&common_tls_context->certificate_validation_context);
if (error != GRPC_ERROR_NONE) errors.push_back(error);
} else if (
envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_has_validation_context_sds_secret_config(
common_tls_context_proto)) {
errors.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"validation_context_sds_secret_config unsupported"));
}
}
auto* tls_certificate_certificate_provider_instance =
envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_tls_certificate_certificate_provider_instance(
auto* tls_certificate_provider_instance =
envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_tls_certificate_provider_instance(
common_tls_context_proto);
if (tls_certificate_certificate_provider_instance != nullptr) {
grpc_error_handle error = CertificateProviderInstanceParse(
context, tls_certificate_certificate_provider_instance,
&common_tls_context->tls_certificate_certificate_provider_instance);
if (tls_certificate_provider_instance != nullptr) {
grpc_error_handle error = CertificateProviderPluginInstanceParse(
context, tls_certificate_provider_instance,
&common_tls_context->tls_certificate_provider_instance);
if (error != GRPC_ERROR_NONE) errors.push_back(error);
} else {
// Fall back onto 'tls_certificate_certificate_provider_instance'. Note that
// this way of fetching identity certificates is deprecated and will be
// removed in the future.
// TODO(yashykt): Remove this once it's no longer needed.
auto* tls_certificate_certificate_provider_instance =
envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_tls_certificate_certificate_provider_instance(
common_tls_context_proto);
if (tls_certificate_certificate_provider_instance != nullptr) {
grpc_error_handle error = CertificateProviderInstanceParse(
context, tls_certificate_certificate_provider_instance,
&common_tls_context->tls_certificate_provider_instance);
if (error != GRPC_ERROR_NONE) errors.push_back(error);
} else {
if (envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_has_tls_certificates(
common_tls_context_proto)) {
errors.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"tls_certificates unsupported"));
}
if (envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_has_tls_certificate_sds_secret_configs(
common_tls_context_proto)) {
errors.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"tls_certificate_sds_secret_configs unsupported"));
}
}
}
if (envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_has_tls_params(
common_tls_context_proto)) {
errors.push_back(
GRPC_ERROR_CREATE_FROM_STATIC_STRING("tls_params unsupported"));
}
if (envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_has_custom_handshaker(
common_tls_context_proto)) {
errors.push_back(
GRPC_ERROR_CREATE_FROM_STATIC_STRING("custom_handshaker unsupported"));
}
return GRPC_ERROR_CREATE_FROM_VECTOR("Error parsing CommonTlsContext",
&errors);
@ -2335,20 +2420,23 @@ grpc_error_handle DownstreamTlsContextParse(
}
}
if (downstream_tls_context->common_tls_context
.tls_certificate_certificate_provider_instance.instance_name
.empty()) {
.tls_certificate_provider_instance.instance_name.empty()) {
errors.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"TLS configuration provided but no "
"tls_certificate_certificate_provider_instance found."));
"tls_certificate_provider_instance found."));
}
if (downstream_tls_context->require_client_certificate &&
downstream_tls_context->common_tls_context.combined_validation_context
.validation_context_certificate_provider_instance.instance_name
.empty()) {
downstream_tls_context->common_tls_context.certificate_validation_context
.ca_certificate_provider_instance.instance_name.empty()) {
errors.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"TLS configuration requires client certificates but no certificate "
"provider instance specified for validation."));
}
if (!downstream_tls_context->common_tls_context.certificate_validation_context
.match_subject_alt_names.empty()) {
errors.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"match_subject_alt_names not supported on servers"));
}
return GRPC_ERROR_CREATE_FROM_VECTOR("Error parsing DownstreamTlsContext",
&errors);
}
@ -2840,13 +2928,11 @@ grpc_error_handle UpstreamTlsContextParse(
}
}
}
if (common_tls_context->combined_validation_context
.validation_context_certificate_provider_instance.instance_name
.empty()) {
if (common_tls_context->certificate_validation_context
.ca_certificate_provider_instance.instance_name.empty()) {
return GRPC_ERROR_CREATE_FROM_COPIED_STRING(
"UpstreamTlsContext: TLS configuration provided but no "
"validation_context_certificate_provider_instance "
"found.");
"ca_certificate_provider_instance found.");
}
return GRPC_ERROR_NONE;
}

@ -193,22 +193,11 @@ class XdsApi {
};
struct CommonTlsContext {
struct CertificateValidationContext {
std::vector<StringMatcher> match_subject_alt_names;
bool operator==(const CertificateValidationContext& other) const {
return match_subject_alt_names == other.match_subject_alt_names;
}
std::string ToString() const;
bool Empty() const;
};
struct CertificateProviderInstance {
struct CertificateProviderPluginInstance {
std::string instance_name;
std::string certificate_name;
bool operator==(const CertificateProviderInstance& other) const {
bool operator==(const CertificateProviderPluginInstance& other) const {
return instance_name == other.instance_name &&
certificate_name == other.certificate_name;
}
@ -217,28 +206,28 @@ class XdsApi {
bool Empty() const;
};
struct CombinedCertificateValidationContext {
CertificateValidationContext default_validation_context;
CertificateProviderInstance
validation_context_certificate_provider_instance;
struct CertificateValidationContext {
CertificateProviderPluginInstance ca_certificate_provider_instance;
std::vector<StringMatcher> match_subject_alt_names;
bool operator==(const CombinedCertificateValidationContext& other) const {
return default_validation_context == other.default_validation_context &&
validation_context_certificate_provider_instance ==
other.validation_context_certificate_provider_instance;
bool operator==(const CertificateValidationContext& other) const {
return ca_certificate_provider_instance ==
other.ca_certificate_provider_instance &&
match_subject_alt_names == other.match_subject_alt_names;
}
std::string ToString() const;
bool Empty() const;
};
CertificateProviderInstance tls_certificate_certificate_provider_instance;
CombinedCertificateValidationContext combined_validation_context;
CertificateValidationContext certificate_validation_context;
CertificateProviderPluginInstance tls_certificate_provider_instance;
bool operator==(const CommonTlsContext& other) const {
return tls_certificate_certificate_provider_instance ==
other.tls_certificate_certificate_provider_instance &&
combined_validation_context == other.combined_validation_context;
return certificate_validation_context ==
other.certificate_validation_context &&
tls_certificate_provider_instance ==
other.tls_certificate_provider_instance;
}
std::string ToString() const;

@ -259,12 +259,12 @@ FilterChainMatchManager::CreateOrGetXdsCertificateProviderFromFilterChainData(
// Configure root cert.
absl::string_view root_provider_instance_name =
filter_chain->downstream_tls_context.common_tls_context
.combined_validation_context
.validation_context_certificate_provider_instance.instance_name;
.certificate_validation_context.ca_certificate_provider_instance
.instance_name;
absl::string_view root_provider_cert_name =
filter_chain->downstream_tls_context.common_tls_context
.combined_validation_context
.validation_context_certificate_provider_instance.certificate_name;
.certificate_validation_context.ca_certificate_provider_instance
.certificate_name;
if (!root_provider_instance_name.empty()) {
certificate_providers.root =
xds_client_->certificate_provider_store()
@ -278,10 +278,10 @@ FilterChainMatchManager::CreateOrGetXdsCertificateProviderFromFilterChainData(
// Configure identity cert.
absl::string_view identity_provider_instance_name =
filter_chain->downstream_tls_context.common_tls_context
.tls_certificate_certificate_provider_instance.instance_name;
.tls_certificate_provider_instance.instance_name;
absl::string_view identity_provider_cert_name =
filter_chain->downstream_tls_context.common_tls_context
.tls_certificate_certificate_provider_instance.certificate_name;
.tls_certificate_provider_instance.certificate_name;
if (!identity_provider_instance_name.empty()) {
certificate_providers.instance =
xds_client_->certificate_provider_store()

@ -24,7 +24,33 @@ import "src/proto/grpc/testing/xds/v3/string.proto";
import "google/protobuf/wrappers.proto";
// Indicates a certificate to be obtained from a named CertificateProvider plugin instance.
// The plugin instances are defined in the client's bootstrap file.
// The plugin allows certificates to be fetched/refreshed over the network asynchronously with
// respect to the TLS handshake.
// [#not-implemented-hide:]
message CertificateProviderPluginInstance {
// Provider instance name. If not present, defaults to "default".
//
// Instance names should generally be defined not in terms of the underlying provider
// implementation (e.g., "file_watcher") but rather in terms of the function of the
// certificates (e.g., "foo_deployment_identity").
string instance_name = 1;
// Opaque name used to specify certificate instances or types. For example, "ROOTCA" to specify
// a root-certificate (validation context) or "example.com" to specify a certificate for a
// particular domain. Not all provider instances will actually use this field, so the value
// defaults to the empty string.
string certificate_name = 2;
}
message CertificateValidationContext {
// Certificate provider instance for fetching TLS certificates.
//
// Only one of *trusted_ca* and *ca_certificate_provider_instance* may be specified.
// [#not-implemented-hide:]
CertificateProviderPluginInstance ca_certificate_provider_instance = 13;
// An optional list of base64-encoded SHA-256 hashes. If specified, Envoy will verify that the
// SHA-256 of the DER-encoded Subject Public Key Information (SPKI) of the presented certificate
// matches one of the specified values.
@ -212,10 +238,60 @@ message CommonTlsContext {
CertificateProviderInstance validation_context_certificate_provider_instance = 4;
}
message TlsParameters {}
// TLS protocol versions, cipher suites etc.
TlsParameters tls_params = 1;
message TlsCertificate {}
// :ref:`Multiple TLS certificates <arch_overview_ssl_cert_select>` can be associated with the
// same context to allow both RSA and ECDSA certificates.
//
// Only a single TLS certificate is supported in client contexts. In server contexts, the first
// RSA certificate is used for clients that only support RSA and the first ECDSA certificate is
// used for clients that support ECDSA.
//
// Only one of *tls_certificates*, *tls_certificate_sds_secret_configs*,
// and *tls_certificate_provider_instance* may be used.
// [#next-major-version: These mutually exclusive fields should ideally be in a oneof, but it's
// not legal to put a repeated field in a oneof. In the next major version, we should rework
// this to avoid this problem.]
repeated TlsCertificate tls_certificates = 2;
message SdsSecretConfig {}
// Configs for fetching TLS certificates via SDS API. Note SDS API allows certificates to be
// fetched/refreshed over the network asynchronously with respect to the TLS handshake.
//
// The same number and types of certificates as :ref:`tls_certificates <envoy_v3_api_field_extensions.transport_sockets.tls.v3.CommonTlsContext.tls_certificates>`
// are valid in the the certificates fetched through this setting.
//
// Only one of *tls_certificates*, *tls_certificate_sds_secret_configs*,
// and *tls_certificate_provider_instance* may be used.
// [#next-major-version: These mutually exclusive fields should ideally be in a oneof, but it's
// not legal to put a repeated field in a oneof. In the next major version, we should rework
// this to avoid this problem.]
repeated SdsSecretConfig tls_certificate_sds_secret_configs = 6;
// Certificate provider instance for fetching TLS certs.
//
// Only one of *tls_certificates*, *tls_certificate_sds_secret_configs*,
// and *tls_certificate_provider_instance* may be used.
// [#not-implemented-hide:]
CertificateProviderPluginInstance tls_certificate_provider_instance = 14;
// Certificate provider instance for fetching TLS certificates.
CertificateProviderInstance tls_certificate_certificate_provider_instance = 11;
oneof validation_context_type {
// How to validate peer certificates.
CertificateValidationContext validation_context = 3;
// Config for fetching validation context via SDS API. Note SDS API allows certificates to be
// fetched/refreshed over the network asynchronously with respect to the TLS handshake.
SdsSecretConfig validation_context_sds_secret_config = 7;
// Combined certificate validation context holds a default CertificateValidationContext
// and SDS config. When SDS server returns dynamic CertificateValidationContext, both dynamic
// and default CertificateValidationContext are merged into a new CertificateValidationContext
@ -225,4 +301,8 @@ message CommonTlsContext {
// CertificateValidationContext, and logical OR is applied to boolean fields.
CombinedCertificateValidationContext combined_validation_context = 8;
}
// Custom TLS handshaker. If empty, defaults to native TLS handshaking
// behavior.
config.core.v3.TypedExtensionConfig custom_handshaker = 13;
}

@ -8257,27 +8257,26 @@ class XdsSecurityTest : public BasicTest {
UpstreamTlsContext upstream_tls_context;
if (!identity_instance_name.empty()) {
upstream_tls_context.mutable_common_tls_context()
->mutable_tls_certificate_certificate_provider_instance()
->mutable_tls_certificate_provider_instance()
->set_instance_name(std::string(identity_instance_name));
upstream_tls_context.mutable_common_tls_context()
->mutable_tls_certificate_certificate_provider_instance()
->mutable_tls_certificate_provider_instance()
->set_certificate_name(std::string(identity_certificate_name));
}
if (!root_instance_name.empty()) {
upstream_tls_context.mutable_common_tls_context()
->mutable_combined_validation_context()
->mutable_validation_context_certificate_provider_instance()
->mutable_validation_context()
->mutable_ca_certificate_provider_instance()
->set_instance_name(std::string(root_instance_name));
upstream_tls_context.mutable_common_tls_context()
->mutable_combined_validation_context()
->mutable_validation_context_certificate_provider_instance()
->mutable_validation_context()
->mutable_ca_certificate_provider_instance()
->set_certificate_name(std::string(root_certificate_name));
}
if (!san_matchers.empty()) {
auto* validation_context =
upstream_tls_context.mutable_common_tls_context()
->mutable_combined_validation_context()
->mutable_default_validation_context();
->mutable_validation_context();
for (const auto& san_matcher : san_matchers) {
*validation_context->add_match_subject_alt_names() = san_matcher;
}
@ -8367,9 +8366,8 @@ TEST_P(XdsSecurityTest,
balancers_[0]->ads_service()->cds_response_state();
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED);
EXPECT_THAT(response_state.error_message,
::testing::HasSubstr(
"TLS configuration provided but no "
"validation_context_certificate_provider_instance found."));
::testing::HasSubstr("TLS configuration provided but no "
"ca_certificate_provider_instance found."));
}
TEST_P(
@ -8380,8 +8378,7 @@ TEST_P(
transport_socket->set_name("envoy.transport_sockets.tls");
UpstreamTlsContext upstream_tls_context;
auto* validation_context = upstream_tls_context.mutable_common_tls_context()
->mutable_combined_validation_context()
->mutable_default_validation_context();
->mutable_validation_context();
*validation_context->add_match_subject_alt_names() = server_san_exact_;
transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context);
balancers_[0]->ads_service()->SetCdsResource(cluster);
@ -8390,20 +8387,19 @@ TEST_P(
balancers_[0]->ads_service()->cds_response_state();
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED);
EXPECT_THAT(response_state.error_message,
::testing::HasSubstr(
"TLS configuration provided but no "
"validation_context_certificate_provider_instance found."));
::testing::HasSubstr("TLS configuration provided but no "
"ca_certificate_provider_instance found."));
}
TEST_P(
XdsSecurityTest,
TlsCertificateCertificateProviderInstanceWithoutValidationContextCertificateProviderInstance) {
TlsCertificateProviderInstanceWithoutValidationContextCertificateProviderInstance) {
auto cluster = default_cluster_;
auto* transport_socket = cluster.mutable_transport_socket();
transport_socket->set_name("envoy.transport_sockets.tls");
UpstreamTlsContext upstream_tls_context;
upstream_tls_context.mutable_common_tls_context()
->mutable_tls_certificate_certificate_provider_instance()
->mutable_tls_certificate_provider_instance()
->set_instance_name(std::string("fake_plugin1"));
transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context);
balancers_[0]->ads_service()->SetCdsResource(cluster);
@ -8412,9 +8408,8 @@ TEST_P(
balancers_[0]->ads_service()->cds_response_state();
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED);
EXPECT_THAT(response_state.error_message,
::testing::HasSubstr(
"TLS configuration provided but no "
"validation_context_certificate_provider_instance found."));
::testing::HasSubstr("TLS configuration provided but no "
"ca_certificate_provider_instance found."));
}
TEST_P(XdsSecurityTest, RegexSanMatcherDoesNotAllowIgnoreCase) {
@ -8423,12 +8418,11 @@ TEST_P(XdsSecurityTest, RegexSanMatcherDoesNotAllowIgnoreCase) {
transport_socket->set_name("envoy.transport_sockets.tls");
UpstreamTlsContext upstream_tls_context;
upstream_tls_context.mutable_common_tls_context()
->mutable_combined_validation_context()
->mutable_validation_context_certificate_provider_instance()
->mutable_validation_context()
->mutable_ca_certificate_provider_instance()
->set_instance_name(std::string("fake_plugin1"));
auto* validation_context = upstream_tls_context.mutable_common_tls_context()
->mutable_combined_validation_context()
->mutable_default_validation_context();
->mutable_validation_context();
StringMatcher matcher;
matcher.mutable_safe_regex()->mutable_google_re2();
matcher.mutable_safe_regex()->set_regex(
@ -8452,8 +8446,8 @@ TEST_P(XdsSecurityTest, UnknownRootCertificateProvider) {
transport_socket->set_name("envoy.transport_sockets.tls");
UpstreamTlsContext upstream_tls_context;
upstream_tls_context.mutable_common_tls_context()
->mutable_combined_validation_context()
->mutable_validation_context_certificate_provider_instance()
->mutable_validation_context()
->mutable_ca_certificate_provider_instance()
->set_instance_name("unknown");
transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context);
balancers_[0]->ads_service()->SetCdsResource(cluster);
@ -8475,11 +8469,11 @@ TEST_P(XdsSecurityTest, UnknownIdentityCertificateProvider) {
transport_socket->set_name("envoy.transport_sockets.tls");
UpstreamTlsContext upstream_tls_context;
upstream_tls_context.mutable_common_tls_context()
->mutable_tls_certificate_certificate_provider_instance()
->mutable_tls_certificate_provider_instance()
->set_instance_name("unknown");
upstream_tls_context.mutable_common_tls_context()
->mutable_combined_validation_context()
->mutable_validation_context_certificate_provider_instance()
->mutable_validation_context()
->mutable_ca_certificate_provider_instance()
->set_instance_name("fake_plugin1");
transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context);
balancers_[0]->ads_service()->SetCdsResource(cluster);
@ -8503,12 +8497,11 @@ TEST_P(XdsSecurityTest,
transport_socket->set_name("envoy.transport_sockets.tls");
UpstreamTlsContext upstream_tls_context;
upstream_tls_context.mutable_common_tls_context()
->mutable_combined_validation_context()
->mutable_validation_context_certificate_provider_instance()
->mutable_validation_context()
->mutable_ca_certificate_provider_instance()
->set_instance_name("fake_plugin1");
upstream_tls_context.mutable_common_tls_context()
->mutable_combined_validation_context()
->mutable_default_validation_context()
->mutable_validation_context()
->add_verify_certificate_spki("spki");
transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context);
balancers_[0]->ads_service()->SetCdsResource(cluster);
@ -8532,12 +8525,11 @@ TEST_P(XdsSecurityTest,
transport_socket->set_name("envoy.transport_sockets.tls");
UpstreamTlsContext upstream_tls_context;
upstream_tls_context.mutable_common_tls_context()
->mutable_combined_validation_context()
->mutable_validation_context_certificate_provider_instance()
->mutable_validation_context()
->mutable_ca_certificate_provider_instance()
->set_instance_name("fake_plugin1");
upstream_tls_context.mutable_common_tls_context()
->mutable_combined_validation_context()
->mutable_default_validation_context()
->mutable_validation_context()
->add_verify_certificate_hash("hash");
transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context);
balancers_[0]->ads_service()->SetCdsResource(cluster);
@ -8561,12 +8553,11 @@ TEST_P(XdsSecurityTest,
transport_socket->set_name("envoy.transport_sockets.tls");
UpstreamTlsContext upstream_tls_context;
upstream_tls_context.mutable_common_tls_context()
->mutable_combined_validation_context()
->mutable_validation_context_certificate_provider_instance()
->mutable_validation_context()
->mutable_ca_certificate_provider_instance()
->set_instance_name("fake_plugin1");
upstream_tls_context.mutable_common_tls_context()
->mutable_combined_validation_context()
->mutable_default_validation_context()
->mutable_validation_context()
->mutable_require_signed_certificate_timestamp()
->set_value(true);
transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context);
@ -8590,12 +8581,11 @@ TEST_P(XdsSecurityTest, NacksCertificateValidationContextWithCrl) {
transport_socket->set_name("envoy.transport_sockets.tls");
UpstreamTlsContext upstream_tls_context;
upstream_tls_context.mutable_common_tls_context()
->mutable_combined_validation_context()
->mutable_validation_context_certificate_provider_instance()
->mutable_validation_context()
->mutable_ca_certificate_provider_instance()
->set_instance_name("fake_plugin1");
upstream_tls_context.mutable_common_tls_context()
->mutable_combined_validation_context()
->mutable_default_validation_context()
->mutable_validation_context()
->mutable_crl();
transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context);
balancers_[0]->ads_service()->SetCdsResource(cluster);
@ -8618,12 +8608,11 @@ TEST_P(XdsSecurityTest,
transport_socket->set_name("envoy.transport_sockets.tls");
UpstreamTlsContext upstream_tls_context;
upstream_tls_context.mutable_common_tls_context()
->mutable_combined_validation_context()
->mutable_validation_context_certificate_provider_instance()
->mutable_validation_context()
->mutable_ca_certificate_provider_instance()
->set_instance_name("fake_plugin1");
upstream_tls_context.mutable_common_tls_context()
->mutable_combined_validation_context()
->mutable_default_validation_context()
->mutable_validation_context()
->mutable_custom_validator_config();
transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context);
balancers_[0]->ads_service()->SetCdsResource(cluster);
@ -8637,6 +8626,165 @@ TEST_P(XdsSecurityTest,
"CertificateValidationContext: custom_validator_config unsupported"));
}
TEST_P(XdsSecurityTest, NacksValidationContextSdsSecretConfig) {
FakeCertificateProvider::CertDataMap fake1_cert_map = {
{"", {root_cert_, identity_pair_}}};
g_fake1_cert_data_map = &fake1_cert_map;
auto cluster = default_cluster_;
auto* transport_socket = cluster.mutable_transport_socket();
transport_socket->set_name("envoy.transport_sockets.tls");
UpstreamTlsContext upstream_tls_context;
upstream_tls_context.mutable_common_tls_context()
->mutable_validation_context_sds_secret_config();
transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context);
balancers_[0]->ads_service()->SetCdsResource(cluster);
ASSERT_TRUE(WaitForCdsNack()) << "timed out waiting for NACK";
const auto response_state =
balancers_[0]->ads_service()->cds_response_state();
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED);
EXPECT_THAT(
response_state.error_message,
::testing::HasSubstr("validation_context_sds_secret_config unsupported"));
}
TEST_P(XdsSecurityTest, NacksTlsParams) {
FakeCertificateProvider::CertDataMap fake1_cert_map = {
{"", {root_cert_, identity_pair_}}};
g_fake1_cert_data_map = &fake1_cert_map;
auto cluster = default_cluster_;
auto* transport_socket = cluster.mutable_transport_socket();
transport_socket->set_name("envoy.transport_sockets.tls");
UpstreamTlsContext upstream_tls_context;
upstream_tls_context.mutable_common_tls_context()
->mutable_validation_context()
->mutable_ca_certificate_provider_instance()
->set_instance_name("fake_plugin1");
upstream_tls_context.mutable_common_tls_context()->mutable_tls_params();
transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context);
balancers_[0]->ads_service()->SetCdsResource(cluster);
ASSERT_TRUE(WaitForCdsNack()) << "timed out waiting for NACK";
const auto response_state =
balancers_[0]->ads_service()->cds_response_state();
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED);
EXPECT_THAT(response_state.error_message,
::testing::HasSubstr("tls_params unsupported"));
}
TEST_P(XdsSecurityTest, NacksCustomHandshaker) {
FakeCertificateProvider::CertDataMap fake1_cert_map = {
{"", {root_cert_, identity_pair_}}};
g_fake1_cert_data_map = &fake1_cert_map;
auto cluster = default_cluster_;
auto* transport_socket = cluster.mutable_transport_socket();
transport_socket->set_name("envoy.transport_sockets.tls");
UpstreamTlsContext upstream_tls_context;
upstream_tls_context.mutable_common_tls_context()
->mutable_validation_context()
->mutable_ca_certificate_provider_instance()
->set_instance_name("fake_plugin1");
upstream_tls_context.mutable_common_tls_context()
->mutable_custom_handshaker();
transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context);
balancers_[0]->ads_service()->SetCdsResource(cluster);
ASSERT_TRUE(WaitForCdsNack()) << "timed out waiting for NACK";
const auto response_state =
balancers_[0]->ads_service()->cds_response_state();
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED);
EXPECT_THAT(response_state.error_message,
::testing::HasSubstr("custom_handshaker unsupported"));
}
TEST_P(XdsSecurityTest, NacksTlsCertificates) {
FakeCertificateProvider::CertDataMap fake1_cert_map = {
{"", {root_cert_, identity_pair_}}};
g_fake1_cert_data_map = &fake1_cert_map;
auto cluster = default_cluster_;
auto* transport_socket = cluster.mutable_transport_socket();
transport_socket->set_name("envoy.transport_sockets.tls");
UpstreamTlsContext upstream_tls_context;
upstream_tls_context.mutable_common_tls_context()
->mutable_validation_context()
->mutable_ca_certificate_provider_instance()
->set_instance_name("fake_plugin1");
upstream_tls_context.mutable_common_tls_context()->add_tls_certificates();
transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context);
balancers_[0]->ads_service()->SetCdsResource(cluster);
ASSERT_TRUE(WaitForCdsNack()) << "timed out waiting for NACK";
const auto response_state =
balancers_[0]->ads_service()->cds_response_state();
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED);
EXPECT_THAT(response_state.error_message,
::testing::HasSubstr("tls_certificates unsupported"));
}
TEST_P(XdsSecurityTest, NacksTlsCertificateSdsSecretConfigs) {
FakeCertificateProvider::CertDataMap fake1_cert_map = {
{"", {root_cert_, identity_pair_}}};
g_fake1_cert_data_map = &fake1_cert_map;
auto cluster = default_cluster_;
auto* transport_socket = cluster.mutable_transport_socket();
transport_socket->set_name("envoy.transport_sockets.tls");
UpstreamTlsContext upstream_tls_context;
upstream_tls_context.mutable_common_tls_context()
->mutable_validation_context()
->mutable_ca_certificate_provider_instance()
->set_instance_name("fake_plugin1");
upstream_tls_context.mutable_common_tls_context()
->add_tls_certificate_sds_secret_configs();
transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context);
balancers_[0]->ads_service()->SetCdsResource(cluster);
ASSERT_TRUE(WaitForCdsNack()) << "timed out waiting for NACK";
const auto response_state =
balancers_[0]->ads_service()->cds_response_state();
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED);
EXPECT_THAT(
response_state.error_message,
::testing::HasSubstr("tls_certificate_sds_secret_configs unsupported"));
}
TEST_P(XdsSecurityTest, TestTlsConfigurationInCombinedValidationContext) {
FakeCertificateProvider::CertDataMap fake1_cert_map = {
{"", {root_cert_, identity_pair_}}};
g_fake1_cert_data_map = &fake1_cert_map;
auto cluster = default_cluster_;
auto* transport_socket = cluster.mutable_transport_socket();
transport_socket->set_name("envoy.transport_sockets.tls");
UpstreamTlsContext upstream_tls_context;
upstream_tls_context.mutable_common_tls_context()
->mutable_combined_validation_context()
->mutable_default_validation_context()
->mutable_ca_certificate_provider_instance()
->set_instance_name("fake_plugin1");
transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context);
balancers_[0]->ads_service()->SetCdsResource(cluster);
WaitForBackend(0, WaitForBackendOptions().set_allow_failures(true));
Status status = SendRpc();
EXPECT_TRUE(status.ok()) << "code=" << status.error_code()
<< " message=" << status.error_message();
}
// TODO(yashykt): Remove this test once we stop supporting old fields
TEST_P(XdsSecurityTest,
TestTlsConfigurationInValidationContextCertificateProviderInstance) {
FakeCertificateProvider::CertDataMap fake1_cert_map = {
{"", {root_cert_, identity_pair_}}};
g_fake1_cert_data_map = &fake1_cert_map;
auto cluster = default_cluster_;
auto* transport_socket = cluster.mutable_transport_socket();
transport_socket->set_name("envoy.transport_sockets.tls");
UpstreamTlsContext upstream_tls_context;
upstream_tls_context.mutable_common_tls_context()
->mutable_combined_validation_context()
->mutable_validation_context_certificate_provider_instance()
->set_instance_name("fake_plugin1");
transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context);
balancers_[0]->ads_service()->SetCdsResource(cluster);
WaitForBackend(0, WaitForBackendOptions().set_allow_failures(true));
Status status = SendRpc();
EXPECT_TRUE(status.ok()) << "code=" << status.error_code()
<< " message=" << status.error_message();
}
TEST_P(XdsSecurityTest, TestMtlsConfigurationWithNoSanMatchers) {
FakeCertificateProvider::CertDataMap fake1_cert_map = {
{"", {root_cert_, identity_pair_}}};
@ -9261,19 +9409,19 @@ class XdsServerSecurityTest : public XdsEnd2endTest {
transport_socket->set_name("envoy.transport_sockets.tls");
DownstreamTlsContext downstream_tls_context;
downstream_tls_context.mutable_common_tls_context()
->mutable_tls_certificate_certificate_provider_instance()
->mutable_tls_certificate_provider_instance()
->set_instance_name(std::string(identity_instance_name));
downstream_tls_context.mutable_common_tls_context()
->mutable_tls_certificate_certificate_provider_instance()
->mutable_tls_certificate_provider_instance()
->set_certificate_name(std::string(identity_certificate_name));
if (!root_instance_name.empty()) {
downstream_tls_context.mutable_common_tls_context()
->mutable_combined_validation_context()
->mutable_validation_context_certificate_provider_instance()
->mutable_validation_context()
->mutable_ca_certificate_provider_instance()
->set_instance_name(std::string(root_instance_name));
downstream_tls_context.mutable_common_tls_context()
->mutable_combined_validation_context()
->mutable_validation_context_certificate_provider_instance()
->mutable_validation_context()
->mutable_ca_certificate_provider_instance()
->set_certificate_name(std::string(root_certificate_name));
downstream_tls_context.mutable_require_client_certificate()->set_value(
require_client_certificates);
@ -9467,7 +9615,7 @@ TEST_P(XdsServerSecurityTest, NacksRequireSNI) {
transport_socket->set_name("envoy.transport_sockets.tls");
DownstreamTlsContext downstream_tls_context;
downstream_tls_context.mutable_common_tls_context()
->mutable_tls_certificate_certificate_provider_instance()
->mutable_tls_certificate_provider_instance()
->set_instance_name("fake_plugin1");
downstream_tls_context.mutable_require_sni()->set_value(true);
transport_socket->mutable_typed_config()->PackFrom(downstream_tls_context);
@ -9496,7 +9644,7 @@ TEST_P(XdsServerSecurityTest, NacksOcspStaplePolicyOtherThanLenientStapling) {
transport_socket->set_name("envoy.transport_sockets.tls");
DownstreamTlsContext downstream_tls_context;
downstream_tls_context.mutable_common_tls_context()
->mutable_tls_certificate_certificate_provider_instance()
->mutable_tls_certificate_provider_instance()
->set_instance_name("fake_plugin1");
downstream_tls_context.set_ocsp_staple_policy(
envoy::extensions::transport_sockets::tls::v3::
@ -9530,7 +9678,7 @@ TEST_P(
transport_socket->set_name("envoy.transport_sockets.tls");
DownstreamTlsContext downstream_tls_context;
downstream_tls_context.mutable_common_tls_context()
->mutable_tls_certificate_certificate_provider_instance()
->mutable_tls_certificate_provider_instance()
->set_instance_name("fake_plugin1");
downstream_tls_context.mutable_require_client_certificate()->set_value(true);
transport_socket->mutable_typed_config()->PackFrom(downstream_tls_context);
@ -9569,9 +9717,41 @@ TEST_P(XdsServerSecurityTest,
balancers_[0]->ads_service()->lds_response_state();
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED);
EXPECT_THAT(response_state.error_message,
::testing::HasSubstr(
"TLS configuration provided but no "
"tls_certificate_certificate_provider_instance found."));
::testing::HasSubstr("TLS configuration provided but no "
"tls_certificate_provider_instance found."));
}
TEST_P(XdsServerSecurityTest, NacksMatchSubjectAltNames) {
Listener listener;
listener.set_name(
absl::StrCat("grpc/server?xds.resource.listening_address=",
ipv6_only_ ? "[::1]:" : "127.0.0.1:", backends_[0]->port()));
auto* socket_address = listener.mutable_address()->mutable_socket_address();
socket_address->set_address(ipv6_only_ ? "::1" : "127.0.0.1");
socket_address->set_port_value(backends_[0]->port());
auto* filter_chain = listener.add_filter_chains();
filter_chain->add_filters()->mutable_typed_config()->PackFrom(
HttpConnectionManager());
auto* transport_socket = filter_chain->mutable_transport_socket();
transport_socket->set_name("envoy.transport_sockets.tls");
DownstreamTlsContext downstream_tls_context;
downstream_tls_context.mutable_common_tls_context()
->mutable_tls_certificate_provider_instance()
->set_instance_name("fake_plugin1");
downstream_tls_context.mutable_common_tls_context()
->mutable_validation_context()
->add_match_subject_alt_names()
->set_exact("*.test.google.fr");
transport_socket->mutable_typed_config()->PackFrom(downstream_tls_context);
balancers_[0]->ads_service()->SetLdsResource(listener);
ASSERT_TRUE(WaitForLdsNack(StatusCode::DEADLINE_EXCEEDED))
<< "timed out waiting for NACK";
const auto response_state =
balancers_[0]->ads_service()->lds_response_state();
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED);
EXPECT_THAT(
response_state.error_message,
::testing::HasSubstr("match_subject_alt_names not supported on servers"));
}
TEST_P(XdsServerSecurityTest, UnknownIdentityCertificateProvider) {
@ -9602,6 +9782,35 @@ TEST_P(XdsServerSecurityTest, UnknownRootCertificateProvider) {
"Unrecognized certificate provider instance name: unknown"));
}
TEST_P(XdsServerSecurityTest,
TestDeprecateTlsCertificateCertificateProviderInstanceField) {
FakeCertificateProvider::CertDataMap fake1_cert_map = {
{"", {root_cert_, identity_pair_}}};
g_fake1_cert_data_map = &fake1_cert_map;
Listener listener;
listener.set_name(absl::StrCat(
ipv6_only_ ? "grpc/server?xds.resource.listening_address=[::1]:"
: "grpc/server?xds.resource.listening_address=127.0.0.1:",
backends_[0]->port()));
listener.mutable_address()->mutable_socket_address()->set_address(
ipv6_only_ ? "[::1]" : "127.0.0.1");
listener.mutable_address()->mutable_socket_address()->set_port_value(
backends_[0]->port());
auto* filter_chain = listener.add_filter_chains();
filter_chain->add_filters()->mutable_typed_config()->PackFrom(
HttpConnectionManager());
auto* transport_socket = filter_chain->mutable_transport_socket();
transport_socket->set_name("envoy.transport_sockets.tls");
DownstreamTlsContext downstream_tls_context;
downstream_tls_context.mutable_common_tls_context()
->mutable_tls_certificate_certificate_provider_instance()
->set_instance_name("fake_plugin1");
transport_socket->mutable_typed_config()->PackFrom(downstream_tls_context);
balancers_[0]->ads_service()->SetLdsResource(listener);
SendRpc([this]() { return CreateTlsChannel(); },
server_authenticated_identity_, {});
}
TEST_P(XdsServerSecurityTest, CertificatesNotAvailable) {
FakeCertificateProvider::CertDataMap fake1_cert_map;
g_fake1_cert_data_map = &fake1_cert_map;
@ -10340,7 +10549,7 @@ TEST_P(XdsServerFilterChainMatchTest,
transport_socket->set_name("envoy.transport_sockets.tls");
DownstreamTlsContext downstream_tls_context;
downstream_tls_context.mutable_common_tls_context()
->mutable_tls_certificate_certificate_provider_instance()
->mutable_tls_certificate_provider_instance()
->set_instance_name("fake_plugin1");
transport_socket->mutable_typed_config()->PackFrom(downstream_tls_context);
balancers_[0]->ads_service()->SetLdsResource(listener);

Loading…
Cancel
Save