Merge pull request #24834 from yashykt/addsanstocheck

Add SANs matching for xDS credentials
pull/24938/head
Yash Tibrewal 4 years ago committed by GitHub
commit 8d9b37362c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 56
      BUILD
  2. 4
      BUILD.gn
  3. 42
      CMakeLists.txt
  4. 8
      Makefile
  5. 21
      build_autogenerated.yaml
  6. 2
      config.m4
  7. 2
      config.w32
  8. 4
      gRPC-C++.podspec
  9. 6
      gRPC-Core.podspec
  10. 4
      grpc.gemspec
  11. 2
      grpc.gyp
  12. 4
      include/grpc/grpc_security.h
  13. 4
      package.xml
  14. 23
      src/core/ext/filters/client_channel/lb_policy/xds/cds.cc
  15. 250
      src/core/ext/xds/xds_api.cc
  16. 43
      src/core/ext/xds/xds_api.h
  17. 10
      src/core/ext/xds/xds_certificate_provider.cc
  18. 32
      src/core/ext/xds/xds_certificate_provider.h
  19. 9
      src/core/ext/xds/xds_client.cc
  20. 91
      src/core/lib/security/credentials/tls/tls_utils.cc
  21. 38
      src/core/lib/security/credentials/tls/tls_utils.h
  22. 54
      src/core/lib/security/credentials/xds/xds_credentials.cc
  23. 6
      src/core/lib/security/credentials/xds/xds_credentials.h
  24. 42
      src/core/lib/security/security_connector/tls/tls_security_connector.cc
  25. 3
      src/proto/grpc/testing/xds/v3/BUILD
  26. 29
      src/proto/grpc/testing/xds/v3/string.proto
  27. 2
      src/python/grpcio/grpc_core_dependencies.py
  28. 14
      test/core/security/BUILD
  29. 306
      test/core/security/xds_credentials_test.cc
  30. 1
      test/core/xds/BUILD
  31. 13
      test/core/xds/xds_certificate_provider_test.cc
  32. 298
      test/cpp/end2end/xds_end2end_test.cc
  33. 4
      tools/doxygen/Doxyfile.c++.internal
  34. 4
      tools/doxygen/Doxyfile.core.internal
  35. 24
      tools/run_tests/generated/tests.json

56
BUILD

@ -327,7 +327,6 @@ grpc_cc_library(
"grpc_lb_policy_xds_cluster_impl",
"grpc_lb_policy_xds_cluster_manager",
"grpc_resolver_xds",
"grpc_xds_credentials",
],
},
standalone = True,
@ -1343,45 +1342,33 @@ grpc_cc_library(
)
grpc_cc_library(
name = "grpc_xds_credentials",
name = "grpc_xds_client",
srcs = [
"src/core/ext/xds/certificate_provider_registry.cc",
"src/core/ext/xds/certificate_provider_store.cc",
"src/core/ext/xds/file_watcher_certificate_provider_factory.cc",
"src/core/ext/xds/xds_api.cc",
"src/core/ext/xds/xds_bootstrap.cc",
"src/core/ext/xds/xds_certificate_provider.cc",
"src/core/ext/xds/xds_client.cc",
"src/core/ext/xds/xds_client_stats.cc",
"src/core/lib/security/credentials/xds/xds_credentials.cc",
],
hdrs = [
"src/core/ext/xds/certificate_provider_factory.h",
"src/core/ext/xds/certificate_provider_registry.h",
"src/core/ext/xds/certificate_provider_store.h",
"src/core/ext/xds/xds_certificate_provider.h",
"src/core/lib/security/credentials/xds/xds_credentials.h",
],
external_deps = [
"absl/functional:bind_front",
],
language = "c++",
deps = [
"grpc_secure",
],
)
grpc_cc_library(
name = "grpc_xds_client",
srcs = [
"src/core/ext/xds/xds_api.cc",
"src/core/ext/xds/xds_bootstrap.cc",
"src/core/ext/xds/xds_client.cc",
"src/core/ext/xds/xds_client_stats.cc",
],
hdrs = [
"src/core/ext/xds/file_watcher_certificate_provider_factory.h",
"src/core/ext/xds/xds_api.h",
"src/core/ext/xds/xds_bootstrap.h",
"src/core/ext/xds/xds_certificate_provider.h",
"src/core/ext/xds/xds_channel_args.h",
"src/core/ext/xds/xds_client.h",
"src/core/ext/xds/xds_client_stats.h",
"src/core/lib/security/credentials/xds/xds_credentials.h",
],
external_deps = [
"absl/functional:bind_front",
"upb_lib",
"upb_textformat_lib",
"re2",
@ -1392,25 +1379,8 @@ grpc_cc_library(
"envoy_ads_upbdefs",
"grpc_base",
"grpc_client_channel",
"grpc_file_watcher_certificate_provider_factory",
"grpc_google_mesh_ca_certificate_provider_factory",
"grpc_secure",
"grpc_transport_chttp2_client_secure",
"grpc_xds_credentials",
],
)
grpc_cc_library(
name = "grpc_file_watcher_certificate_provider_factory",
srcs = [
"src/core/ext/xds/file_watcher_certificate_provider_factory.cc",
],
hdrs = [
"src/core/ext/xds/file_watcher_certificate_provider_factory.h",
],
language = "c++",
deps = [
"grpc_base",
"grpc_xds_credentials",
],
)
@ -1425,7 +1395,7 @@ grpc_cc_library(
language = "c++",
deps = [
"grpc_base",
"grpc_xds_credentials",
"grpc_xds_client",
],
)
@ -1841,6 +1811,7 @@ grpc_cc_library(
"src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc",
"src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc",
"src/core/lib/security/credentials/tls/tls_credentials.cc",
"src/core/lib/security/credentials/tls/tls_utils.cc",
"src/core/lib/security/security_connector/alts/alts_security_connector.cc",
"src/core/lib/security/security_connector/fake/fake_security_connector.cc",
"src/core/lib/security/security_connector/insecure/insecure_security_connector.cc",
@ -1886,6 +1857,7 @@ grpc_cc_library(
"src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h",
"src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h",
"src/core/lib/security/credentials/tls/tls_credentials.h",
"src/core/lib/security/credentials/tls/tls_utils.h",
"src/core/lib/security/security_connector/alts/alts_security_connector.h",
"src/core/lib/security/security_connector/fake/fake_security_connector.h",
"src/core/lib/security/security_connector/insecure/insecure_security_connector.h",

@ -728,8 +728,6 @@ config("grpc_config") {
"src/core/ext/xds/certificate_provider_store.h",
"src/core/ext/xds/file_watcher_certificate_provider_factory.cc",
"src/core/ext/xds/file_watcher_certificate_provider_factory.h",
"src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc",
"src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h",
"src/core/ext/xds/xds_api.cc",
"src/core/ext/xds/xds_api.h",
"src/core/ext/xds/xds_bootstrap.cc",
@ -1047,6 +1045,8 @@ config("grpc_config") {
"src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h",
"src/core/lib/security/credentials/tls/tls_credentials.cc",
"src/core/lib/security/credentials/tls/tls_credentials.h",
"src/core/lib/security/credentials/tls/tls_utils.cc",
"src/core/lib/security/credentials/tls/tls_utils.h",
"src/core/lib/security/credentials/xds/xds_credentials.cc",
"src/core/lib/security/credentials/xds/xds_credentials.h",
"src/core/lib/security/security_connector/alts/alts_security_connector.cc",

@ -947,6 +947,7 @@ if(gRPC_BUILD_TESTS)
add_dependencies(buildtests_cxx xds_bootstrap_test)
add_dependencies(buildtests_cxx xds_certificate_provider_test)
add_dependencies(buildtests_cxx xds_credentials_end2end_test)
add_dependencies(buildtests_cxx xds_credentials_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx xds_end2end_test)
endif()
@ -1715,7 +1716,6 @@ add_library(grpc
src/core/ext/xds/certificate_provider_registry.cc
src/core/ext/xds/certificate_provider_store.cc
src/core/ext/xds/file_watcher_certificate_provider_factory.cc
src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc
src/core/ext/xds/xds_api.cc
src/core/ext/xds/xds_bootstrap.cc
src/core/ext/xds/xds_certificate_provider.cc
@ -1881,6 +1881,7 @@ add_library(grpc
src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc
src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc
src/core/lib/security/credentials/tls/tls_credentials.cc
src/core/lib/security/credentials/tls/tls_utils.cc
src/core/lib/security/credentials/xds/xds_credentials.cc
src/core/lib/security/security_connector/alts/alts_security_connector.cc
src/core/lib/security/security_connector/fake/fake_security_connector.cc
@ -11324,6 +11325,7 @@ endif()
if(gRPC_BUILD_TESTS)
add_executable(google_mesh_ca_certificate_provider_factory_test
src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc
test/core/xds/google_mesh_ca_certificate_provider_factory_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
@ -15428,6 +15430,44 @@ target_link_libraries(xds_credentials_end2end_test
)
endif()
if(gRPC_BUILD_TESTS)
add_executable(xds_credentials_test
test/core/security/xds_credentials_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
target_include_directories(xds_credentials_test
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
${_gRPC_RE2_INCLUDE_DIR}
${_gRPC_SSL_INCLUDE_DIR}
${_gRPC_UPB_GENERATED_DIR}
${_gRPC_UPB_GRPC_GENERATED_DIR}
${_gRPC_UPB_INCLUDE_DIR}
${_gRPC_ZLIB_INCLUDE_DIR}
third_party/googletest/googletest/include
third_party/googletest/googletest
third_party/googletest/googlemock/include
third_party/googletest/googlemock
${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(xds_credentials_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc
gpr
address_sorting
upb
)
endif()
if(gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)

@ -1566,12 +1566,12 @@ $(GENDIR)/src/proto/grpc/testing/xds/v3/string.pb.cc: protoc_dep_error
$(GENDIR)/src/proto/grpc/testing/xds/v3/string.grpc.pb.cc: protoc_dep_error
else
$(GENDIR)/src/proto/grpc/testing/xds/v3/string.pb.cc: src/proto/grpc/testing/xds/v3/string.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(GENDIR)/src/proto/grpc/testing/xds/v3/string.pb.cc: src/proto/grpc/testing/xds/v3/string.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/xds/v3/regex.pb.cc
$(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@`
$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
$(GENDIR)/src/proto/grpc/testing/xds/v3/string.grpc.pb.cc: src/proto/grpc/testing/xds/v3/string.proto $(GENDIR)/src/proto/grpc/testing/xds/v3/string.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(GENDIR)/src/proto/grpc/testing/xds/v3/string.grpc.pb.cc: src/proto/grpc/testing/xds/v3/string.proto $(GENDIR)/src/proto/grpc/testing/xds/v3/string.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/xds/v3/regex.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/regex.grpc.pb.cc
$(E) "[GRPC] Generating gRPC's protobuf service CC file from $<"
$(Q) mkdir -p `dirname $@`
$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
@ -2141,7 +2141,6 @@ LIBGRPC_SRC = \
src/core/ext/xds/certificate_provider_registry.cc \
src/core/ext/xds/certificate_provider_store.cc \
src/core/ext/xds/file_watcher_certificate_provider_factory.cc \
src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc \
src/core/ext/xds/xds_api.cc \
src/core/ext/xds/xds_bootstrap.cc \
src/core/ext/xds/xds_certificate_provider.cc \
@ -2307,6 +2306,7 @@ LIBGRPC_SRC = \
src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc \
src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc \
src/core/lib/security/credentials/tls/tls_credentials.cc \
src/core/lib/security/credentials/tls/tls_utils.cc \
src/core/lib/security/credentials/xds/xds_credentials.cc \
src/core/lib/security/security_connector/alts/alts_security_connector.cc \
src/core/lib/security/security_connector/fake/fake_security_connector.cc \
@ -4812,7 +4812,6 @@ src/core/ext/upbdefs-generated/validate/validate.upbdefs.c: $(OPENSSL_DEP)
src/core/ext/xds/certificate_provider_registry.cc: $(OPENSSL_DEP)
src/core/ext/xds/certificate_provider_store.cc: $(OPENSSL_DEP)
src/core/ext/xds/file_watcher_certificate_provider_factory.cc: $(OPENSSL_DEP)
src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc: $(OPENSSL_DEP)
src/core/ext/xds/xds_api.cc: $(OPENSSL_DEP)
src/core/ext/xds/xds_bootstrap.cc: $(OPENSSL_DEP)
src/core/ext/xds/xds_certificate_provider.cc: $(OPENSSL_DEP)
@ -4854,6 +4853,7 @@ src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.cc: $(OPE
src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc: $(OPENSSL_DEP)
src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc: $(OPENSSL_DEP)
src/core/lib/security/credentials/tls/tls_credentials.cc: $(OPENSSL_DEP)
src/core/lib/security/credentials/tls/tls_utils.cc: $(OPENSSL_DEP)
src/core/lib/security/credentials/xds/xds_credentials.cc: $(OPENSSL_DEP)
src/core/lib/security/security_connector/alts/alts_security_connector.cc: $(OPENSSL_DEP)
src/core/lib/security/security_connector/fake/fake_security_connector.cc: $(OPENSSL_DEP)

@ -632,7 +632,6 @@ libs:
- src/core/ext/xds/certificate_provider_registry.h
- src/core/ext/xds/certificate_provider_store.h
- src/core/ext/xds/file_watcher_certificate_provider_factory.h
- src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h
- src/core/ext/xds/xds_api.h
- src/core/ext/xds/xds_bootstrap.h
- src/core/ext/xds/xds_certificate_provider.h
@ -785,6 +784,7 @@ libs:
- src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h
- src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h
- src/core/lib/security/credentials/tls/tls_credentials.h
- src/core/lib/security/credentials/tls/tls_utils.h
- src/core/lib/security/credentials/xds/xds_credentials.h
- src/core/lib/security/security_connector/alts/alts_security_connector.h
- src/core/lib/security/security_connector/fake/fake_security_connector.h
@ -1136,7 +1136,6 @@ libs:
- src/core/ext/xds/certificate_provider_registry.cc
- src/core/ext/xds/certificate_provider_store.cc
- src/core/ext/xds/file_watcher_certificate_provider_factory.cc
- src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc
- src/core/ext/xds/xds_api.cc
- src/core/ext/xds/xds_bootstrap.cc
- src/core/ext/xds/xds_certificate_provider.cc
@ -1302,6 +1301,7 @@ libs:
- src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc
- src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc
- src/core/lib/security/credentials/tls/tls_credentials.cc
- src/core/lib/security/credentials/tls/tls_utils.cc
- src/core/lib/security/credentials/xds/xds_credentials.cc
- src/core/lib/security/security_connector/alts/alts_security_connector.cc
- src/core/lib/security/security_connector/fake/fake_security_connector.cc
@ -6091,8 +6091,10 @@ targets:
gtest: true
build: test
language: c++
headers: []
headers:
- src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h
src:
- src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc
- test/core/xds/google_mesh_ca_certificate_provider_factory_test.cc
deps:
- grpc_test_util
@ -7919,6 +7921,19 @@ targets:
- gpr
- address_sorting
- upb
- name: xds_credentials_test
gtest: true
build: test
language: c++
headers: []
src:
- test/core/security/xds_credentials_test.cc
deps:
- grpc_test_util
- grpc
- gpr
- address_sorting
- upb
- name: xds_end2end_test
gtest: true
build: test

@ -312,7 +312,6 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/xds/certificate_provider_registry.cc \
src/core/ext/xds/certificate_provider_store.cc \
src/core/ext/xds/file_watcher_certificate_provider_factory.cc \
src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc \
src/core/ext/xds/xds_api.cc \
src/core/ext/xds/xds_bootstrap.cc \
src/core/ext/xds/xds_certificate_provider.cc \
@ -522,6 +521,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc \
src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc \
src/core/lib/security/credentials/tls/tls_credentials.cc \
src/core/lib/security/credentials/tls/tls_utils.cc \
src/core/lib/security/credentials/xds/xds_credentials.cc \
src/core/lib/security/security_connector/alts/alts_security_connector.cc \
src/core/lib/security/security_connector/fake/fake_security_connector.cc \

@ -279,7 +279,6 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\xds\\certificate_provider_registry.cc " +
"src\\core\\ext\\xds\\certificate_provider_store.cc " +
"src\\core\\ext\\xds\\file_watcher_certificate_provider_factory.cc " +
"src\\core\\ext\\xds\\google_mesh_ca_certificate_provider_factory.cc " +
"src\\core\\ext\\xds\\xds_api.cc " +
"src\\core\\ext\\xds\\xds_bootstrap.cc " +
"src\\core\\ext\\xds\\xds_certificate_provider.cc " +
@ -489,6 +488,7 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\security\\credentials\\tls\\grpc_tls_certificate_provider.cc " +
"src\\core\\lib\\security\\credentials\\tls\\grpc_tls_credentials_options.cc " +
"src\\core\\lib\\security\\credentials\\tls\\tls_credentials.cc " +
"src\\core\\lib\\security\\credentials\\tls\\tls_utils.cc " +
"src\\core\\lib\\security\\credentials\\xds\\xds_credentials.cc " +
"src\\core\\lib\\security\\security_connector\\alts\\alts_security_connector.cc " +
"src\\core\\lib\\security\\security_connector\\fake\\fake_security_connector.cc " +

@ -448,7 +448,6 @@ Pod::Spec.new do |s|
'src/core/ext/xds/certificate_provider_registry.h',
'src/core/ext/xds/certificate_provider_store.h',
'src/core/ext/xds/file_watcher_certificate_provider_factory.h',
'src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h',
'src/core/ext/xds/xds_api.h',
'src/core/ext/xds/xds_bootstrap.h',
'src/core/ext/xds/xds_certificate_provider.h',
@ -632,6 +631,7 @@ Pod::Spec.new do |s|
'src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h',
'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h',
'src/core/lib/security/credentials/tls/tls_credentials.h',
'src/core/lib/security/credentials/tls/tls_utils.h',
'src/core/lib/security/credentials/xds/xds_credentials.h',
'src/core/lib/security/security_connector/alts/alts_security_connector.h',
'src/core/lib/security/security_connector/fake/fake_security_connector.h',
@ -1059,7 +1059,6 @@ Pod::Spec.new do |s|
'src/core/ext/xds/certificate_provider_registry.h',
'src/core/ext/xds/certificate_provider_store.h',
'src/core/ext/xds/file_watcher_certificate_provider_factory.h',
'src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h',
'src/core/ext/xds/xds_api.h',
'src/core/ext/xds/xds_bootstrap.h',
'src/core/ext/xds/xds_certificate_provider.h',
@ -1243,6 +1242,7 @@ Pod::Spec.new do |s|
'src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h',
'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h',
'src/core/lib/security/credentials/tls/tls_credentials.h',
'src/core/lib/security/credentials/tls/tls_utils.h',
'src/core/lib/security/credentials/xds/xds_credentials.h',
'src/core/lib/security/security_connector/alts/alts_security_connector.h',
'src/core/lib/security/security_connector/fake/fake_security_connector.h',

@ -711,8 +711,6 @@ Pod::Spec.new do |s|
'src/core/ext/xds/certificate_provider_store.h',
'src/core/ext/xds/file_watcher_certificate_provider_factory.cc',
'src/core/ext/xds/file_watcher_certificate_provider_factory.h',
'src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc',
'src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h',
'src/core/ext/xds/xds_api.cc',
'src/core/ext/xds/xds_api.h',
'src/core/ext/xds/xds_bootstrap.cc',
@ -1105,6 +1103,8 @@ Pod::Spec.new do |s|
'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h',
'src/core/lib/security/credentials/tls/tls_credentials.cc',
'src/core/lib/security/credentials/tls/tls_credentials.h',
'src/core/lib/security/credentials/tls/tls_utils.cc',
'src/core/lib/security/credentials/tls/tls_utils.h',
'src/core/lib/security/credentials/xds/xds_credentials.cc',
'src/core/lib/security/credentials/xds/xds_credentials.h',
'src/core/lib/security/security_connector/alts/alts_security_connector.cc',
@ -1589,7 +1589,6 @@ Pod::Spec.new do |s|
'src/core/ext/xds/certificate_provider_registry.h',
'src/core/ext/xds/certificate_provider_store.h',
'src/core/ext/xds/file_watcher_certificate_provider_factory.h',
'src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h',
'src/core/ext/xds/xds_api.h',
'src/core/ext/xds/xds_bootstrap.h',
'src/core/ext/xds/xds_certificate_provider.h',
@ -1773,6 +1772,7 @@ Pod::Spec.new do |s|
'src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h',
'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h',
'src/core/lib/security/credentials/tls/tls_credentials.h',
'src/core/lib/security/credentials/tls/tls_utils.h',
'src/core/lib/security/credentials/xds/xds_credentials.h',
'src/core/lib/security/security_connector/alts/alts_security_connector.h',
'src/core/lib/security/security_connector/fake/fake_security_connector.h',

@ -626,8 +626,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/xds/certificate_provider_store.h )
s.files += %w( src/core/ext/xds/file_watcher_certificate_provider_factory.cc )
s.files += %w( src/core/ext/xds/file_watcher_certificate_provider_factory.h )
s.files += %w( src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc )
s.files += %w( src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h )
s.files += %w( src/core/ext/xds/xds_api.cc )
s.files += %w( src/core/ext/xds/xds_api.h )
s.files += %w( src/core/ext/xds/xds_bootstrap.cc )
@ -1020,6 +1018,8 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h )
s.files += %w( src/core/lib/security/credentials/tls/tls_credentials.cc )
s.files += %w( src/core/lib/security/credentials/tls/tls_credentials.h )
s.files += %w( src/core/lib/security/credentials/tls/tls_utils.cc )
s.files += %w( src/core/lib/security/credentials/tls/tls_utils.h )
s.files += %w( src/core/lib/security/credentials/xds/xds_credentials.cc )
s.files += %w( src/core/lib/security/credentials/xds/xds_credentials.h )
s.files += %w( src/core/lib/security/security_connector/alts/alts_security_connector.cc )

@ -724,7 +724,6 @@
'src/core/ext/xds/certificate_provider_registry.cc',
'src/core/ext/xds/certificate_provider_store.cc',
'src/core/ext/xds/file_watcher_certificate_provider_factory.cc',
'src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc',
'src/core/ext/xds/xds_api.cc',
'src/core/ext/xds/xds_bootstrap.cc',
'src/core/ext/xds/xds_certificate_provider.cc',
@ -890,6 +889,7 @@
'src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc',
'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc',
'src/core/lib/security/credentials/tls/tls_credentials.cc',
'src/core/lib/security/credentials/tls/tls_utils.cc',
'src/core/lib/security/credentials/xds/xds_credentials.cc',
'src/core/lib/security/security_connector/alts/alts_security_connector.cc',
'src/core/lib/security/security_connector/fake/fake_security_connector.cc',

@ -942,6 +942,8 @@ typedef void (*grpc_tls_on_server_authorization_check_done_cb)(
- target_name is the name of an endpoint the channel is connecting to.
- peer_cert represents a complete certificate chain including both
signing and leaf certificates.
- \a subject_alternative_names is an array of size
\a subject_alternative_names_size consisting of pointers to strings.
- status and error_details contain information
about errors occurred when a server authorization check request is
scheduled/cancelled.
@ -961,6 +963,8 @@ struct grpc_tls_server_authorization_check_arg {
const char* target_name;
const char* peer_cert;
const char* peer_cert_full_chain;
char** subject_alternative_names;
size_t subject_alternative_names_size;
grpc_status_code status;
grpc_tls_error_details* error_details;
grpc_tls_server_authorization_check_config* config;

@ -606,8 +606,6 @@
<file baseinstalldir="/" name="src/core/ext/xds/certificate_provider_store.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/file_watcher_certificate_provider_factory.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/file_watcher_certificate_provider_factory.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/xds_api.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/xds_api.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/xds_bootstrap.cc" role="src" />
@ -1000,6 +998,8 @@
<file baseinstalldir="/" name="src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/tls/tls_credentials.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/tls/tls_credentials.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/tls/tls_utils.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/tls/tls_utils.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/xds/xds_credentials.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/xds/xds_credentials.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/security_connector/alts/alts_security_connector.cc" role="src" />

@ -321,15 +321,8 @@ void CdsLb::UpdateLocked(UpdateArgs args) {
void CdsLb::OnClusterChanged(XdsApi::CdsUpdate cluster_data) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_cds_lb_trace)) {
gpr_log(GPR_INFO,
"[cdslb %p] received CDS update from xds client %p: "
"eds_service_name=%s lrs_load_reporting_server_name=%s "
"max_concurrent_requests=%d",
this, xds_client_.get(), cluster_data.eds_service_name.c_str(),
cluster_data.lrs_load_reporting_server_name.has_value()
? cluster_data.lrs_load_reporting_server_name.value().c_str()
: "(unset)",
cluster_data.max_concurrent_requests);
gpr_log(GPR_INFO, "[cdslb %p] received CDS update from xds client %p: %s",
this, xds_client_.get(), cluster_data.ToString().c_str());
}
grpc_error* error = GRPC_ERROR_NONE;
error = UpdateXdsCertificateProvider(cluster_data);
@ -517,6 +510,9 @@ grpc_error* CdsLb::UpdateXdsCertificateProvider(
}
identity_certificate_provider_ = std::move(new_identity_provider);
}
const std::vector<XdsApi::StringMatcher>& match_subject_alt_names =
cluster_data.common_tls_context.combined_validation_context
.default_validation_context.match_subject_alt_names;
if (!root_provider_instance_name.empty() &&
!identity_provider_instance_name.empty()) {
// Using mTLS configuration
@ -528,6 +524,8 @@ grpc_error* CdsLb::UpdateXdsCertificateProvider(
xds_certificate_provider_->UpdateIdentityCertNameAndDistributor(
identity_provider_cert_name,
identity_certificate_provider_->distributor());
xds_certificate_provider_->UpdateSubjectAlternativeNameMatchers(
match_subject_alt_names);
} else {
// Existing xDS certificate provider does not have mTLS configuration.
// Create new certificate provider so that new subchannel connectors are
@ -535,7 +533,8 @@ grpc_error* CdsLb::UpdateXdsCertificateProvider(
xds_certificate_provider_ = MakeRefCounted<XdsCertificateProvider>(
root_provider_cert_name, root_certificate_provider_->distributor(),
identity_provider_cert_name,
identity_certificate_provider_->distributor());
identity_certificate_provider_->distributor(),
match_subject_alt_names);
}
} else if (!root_provider_instance_name.empty()) {
// Using TLS configuration
@ -544,13 +543,15 @@ grpc_error* CdsLb::UpdateXdsCertificateProvider(
!xds_certificate_provider_->ProvidesIdentityCerts()) {
xds_certificate_provider_->UpdateRootCertNameAndDistributor(
root_provider_cert_name, root_certificate_provider_->distributor());
xds_certificate_provider_->UpdateSubjectAlternativeNameMatchers(
match_subject_alt_names);
} else {
// Existing xDS certificate provider does not have TLS configuration.
// Create new certificate provider so that new subchannel connectors are
// created.
xds_certificate_provider_ = MakeRefCounted<XdsCertificateProvider>(
root_provider_cert_name, root_certificate_provider_->distributor(),
"", nullptr);
"", nullptr, match_subject_alt_names);
}
} else {
// No configuration provided.

@ -429,38 +429,207 @@ XdsApi::RdsUpdate::VirtualHost* XdsApi::RdsUpdate::FindVirtualHostForDomain(
// XdsApi::StringMatcher
//
XdsApi::StringMatcher::StringMatcher(StringMatcherType type,
const std::string& matcher,
bool ignore_case)
: type_(type), ignore_case_(ignore_case) {
if (type_ == StringMatcherType::SAFE_REGEX) {
regex_matcher_ = absl::make_unique<RE2>(matcher);
} else {
string_matcher_ = matcher;
}
}
XdsApi::StringMatcher::StringMatcher(const StringMatcher& other)
: type(other.type) {
switch (type) {
: type_(other.type_), ignore_case_(other.ignore_case_) {
switch (type_) {
case StringMatcherType::SAFE_REGEX:
regex_match = absl::make_unique<RE2>(other.regex_match->pattern());
regex_matcher_ = absl::make_unique<RE2>(other.regex_matcher_->pattern());
break;
default:
string_matcher = other.string_matcher;
string_matcher_ = other.string_matcher_;
}
}
XdsApi::StringMatcher& XdsApi::StringMatcher::operator=(
const StringMatcher& other) {
type = other.type;
switch (type) {
type_ = other.type_;
switch (type_) {
case StringMatcherType::SAFE_REGEX:
regex_match = absl::make_unique<RE2>(other.regex_match->pattern());
regex_matcher_ = absl::make_unique<RE2>(other.regex_matcher_->pattern());
break;
default:
string_matcher = other.string_matcher;
string_matcher_ = other.string_matcher_;
}
ignore_case_ = other.ignore_case_;
return *this;
}
bool XdsApi::StringMatcher::operator==(const StringMatcher& other) const {
if (type != other.type) return false;
switch (type) {
if (type_ != other.type_ || ignore_case_ != other.ignore_case_) return false;
switch (type_) {
case StringMatcherType::SAFE_REGEX:
return regex_match->pattern() != other.regex_match->pattern();
return regex_matcher_->pattern() == other.regex_matcher_->pattern();
default:
return string_matcher != other.string_matcher;
return string_matcher_ == other.string_matcher_;
}
}
bool XdsApi::StringMatcher::Match(absl::string_view value) const {
switch (type_) {
case XdsApi::StringMatcher::StringMatcherType::EXACT:
return ignore_case_ ? absl::EqualsIgnoreCase(value, string_matcher_)
: value == string_matcher_;
case XdsApi::StringMatcher::StringMatcherType::PREFIX:
return ignore_case_ ? absl::StartsWithIgnoreCase(value, string_matcher_)
: absl::StartsWith(value, string_matcher_);
case XdsApi::StringMatcher::StringMatcherType::SUFFIX:
return ignore_case_ ? absl::EndsWithIgnoreCase(value, string_matcher_)
: absl::EndsWith(value, string_matcher_);
case XdsApi::StringMatcher::StringMatcherType::CONTAINS:
return ignore_case_
? absl::StrContains(absl::AsciiStrToLower(value),
absl::AsciiStrToLower(string_matcher_))
: absl::StrContains(value, string_matcher_);
case XdsApi::StringMatcher::StringMatcherType::SAFE_REGEX:
// ignore_case_ is ignored for SAFE_REGEX
return RE2::FullMatch(std::string(value), *regex_matcher_);
default:
return false;
}
}
std::string XdsApi::StringMatcher::ToString() const {
switch (type_) {
case StringMatcherType::EXACT:
return absl::StrFormat("StringMatcher{exact=%s%s}", string_matcher_,
ignore_case_ ? ", ignore_case" : "");
case StringMatcherType::PREFIX:
return absl::StrFormat("StringMatcher{prefix=%s%s}", string_matcher_,
ignore_case_ ? ", ignore_case" : "");
case StringMatcherType::SUFFIX:
return absl::StrFormat("StringMatcher{suffix=%s%s}", string_matcher_,
ignore_case_ ? ", ignore_case" : "");
case StringMatcherType::CONTAINS:
return absl::StrFormat("StringMatcher{contains=%s%s}", string_matcher_,
ignore_case_ ? ", ignore_case" : "");
case StringMatcherType::SAFE_REGEX:
return absl::StrFormat("StringMatcher{safe_regex=%s}",
regex_matcher_->pattern());
default:
return "";
}
}
//
// XdsApi::CommonTlsContext::CertificateValidationContext
//
std::string XdsApi::CommonTlsContext::CertificateValidationContext::ToString()
const {
std::vector<std::string> contents;
for (const auto& match : match_subject_alt_names) {
contents.push_back(match.ToString());
}
return absl::StrFormat("{match_subject_alt_names=[%s]}",
absl::StrJoin(contents, ", "));
}
bool XdsApi::CommonTlsContext::CertificateValidationContext::Empty() const {
return match_subject_alt_names.empty();
}
//
// XdsApi::CommonTlsContext::CertificateValidationContext
//
std::string XdsApi::CommonTlsContext::CertificateProviderInstance::ToString()
const {
absl::InlinedVector<std::string, 2> contents;
if (!instance_name.empty()) {
contents.push_back(absl::StrFormat("instance_name=%s", instance_name));
}
if (!certificate_name.empty()) {
contents.push_back(
absl::StrFormat("certificate_name=%s", certificate_name));
}
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()
const {
return default_validation_context.Empty() &&
validation_context_certificate_provider_instance.Empty();
}
//
// XdsApi::CommonTlsContext
//
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 (!combined_validation_context.Empty()) {
contents.push_back(absl::StrFormat("combined_validation_context=%s",
combined_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();
}
//
// XdsApi::CdsUpdate
//
std::string XdsApi::CdsUpdate::ToString() const {
absl::InlinedVector<std::string, 4> contents;
if (!eds_service_name.empty()) {
contents.push_back(
absl::StrFormat("eds_service_name=%s", eds_service_name));
}
if (!common_tls_context.Empty()) {
contents.push_back(absl::StrFormat("common_tls_context=%s",
common_tls_context.ToString()));
}
if (lrs_load_reporting_server_name.has_value()) {
contents.push_back(absl::StrFormat("lrs_load_reporting_server_name=%s",
lrs_load_reporting_server_name.value()));
}
contents.push_back(
absl::StrFormat("max_concurrent_requests=%d", max_concurrent_requests));
return absl::StrCat("{", absl::StrJoin(contents, ", "), "}");
}
//
@ -1442,47 +1611,59 @@ grpc_error* CommonTlsContextParse(
envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_match_subject_alt_names(
default_validation_context, &len);
for (size_t i = 0; i < len; ++i) {
XdsApi::StringMatcher matcher;
XdsApi::StringMatcher::StringMatcherType type;
std::string matcher;
if (envoy_type_matcher_v3_StringMatcher_has_exact(
subject_alt_names_matchers[i])) {
matcher.type = XdsApi::StringMatcher::StringMatcherType::EXACT;
matcher.string_matcher =
type = XdsApi::StringMatcher::StringMatcherType::EXACT;
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])) {
matcher.type = XdsApi::StringMatcher::StringMatcherType::PREFIX;
matcher.string_matcher =
type = XdsApi::StringMatcher::StringMatcherType::PREFIX;
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])) {
matcher.type = XdsApi::StringMatcher::StringMatcherType::SUFFIX;
matcher.string_matcher =
type = XdsApi::StringMatcher::StringMatcherType::SUFFIX;
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 = XdsApi::StringMatcher::StringMatcherType::CONTAINS;
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])) {
matcher.type = XdsApi::StringMatcher::StringMatcherType::SAFE_REGEX;
type = XdsApi::StringMatcher::StringMatcherType::SAFE_REGEX;
auto* regex_matcher = envoy_type_matcher_v3_StringMatcher_safe_regex(
subject_alt_names_matchers[i]);
std::unique_ptr<RE2> regex =
absl::make_unique<RE2>(UpbStringToStdString(
envoy_type_matcher_v3_RegexMatcher_regex(regex_matcher)));
if (!regex->ok()) {
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Invalid regex string specified in string matcher.");
}
matcher.regex_match = std::move(regex);
matcher = UpbStringToStdString(
envoy_type_matcher_v3_RegexMatcher_regex(regex_matcher));
} else {
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Invalid StringMatcher specified");
}
matcher.ignore_case = envoy_type_matcher_v3_StringMatcher_ignore_case(
bool ignore_case = envoy_type_matcher_v3_StringMatcher_ignore_case(
subject_alt_names_matchers[i]);
XdsApi::StringMatcher string_matcher(type, matcher, ignore_case);
if (type == XdsApi::StringMatcher::StringMatcherType::SAFE_REGEX) {
if (!string_matcher.regex_matcher()->ok()) {
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Invalid regex string specified in string matcher.");
}
if (ignore_case) {
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"StringMatcher: ignore_case has no effect for SAFE_REGEX.");
}
}
common_tls_context->combined_validation_context
.default_validation_context.match_subject_alt_names.emplace_back(
matcher);
.default_validation_context.match_subject_alt_names.push_back(
std::move(string_matcher));
}
}
auto* validation_context_certificate_provider_instance =
@ -1608,6 +1789,13 @@ grpc_error* CdsResponseParse(
if (error != GRPC_ERROR_NONE) return error;
}
}
if (cds_update.common_tls_context.combined_validation_context
.validation_context_certificate_provider_instance
.instance_name.empty()) {
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"TLS configuration provided but no "
"validation_context_certificate_provider_instance found.");
}
}
}
}

@ -175,23 +175,40 @@ class XdsApi {
VirtualHost* FindVirtualHostForDomain(const std::string& domain);
};
struct StringMatcher {
class StringMatcher {
public:
enum class StringMatcherType {
EXACT, // value stored in string_matcher_ field
PREFIX, // value stored in string_matcher_ field
SUFFIX, // value stored in string_matcher_ field
SAFE_REGEX, // use regex_match field
SAFE_REGEX, // pattern stored in regex_matcher_ field
CONTAINS, // value stored in string_matcher_ field
};
StringMatcherType type;
std::string string_matcher;
std::unique_ptr<RE2> regex_match;
bool ignore_case;
StringMatcher() = default;
StringMatcher(const StringMatcher& other);
StringMatcher(StringMatcherType type, const std::string& matcher,
bool ignore_case = false);
StringMatcher& operator=(const StringMatcher& other);
bool operator==(const StringMatcher& other) const;
bool Match(absl::string_view value) const;
std::string ToString() const;
StringMatcherType type() const { return type_; }
// Valid for EXACT, PREFIX, SUFFIX and CONTAINS
const std::string& string_matcher() const { return string_matcher_; }
// Valid for SAFE_REGEX
RE2* regex_matcher() const { return regex_matcher_.get(); }
private:
StringMatcherType type_ = StringMatcherType::EXACT;
std::string string_matcher_;
std::unique_ptr<RE2> regex_matcher_;
bool ignore_case_ = false;
};
struct CommonTlsContext {
@ -201,6 +218,9 @@ class XdsApi {
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 {
@ -211,6 +231,9 @@ class XdsApi {
return instance_name == other.instance_name &&
certificate_name == other.certificate_name;
}
std::string ToString() const;
bool Empty() const;
};
struct CombinedCertificateValidationContext {
@ -223,6 +246,9 @@ class XdsApi {
validation_context_certificate_provider_instance ==
other.validation_context_certificate_provider_instance;
}
std::string ToString() const;
bool Empty() const;
};
CertificateProviderInstance tls_certificate_certificate_provider_instance;
@ -233,6 +259,9 @@ class XdsApi {
other.tls_certificate_certificate_provider_instance &&
combined_validation_context == other.combined_validation_context;
}
std::string ToString() const;
bool Empty() const;
};
// TODO(roth): When we can use absl::variant<>, consider using that
@ -280,6 +309,8 @@ class XdsApi {
other.lrs_load_reporting_server_name &&
max_concurrent_requests == other.max_concurrent_requests;
}
std::string ToString() const;
};
using CdsUpdateMap = std::map<std::string /*cluster_name*/, CdsUpdate>;

@ -102,11 +102,13 @@ XdsCertificateProvider::XdsCertificateProvider(
absl::string_view root_cert_name,
RefCountedPtr<grpc_tls_certificate_distributor> root_cert_distributor,
absl::string_view identity_cert_name,
RefCountedPtr<grpc_tls_certificate_distributor> identity_cert_distributor)
RefCountedPtr<grpc_tls_certificate_distributor> identity_cert_distributor,
std::vector<XdsApi::StringMatcher> san_matchers)
: root_cert_name_(root_cert_name),
identity_cert_name_(identity_cert_name),
root_cert_distributor_(std::move(root_cert_distributor)),
identity_cert_distributor_(std::move(identity_cert_distributor)),
san_matchers_(std::move(san_matchers)),
distributor_(MakeRefCounted<grpc_tls_certificate_distributor>()) {
distributor_->SetWatchStatusCallback(
absl::bind_front(&XdsCertificateProvider::WatchStatusCallback, this));
@ -174,6 +176,12 @@ void XdsCertificateProvider::UpdateIdentityCertNameAndDistributor(
identity_cert_distributor_ = std::move(identity_cert_distributor);
}
void XdsCertificateProvider::UpdateSubjectAlternativeNameMatchers(
std::vector<XdsApi::StringMatcher> matchers) {
MutexLock lock(&san_matchers_mu_);
san_matchers_ = std::move(matchers);
}
void XdsCertificateProvider::WatchStatusCallback(std::string cert_name,
bool root_being_watched,
bool identity_being_watched) {

@ -21,6 +21,7 @@
#include <grpc/support/port_platform.h>
#include "src/core/ext/xds/xds_api.h"
#include "src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h"
#define GRPC_ARG_XDS_CERTIFICATE_PROVIDER \
@ -34,8 +35,8 @@ class XdsCertificateProvider : public grpc_tls_certificate_provider {
absl::string_view root_cert_name,
RefCountedPtr<grpc_tls_certificate_distributor> root_cert_distributor,
absl::string_view identity_cert_name,
RefCountedPtr<grpc_tls_certificate_distributor>
identity_cert_distributor);
RefCountedPtr<grpc_tls_certificate_distributor> identity_cert_distributor,
std::vector<XdsApi::StringMatcher> san_matchers);
~XdsCertificateProvider() override;
@ -46,15 +47,28 @@ class XdsCertificateProvider : public grpc_tls_certificate_provider {
absl::string_view identity_cert_name,
RefCountedPtr<grpc_tls_certificate_distributor>
identity_cert_distributor);
void UpdateSubjectAlternativeNameMatchers(
std::vector<XdsApi::StringMatcher> matchers);
grpc_core::RefCountedPtr<grpc_tls_certificate_distributor> distributor()
const override {
return distributor_;
}
bool ProvidesRootCerts() { return root_cert_distributor_ != nullptr; }
bool ProvidesRootCerts() {
MutexLock lock(&mu_);
return root_cert_distributor_ != nullptr;
}
bool ProvidesIdentityCerts() {
MutexLock lock(&mu_);
return identity_cert_distributor_ != nullptr;
}
bool ProvidesIdentityCerts() { return identity_cert_distributor_ != nullptr; }
std::vector<XdsApi::StringMatcher> subject_alternative_name_matchers() {
MutexLock lock(&san_matchers_mu_);
return san_matchers_;
}
grpc_arg MakeChannelArg() const;
@ -70,12 +84,22 @@ class XdsCertificateProvider : public grpc_tls_certificate_provider {
grpc_tls_certificate_distributor* identity_cert_distributor);
Mutex mu_;
// Use a separate mutex for san_matchers_ to avoid deadlocks since
// san_matchers_ needs to be accessed when a handshake is being done and we
// run into a possible deadlock scenario if using the same mutex. The mutex
// deadlock cycle is formed as -
// WatchStatusCallback() -> SetKeyMaterials() ->
// TlsChannelSecurityConnector::TlsChannelCertificateWatcher::OnCertificatesChanged()
// -> HandshakeManager::Add() -> SecurityHandshaker::DoHandshake() ->
// subject_alternative_names_matchers()
Mutex san_matchers_mu_;
bool watching_root_certs_ = false;
bool watching_identity_certs_ = false;
std::string root_cert_name_;
std::string identity_cert_name_;
RefCountedPtr<grpc_tls_certificate_distributor> root_cert_distributor_;
RefCountedPtr<grpc_tls_certificate_distributor> identity_cert_distributor_;
std::vector<XdsApi::StringMatcher> san_matchers_;
RefCountedPtr<grpc_tls_certificate_distributor> distributor_;
grpc_tls_certificate_distributor::TlsCertificatesWatcherInterface*
root_cert_watcher_ = nullptr;

@ -1005,13 +1005,8 @@ void XdsClient::ChannelState::AdsCallState::AcceptCdsUpdate(
auto& state = cds_state.subscribed_resources[cluster_name];
if (state != nullptr) state->Finish();
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
gpr_log(GPR_INFO,
"[xds_client %p] cluster=%s: eds_service_name=%s, "
"lrs_load_reporting_server_name=%s",
xds_client(), cluster_name, cds_update.eds_service_name.c_str(),
cds_update.lrs_load_reporting_server_name.has_value()
? cds_update.lrs_load_reporting_server_name.value().c_str()
: "(N/A)");
gpr_log(GPR_INFO, "[xds_client %p] cluster=%s: %s", xds_client(),
cluster_name, cds_update.ToString().c_str());
}
// Record the EDS resource names seen.
eds_resource_names_seen.insert(cds_update.eds_service_name.empty()

@ -0,0 +1,91 @@
//
//
// Copyright 2020 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//
#include <grpc/support/port_platform.h>
#include "src/core/lib/security/credentials/tls/tls_utils.h"
#include "absl/strings/ascii.h"
#include "absl/strings/match.h"
#include "absl/strings/str_cat.h"
namespace grpc_core {
// Based on
// https://github.com/grpc/grpc-java/blob/ca12e7a339add0ef48202fb72434b9dc0df41756/xds/src/main/java/io/grpc/xds/internal/sds/trust/SdsX509TrustManager.java#L62
bool VerifySubjectAlternativeName(absl::string_view subject_alternative_name,
const std::string& matcher) {
if (subject_alternative_name.empty() ||
absl::StartsWith(subject_alternative_name, ".")) {
// Illegal pattern/domain name
return false;
}
if (matcher.empty() || absl::StartsWith(matcher, ".")) {
// Illegal domain name
return false;
}
// Normalize \a subject_alternative_name and \a matcher by turning them into
// absolute domain names if they are not yet absolute. This is needed because
// server certificates do not normally contain absolute names or patterns, but
// they should be treated as absolute. At the same time, any
// subject_alternative_name presented to this method should also be treated as
// absolute for the purposes of matching to the server certificate.
std::string normalized_san =
absl::EndsWith(subject_alternative_name, ".")
? std::string(subject_alternative_name)
: absl::StrCat(subject_alternative_name, ".");
std::string normalized_matcher =
absl::EndsWith(matcher, ".") ? matcher : absl::StrCat(matcher, ".");
absl::AsciiStrToLower(&normalized_san);
absl::AsciiStrToLower(&normalized_matcher);
if (!absl::StrContains(normalized_san, "*")) {
return normalized_san == normalized_matcher;
}
// WILDCARD PATTERN RULES:
// 1. Asterisk (*) is only permitted in the left-most domain name label and
// must be the only character in that label (i.e., must match the whole
// left-most label). For example, *.example.com is permitted, while
// *a.example.com, a*.example.com, a*b.example.com, a.*.example.com are
// not permitted.
// 2. Asterisk (*) cannot match across domain name labels.
// For example, *.example.com matches test.example.com but does not match
// sub.test.example.com.
// 3. Wildcard patterns for single-label domain names are not permitted.
if (!absl::StartsWith(normalized_san, "*.")) {
// Asterisk (*) is only permitted in the left-most domain name label and
// must be the only character in that label
return false;
}
if (normalized_san == "*.") {
// Wildcard pattern for single-label domain name -- not permitted.
return false;
}
absl::string_view suffix = absl::string_view(normalized_san).substr(1);
if (absl::StrContains(suffix, "*")) {
// Asterisk (*) is not permitted in the suffix
return false;
}
if (!absl::EndsWith(normalized_matcher, suffix)) return false;
int suffix_start_index = normalized_matcher.length() - suffix.length();
// Asterisk matching across domain labels is not permitted.
return suffix_start_index <= 0 /* should not happen */ ||
normalized_matcher.find_last_of('.', suffix_start_index - 1) ==
std::string::npos;
}
} // namespace grpc_core

@ -0,0 +1,38 @@
//
//
// Copyright 2020 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//
#ifndef GRPC_CORE_LIB_SECURITY_CREDENTIALS_TLS_TLS_UTILS_H
#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_TLS_TLS_UTILS_H
#include <grpc/support/port_platform.h>
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
namespace grpc_core {
// Matches \a subject_alternative_name with \a matcher. Returns true if there
// is a match, false otherwise.
bool VerifySubjectAlternativeName(absl::string_view subject_alternative_name,
const std::string& matcher);
} // namespace grpc_core
#endif // GRPC_CORE_LIB_SECURITY_CREDENTIALS_TLS_TLS_UTILS_H

@ -23,6 +23,7 @@
#include "src/core/ext/xds/xds_certificate_provider.h"
#include "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h"
#include "src/core/lib/security/credentials/tls/tls_credentials.h"
#include "src/core/lib/security/credentials/tls/tls_utils.h"
#include "src/core/lib/uri/uri_parser.h"
namespace grpc_core {
@ -31,11 +32,52 @@ const char kCredentialsTypeXds[] = "Xds";
namespace {
int ServerAuthCheckSchedule(void* /* config_user_data */,
bool XdsVerifySubjectAlternativeNames(
const char* const* subject_alternative_names,
size_t subject_alternative_names_size,
const std::vector<XdsApi::StringMatcher>& matchers) {
if (matchers.empty()) return true;
for (size_t i = 0; i < subject_alternative_names_size; ++i) {
for (const auto& matcher : matchers) {
if (matcher.type() == XdsApi::StringMatcher::StringMatcherType::EXACT) {
// For EXACT match, use DNS rules for verifying SANs
// TODO(zhenlian): Right now, the SSL layer does not save the type of
// the SAN, so we are doing a DNS style verification for all SANs when
// the type is EXACT. When we expose the SAN type, change this to only
// do this verification when the SAN type is DNS and match type is
// EXACT. For all other cases, we should use matcher.Match().
if (VerifySubjectAlternativeName(subject_alternative_names[i],
matcher.string_matcher())) {
return true;
}
} else {
if (matcher.Match(subject_alternative_names[i])) {
return true;
}
}
}
}
return false;
}
int ServerAuthCheckSchedule(void* config_user_data,
grpc_tls_server_authorization_check_arg* arg) {
// TODO(yashykt): To be filled
XdsCertificateProvider* xds_certificate_provider =
static_cast<XdsCertificateProvider*>(config_user_data);
if (XdsVerifySubjectAlternativeNames(
arg->subject_alternative_names, arg->subject_alternative_names_size,
xds_certificate_provider->subject_alternative_name_matchers())) {
arg->success = 1;
arg->status = GRPC_STATUS_OK;
} else {
arg->success = 0;
arg->status = GRPC_STATUS_UNAUTHENTICATED;
if (arg->error_details) {
arg->error_details->set_error_details(
"SANs from certificate did not match SANs from xDS control plane");
}
}
return 0; /* synchronous check */
}
@ -47,6 +89,14 @@ void ServerAuthCheckDestroy(void* config_user_data) {
} // namespace
bool TestOnlyXdsVerifySubjectAlternativeNames(
const char* const* subject_alternative_names,
size_t subject_alternative_names_size,
const std::vector<XdsApi::StringMatcher>& matchers) {
return XdsVerifySubjectAlternativeNames(
subject_alternative_names, subject_alternative_names_size, matchers);
}
//
// XdsCredentials
//

@ -23,6 +23,7 @@
#include <grpc/grpc_security.h>
#include "src/core/ext/xds/xds_api.h"
#include "src/core/lib/security/credentials/credentials.h"
namespace grpc_core {
@ -58,6 +59,11 @@ class XdsServerCredentials final : public grpc_server_credentials {
RefCountedPtr<grpc_server_credentials> fallback_credentials_;
};
bool TestOnlyXdsVerifySubjectAlternativeNames(
const char* const* subject_alternative_names,
size_t subject_alternative_names_size,
const std::vector<XdsApi::StringMatcher>& matchers);
} // namespace grpc_core
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_XDS_XDS_CREDENTIALS_H */

@ -243,6 +243,39 @@ void TlsChannelSecurityConnector::check_peer(
: check_arg_->peer_cert_full_chain;
gpr_free(peer_pem_chain);
}
// TODO(zhenlian) - This should be cleaned up as part of the custom
// verification changes. Fill in the subject alternative names
std::vector<char*> subject_alternative_names;
for (size_t i = 0; i < peer.property_count; i++) {
const tsi_peer_property* prop = &peer.properties[i];
if (strcmp(prop->name,
TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) == 0) {
char* san = new char[prop->value.length + 1];
memcpy(san, prop->value.data, prop->value.length);
san[prop->value.length] = '\0';
subject_alternative_names.emplace_back(san);
}
}
if (check_arg_->subject_alternative_names != nullptr) {
for (size_t i = 0; i < check_arg_->subject_alternative_names_size;
++i) {
delete check_arg_->subject_alternative_names[i];
}
delete check_arg_->subject_alternative_names;
}
check_arg_->subject_alternative_names_size =
subject_alternative_names.size();
if (subject_alternative_names.empty()) {
check_arg_->subject_alternative_names = nullptr;
} else {
check_arg_->subject_alternative_names =
new char*[check_arg_->subject_alternative_names_size];
for (size_t i = 0; i < check_arg_->subject_alternative_names_size;
++i) {
check_arg_->subject_alternative_names[i] =
subject_alternative_names[i];
}
}
int callback_status = config->Schedule(check_arg_);
/* Server authorization check is handled asynchronously. */
if (callback_status) {
@ -409,6 +442,11 @@ TlsChannelSecurityConnector::ServerAuthorizationCheckArgCreate(
void* user_data) {
grpc_tls_server_authorization_check_arg* arg =
new grpc_tls_server_authorization_check_arg();
arg->target_name = nullptr;
arg->peer_cert = nullptr;
arg->peer_cert_full_chain = nullptr;
arg->subject_alternative_names = nullptr;
arg->subject_alternative_names_size = 0;
arg->error_details = new grpc_tls_error_details();
arg->cb = ServerAuthorizationCheckDone;
arg->cb_user_data = user_data;
@ -424,6 +462,10 @@ void TlsChannelSecurityConnector::ServerAuthorizationCheckArgDestroy(
gpr_free(const_cast<char*>(arg->target_name));
gpr_free(const_cast<char*>(arg->peer_cert));
gpr_free(const_cast<char*>(arg->peer_cert_full_chain));
for (size_t i = 0; i < arg->subject_alternative_names_size; ++i) {
delete arg->subject_alternative_names[i];
}
delete arg->subject_alternative_names;
delete arg->error_details;
if (arg->destroy_context != nullptr) {
arg->destroy_context(arg->context);

@ -195,6 +195,9 @@ grpc_proto_library(
"string.proto",
],
well_known_protos = True,
deps = [
"regex_proto",
],
)
grpc_proto_library(

@ -18,6 +18,8 @@ syntax = "proto3";
package envoy.type.matcher.v3;
import "src/proto/grpc/testing/xds/v3/regex.proto";
message StringMatcher {
oneof match_pattern {
// The input string must match exactly the string specified here.
@ -26,6 +28,33 @@ message StringMatcher {
//
// * *abc* only matches the value *abc*.
string exact = 1;
// The input string must have the prefix specified here.
// Note: empty prefix is not allowed, please use regex instead.
//
// Examples:
//
// * *abc* matches the value *abc.xyz*
string prefix = 2;
// The input string must have the suffix specified here.
// Note: empty prefix is not allowed, please use regex instead.
//
// Examples:
//
// * *abc* matches the value *xyz.abc*
string suffix = 3;
// The input string must match the regular expression specified here.
RegexMatcher safe_regex = 5;
// The input string must have the substring specified here.
// Note: empty contains match is not allowed, please use regex instead.
//
// Examples:
//
// * *abc* matches the value *xyz.abc.def*
string contains = 7;
}
// If true, indicates the exact/prefix/suffix matching should be case insensitive. This has no

@ -288,7 +288,6 @@ CORE_SOURCE_FILES = [
'src/core/ext/xds/certificate_provider_registry.cc',
'src/core/ext/xds/certificate_provider_store.cc',
'src/core/ext/xds/file_watcher_certificate_provider_factory.cc',
'src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc',
'src/core/ext/xds/xds_api.cc',
'src/core/ext/xds/xds_bootstrap.cc',
'src/core/ext/xds/xds_certificate_provider.cc',
@ -498,6 +497,7 @@ CORE_SOURCE_FILES = [
'src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc',
'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc',
'src/core/lib/security/credentials/tls/tls_credentials.cc',
'src/core/lib/security/credentials/tls/tls_utils.cc',
'src/core/lib/security/credentials/xds/xds_credentials.cc',
'src/core/lib/security/security_connector/alts/alts_security_connector.cc',
'src/core/lib/security/security_connector/fake/fake_security_connector.cc',

@ -383,3 +383,17 @@ grpc_cc_test(
"//test/core/util:grpc_test_util",
],
)
grpc_cc_test(
name = "xds_credentials_test",
srcs = ["xds_credentials_test.cc"],
external_deps = [
"gtest",
],
deps = [
"//:gpr",
"//:grpc",
"//:grpc_secure",
"//test/core/util:grpc_test_util",
],
)

@ -0,0 +1,306 @@
//
//
// Copyright 2020 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//
#include "src/core/lib/security/credentials/xds/xds_credentials.h"
#include <gtest/gtest.h>
#include <grpc/grpc.h>
#include "test/core/util/test_config.h"
namespace grpc_core {
namespace testing {
namespace {
XdsApi::StringMatcher ExactMatcher(const char* string) {
return XdsApi::StringMatcher(XdsApi::StringMatcher::StringMatcherType::EXACT,
string);
}
XdsApi::StringMatcher PrefixMatcher(const char* string,
bool ignore_case = false) {
return XdsApi::StringMatcher(XdsApi::StringMatcher::StringMatcherType::PREFIX,
string, ignore_case);
}
XdsApi::StringMatcher SuffixMatcher(const char* string,
bool ignore_case = false) {
return XdsApi::StringMatcher(XdsApi::StringMatcher::StringMatcherType::SUFFIX,
string, ignore_case);
}
XdsApi::StringMatcher ContainsMatcher(const char* string,
bool ignore_case = false) {
return XdsApi::StringMatcher(
XdsApi::StringMatcher::StringMatcherType::CONTAINS, string, ignore_case);
}
XdsApi::StringMatcher SafeRegexMatcher(const char* string) {
return XdsApi::StringMatcher(
XdsApi::StringMatcher::StringMatcherType::SAFE_REGEX, string);
}
TEST(XdsSanMatchingTest, EmptySansList) {
std::vector<const char*> sans = {};
EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(),
{ExactMatcher("a.example.com"), ExactMatcher("b.example.com")}));
}
TEST(XdsSanMatchingTest, EmptyMatchersList) {
std::vector<const char*> sans = {"a.example.com", "foo.example.com"};
EXPECT_TRUE(
TestOnlyXdsVerifySubjectAlternativeNames(sans.data(), sans.size(), {}));
}
TEST(XdsSanMatchingTest, ExactMatchIllegalValues) {
std::vector<const char*> sans = {".a.example.com"};
EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(),
{ExactMatcher(""), ExactMatcher("a.example.com"),
ExactMatcher(".a.example.com")}));
sans = {""};
EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(),
{ExactMatcher(""), ExactMatcher("a.example.com"),
ExactMatcher(".a.example.com")}));
sans = {"a.example.com"};
EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(),
{ExactMatcher(""), ExactMatcher("a.example.com"),
ExactMatcher(".a.example.com")}));
}
TEST(XdsSanMatchingTest, ExactMatchDns) {
std::vector<const char*> sans = {"a.example.com"};
EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {ExactMatcher("a.example.com")}));
EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {ExactMatcher("b.example.com")}));
sans = {"b.example.com."};
EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {ExactMatcher("a.example.com.")}));
EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {ExactMatcher("b.example.com.")}));
}
TEST(XdsSanMatchingTest, ExactMatchWithFullyQualifiedSan) {
std::vector<const char*> sans = {"a.example.com."};
EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {ExactMatcher("a.example.com")}));
EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {ExactMatcher("b.example.com")}));
}
TEST(XdsSanMatchingTest, ExactMatchWithFullyQualifiedMatcher) {
std::vector<const char*> sans = {"a.example.com"};
EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {ExactMatcher("a.example.com.")}));
EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {ExactMatcher("b.example.com.")}));
}
TEST(XdsSanMatchingTest, ExactMatchDnsCaseInsensitive) {
std::vector<const char*> sans = {"A.eXaMpLe.CoM"};
EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {ExactMatcher("a.example.com")}));
EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {ExactMatcher("a.ExAmPlE.cOm")}));
}
TEST(XdsSanMatchingTest, ExactMatchMultipleSansMultipleMatchers) {
std::vector<const char*> sans = {"a.example.com", "foo.example.com",
"b.example.com"};
EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(),
{ExactMatcher("abc.example.com"), ExactMatcher("foo.example.com"),
ExactMatcher("xyz.example.com")}));
}
TEST(XdsSanMatchingTest, ExactMatchWildCard) {
std::vector<const char*> sans = {"*.example.com"};
EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {ExactMatcher("a.example.com")}));
EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {ExactMatcher("fOo.ExAmPlE.cOm")}));
EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {ExactMatcher("BaR.eXaMpLe.CoM")}));
EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {ExactMatcher(".example.com")}));
EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {ExactMatcher("example.com")}));
EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {ExactMatcher("foo.bar.com")}));
}
TEST(XdsSanMatchingTest, ExactMatchWildCardDoesNotMatchSingleLabelDomain) {
std::vector<const char*> sans = {"*"};
EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {ExactMatcher("abc")}));
EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {ExactMatcher("abc.com.")}));
EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {ExactMatcher("bar.baz.com")}));
sans = {"*."};
EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {ExactMatcher("abc")}));
EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {ExactMatcher("abc.com.")}));
EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {ExactMatcher("bar.baz.com")}));
}
TEST(XdsSanMatchingTest, ExactMatchAsteriskOnlyPermittedInLeftMostDomainName) {
std::vector<const char*> sans = {"*.example.*.com"};
EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {ExactMatcher("abc.example.xyz.com")}));
sans = {"*.exam*ple.com"};
EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {ExactMatcher("abc.example.com")}));
}
TEST(XdsSanMatchingTest,
ExactMatchAsteriskMustBeOnlyCharacterInLeftMostDomainName) {
std::vector<const char*> sans = {"*c.example.com"};
EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {ExactMatcher("abc.example.com")}));
}
TEST(XdsSanMatchingTest,
ExactMatchAsteriskMatchingAcrossDomainLabelsNotPermitted) {
std::vector<const char*> sans = {"*.com"};
EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {ExactMatcher("abc.example.com")}));
EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {ExactMatcher("foo.bar.baz.com")}));
EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {ExactMatcher("abc.com")}));
}
TEST(XdsSanMatchingTest, PrefixMatch) {
std::vector<const char*> sans = {"abc.com"};
EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(sans.data(), sans.size(),
{PrefixMatcher("abc")}));
sans = {"AbC.CoM"};
EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {PrefixMatcher("abc")}));
sans = {"xyz.com"};
EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {PrefixMatcher("abc")}));
}
TEST(XdsSanMatchingTest, PrefixMatchIgnoreCase) {
std::vector<const char*> sans = {"aBc.cOm"};
EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(),
{PrefixMatcher("AbC", true /* ignore_case */)}));
sans = {"abc.com"};
EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(),
{PrefixMatcher("AbC", true /* ignore_case */)}));
sans = {"xyz.com"};
EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(),
{PrefixMatcher("AbC", true /* ignore_case */)}));
}
TEST(XdsSanMatchingTest, SuffixMatch) {
std::vector<const char*> sans = {"abc.com"};
EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {SuffixMatcher(".com")}));
sans = {"AbC.CoM"};
EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {SuffixMatcher(".com")}));
sans = {"abc.xyz"};
EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {SuffixMatcher(".com")}));
}
TEST(XdsSanMatchingTest, SuffixMatchIgnoreCase) {
std::vector<const char*> sans = {"abc.com"};
EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(),
{SuffixMatcher(".CoM", true /* ignore_case */)}));
sans = {"AbC.cOm"};
EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(),
{SuffixMatcher(".CoM", true /* ignore_case */)}));
sans = {"abc.xyz"};
EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(),
{SuffixMatcher(".CoM", true /* ignore_case */)}));
}
TEST(XdsSanMatchingTest, ContainsMatch) {
std::vector<const char*> sans = {"abc.com"};
EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {ContainsMatcher("abc")}));
sans = {"xyz.abc.com"};
EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {ContainsMatcher("abc")}));
sans = {"foo.AbC.com"};
EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {ContainsMatcher("abc")}));
}
TEST(XdsSanMatchingTest, ContainsMatchIgnoresCase) {
std::vector<const char*> sans = {"abc.com"};
EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(),
{ContainsMatcher("AbC", true /* ignore_case */)}));
sans = {"xyz.abc.com"};
EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(),
{ContainsMatcher("AbC", true /* ignore_case */)}));
sans = {"foo.aBc.com"};
EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(),
{ContainsMatcher("AbC", true /* ignore_case */)}));
sans = {"foo.Ab.com"};
EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(),
{ContainsMatcher("AbC", true /* ignore_case */)}));
}
TEST(XdsSanMatchingTest, RegexMatch) {
std::vector<const char*> sans = {"abc.example.com"};
EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {SafeRegexMatcher("(abc|xyz).example.com")}));
sans = {"xyz.example.com"};
EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {SafeRegexMatcher("(abc|xyz).example.com")}));
sans = {"foo.example.com"};
EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
sans.data(), sans.size(), {SafeRegexMatcher("(abc|xyz).example.com")}));
}
} // namespace
} // namespace testing
} // namespace grpc_core
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
auto result = RUN_ALL_TESTS();
grpc_shutdown();
return result;
}

@ -64,6 +64,7 @@ grpc_cc_test(
deps = [
"//:gpr",
"//:grpc",
"//:grpc_google_mesh_ca_certificate_provider_factory",
"//test/core/util:grpc_test_util",
],
)

@ -106,7 +106,7 @@ TEST(
auto identity_cert_distributor =
MakeRefCounted<grpc_tls_certificate_distributor>();
XdsCertificateProvider provider("root", root_cert_distributor, "identity",
identity_cert_distributor);
identity_cert_distributor, {});
auto* watcher = new TestCertificatesWatcher;
provider.distributor()->WatchTlsCertificates(
std::unique_ptr<TestCertificatesWatcher>(watcher), "", "");
@ -175,7 +175,7 @@ TEST(XdsCertificateProviderTest,
auto identity_cert_distributor =
MakeRefCounted<grpc_tls_certificate_distributor>();
XdsCertificateProvider provider("test", root_cert_distributor, "test",
identity_cert_distributor);
identity_cert_distributor, {});
auto* watcher = new TestCertificatesWatcher;
provider.distributor()->WatchTlsCertificates(
std::unique_ptr<TestCertificatesWatcher>(watcher), "", "");
@ -242,7 +242,8 @@ TEST(XdsCertificateProviderTest,
TEST(XdsCertificateProviderTest,
RootCertDistributorSameAsIdentityCertDistributorDifferentCertNames) {
auto distributor = MakeRefCounted<grpc_tls_certificate_distributor>();
XdsCertificateProvider provider("root", distributor, "identity", distributor);
XdsCertificateProvider provider("root", distributor, "identity", distributor,
{});
auto* watcher = new TestCertificatesWatcher;
provider.distributor()->WatchTlsCertificates(
std::unique_ptr<TestCertificatesWatcher>(watcher), "", "");
@ -305,7 +306,7 @@ TEST(XdsCertificateProviderTest,
TEST(XdsCertificateProviderTest,
RootCertDistributorSameAsIdentityCertDistributorSameCertNames) {
auto distributor = MakeRefCounted<grpc_tls_certificate_distributor>();
XdsCertificateProvider provider("", distributor, "", distributor);
XdsCertificateProvider provider("", distributor, "", distributor, {});
auto* watcher = new TestCertificatesWatcher;
provider.distributor()->WatchTlsCertificates(
std::unique_ptr<TestCertificatesWatcher>(watcher), "", "");
@ -368,7 +369,7 @@ TEST(XdsCertificateProviderTest,
TEST(XdsCertificateProviderTest, SwapOutDistributorsMultipleTimes) {
auto distributor = MakeRefCounted<grpc_tls_certificate_distributor>();
distributor->SetKeyMaterials("", kRootCert1, MakeKeyCertPairsType1());
XdsCertificateProvider provider("", nullptr, "", nullptr);
XdsCertificateProvider provider("", nullptr, "", nullptr, {});
auto* watcher = new TestCertificatesWatcher;
provider.distributor()->WatchTlsCertificates(
std::unique_ptr<TestCertificatesWatcher>(watcher), "", "");
@ -493,7 +494,7 @@ TEST(XdsCertificateProviderTest, SwapOutDistributorsMultipleTimes) {
}
TEST(XdsCertificateProviderTest, CertificateNameNotEmpty) {
XdsCertificateProvider provider("", nullptr, "", nullptr);
XdsCertificateProvider provider("", nullptr, "", nullptr, {});
auto* watcher = new TestCertificatesWatcher;
provider.distributor()->WatchTlsCertificates(
std::unique_ptr<TestCertificatesWatcher>(watcher), "test", "test");

@ -103,6 +103,7 @@ using ::envoy::config::route::v3::RouteConfiguration;
using ::envoy::extensions::filters::network::http_connection_manager::v3::
HttpConnectionManager;
using ::envoy::extensions::transport_sockets::tls::v3::UpstreamTlsContext;
using ::envoy::type::matcher::v3::StringMatcher;
using ::envoy::type::v3::FractionalPercent;
constexpr char kLdsTypeUrl[] =
@ -5311,10 +5312,21 @@ class XdsSecurityTest : public BasicTest {
root_cert_ = ReadFile(kCaCertPath);
bad_root_cert_ = ReadFile(kBadClientCertPath);
identity_pair_ = ReadTlsIdentityPair(kClientKeyPath, kClientCertPath);
// TODO(yashykt): Use different client certs here instead of reusing server
// certs after https://github.com/grpc/grpc/pull/24876 is merged
fallback_identity_pair_ =
ReadTlsIdentityPair(kServerKeyPath, kServerCertPath);
bad_identity_pair_ =
ReadTlsIdentityPair(kBadClientKeyPath, kBadClientCertPath);
server_san_exact_.set_exact("*.test.google.fr");
server_san_prefix_.set_prefix("waterzooi.test.google");
server_san_suffix_.set_suffix("google.fr");
server_san_contains_.set_contains("google");
server_san_regex_.mutable_safe_regex()->mutable_google_re2();
server_san_regex_.mutable_safe_regex()->set_regex(
"(foo|waterzooi).test.google.(fr|be)");
bad_san_1_.set_exact("192.168.1.4");
bad_san_2_.set_exact("foo.test.google.in");
authenticated_identity_ = {"testclient"};
fallback_authenticated_identity_ = {"*.test.google.fr",
"waterzooi.test.google.be",
@ -5342,6 +5354,7 @@ class XdsSecurityTest : public BasicTest {
absl::string_view root_certificate_name,
absl::string_view identity_instance_name,
absl::string_view identity_certificate_name,
const std::vector<StringMatcher>& san_matchers,
const std::vector<std::string>& expected_authenticated_identity,
bool test_expects_failure = false) {
auto cluster = default_cluster_;
@ -5367,6 +5380,15 @@ class XdsSecurityTest : public BasicTest {
->mutable_validation_context_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();
for (const auto& san_matcher : san_matchers) {
*validation_context->add_match_subject_alt_names() = san_matcher;
}
}
transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context);
}
balancers_[0]->ads_service()->SetCdsResource(cluster);
@ -5399,10 +5421,103 @@ class XdsSecurityTest : public BasicTest {
grpc_core::PemKeyCertPairList identity_pair_;
grpc_core::PemKeyCertPairList fallback_identity_pair_;
grpc_core::PemKeyCertPairList bad_identity_pair_;
StringMatcher server_san_exact_;
StringMatcher server_san_prefix_;
StringMatcher server_san_suffix_;
StringMatcher server_san_contains_;
StringMatcher server_san_regex_;
StringMatcher bad_san_1_;
StringMatcher bad_san_2_;
std::vector<std::string> authenticated_identity_;
std::vector<std::string> fallback_authenticated_identity_;
};
TEST_P(XdsSecurityTest,
TLSConfigurationWithoutValidationContextCertificateProviderInstance) {
auto cluster = default_cluster_;
auto* transport_socket = cluster.mutable_transport_socket();
transport_socket->set_name("envoy.transport_sockets.tls");
balancers_[0]->ads_service()->SetCdsResource(cluster);
CheckRpcSendFailure();
const auto& response_state =
balancers_[0]->ads_service()->cds_response_state();
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED);
EXPECT_EQ(response_state.error_message,
"TLS configuration provided but no "
"validation_context_certificate_provider_instance found.");
}
TEST_P(
XdsSecurityTest,
MatchSubjectAltNamesProvidedWithoutValidationContextCertificateProviderInstance) {
auto cluster = default_cluster_;
auto* transport_socket = cluster.mutable_transport_socket();
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();
*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);
CheckRpcSendFailure();
const auto& response_state =
balancers_[0]->ads_service()->cds_response_state();
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED);
EXPECT_EQ(response_state.error_message,
"TLS configuration provided but no "
"validation_context_certificate_provider_instance found.");
}
TEST_P(
XdsSecurityTest,
TlsCertificateCertificateProviderInstanceWithoutValidationContextCertificateProviderInstance) {
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()
->set_instance_name(std::string("instance_name"));
transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context);
balancers_[0]->ads_service()->SetCdsResource(cluster);
CheckRpcSendFailure();
const auto& response_state =
balancers_[0]->ads_service()->cds_response_state();
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED);
EXPECT_EQ(response_state.error_message,
"TLS configuration provided but no "
"validation_context_certificate_provider_instance found.");
}
TEST_P(XdsSecurityTest, RegexSanMatcherDoesNotAllowIgnoreCase) {
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(std::string("fake_plugin1"));
auto* validation_context = upstream_tls_context.mutable_common_tls_context()
->mutable_combined_validation_context()
->mutable_default_validation_context();
StringMatcher matcher;
matcher.mutable_safe_regex()->mutable_google_re2();
matcher.mutable_safe_regex()->set_regex(
"(foo|waterzooi).test.google.(fr|be)");
matcher.set_ignore_case(true);
*validation_context->add_match_subject_alt_names() = matcher;
transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context);
balancers_[0]->ads_service()->SetCdsResource(cluster);
CheckRpcSendFailure();
const auto& response_state =
balancers_[0]->ads_service()->cds_response_state();
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED);
EXPECT_EQ(response_state.error_message,
"StringMatcher: ignore_case has no effect for SAFE_REGEX.");
}
TEST_P(XdsSecurityTest, UnknownRootCertificateProvider) {
auto cluster = default_cluster_;
auto* transport_socket = cluster.mutable_transport_socket();
@ -5438,12 +5553,78 @@ TEST_P(XdsSecurityTest, UnknownIdentityCertificateProvider) {
g_fake1_cert_data_map = nullptr;
}
TEST_P(XdsSecurityTest, TestMtlsConfiguration) {
TEST_P(XdsSecurityTest, TestMtlsConfigurationWithNoSanMatchers) {
FakeCertificateProvider::CertDataMap fake1_cert_map = {
{"", {root_cert_, identity_pair_}}};
g_fake1_cert_data_map = &fake1_cert_map;
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
"", {}, authenticated_identity_);
g_fake1_cert_data_map = nullptr;
}
TEST_P(XdsSecurityTest, TestMtlsConfigurationWithExactSanMatcher) {
FakeCertificateProvider::CertDataMap fake1_cert_map = {
{"", {root_cert_, identity_pair_}}};
g_fake1_cert_data_map = &fake1_cert_map;
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
"", authenticated_identity_);
"", {server_san_exact_},
authenticated_identity_);
g_fake1_cert_data_map = nullptr;
}
TEST_P(XdsSecurityTest, TestMtlsConfigurationWithPrefixSanMatcher) {
FakeCertificateProvider::CertDataMap fake1_cert_map = {
{"", {root_cert_, identity_pair_}}};
g_fake1_cert_data_map = &fake1_cert_map;
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
"", {server_san_prefix_},
authenticated_identity_);
g_fake1_cert_data_map = nullptr;
}
TEST_P(XdsSecurityTest, TestMtlsConfigurationWithSuffixSanMatcher) {
FakeCertificateProvider::CertDataMap fake1_cert_map = {
{"", {root_cert_, identity_pair_}}};
g_fake1_cert_data_map = &fake1_cert_map;
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
"", {server_san_suffix_},
authenticated_identity_);
g_fake1_cert_data_map = nullptr;
}
TEST_P(XdsSecurityTest, TestMtlsConfigurationWithContainsSanMatcher) {
FakeCertificateProvider::CertDataMap fake1_cert_map = {
{"", {root_cert_, identity_pair_}}};
g_fake1_cert_data_map = &fake1_cert_map;
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
"", {server_san_contains_},
authenticated_identity_);
g_fake1_cert_data_map = nullptr;
}
TEST_P(XdsSecurityTest, TestMtlsConfigurationWithRegexSanMatcher) {
FakeCertificateProvider::CertDataMap fake1_cert_map = {
{"", {root_cert_, identity_pair_}}};
g_fake1_cert_data_map = &fake1_cert_map;
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
"", {server_san_regex_},
authenticated_identity_);
g_fake1_cert_data_map = nullptr;
}
TEST_P(XdsSecurityTest, TestMtlsConfigurationWithSanMatchersUpdate) {
FakeCertificateProvider::CertDataMap fake1_cert_map = {
{"", {root_cert_, identity_pair_}}};
g_fake1_cert_data_map = &fake1_cert_map;
UpdateAndVerifyXdsSecurityConfiguration(
"fake_plugin1", "", "fake_plugin1", "",
{server_san_exact_, server_san_prefix_}, authenticated_identity_);
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
"", {bad_san_1_, bad_san_2_}, {},
true /* failure */);
UpdateAndVerifyXdsSecurityConfiguration(
"fake_plugin1", "", "fake_plugin1", "",
{server_san_prefix_, server_san_regex_}, authenticated_identity_);
g_fake1_cert_data_map = nullptr;
}
@ -5455,12 +5636,14 @@ TEST_P(XdsSecurityTest, TestMtlsConfigurationWithRootPluginUpdate) {
{"", {bad_root_cert_, bad_identity_pair_}}};
g_fake2_cert_data_map = &fake2_cert_map;
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
"", authenticated_identity_);
"", {server_san_exact_},
authenticated_identity_);
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin2" /* bad root */, "",
"fake_plugin1", "", {},
"fake_plugin1", "", {}, {},
true /* failure */);
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
"", authenticated_identity_);
"", {server_san_exact_},
authenticated_identity_);
g_fake1_cert_data_map = nullptr;
g_fake2_cert_data_map = nullptr;
}
@ -5473,9 +5656,11 @@ TEST_P(XdsSecurityTest, TestMtlsConfigurationWithIdentityPluginUpdate) {
{"", {root_cert_, fallback_identity_pair_}}};
g_fake2_cert_data_map = &fake2_cert_map;
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
"", authenticated_identity_);
"", {server_san_exact_},
authenticated_identity_);
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin2",
"", fallback_authenticated_identity_);
"", {server_san_exact_},
fallback_authenticated_identity_);
g_fake1_cert_data_map = nullptr;
g_fake2_cert_data_map = nullptr;
}
@ -5489,11 +5674,12 @@ TEST_P(XdsSecurityTest, TestMtlsConfigurationWithBothPluginsUpdated) {
{"good", {root_cert_, fallback_identity_pair_}}};
g_fake2_cert_data_map = &fake2_cert_map;
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin2", "", "fake_plugin2",
"", {}, true /* failure */);
"", {}, {}, true /* failure */);
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
"", authenticated_identity_);
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin2", "good",
"fake_plugin2", "good",
"", {server_san_prefix_},
authenticated_identity_);
UpdateAndVerifyXdsSecurityConfiguration(
"fake_plugin2", "good", "fake_plugin2", "good", {server_san_prefix_},
fallback_authenticated_identity_);
g_fake1_cert_data_map = nullptr;
g_fake2_cert_data_map = nullptr;
@ -5505,9 +5691,11 @@ TEST_P(XdsSecurityTest, TestMtlsConfigurationWithRootCertificateNameUpdate) {
{"bad", {bad_root_cert_, bad_identity_pair_}}};
g_fake1_cert_data_map = &fake1_cert_map;
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
"", authenticated_identity_);
"", {server_san_regex_},
authenticated_identity_);
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "bad", "fake_plugin1",
"", {}, true /* failure */);
"", {server_san_regex_}, {},
true /* failure */);
g_fake1_cert_data_map = nullptr;
}
@ -5518,9 +5706,11 @@ TEST_P(XdsSecurityTest,
{"bad", {bad_root_cert_, bad_identity_pair_}}};
g_fake1_cert_data_map = &fake1_cert_map;
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
"", authenticated_identity_);
"", {server_san_exact_},
authenticated_identity_);
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
"bad", {}, true /* failure */);
"bad", {server_san_exact_}, {},
true /* failure */);
g_fake1_cert_data_map = nullptr;
}
@ -5531,9 +5721,10 @@ TEST_P(XdsSecurityTest,
{"good", {root_cert_, fallback_identity_pair_}}};
g_fake1_cert_data_map = &fake1_cert_map;
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
"", authenticated_identity_);
"", {server_san_exact_},
authenticated_identity_);
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
"good",
"good", {server_san_exact_},
fallback_authenticated_identity_);
g_fake1_cert_data_map = nullptr;
}
@ -5544,17 +5735,46 @@ TEST_P(XdsSecurityTest, TestMtlsConfigurationWithBothCertificateNamesUpdated) {
{"bad", {bad_root_cert_, bad_identity_pair_}}};
g_fake1_cert_data_map = &fake1_cert_map;
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "bad", "fake_plugin1",
"bad", {}, true /* failure */);
"bad", {server_san_prefix_}, {},
true /* failure */);
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
"", authenticated_identity_);
"", {server_san_prefix_},
authenticated_identity_);
g_fake1_cert_data_map = nullptr;
}
TEST_P(XdsSecurityTest, TestTlsConfiguration) {
TEST_P(XdsSecurityTest, TestTlsConfigurationWithNoSanMatchers) {
FakeCertificateProvider::CertDataMap fake1_cert_map = {
{"", {root_cert_, identity_pair_}}};
g_fake1_cert_data_map = &fake1_cert_map;
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "", "",
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "", "", {},
{} /* unauthenticated */);
g_fake1_cert_data_map = nullptr;
}
TEST_P(XdsSecurityTest, TestTlsConfigurationWithSanMatchers) {
FakeCertificateProvider::CertDataMap fake1_cert_map = {
{"", {root_cert_, identity_pair_}}};
g_fake1_cert_data_map = &fake1_cert_map;
UpdateAndVerifyXdsSecurityConfiguration(
"fake_plugin1", "", "", "",
{server_san_exact_, server_san_prefix_, server_san_regex_},
{} /* unauthenticated */);
g_fake1_cert_data_map = nullptr;
}
TEST_P(XdsSecurityTest, TestTlsConfigurationWithSanMatchersUpdate) {
FakeCertificateProvider::CertDataMap fake1_cert_map = {
{"", {root_cert_, identity_pair_}}};
g_fake1_cert_data_map = &fake1_cert_map;
UpdateAndVerifyXdsSecurityConfiguration(
"fake_plugin1", "", "", "", {server_san_exact_, server_san_prefix_},
{} /* unauthenticated */);
UpdateAndVerifyXdsSecurityConfiguration(
"fake_plugin1", "", "", "", {bad_san_1_, bad_san_2_},
{} /* unauthenticated */, true /* failure */);
UpdateAndVerifyXdsSecurityConfiguration(
"fake_plugin1", "", "", "", {server_san_prefix_, server_san_regex_},
{} /* unauthenticated */);
g_fake1_cert_data_map = nullptr;
}
@ -5565,8 +5785,10 @@ TEST_P(XdsSecurityTest, TestTlsConfigurationWithRootCertificateNameUpdate) {
{"bad", {bad_root_cert_, bad_identity_pair_}}};
g_fake1_cert_data_map = &fake1_cert_map;
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "", "",
{server_san_exact_},
{} /* unauthenticated */);
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "bad", "", "", {},
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "bad", "", "",
{server_san_exact_}, {},
true /* failure */);
g_fake1_cert_data_map = nullptr;
}
@ -5579,15 +5801,16 @@ TEST_P(XdsSecurityTest, TestTlsConfigurationWithRootPluginUpdate) {
{"", {bad_root_cert_, bad_identity_pair_}}};
g_fake2_cert_data_map = &fake2_cert_map;
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "", "",
{server_san_exact_},
{} /* unauthenticated */);
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin2", "", "", "", {},
true /* failure */);
UpdateAndVerifyXdsSecurityConfiguration(
"fake_plugin2", "", "", "", {server_san_exact_}, {}, true /* failure */);
g_fake1_cert_data_map = nullptr;
g_fake2_cert_data_map = nullptr;
}
TEST_P(XdsSecurityTest, TestFallbackConfiguration) {
UpdateAndVerifyXdsSecurityConfiguration("", "", "", "",
UpdateAndVerifyXdsSecurityConfiguration("", "", "", "", {},
fallback_authenticated_identity_);
g_fake1_cert_data_map = nullptr;
}
@ -5597,8 +5820,10 @@ TEST_P(XdsSecurityTest, TestMtlsToTls) {
{"", {root_cert_, identity_pair_}}};
g_fake1_cert_data_map = &fake1_cert_map;
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
"", authenticated_identity_);
"", {server_san_exact_},
authenticated_identity_);
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "", "",
{server_san_exact_},
{} /* unauthenticated */);
g_fake1_cert_data_map = nullptr;
}
@ -5608,8 +5833,9 @@ TEST_P(XdsSecurityTest, TestMtlsToFallback) {
{"", {root_cert_, identity_pair_}}};
g_fake1_cert_data_map = &fake1_cert_map;
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
"", authenticated_identity_);
UpdateAndVerifyXdsSecurityConfiguration("", "", "", "",
"", {server_san_exact_},
authenticated_identity_);
UpdateAndVerifyXdsSecurityConfiguration("", "", "", "", {},
fallback_authenticated_identity_);
g_fake1_cert_data_map = nullptr;
}
@ -5619,9 +5845,11 @@ TEST_P(XdsSecurityTest, TestTlsToMtls) {
{"", {root_cert_, identity_pair_}}};
g_fake1_cert_data_map = &fake1_cert_map;
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "", "",
{server_san_exact_},
{} /* unauthenticated */);
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
"", authenticated_identity_);
"", {server_san_exact_},
authenticated_identity_);
g_fake1_cert_data_map = nullptr;
}
@ -5630,8 +5858,9 @@ TEST_P(XdsSecurityTest, TestTlsToFallback) {
{"", {root_cert_, identity_pair_}}};
g_fake1_cert_data_map = &fake1_cert_map;
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "", "",
{server_san_exact_},
{} /* unauthenticated */);
UpdateAndVerifyXdsSecurityConfiguration("", "", "", "",
UpdateAndVerifyXdsSecurityConfiguration("", "", "", "", {},
fallback_authenticated_identity_);
g_fake1_cert_data_map = nullptr;
}
@ -5640,10 +5869,11 @@ TEST_P(XdsSecurityTest, TestFallbackToMtls) {
FakeCertificateProvider::CertDataMap fake1_cert_map = {
{"", {root_cert_, identity_pair_}}};
g_fake1_cert_data_map = &fake1_cert_map;
UpdateAndVerifyXdsSecurityConfiguration("", "", "", "",
UpdateAndVerifyXdsSecurityConfiguration("", "", "", "", {},
fallback_authenticated_identity_);
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
"", authenticated_identity_);
"", {server_san_exact_},
authenticated_identity_);
g_fake1_cert_data_map = nullptr;
}
@ -5651,15 +5881,17 @@ TEST_P(XdsSecurityTest, TestFallbackToTls) {
FakeCertificateProvider::CertDataMap fake1_cert_map = {
{"", {root_cert_, identity_pair_}}};
g_fake1_cert_data_map = &fake1_cert_map;
UpdateAndVerifyXdsSecurityConfiguration("", "", "", "",
UpdateAndVerifyXdsSecurityConfiguration("", "", "", "", {},
fallback_authenticated_identity_);
UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "", "",
{server_san_exact_},
{} /* unauthenticated */);
g_fake1_cert_data_map = nullptr;
}
TEST_P(XdsSecurityTest, TestFileWatcherCertificateProvider) {
UpdateAndVerifyXdsSecurityConfiguration("file_plugin", "", "file_plugin", "",
{server_san_exact_},
authenticated_identity_);
}

@ -1558,8 +1558,6 @@ src/core/ext/xds/certificate_provider_store.cc \
src/core/ext/xds/certificate_provider_store.h \
src/core/ext/xds/file_watcher_certificate_provider_factory.cc \
src/core/ext/xds/file_watcher_certificate_provider_factory.h \
src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc \
src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h \
src/core/ext/xds/xds_api.cc \
src/core/ext/xds/xds_api.h \
src/core/ext/xds/xds_bootstrap.cc \
@ -1952,6 +1950,8 @@ src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc \
src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h \
src/core/lib/security/credentials/tls/tls_credentials.cc \
src/core/lib/security/credentials/tls/tls_credentials.h \
src/core/lib/security/credentials/tls/tls_utils.cc \
src/core/lib/security/credentials/tls/tls_utils.h \
src/core/lib/security/credentials/xds/xds_credentials.cc \
src/core/lib/security/credentials/xds/xds_credentials.h \
src/core/lib/security/security_connector/alts/alts_security_connector.cc \

@ -1395,8 +1395,6 @@ src/core/ext/xds/certificate_provider_store.cc \
src/core/ext/xds/certificate_provider_store.h \
src/core/ext/xds/file_watcher_certificate_provider_factory.cc \
src/core/ext/xds/file_watcher_certificate_provider_factory.h \
src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc \
src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h \
src/core/ext/xds/xds_api.cc \
src/core/ext/xds/xds_api.h \
src/core/ext/xds/xds_bootstrap.cc \
@ -1794,6 +1792,8 @@ src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc \
src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h \
src/core/lib/security/credentials/tls/tls_credentials.cc \
src/core/lib/security/credentials/tls/tls_credentials.h \
src/core/lib/security/credentials/tls/tls_utils.cc \
src/core/lib/security/credentials/tls/tls_utils.h \
src/core/lib/security/credentials/xds/xds_credentials.cc \
src/core/lib/security/credentials/xds/xds_credentials.h \
src/core/lib/security/security_connector/alts/alts_security_connector.cc \

@ -6325,6 +6325,30 @@
],
"uses_polling": true
},
{
"args": [],
"benchmark": false,
"ci_platforms": [
"linux",
"mac",
"posix",
"windows"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"exclude_iomgrs": [],
"flaky": false,
"gtest": true,
"language": "c++",
"name": "xds_credentials_test",
"platforms": [
"linux",
"mac",
"posix",
"windows"
],
"uses_polling": true
},
{
"args": [],
"boringssl": true,

Loading…
Cancel
Save