Merge pull request #24227 from ZhenLian/zhen_dynamic_file_reloading_3

C-core changes for TLS credentials
pull/24573/head
ZhenLian 4 years ago committed by GitHub
commit 4d80f376a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      BUILD
  2. 5
      BUILD.gn
  3. 45
      CMakeLists.txt
  4. 6
      Makefile
  5. 20
      build_autogenerated.yaml
  6. 1
      config.m4
  7. 1
      config.w32
  8. 6
      gRPC-C++.podspec
  9. 5
      gRPC-Core.podspec
  10. 18
      grpc.def
  11. 3
      grpc.gemspec
  12. 2
      grpc.gyp
  13. 314
      include/grpc/grpc_security.h
  14. 2
      include/grpcpp/security/credentials.h
  15. 2
      include/grpcpp/security/server_credentials.h
  16. 80
      include/grpcpp/security/tls_certificate_provider.h
  17. 261
      include/grpcpp/security/tls_credentials_options.h
  18. 3
      package.xml
  19. 2
      src/core/ext/xds/certificate_provider_factory.h
  20. 2
      src/core/ext/xds/certificate_provider_store.h
  21. 32
      src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.cc
  22. 16
      src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.h
  23. 78
      src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc
  24. 37
      src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h
  25. 226
      src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc
  26. 257
      src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h
  27. 28
      src/core/lib/security/credentials/tls/tls_credentials.cc
  28. 4
      src/core/lib/security/credentials/tls/tls_credentials.h
  29. 2
      src/core/lib/security/security_connector/ssl_utils.h
  30. 568
      src/core/lib/security/security_connector/tls/tls_security_connector.cc
  31. 167
      src/core/lib/security/security_connector/tls/tls_security_connector.h
  32. 2
      src/cpp/client/secure_credentials.cc
  33. 45
      src/cpp/common/tls_certificate_provider.cc
  34. 268
      src/cpp/common/tls_credentials_options.cc
  35. 75
      src/cpp/common/tls_credentials_options_util.cc
  36. 16
      src/cpp/common/tls_credentials_options_util.h
  37. 3
      src/cpp/server/secure_server_credentials.cc
  38. 1
      src/python/grpcio/grpc_core_dependencies.py
  39. 36
      src/ruby/ext/grpc/rb_grpc_imports.generated.c
  40. 60
      src/ruby/ext/grpc/rb_grpc_imports.generated.h
  41. 129
      test/core/end2end/fixtures/h2_tls.cc
  42. 4
      test/core/security/BUILD
  43. 17
      test/core/security/grpc_tls_certificate_distributor_test.cc
  44. 50
      test/core/security/grpc_tls_credentials_options_test.cc
  45. 626
      test/core/security/tls_security_connector_test.cc
  46. 18
      test/core/surface/public_headers_must_be_c89.c
  47. 441
      test/cpp/client/credentials_test.cc
  48. 14
      test/cpp/server/BUILD
  49. 98
      test/cpp/server/credentials_test.cc
  50. 1
      tools/doxygen/Doxyfile.c++
  51. 5
      tools/doxygen/Doxyfile.c++.internal
  52. 3
      tools/doxygen/Doxyfile.core.internal
  53. 24
      tools/run_tests/generated/tests.json

@ -252,6 +252,7 @@ GRPCXX_PUBLIC_HDRS = [
"include/grpcpp/security/auth_metadata_processor.h",
"include/grpcpp/security/credentials.h",
"include/grpcpp/security/server_credentials.h",
"include/grpcpp/security/tls_certificate_provider.h",
"include/grpcpp/security/tls_credentials_options.h",
"include/grpcpp/server.h",
"include/grpcpp/server_builder.h",
@ -355,6 +356,7 @@ grpc_cc_library(
"src/cpp/common/secure_auth_context.cc",
"src/cpp/common/secure_channel_arguments.cc",
"src/cpp/common/secure_create_auth_context.cc",
"src/cpp/common/tls_certificate_provider.cc",
"src/cpp/common/tls_credentials_options.cc",
"src/cpp/common/tls_credentials_options_util.cc",
"src/cpp/server/insecure_server_credentials.cc",
@ -1796,6 +1798,7 @@ grpc_cc_library(
"src/core/lib/security/credentials/plugin/plugin_credentials.cc",
"src/core/lib/security/credentials/ssl/ssl_credentials.cc",
"src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.cc",
"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/security_connector/alts/alts_security_connector.cc",
@ -1820,7 +1823,6 @@ grpc_cc_library(
hdrs = [
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h",
"src/core/ext/xds/xds_channel_args.h",
"src/core/lib/security/certificate_provider.h",
"src/core/lib/security/context/security_context.h",
"src/core/lib/security/credentials/alts/alts_credentials.h",
"src/core/lib/security/credentials/composite/composite_credentials.h",
@ -1838,6 +1840,7 @@ grpc_cc_library(
"src/core/lib/security/credentials/plugin/plugin_credentials.h",
"src/core/lib/security/credentials/ssl/ssl_credentials.h",
"src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.h",
"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/security_connector/alts/alts_security_connector.h",

@ -976,7 +976,6 @@ config("grpc_config") {
"src/core/lib/security/authorization/evaluate_args.h",
"src/core/lib/security/authorization/mock_cel/activation.h",
"src/core/lib/security/authorization/mock_cel/cel_value.h",
"src/core/lib/security/certificate_provider.h",
"src/core/lib/security/context/security_context.cc",
"src/core/lib/security/context/security_context.h",
"src/core/lib/security/credentials/alts/alts_credentials.cc",
@ -1023,6 +1022,8 @@ config("grpc_config") {
"src/core/lib/security/credentials/ssl/ssl_credentials.h",
"src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.cc",
"src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.h",
"src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc",
"src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h",
"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",
@ -1376,6 +1377,7 @@ config("grpc_config") {
"include/grpcpp/security/auth_metadata_processor.h",
"include/grpcpp/security/credentials.h",
"include/grpcpp/security/server_credentials.h",
"include/grpcpp/security/tls_certificate_provider.h",
"include/grpcpp/security/tls_credentials_options.h",
"include/grpcpp/server.h",
"include/grpcpp/server_builder.h",
@ -1430,6 +1432,7 @@ config("grpc_config") {
"src/cpp/common/secure_auth_context.h",
"src/cpp/common/secure_channel_arguments.cc",
"src/cpp/common/secure_create_auth_context.cc",
"src/cpp/common/tls_certificate_provider.cc",
"src/cpp/common/tls_credentials_options.cc",
"src/cpp/common/tls_credentials_options_util.cc",
"src/cpp/common/tls_credentials_options_util.h",

@ -908,6 +908,7 @@ if(gRPC_BUILD_TESTS)
endif()
add_dependencies(buildtests_cxx string_ref_test)
add_dependencies(buildtests_cxx test_cpp_client_credentials_test)
add_dependencies(buildtests_cxx test_cpp_server_credentials_test)
add_dependencies(buildtests_cxx test_cpp_util_slice_test)
add_dependencies(buildtests_cxx test_cpp_util_time_test)
add_dependencies(buildtests_cxx thread_manager_test)
@ -1852,6 +1853,7 @@ add_library(grpc
src/core/lib/security/credentials/plugin/plugin_credentials.cc
src/core/lib/security/credentials/ssl/ssl_credentials.cc
src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.cc
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/xds/xds_credentials.cc
@ -2671,6 +2673,7 @@ add_library(grpc++
src/cpp/common/secure_auth_context.cc
src/cpp/common/secure_channel_arguments.cc
src/cpp/common/secure_create_auth_context.cc
src/cpp/common/tls_certificate_provider.cc
src/cpp/common/tls_credentials_options.cc
src/cpp/common/tls_credentials_options_util.cc
src/cpp/common/validate_service_config.cc
@ -2893,6 +2896,7 @@ foreach(_hdr
include/grpcpp/security/auth_metadata_processor.h
include/grpcpp/security/credentials.h
include/grpcpp/security/server_credentials.h
include/grpcpp/security/tls_certificate_provider.h
include/grpcpp/security/tls_credentials_options.h
include/grpcpp/server.h
include/grpcpp/server_builder.h
@ -3562,6 +3566,7 @@ foreach(_hdr
include/grpcpp/security/auth_metadata_processor.h
include/grpcpp/security/credentials.h
include/grpcpp/security/server_credentials.h
include/grpcpp/security/tls_certificate_provider.h
include/grpcpp/security/tls_credentials_options.h
include/grpcpp/server.h
include/grpcpp/server_builder.h
@ -14572,6 +14577,46 @@ target_link_libraries(test_cpp_client_credentials_test
)
endif()
if(gRPC_BUILD_TESTS)
add_executable(test_cpp_server_credentials_test
test/cpp/server/credentials_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
target_include_directories(test_cpp_server_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(test_cpp_server_credentials_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc++
grpc
gpr
address_sorting
upb
${_gRPC_GFLAGS_LIBRARIES}
)
endif()
if(gRPC_BUILD_TESTS)

@ -2265,6 +2265,7 @@ LIBGRPC_SRC = \
src/core/lib/security/credentials/plugin/plugin_credentials.cc \
src/core/lib/security/credentials/ssl/ssl_credentials.cc \
src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.cc \
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/xds/xds_credentials.cc \
@ -2844,6 +2845,7 @@ LIBGRPC++_SRC = \
src/cpp/common/secure_auth_context.cc \
src/cpp/common/secure_channel_arguments.cc \
src/cpp/common/secure_create_auth_context.cc \
src/cpp/common/tls_certificate_provider.cc \
src/cpp/common/tls_credentials_options.cc \
src/cpp/common/tls_credentials_options_util.cc \
src/cpp/common/validate_service_config.cc \
@ -3026,6 +3028,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/security/auth_metadata_processor.h \
include/grpcpp/security/credentials.h \
include/grpcpp/security/server_credentials.h \
include/grpcpp/security/tls_certificate_provider.h \
include/grpcpp/security/tls_credentials_options.h \
include/grpcpp/server.h \
include/grpcpp/server_builder.h \
@ -3540,6 +3543,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/security/auth_metadata_processor.h \
include/grpcpp/security/credentials.h \
include/grpcpp/security/server_credentials.h \
include/grpcpp/security/tls_certificate_provider.h \
include/grpcpp/security/tls_credentials_options.h \
include/grpcpp/server.h \
include/grpcpp/server_builder.h \
@ -4801,6 +4805,7 @@ src/core/lib/security/credentials/oauth2/oauth2_credentials.cc: $(OPENSSL_DEP)
src/core/lib/security/credentials/plugin/plugin_credentials.cc: $(OPENSSL_DEP)
src/core/lib/security/credentials/ssl/ssl_credentials.cc: $(OPENSSL_DEP)
src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.cc: $(OPENSSL_DEP)
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/xds/xds_credentials.cc: $(OPENSSL_DEP)
@ -4858,6 +4863,7 @@ src/cpp/common/auth_property_iterator.cc: $(OPENSSL_DEP)
src/cpp/common/secure_auth_context.cc: $(OPENSSL_DEP)
src/cpp/common/secure_channel_arguments.cc: $(OPENSSL_DEP)
src/cpp/common/secure_create_auth_context.cc: $(OPENSSL_DEP)
src/cpp/common/tls_certificate_provider.cc: $(OPENSSL_DEP)
src/cpp/common/tls_credentials_options.cc: $(OPENSSL_DEP)
src/cpp/common/tls_credentials_options_util.cc: $(OPENSSL_DEP)
src/cpp/ext/proto_server_reflection.cc: $(OPENSSL_DEP)

@ -748,7 +748,6 @@ libs:
- src/core/lib/security/authorization/evaluate_args.h
- src/core/lib/security/authorization/mock_cel/activation.h
- src/core/lib/security/authorization/mock_cel/cel_value.h
- src/core/lib/security/certificate_provider.h
- src/core/lib/security/context/security_context.h
- src/core/lib/security/credentials/alts/alts_credentials.h
- src/core/lib/security/credentials/alts/check_gcp_environment.h
@ -768,6 +767,7 @@ libs:
- src/core/lib/security/credentials/plugin/plugin_credentials.h
- src/core/lib/security/credentials/ssl/ssl_credentials.h
- src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.h
- 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/xds/xds_credentials.h
@ -1280,6 +1280,7 @@ libs:
- src/core/lib/security/credentials/plugin/plugin_credentials.cc
- src/core/lib/security/credentials/ssl/ssl_credentials.cc
- src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.cc
- 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/xds/xds_credentials.cc
@ -2249,6 +2250,7 @@ libs:
- include/grpcpp/security/auth_metadata_processor.h
- include/grpcpp/security/credentials.h
- include/grpcpp/security/server_credentials.h
- include/grpcpp/security/tls_certificate_provider.h
- include/grpcpp/security/tls_credentials_options.h
- include/grpcpp/server.h
- include/grpcpp/server_builder.h
@ -2312,6 +2314,7 @@ libs:
- src/cpp/common/secure_auth_context.cc
- src/cpp/common/secure_channel_arguments.cc
- src/cpp/common/secure_create_auth_context.cc
- src/cpp/common/tls_certificate_provider.cc
- src/cpp/common/tls_credentials_options.cc
- src/cpp/common/tls_credentials_options_util.cc
- src/cpp/common/validate_service_config.cc
@ -2611,6 +2614,7 @@ libs:
- include/grpcpp/security/auth_metadata_processor.h
- include/grpcpp/security/credentials.h
- include/grpcpp/security/server_credentials.h
- include/grpcpp/security/tls_certificate_provider.h
- include/grpcpp/security/tls_credentials_options.h
- include/grpcpp/server.h
- include/grpcpp/server_builder.h
@ -7449,6 +7453,20 @@ targets:
- gpr
- address_sorting
- upb
- name: test_cpp_server_credentials_test
gtest: true
build: test
language: c++
headers: []
src:
- test/cpp/server/credentials_test.cc
deps:
- grpc_test_util
- grpc++
- grpc
- gpr
- address_sorting
- upb
- name: test_cpp_util_slice_test
gtest: true
build: test

@ -512,6 +512,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/security/credentials/plugin/plugin_credentials.cc \
src/core/lib/security/credentials/ssl/ssl_credentials.cc \
src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.cc \
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/xds/xds_credentials.cc \

@ -479,6 +479,7 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\security\\credentials\\plugin\\plugin_credentials.cc " +
"src\\core\\lib\\security\\credentials\\ssl\\ssl_credentials.cc " +
"src\\core\\lib\\security\\credentials\\tls\\grpc_tls_certificate_distributor.cc " +
"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\\xds\\xds_credentials.cc " +

@ -150,6 +150,7 @@ Pod::Spec.new do |s|
'include/grpcpp/security/auth_metadata_processor.h',
'include/grpcpp/security/credentials.h',
'include/grpcpp/security/server_credentials.h',
'include/grpcpp/security/tls_certificate_provider.h',
'include/grpcpp/security/tls_credentials_options.h',
'include/grpcpp/server.h',
'include/grpcpp/server_builder.h',
@ -596,7 +597,6 @@ Pod::Spec.new do |s|
'src/core/lib/security/authorization/evaluate_args.h',
'src/core/lib/security/authorization/mock_cel/activation.h',
'src/core/lib/security/authorization/mock_cel/cel_value.h',
'src/core/lib/security/certificate_provider.h',
'src/core/lib/security/context/security_context.h',
'src/core/lib/security/credentials/alts/alts_credentials.h',
'src/core/lib/security/credentials/alts/check_gcp_environment.h',
@ -616,6 +616,7 @@ Pod::Spec.new do |s|
'src/core/lib/security/credentials/plugin/plugin_credentials.h',
'src/core/lib/security/credentials/ssl/ssl_credentials.h',
'src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.h',
'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/xds/xds_credentials.h',
@ -723,6 +724,7 @@ Pod::Spec.new do |s|
'src/cpp/common/secure_auth_context.h',
'src/cpp/common/secure_channel_arguments.cc',
'src/cpp/common/secure_create_auth_context.cc',
'src/cpp/common/tls_certificate_provider.cc',
'src/cpp/common/tls_credentials_options.cc',
'src/cpp/common/tls_credentials_options_util.cc',
'src/cpp/common/tls_credentials_options_util.h',
@ -1195,7 +1197,6 @@ Pod::Spec.new do |s|
'src/core/lib/security/authorization/evaluate_args.h',
'src/core/lib/security/authorization/mock_cel/activation.h',
'src/core/lib/security/authorization/mock_cel/cel_value.h',
'src/core/lib/security/certificate_provider.h',
'src/core/lib/security/context/security_context.h',
'src/core/lib/security/credentials/alts/alts_credentials.h',
'src/core/lib/security/credentials/alts/check_gcp_environment.h',
@ -1215,6 +1216,7 @@ Pod::Spec.new do |s|
'src/core/lib/security/credentials/plugin/plugin_credentials.h',
'src/core/lib/security/credentials/ssl/ssl_credentials.h',
'src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.h',
'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/xds/xds_credentials.h',

@ -1033,7 +1033,6 @@ Pod::Spec.new do |s|
'src/core/lib/security/authorization/evaluate_args.h',
'src/core/lib/security/authorization/mock_cel/activation.h',
'src/core/lib/security/authorization/mock_cel/cel_value.h',
'src/core/lib/security/certificate_provider.h',
'src/core/lib/security/context/security_context.cc',
'src/core/lib/security/context/security_context.h',
'src/core/lib/security/credentials/alts/alts_credentials.cc',
@ -1080,6 +1079,8 @@ Pod::Spec.new do |s|
'src/core/lib/security/credentials/ssl/ssl_credentials.h',
'src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.cc',
'src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.h',
'src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc',
'src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h',
'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',
@ -1720,7 +1721,6 @@ Pod::Spec.new do |s|
'src/core/lib/security/authorization/evaluate_args.h',
'src/core/lib/security/authorization/mock_cel/activation.h',
'src/core/lib/security/authorization/mock_cel/cel_value.h',
'src/core/lib/security/certificate_provider.h',
'src/core/lib/security/context/security_context.h',
'src/core/lib/security/credentials/alts/alts_credentials.h',
'src/core/lib/security/credentials/alts/check_gcp_environment.h',
@ -1740,6 +1740,7 @@ Pod::Spec.new do |s|
'src/core/lib/security/credentials/plugin/plugin_credentials.h',
'src/core/lib/security/credentials/ssl/ssl_credentials.h',
'src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.h',
'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/xds/xds_credentials.h',

@ -135,18 +135,22 @@ EXPORTS
grpc_alts_server_credentials_create
grpc_local_credentials_create
grpc_local_server_credentials_create
grpc_tls_identity_pairs_create
grpc_tls_identity_pairs_add_pair
grpc_tls_identity_pairs_destroy
grpc_tls_certificate_provider_static_data_create
grpc_tls_certificate_provider_release
grpc_tls_credentials_options_create
grpc_tls_credentials_options_set_cert_request_type
grpc_tls_credentials_options_set_server_verification_option
grpc_tls_credentials_options_set_key_materials_config
grpc_tls_credentials_options_set_credential_reload_config
grpc_tls_credentials_options_set_certificate_provider
grpc_tls_credentials_options_watch_root_certs
grpc_tls_credentials_options_set_root_cert_name
grpc_tls_credentials_options_watch_identity_key_cert_pairs
grpc_tls_credentials_options_set_identity_cert_name
grpc_tls_credentials_options_set_server_authorization_check_config
grpc_tls_key_materials_config_create
grpc_tls_key_materials_config_set_key_materials
grpc_tls_key_materials_config_set_version
grpc_tls_key_materials_config_get_version
grpc_tls_credential_reload_config_create
grpc_tls_server_authorization_check_config_create
grpc_tls_server_authorization_check_config_release
grpc_xds_credentials_create
grpc_raw_byte_buffer_create
grpc_raw_compressed_byte_buffer_create

@ -951,7 +951,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/security/authorization/evaluate_args.h )
s.files += %w( src/core/lib/security/authorization/mock_cel/activation.h )
s.files += %w( src/core/lib/security/authorization/mock_cel/cel_value.h )
s.files += %w( src/core/lib/security/certificate_provider.h )
s.files += %w( src/core/lib/security/context/security_context.cc )
s.files += %w( src/core/lib/security/context/security_context.h )
s.files += %w( src/core/lib/security/credentials/alts/alts_credentials.cc )
@ -998,6 +997,8 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/security/credentials/ssl/ssl_credentials.h )
s.files += %w( src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.cc )
s.files += %w( src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.h )
s.files += %w( src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc )
s.files += %w( src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h )
s.files += %w( src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc )
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 )

@ -875,6 +875,7 @@
'src/core/lib/security/credentials/plugin/plugin_credentials.cc',
'src/core/lib/security/credentials/ssl/ssl_credentials.cc',
'src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.cc',
'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/xds/xds_credentials.cc',
@ -1403,6 +1404,7 @@
'src/cpp/common/secure_auth_context.cc',
'src/cpp/common/secure_channel_arguments.cc',
'src/cpp/common/secure_create_auth_context.cc',
'src/cpp/common/tls_certificate_provider.cc',
'src/cpp/common/tls_credentials_options.cc',
'src/cpp/common/tls_credentials_options_util.cc',
'src/cpp/common/validate_service_config.cc',

@ -743,183 +743,156 @@ GRPCAPI grpc_server_credentials* grpc_local_server_credentials_create(
* experimental purpose for now and subject to change. */
typedef struct grpc_tls_error_details grpc_tls_error_details;
/** Config for TLS key materials. It is used for
* experimental purpose for now and subject to change. */
typedef struct grpc_tls_key_materials_config grpc_tls_key_materials_config;
/** Config for TLS credential reload. It is used for
* experimental purpose for now and subject to change. */
typedef struct grpc_tls_credential_reload_config
grpc_tls_credential_reload_config;
/** Config for TLS server authorization check. It is used for
* experimental purpose for now and subject to change. */
typedef struct grpc_tls_server_authorization_check_config
grpc_tls_server_authorization_check_config;
/** TLS credentials options. It is used for
* experimental purpose for now and subject to change. */
/**
* A struct that can be specified by callers to configure underlying TLS
* behaviors. It is used for experimental purpose for now and subject to change.
*/
typedef struct grpc_tls_credentials_options grpc_tls_credentials_options;
/** Create an empty TLS credentials options. It is used for
* experimental purpose for now and subject to change. */
/**
* A struct provides ways to gain credential data that will be used in the TLS
* handshake. It is used for experimental purpose for now and subject to change.
*/
typedef struct grpc_tls_certificate_provider grpc_tls_certificate_provider;
/**
* A struct that stores the credential data presented to the peer in handshake
* to show local identity. It is used for experimental purpose for now and
* subject to change.
*/
typedef struct grpc_tls_identity_pairs grpc_tls_identity_pairs;
/**
* Creates a grpc_tls_identity_pairs that stores a list of identity credential
* data, including identity private key and identity certificate chain. It is
* used for experimental purpose for now and subject to change.
*/
GRPCAPI grpc_tls_identity_pairs* grpc_tls_identity_pairs_create();
/**
* Adds a identity private key and a identity certificate chain to
* grpc_tls_identity_pairs. This function will make an internal copy of
* |private_key| and |cert_chain|. It is used for experimental purpose for now
* and subject to change.
*/
GRPCAPI void grpc_tls_identity_pairs_add_pair(grpc_tls_identity_pairs* pairs,
const char* private_key,
const char* cert_chain);
/**
* Destroys a grpc_tls_identity_pairs object. If this object is passed to a
* provider initiation function, the ownership is transferred so this function
* doesn't need to be called. Otherwise the creator of the
* grpc_tls_identity_pairs object is responsible for its destruction. It is
* used for experimental purpose for now and subject to change.
*/
GRPCAPI void grpc_tls_identity_pairs_destroy(grpc_tls_identity_pairs* pairs);
/**
* Creates a grpc_tls_certificate_provider that will load credential data from
* static string during initialization. This provider will always return the
* same cert data for all cert names.
* root_certificate and pem_key_cert_pairs can be nullptr, indicating the
* corresponding credential data is not needed.
* This function will make a copy of |root_certificate|.
* The ownership of |pem_key_cert_pairs| is transferred.
* It is used for experimental purpose for now and subject to change.
*/
GRPCAPI grpc_tls_certificate_provider*
grpc_tls_certificate_provider_static_data_create(
const char* root_certificate, grpc_tls_identity_pairs* pem_key_cert_pairs);
/**
* Releases a grpc_tls_certificate_provider object. The creator of the
* grpc_tls_certificate_provider object is responsible for its release. It is
* used for experimental purpose for now and subject to change.
*/
GRPCAPI void grpc_tls_certificate_provider_release(
grpc_tls_certificate_provider* provider);
/**
* Creates an grpc_tls_credentials_options.
* It is used for experimental purpose for now and subject to change.
*/
GRPCAPI grpc_tls_credentials_options* grpc_tls_credentials_options_create(void);
/** Set grpc_ssl_client_certificate_request_type field in credentials options
with the provided type. options should not be NULL.
It returns 1 on success and 0 on failure. It is used for
experimental purpose for now and subject to change. */
GRPCAPI int grpc_tls_credentials_options_set_cert_request_type(
/**
* Sets the options of whether to request and verify client certs. This should
* be called only on the server side. It returns 1 on success and 0 on failure.
* It is used for experimental purpose for now and subject to change.
*/
GRPCAPI void grpc_tls_credentials_options_set_cert_request_type(
grpc_tls_credentials_options* options,
grpc_ssl_client_certificate_request_type type);
/** Set grpc_tls_server_verification_option field in credentials options
with the provided server_verification_option. options should not be NULL.
This should be called only on the client side.
If grpc_tls_server_verification_option is not
GRPC_TLS_SERVER_VERIFICATION, use of a customer server
authorization check (grpc_tls_server_authorization_check_config)
will be mandatory.
It returns 1 on success and 0 on failure. It is used for
experimental purpose for now and subject to change. */
GRPCAPI int grpc_tls_credentials_options_set_server_verification_option(
/**
* Sets the options of whether to choose certain checks, e.g. certificate check,
* hostname check, etc. This should be called only on the client side. If
* |server_verification_option| is not GRPC_TLS_SERVER_VERIFICATION, use of a
* custom authorization check (grpc_tls_server_authorization_check_config) is
* mandatory. It returns 1 on success and 0 on failure. It is used for
* experimental purpose for now and subject to change.
*/
GRPCAPI void grpc_tls_credentials_options_set_server_verification_option(
grpc_tls_credentials_options* options,
grpc_tls_server_verification_option server_verification_option);
/** Set grpc_tls_key_materials_config field in credentials options
with the provided config struct whose ownership is transferred.
Both parameters should not be NULL.
It returns 1 on success and 0 on failure. It is used for
experimental purpose for now and subject to change. */
GRPCAPI int grpc_tls_credentials_options_set_key_materials_config(
grpc_tls_credentials_options* options,
grpc_tls_key_materials_config* config);
/** Set grpc_tls_credential_reload_config field in credentials options
with the provided config struct whose ownership is transferred.
Both parameters should not be NULL.
It returns 1 on success and 0 on failure. It is used for
experimental purpose for now and subject to change. */
GRPCAPI int grpc_tls_credentials_options_set_credential_reload_config(
grpc_tls_credentials_options* options,
grpc_tls_credential_reload_config* config);
/** Set grpc_tls_server_authorization_check_config field in credentials options
with the provided config struct whose ownership is transferred.
Both parameters should not be NULL.
It returns 1 on success and 0 on failure. It is used for
experimental purpose for now and subject to change. */
GRPCAPI int grpc_tls_credentials_options_set_server_authorization_check_config(
/**
* Sets the credential provider in the options.
* The |options| will implicitly take a new ref to the |provider|.
* It returns 1 on success and 0 on failure.
* It is used for experimental purpose for now and subject to change.
*/
GRPCAPI void grpc_tls_credentials_options_set_certificate_provider(
grpc_tls_credentials_options* options,
grpc_tls_server_authorization_check_config* config);
grpc_tls_certificate_provider* provider);
/** --- TLS key materials config. ---
It is used for experimental purpose for now and subject to change. */
/**
* If set, gRPC stack will keep watching the root certificates with
* name |root_cert_name|. It returns 1 on success and 0 on failure. It is used
* for experimental purpose for now and subject to change.
*/
GRPCAPI void grpc_tls_credentials_options_watch_root_certs(
grpc_tls_credentials_options* options);
/** Create an empty grpc_tls_key_materials_config instance.
* It is used for experimental purpose for now and subject to change. */
GRPCAPI grpc_tls_key_materials_config* grpc_tls_key_materials_config_create(
void);
/** Set grpc_tls_key_materials_config instance with provided a TLS certificate.
It's valid for the caller to provide nullptr pem_root_certs, in which case
the gRPC-provided root cert will be used. pem_key_cert_pairs should not be
NULL.
The ownerships of |pem_root_certs| and |pem_key_cert_pairs| remain with the
caller.
It returns 1 on success and 0 on failure. It is used for experimental
purpose for now and subject to change.
/**
* Sets the name of the root certificates being watched.
* If not set, We will use a default empty string as the root certificate name.
* It is used for experimental purpose for now and subject to change.
*/
GRPCAPI int grpc_tls_key_materials_config_set_key_materials(
grpc_tls_key_materials_config* config, const char* pem_root_certs,
const grpc_ssl_pem_key_cert_pair** pem_key_cert_pairs,
size_t num_key_cert_pairs);
GRPCAPI void grpc_tls_credentials_options_set_root_cert_name(
grpc_tls_credentials_options* options, const char* root_cert_name);
/** Set grpc_tls_key_materials_config instance with a provided version number,
which is used to keep track of the version of key materials.
It returns 1 on success and 0 on failure. It is used for
experimental purpose for now and subject to change.
/**
* If set, gRPC stack will keep watching the identity key-cert pairs
* with name |identity_cert_name|. It returns 1 on success and 0 on failure. It
* is used for experimental purpose for now and subject to change.
*/
GRPCAPI int grpc_tls_key_materials_config_set_version(
grpc_tls_key_materials_config* config, int version);
GRPCAPI void grpc_tls_credentials_options_watch_identity_key_cert_pairs(
grpc_tls_credentials_options* options);
/** Get the version number of a grpc_tls_key_materials_config instance.
It returns the version number on success and -1 on failure.
It is used for experimental purpose for now and subject to change.
/**
* Sets the name of the identity certificates being watched.
* If not set, We will use a default empty string as the identity certificate
* name. It is used for experimental purpose for now and subject to change.
*/
GRPCAPI int grpc_tls_key_materials_config_get_version(
grpc_tls_key_materials_config* config);
/** --- TLS credential reload config. ---
It is used for experimental purpose for now and subject to change.*/
typedef struct grpc_tls_credential_reload_arg grpc_tls_credential_reload_arg;
/** A callback function provided by gRPC to handle the result of credential
reload. It is used when schedule API is implemented asynchronously and
serves to bring the control back to grpc C core. It is used for
experimental purpose for now and subject to change. */
typedef void (*grpc_tls_on_credential_reload_done_cb)(
grpc_tls_credential_reload_arg* arg);
/** A struct containing all information necessary to schedule/cancel a
credential reload request.
- cb and cb_user_data represent a gRPC-provided
callback and an argument passed to it.
- key_materials_config is an in/output parameter containing currently
used/newly reloaded credentials. If credential reload does not result in
a new credential, key_materials_config should not be modified. The same
key_materials_config object can be updated if new key materials is
available.
- status and error_details are used to hold information about
errors occurred when a credential reload request is scheduled/cancelled.
- config is a pointer to the unique grpc_tls_credential_reload_config
instance that this argument corresponds to.
- context is a pointer to a wrapped language implementation of this
grpc_tls_credential_reload_arg instance.
- destroy_context is a pointer to a caller-provided method that cleans
up any data associated with the context pointer.
It is used for experimental purposes for now and subject to change.
*/
struct grpc_tls_credential_reload_arg {
grpc_tls_on_credential_reload_done_cb cb;
void* cb_user_data;
grpc_tls_key_materials_config* key_materials_config;
grpc_ssl_certificate_config_reload_status status;
grpc_tls_error_details* error_details;
grpc_tls_credential_reload_config* config;
void* context;
void (*destroy_context)(void* ctx);
};
GRPCAPI void grpc_tls_credentials_options_set_identity_cert_name(
grpc_tls_credentials_options* options, const char* identity_cert_name);
/** Create a grpc_tls_credential_reload_config instance.
- config_user_data is config-specific, read-only user data
that works for all channels created with a credential using the config.
- schedule is a pointer to an application-provided callback used to invoke
credential reload API. The implementation of this method has to be
non-blocking, but can be performed synchronously or asynchronously.
1) If processing occurs synchronously, it populates
arg->key_materials_config, arg->status, and arg->error_details
and returns zero.
2) If processing occurs asynchronously, it returns a non-zero value.
The application then invokes arg->cb when processing is completed. Note
that arg->cb cannot be invoked before schedule API returns.
- cancel is a pointer to an application-provided callback used to cancel
a credential reload request scheduled via an asynchronous schedule API.
arg is used to pinpoint an exact reloading request to be cancelled.
The operation may not have any effect if the request has already been
processed.
- destruct is a pointer to an application-provided callback used to clean up
any data associated with the config.
It is used for experimental purpose for now and subject to change.
*/
GRPCAPI grpc_tls_credential_reload_config*
grpc_tls_credential_reload_config_create(
const void* config_user_data,
int (*schedule)(void* config_user_data,
grpc_tls_credential_reload_arg* arg),
void (*cancel)(void* config_user_data, grpc_tls_credential_reload_arg* arg),
void (*destruct)(void* config_user_data));
/**
* Sets the configuration for a custom authorization check performed at the end
* of the handshake. The |options| will implicitly take a new ref to the
* |config|. It returns 1 on success and 0 on failure. It is used for
* experimental purpose for now and subject to change.
*/
GRPCAPI void grpc_tls_credentials_options_set_server_authorization_check_config(
grpc_tls_credentials_options* options,
grpc_tls_server_authorization_check_config* config);
/** --- TLS server authorization check config. ---
* It is used for experimental purpose for now and subject to change. */
@ -1000,31 +973,28 @@ grpc_tls_server_authorization_check_config_create(
void (*destruct)(void* config_user_data));
/**
* This method creates a TLS channel credential object.
* It takes ownership of the options parameter. The security level
* of the resulting connection is GRPC_PRIVACY_AND_INTEGRITY.
*
* - options: grpc TLS credentials options instance.
*
* It returns the created credential object.
*
* It is used for experimental purpose for now and subject
* to change.
* Releases a grpc_tls_server_authorization_check_config object. The creator of
* the grpc_tls_server_authorization_check_config object is responsible for its
* release. It is used for experimental purpose for now and subject to change.
*/
GRPCAPI void grpc_tls_server_authorization_check_config_release(
grpc_tls_server_authorization_check_config* config);
/**
* Creates a TLS channel credential object based on the
* grpc_tls_credentials_options specified by callers. The
* grpc_channel_credentials will take the ownership of the |options|. The
* security level of the resulting connection is GRPC_PRIVACY_AND_INTEGRITY. It
* is used for experimental purpose for now and subject to change.
*/
grpc_channel_credentials* grpc_tls_credentials_create(
grpc_tls_credentials_options* options);
/**
* This method creates a TLS server credential object.
* It takes ownership of the options parameter.
*
* - options: grpc TLS credentials options instance.
*
* It returns the created credential object.
*
* It is used for experimental purpose for now and subject
* to change.
* Creates a TLS server credential object based on the
* grpc_tls_credentials_options specified by callers. The
* grpc_server_credentials will take the ownership of the |options|. It
* is used for experimental purpose for now and subject to change.
*/
grpc_server_credentials* grpc_tls_server_credentials_create(
grpc_tls_credentials_options* options);

@ -329,7 +329,7 @@ std::shared_ptr<ChannelCredentials> LocalCredentials(
/// Builds TLS Credentials given TLS options.
std::shared_ptr<ChannelCredentials> TlsCredentials(
const TlsCredentialsOptions& options);
const TlsChannelCredentialsOptions& options);
} // namespace experimental
} // namespace grpc

@ -105,7 +105,7 @@ std::shared_ptr<ServerCredentials> LocalServerCredentials(
/// Builds TLS ServerCredentials given TLS options.
std::shared_ptr<ServerCredentials> TlsServerCredentials(
const experimental::TlsCredentialsOptions& options);
const experimental::TlsServerCredentialsOptions& options);
} // namespace experimental
} // namespace grpc

@ -0,0 +1,80 @@
//
// 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 GRPCPP_SECURITY_TLS_CERTIFICATE_PROVIDER_H
#define GRPCPP_SECURITY_TLS_CERTIFICATE_PROVIDER_H
#include <grpc/grpc_security_constants.h>
#include <grpc/status.h>
#include <grpc/support/log.h>
#include <grpcpp/impl/codegen/grpc_library.h>
#include <grpcpp/support/config.h>
#include <memory>
#include <vector>
// TODO(yihuazhang): remove the forward declaration here and include
// <grpc/grpc_security.h> directly once the insecure builds are cleaned up.
typedef struct grpc_tls_certificate_provider grpc_tls_certificate_provider;
namespace grpc {
namespace experimental {
// Interface for a class that handles the process to fetch credential data.
// Implementations should be a wrapper class of an internal provider
// implementation.
class CertificateProviderInterface {
public:
virtual ~CertificateProviderInterface() = default;
virtual grpc_tls_certificate_provider* c_provider() = 0;
};
// A struct that stores the credential data presented to the peer in handshake
// to show local identity. The private_key and certificate_chain should always
// match.
struct IdentityKeyCertPair {
std::string private_key;
std::string certificate_chain;
};
// A basic CertificateProviderInterface implementation that will load credential
// data from static string during initialization. This provider will always
// return the same cert data for all cert names, and reloading is not supported.
class StaticDataCertificateProvider : public CertificateProviderInterface {
public:
StaticDataCertificateProvider(
const std::string& root_certificate,
const std::vector<IdentityKeyCertPair>& identity_key_cert_pairs);
StaticDataCertificateProvider(const std::string& root_certificate)
: StaticDataCertificateProvider(root_certificate, {}) {}
StaticDataCertificateProvider(
const std::vector<IdentityKeyCertPair>& identity_key_cert_pairs)
: StaticDataCertificateProvider("", identity_key_cert_pairs) {}
~StaticDataCertificateProvider();
grpc_tls_certificate_provider* c_provider() override { return c_provider_; }
private:
grpc_tls_certificate_provider* c_provider_ = nullptr;
};
} // namespace experimental
} // namespace grpc
#endif // GRPCPP_SECURITY_TLS_CERTIFICATE_PROVIDER_H

@ -22,151 +22,24 @@
#include <grpc/grpc_security_constants.h>
#include <grpc/status.h>
#include <grpc/support/log.h>
#include <grpcpp/security/tls_certificate_provider.h>
#include <grpcpp/support/config.h>
#include <memory>
#include <vector>
typedef struct grpc_tls_credential_reload_arg grpc_tls_credential_reload_arg;
typedef struct grpc_tls_credential_reload_config
grpc_tls_credential_reload_config;
// TODO(yihuazhang): remove the forward declaration here and include
// <grpc/grpc_security.h> directly once the insecure builds are cleaned up.
typedef struct grpc_tls_server_authorization_check_arg
grpc_tls_server_authorization_check_arg;
typedef struct grpc_tls_server_authorization_check_config
grpc_tls_server_authorization_check_config;
typedef struct grpc_tls_credentials_options grpc_tls_credentials_options;
typedef struct grpc_tls_certificate_provider grpc_tls_certificate_provider;
namespace grpc {
namespace experimental {
/** TLS key materials config, wrapper for grpc_tls_key_materials_config. It is
* used for experimental purposes for now and subject to change. **/
class TlsKeyMaterialsConfig {
public:
struct PemKeyCertPair {
std::string private_key;
std::string cert_chain;
};
/** Getters for member fields. **/
const std::string pem_root_certs() const { return pem_root_certs_; }
const std::vector<PemKeyCertPair>& pem_key_cert_pair_list() const {
return pem_key_cert_pair_list_;
}
int version() const { return version_; }
/** Setter for key materials that will be called by the user. Ownership of the
* arguments will not be transferred. **/
void set_pem_root_certs(const std::string& pem_root_certs);
void add_pem_key_cert_pair(const PemKeyCertPair& pem_key_cert_pair);
void set_key_materials(
const std::string& pem_root_certs,
const std::vector<PemKeyCertPair>& pem_key_cert_pair_list);
void set_version(int version) { version_ = version; };
private:
int version_ = 0;
std::vector<PemKeyCertPair> pem_key_cert_pair_list_;
std::string pem_root_certs_;
};
/** TLS credential reload arguments, wraps grpc_tls_credential_reload_arg. It is
* used for experimental purposes for now and it is subject to change.
*
* The credential reload arg contains all the info necessary to schedule/cancel
* a credential reload request. The callback function must be called after
* finishing the schedule operation. See the description of the
* grpc_tls_credential_reload_arg struct in grpc_security.h for more details.
* **/
class TlsCredentialReloadArg {
public:
/** TlsCredentialReloadArg does not take ownership of the C arg that is passed
* to the constructor. One must remember to free any memory allocated to the
* C arg after using the setter functions below. **/
TlsCredentialReloadArg(grpc_tls_credential_reload_arg* arg);
~TlsCredentialReloadArg();
/** Getters for member fields. **/
void* cb_user_data() const;
bool is_pem_key_cert_pair_list_empty() const;
grpc_ssl_certificate_config_reload_status status() const;
std::string error_details() const;
/** Setters for member fields. Ownership of the arguments will not be
* transferred. **/
void set_cb_user_data(void* cb_user_data);
void set_pem_root_certs(const std::string& pem_root_certs);
void add_pem_key_cert_pair(
const TlsKeyMaterialsConfig::PemKeyCertPair& pem_key_cert_pair);
void set_key_materials(const std::string& pem_root_certs,
std::vector<TlsKeyMaterialsConfig::PemKeyCertPair>
pem_key_cert_pair_list);
void set_key_materials_config(
const std::shared_ptr<TlsKeyMaterialsConfig>& key_materials_config);
void set_status(grpc_ssl_certificate_config_reload_status status);
void set_error_details(const std::string& error_details);
/** Calls the C arg's callback function. **/
void OnCredentialReloadDoneCallback();
private:
grpc_tls_credential_reload_arg* c_arg_;
};
/** An interface that the application derives and uses to instantiate a
* TlsCredentialReloadConfig instance. Refer to the definition of the
* grpc_tls_credential_reload_config in grpc_tls_credentials_options.h for more
* details on the expectations of the member functions of the interface. **/
struct TlsCredentialReloadInterface {
virtual ~TlsCredentialReloadInterface() = default;
/** A callback that invokes the credential reload. **/
virtual int Schedule(TlsCredentialReloadArg* arg) = 0;
/** A callback that cancels a credential reload request. **/
virtual void Cancel(TlsCredentialReloadArg* /* arg */) {}
};
/** TLS credential reloag config, wraps grpc_tls_credential_reload_config. It is
* used for experimental purposes for now and it is subject to change. **/
class TlsCredentialReloadConfig {
public:
TlsCredentialReloadConfig(std::shared_ptr<TlsCredentialReloadInterface>
credential_reload_interface);
~TlsCredentialReloadConfig();
int Schedule(TlsCredentialReloadArg* arg) const {
if (credential_reload_interface_ == nullptr) {
gpr_log(GPR_ERROR, "credential reload interface is nullptr");
if (arg != nullptr) {
arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL);
arg->set_error_details(
"the interface of the credential reload config is nullptr");
}
return 1;
}
return credential_reload_interface_->Schedule(arg);
}
void Cancel(TlsCredentialReloadArg* arg) const {
if (credential_reload_interface_ == nullptr) {
gpr_log(GPR_ERROR, "credential reload interface is nullptr");
if (arg != nullptr) {
arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL);
arg->set_error_details(
"the interface of the credential reload config is nullptr");
}
return;
}
credential_reload_interface_->Cancel(arg);
}
/** Returns a C struct for the credential reload config. **/
grpc_tls_credential_reload_config* c_config() const { return c_config_; }
private:
grpc_tls_credential_reload_config* c_config_;
std::shared_ptr<TlsCredentialReloadInterface> credential_reload_interface_;
};
/** TLS server authorization check arguments, wraps
* grpc_tls_server_authorization_check_arg. It is used for experimental
* purposes for now and it is subject to change.
@ -272,71 +145,85 @@ class TlsServerAuthorizationCheckConfig {
server_authorization_check_interface_;
};
/** TLS credentials options, wrapper for grpc_tls_credentials_options. It is
* used for experimental purposes for now and it is subject to change. See the
* description of the grpc_tls_credentials_options struct in grpc_security.h for
* more details. **/
// Base class of configurable options specified by users to configure their
// certain security features supported in TLS. It is used for experimental
// purposes for now and it is subject to change.
class TlsCredentialsOptions {
public:
// Constructor for client.
// Constructor for base class TlsCredentialsOptions.
//
// @param certificate_provider the provider which fetches TLS credentials that
// will be used in the TLS handshake
explicit TlsCredentialsOptions(
grpc_tls_server_verification_option server_verification_option,
std::shared_ptr<TlsKeyMaterialsConfig> key_materials_config,
std::shared_ptr<TlsCredentialReloadConfig> credential_reload_config,
std::shared_ptr<TlsServerAuthorizationCheckConfig>
server_authorization_check_config);
std::shared_ptr<CertificateProviderInterface> certificate_provider);
// ---- Setters for member fields ----
// Watches the updates of root certificates with name |root_cert_name|.
// If used in TLS credentials, it should always be set unless the root
// certificates are not needed(e.g. in the one-side TLS scenario, the server
// is not required to verify the client).
void watch_root_certs();
// Sets the name of root certificates being watched, if |watch_root_certs| is
// called. If not set, an empty string will be used as the name.
//
// @param root_cert_name the name of root certs being set.
void set_root_cert_name(const std::string& root_cert_name);
// Watches the updates of identity key-cert pairs with name
// |identity_cert_name|. If used in TLS credentials, it should always be set
// unless the identity certificates are not needed(e.g. in the one-side TLS
// scenario, the client is not required to provide certs).
void watch_identity_key_cert_pairs();
// Sets the name of identity key-cert pairs being watched, if
// |watch_identity_key_cert_pairs| is called. If not set, an empty string will
// be used as the name.
//
// @param identity_cert_name the name of identity key-cert pairs being set.
void set_identity_cert_name(const std::string& identity_cert_name);
// ----- Getters for member fields ----
// Get the internal c options. This function shall be used only internally.
grpc_tls_credentials_options* c_credentials_options() const {
return c_credentials_options_;
}
// Constructor for server.
explicit TlsCredentialsOptions(
grpc_ssl_client_certificate_request_type cert_request_type,
std::shared_ptr<TlsKeyMaterialsConfig> key_materials_config,
std::shared_ptr<TlsCredentialReloadConfig> credential_reload_config);
private:
std::shared_ptr<CertificateProviderInterface> certificate_provider_;
grpc_tls_credentials_options* c_credentials_options_ = nullptr;
};
// This constructor will be deprecated.
TlsCredentialsOptions(
grpc_ssl_client_certificate_request_type cert_request_type,
grpc_tls_server_verification_option server_verification_option,
std::shared_ptr<TlsKeyMaterialsConfig> key_materials_config,
std::shared_ptr<TlsCredentialReloadConfig> credential_reload_config,
// Contains configurable options on the client side.
// It is used for experimental purposes for now and it is subject to change.
class TlsChannelCredentialsOptions final : public TlsCredentialsOptions {
public:
explicit TlsChannelCredentialsOptions(
std::shared_ptr<CertificateProviderInterface> certificate_provider)
: TlsCredentialsOptions(std::move(certificate_provider)) {}
// Sets the option to verify the server.
// The default is GRPC_TLS_SERVER_VERIFICATION.
void set_server_verification_option(
grpc_tls_server_verification_option server_verification_option);
// Sets the custom authorization config.
void set_server_authorization_check_config(
std::shared_ptr<TlsServerAuthorizationCheckConfig>
server_authorization_check_config);
~TlsCredentialsOptions();
authorization_check_config);
/** Getters for member fields. **/
grpc_ssl_client_certificate_request_type cert_request_type() const {
return cert_request_type_;
}
grpc_tls_server_verification_option server_verification_option() const {
return server_verification_option_;
}
std::shared_ptr<TlsKeyMaterialsConfig> key_materials_config() const {
return key_materials_config_;
}
std::shared_ptr<TlsCredentialReloadConfig> credential_reload_config() const {
return credential_reload_config_;
}
std::shared_ptr<TlsServerAuthorizationCheckConfig>
server_authorization_check_config() const {
return server_authorization_check_config_;
}
grpc_tls_credentials_options* c_credentials_options() const {
return c_credentials_options_;
}
private:
};
// Contains configurable options on the server side.
// It is used for experimental purposes for now and it is subject to change.
class TlsServerCredentialsOptions final : public TlsCredentialsOptions {
public:
explicit TlsServerCredentialsOptions(
std::shared_ptr<CertificateProviderInterface> certificate_provider)
: TlsCredentialsOptions(std::move(certificate_provider)) {}
// Sets option to request the certificates from the client.
// The default is GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE.
void set_cert_request_type(
grpc_ssl_client_certificate_request_type cert_request_type);
private:
/** The cert_request_type_ flag is only relevant when the
* TlsCredentialsOptions are used to instantiate server credentials; the flag
* goes unused when creating channel credentials, and the user can set it to
* GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE. **/
grpc_ssl_client_certificate_request_type cert_request_type_;
/** The server_verification_option_ flag is only relevant when the
* TlsCredentialsOptions are used to instantiate client credentials; **/
grpc_tls_server_verification_option server_verification_option_;
std::shared_ptr<TlsKeyMaterialsConfig> key_materials_config_;
std::shared_ptr<TlsCredentialReloadConfig> credential_reload_config_;
std::shared_ptr<TlsServerAuthorizationCheckConfig>
server_authorization_check_config_;
grpc_tls_credentials_options* c_credentials_options_;
};
} // namespace experimental

@ -931,7 +931,6 @@
<file baseinstalldir="/" name="src/core/lib/security/authorization/evaluate_args.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/authorization/mock_cel/activation.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/authorization/mock_cel/cel_value.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/certificate_provider.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/context/security_context.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/context/security_context.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/alts/alts_credentials.cc" role="src" />
@ -978,6 +977,8 @@
<file baseinstalldir="/" name="src/core/lib/security/credentials/ssl/ssl_credentials.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc" role="src" />
<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" />

@ -23,7 +23,7 @@
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/json/json.h"
#include "src/core/lib/security/certificate_provider.h"
#include "src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h"
namespace grpc_core {

@ -28,7 +28,7 @@
#include "src/core/ext/xds/certificate_provider_factory.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/gprpp/sync.h"
#include "src/core/lib/security/certificate_provider.h"
#include "src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h"
namespace grpc_core {

@ -26,7 +26,7 @@
void grpc_tls_certificate_distributor::SetKeyMaterials(
const std::string& cert_name, absl::optional<std::string> pem_root_certs,
absl::optional<PemKeyCertPairList> pem_key_cert_pairs) {
absl::optional<grpc_core::PemKeyCertPairList> pem_key_cert_pairs) {
GPR_ASSERT(pem_root_certs.has_value() || pem_key_cert_pairs.has_value());
grpc_core::MutexLock lock(&mu_);
auto& cert_info = certificate_info_map_[cert_name];
@ -38,7 +38,8 @@ void grpc_tls_certificate_distributor::SetKeyMaterials(
const auto watcher_it = watchers_.find(watcher_ptr);
GPR_ASSERT(watcher_it != watchers_.end());
GPR_ASSERT(watcher_it->second.root_cert_name.has_value());
absl::optional<PemKeyCertPairList> pem_key_cert_pairs_to_report;
absl::optional<grpc_core::PemKeyCertPairList>
pem_key_cert_pairs_to_report;
if (pem_key_cert_pairs.has_value() &&
watcher_it->second.identity_cert_name == cert_name) {
pem_key_cert_pairs_to_report = pem_key_cert_pairs;
@ -188,7 +189,7 @@ void grpc_tls_certificate_distributor::WatchTlsCertificates(
watchers_[watcher_ptr] = {std::move(watcher), root_cert_name,
identity_cert_name};
absl::optional<absl::string_view> updated_root_certs;
absl::optional<PemKeyCertPairList> updated_identity_pairs;
absl::optional<grpc_core::PemKeyCertPairList> updated_identity_pairs;
grpc_error* root_error = GRPC_ERROR_NONE;
grpc_error* identity_error = GRPC_ERROR_NONE;
if (root_cert_name.has_value()) {
@ -319,3 +320,28 @@ void grpc_tls_certificate_distributor::CancelTlsCertificatesWatch(
}
}
};
/** -- Wrapper APIs declared in grpc_security.h -- **/
grpc_tls_identity_pairs* grpc_tls_identity_pairs_create() {
return new grpc_tls_identity_pairs();
}
void grpc_tls_identity_pairs_add_pair(grpc_tls_identity_pairs* pairs,
const char* private_key,
const char* cert_chain) {
GPR_ASSERT(pairs != nullptr);
GPR_ASSERT(private_key != nullptr);
GPR_ASSERT(cert_chain != nullptr);
grpc_ssl_pem_key_cert_pair* ssl_pair =
static_cast<grpc_ssl_pem_key_cert_pair*>(
gpr_malloc(sizeof(grpc_ssl_pem_key_cert_pair)));
ssl_pair->private_key = gpr_strdup(private_key);
ssl_pair->cert_chain = gpr_strdup(cert_chain);
pairs->pem_key_cert_pairs.emplace_back(ssl_pair);
}
void grpc_tls_identity_pairs_destroy(grpc_tls_identity_pairs* pairs) {
GPR_ASSERT(pairs != nullptr);
delete pairs;
}

@ -28,12 +28,14 @@
#include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/security/security_connector/ssl_utils.h"
struct grpc_tls_identity_pairs {
grpc_core::PemKeyCertPairList pem_key_cert_pairs;
};
// TLS certificate distributor.
struct grpc_tls_certificate_distributor
: public grpc_core::RefCounted<grpc_tls_certificate_distributor> {
public:
typedef absl::InlinedVector<grpc_core::PemKeyCertPair, 1> PemKeyCertPairList;
// Interface for watching TLS certificates update.
class TlsCertificatesWatcherInterface {
public:
@ -50,7 +52,7 @@ struct grpc_tls_certificate_distributor
// pairs.
virtual void OnCertificatesChanged(
absl::optional<absl::string_view> root_certs,
absl::optional<PemKeyCertPairList> key_cert_pairs) = 0;
absl::optional<grpc_core::PemKeyCertPairList> key_cert_pairs) = 0;
// Handles an error that occurs while attempting to fetch certificate data.
// Note that if a watcher sees an error, it simply means the Provider is
@ -80,9 +82,9 @@ struct grpc_tls_certificate_distributor
// @param cert_name The name of the certificates being updated.
// @param pem_root_certs The content of root certificates.
// @param pem_key_cert_pairs The content of identity key-cert pairs.
void SetKeyMaterials(const std::string& cert_name,
absl::optional<std::string> pem_root_certs,
absl::optional<PemKeyCertPairList> pem_key_cert_pairs);
void SetKeyMaterials(
const std::string& cert_name, absl::optional<std::string> pem_root_certs,
absl::optional<grpc_core::PemKeyCertPairList> pem_key_cert_pairs);
bool HasRootCerts(const std::string& root_cert_name);
@ -170,7 +172,7 @@ struct grpc_tls_certificate_distributor
// The contents of the root certificates.
std::string pem_root_certs;
// The contents of the identity key-certificate pairs.
PemKeyCertPairList pem_key_cert_pairs;
grpc_core::PemKeyCertPairList pem_key_cert_pairs;
// The root cert reloading error propagated by the caller.
grpc_error* root_cert_error = GRPC_ERROR_NONE;
// The identity cert reloading error propagated by the caller.

@ -0,0 +1,78 @@
//
// 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/grpc_tls_certificate_provider.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/surface/api_trace.h"
namespace grpc_core {
StaticDataCertificateProvider::StaticDataCertificateProvider(
std::string root_certificate,
grpc_core::PemKeyCertPairList pem_key_cert_pairs)
: distributor_(MakeRefCounted<grpc_tls_certificate_distributor>()),
root_certificate_(std::move(root_certificate)),
pem_key_cert_pairs_(std::move(pem_key_cert_pairs)) {
distributor_->SetWatchStatusCallback([this](std::string cert_name,
bool root_being_watched,
bool identity_being_watched) {
if (!root_being_watched && !identity_being_watched) return;
absl::optional<std::string> root_certificate;
absl::optional<grpc_core::PemKeyCertPairList> pem_key_cert_pairs;
if (root_being_watched) {
root_certificate = root_certificate_;
}
if (identity_being_watched) {
pem_key_cert_pairs = pem_key_cert_pairs_;
}
distributor_->SetKeyMaterials(cert_name, std::move(root_certificate),
std::move(pem_key_cert_pairs));
});
}
} // namespace grpc_core
/** -- Wrapper APIs declared in grpc_security.h -- **/
grpc_tls_certificate_provider* grpc_tls_certificate_provider_static_data_create(
const char* root_certificate, grpc_tls_identity_pairs* pem_key_cert_pairs) {
GPR_ASSERT(root_certificate != nullptr || pem_key_cert_pairs != nullptr);
grpc_core::PemKeyCertPairList identity_pairs_core;
if (pem_key_cert_pairs != nullptr) {
identity_pairs_core = std::move(pem_key_cert_pairs->pem_key_cert_pairs);
delete pem_key_cert_pairs;
}
std::string root_cert_core;
if (root_certificate != nullptr) {
root_cert_core = root_certificate;
}
return new grpc_core::StaticDataCertificateProvider(
std::move(root_cert_core), std::move(identity_pairs_core));
}
void grpc_tls_certificate_provider_release(
grpc_tls_certificate_provider* provider) {
GRPC_API_TRACE("grpc_tls_certificate_provider_release(provider=%p)", 1,
(provider));
grpc_core::ExecCtx exec_ctx;
if (provider != nullptr) provider->Unref();
}

@ -1,5 +1,4 @@
//
//
// Copyright 2020 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
@ -14,17 +13,22 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
//
#ifndef GRPC_CORE_LIB_SECURITY_CERTIFICATE_PROVIDER_H
#define GRPC_CORE_LIB_SECURITY_CERTIFICATE_PROVIDER_H
#ifndef GRPC_CORE_LIB_SECURITY_CREDENTIALS_TLS_GRPC_TLS_CERTIFICATE_PROVIDER_H
#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_TLS_GRPC_TLS_CERTIFICATE_PROVIDER_H
#include <grpc/support/port_platform.h>
#include <grpc/grpc_security.h>
#include <string.h>
#include "absl/container/inlined_vector.h"
#include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/pollset_set.h"
#include "src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.h"
#include "src/core/lib/security/security_connector/ssl_utils.h"
// Interface for a grpc_tls_certificate_provider that handles the process to
// fetch credentials and validation contexts. Implementations are free to rely
@ -44,4 +48,27 @@ struct grpc_tls_certificate_provider
distributor() const = 0;
};
#endif // GRPC_CORE_LIB_SECURITY_CERTIFICATE_PROVIDER_H
namespace grpc_core {
// A basic provider class that will get credentials from string during
// initialization.
class StaticDataCertificateProvider final
: public grpc_tls_certificate_provider {
public:
StaticDataCertificateProvider(
std::string root_certificate,
grpc_core::PemKeyCertPairList pem_key_cert_pairs);
RefCountedPtr<grpc_tls_certificate_distributor> distributor() const override {
return distributor_;
}
private:
RefCountedPtr<grpc_tls_certificate_distributor> distributor_;
std::string root_certificate_;
grpc_core::PemKeyCertPairList pem_key_cert_pairs_;
};
} // namespace grpc_core
#endif // GRPC_CORE_LIB_SECURITY_CREDENTIALS_TLS_GRPC_TLS_CERTIFICATE_PROVIDER_H

@ -27,49 +27,7 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
/** -- gRPC TLS key materials config API implementation. -- **/
void grpc_tls_key_materials_config::set_key_materials(
const char* pem_root_certs,
const grpc_ssl_pem_key_cert_pair** pem_key_cert_pairs,
size_t num_key_cert_pairs) {
this->set_pem_root_certs(pem_root_certs);
grpc_tls_key_materials_config::PemKeyCertPairList cert_pair_list;
for (size_t i = 0; i < num_key_cert_pairs; i++) {
auto current_pair = static_cast<grpc_ssl_pem_key_cert_pair*>(
gpr_zalloc(sizeof(grpc_ssl_pem_key_cert_pair)));
current_pair->cert_chain = gpr_strdup(pem_key_cert_pairs[i]->cert_chain);
current_pair->private_key = gpr_strdup(pem_key_cert_pairs[i]->private_key);
cert_pair_list.emplace_back(grpc_core::PemKeyCertPair(current_pair));
}
pem_key_cert_pair_list_ = std::move(cert_pair_list);
}
void grpc_tls_key_materials_config::set_key_materials(
const char* pem_root_certs,
const PemKeyCertPairList& pem_key_cert_pair_list) {
this->set_pem_root_certs(pem_root_certs);
grpc_tls_key_materials_config::PemKeyCertPairList dup_list(
pem_key_cert_pair_list);
pem_key_cert_pair_list_ = std::move(dup_list);
}
/** -- gRPC TLS credential reload config API implementation. -- **/
grpc_tls_credential_reload_config::grpc_tls_credential_reload_config(
const void* config_user_data,
int (*schedule)(void* config_user_data,
grpc_tls_credential_reload_arg* arg),
void (*cancel)(void* config_user_data, grpc_tls_credential_reload_arg* arg),
void (*destruct)(void* config_user_data))
: config_user_data_(const_cast<void*>(config_user_data)),
schedule_(schedule),
cancel_(cancel),
destruct_(destruct) {}
grpc_tls_credential_reload_config::~grpc_tls_credential_reload_config() {
if (destruct_ != nullptr) {
destruct_((void*)config_user_data_);
}
}
#include "src/core/lib/surface/api_trace.h"
/** -- gRPC TLS server authorization check API implementation. -- **/
grpc_tls_server_authorization_check_config::
@ -92,138 +50,99 @@ grpc_tls_server_authorization_check_config::
}
}
int grpc_tls_server_authorization_check_config::Schedule(
grpc_tls_server_authorization_check_arg* arg) const {
if (schedule_ == nullptr) {
gpr_log(GPR_ERROR, "schedule API is nullptr");
if (arg != nullptr) {
arg->status = GRPC_STATUS_NOT_FOUND;
arg->error_details->set_error_details(
"schedule API in server authorization check config is nullptr");
}
return 1;
}
if (arg != nullptr && context_ != nullptr) {
arg->config = const_cast<grpc_tls_server_authorization_check_config*>(this);
}
return schedule_(config_user_data_, arg);
}
void grpc_tls_server_authorization_check_config::Cancel(
grpc_tls_server_authorization_check_arg* arg) const {
if (cancel_ == nullptr) {
gpr_log(GPR_ERROR, "cancel API is nullptr.");
if (arg != nullptr) {
arg->status = GRPC_STATUS_NOT_FOUND;
arg->error_details->set_error_details(
"schedule API in server authorization check config is nullptr");
}
return;
}
if (arg != nullptr) {
arg->config = const_cast<grpc_tls_server_authorization_check_config*>(this);
}
cancel_(config_user_data_, arg);
}
/** -- Wrapper APIs declared in grpc_security.h -- **/
grpc_tls_credentials_options* grpc_tls_credentials_options_create() {
return new grpc_tls_credentials_options();
}
int grpc_tls_credentials_options_set_cert_request_type(
void grpc_tls_credentials_options_set_cert_request_type(
grpc_tls_credentials_options* options,
grpc_ssl_client_certificate_request_type type) {
if (options == nullptr) {
gpr_log(GPR_ERROR,
"Invalid nullptr arguments to "
"grpc_tls_credentials_options_set_cert_request_type()");
return 0;
}
GPR_ASSERT(options != nullptr);
options->set_cert_request_type(type);
return 1;
}
int grpc_tls_credentials_options_set_server_verification_option(
void grpc_tls_credentials_options_set_server_verification_option(
grpc_tls_credentials_options* options,
grpc_tls_server_verification_option server_verification_option) {
if (options == nullptr) {
gpr_log(GPR_ERROR,
"Invalid nullptr arguments to "
"grpc_tls_credentials_options_set_server_verification_option()");
return 0;
}
if (server_verification_option != GRPC_TLS_SERVER_VERIFICATION &&
options->server_authorization_check_config() == nullptr) {
gpr_log(GPR_ERROR,
"server_authorization_check_config needs to be specified when"
"server_verification_option is not GRPC_TLS_SERVER_VERIFICATION");
return 0;
}
GPR_ASSERT(options != nullptr);
options->set_server_verification_option(server_verification_option);
return 1;
}
int grpc_tls_credentials_options_set_key_materials_config(
grpc_tls_credentials_options* options,
grpc_tls_key_materials_config* config) {
if (options == nullptr || config == nullptr) {
gpr_log(GPR_ERROR,
"Invalid nullptr arguments to "
"grpc_tls_credentials_options_set_key_materials_config()");
return 0;
}
options->set_key_materials_config(config->Ref());
return 1;
}
int grpc_tls_credentials_options_set_credential_reload_config(
void grpc_tls_credentials_options_set_certificate_provider(
grpc_tls_credentials_options* options,
grpc_tls_credential_reload_config* config) {
if (options == nullptr || config == nullptr) {
gpr_log(GPR_ERROR,
"Invalid nullptr arguments to "
"grpc_tls_credentials_options_set_credential_reload_config()");
return 0;
}
options->set_credential_reload_config(config->Ref());
return 1;
grpc_tls_certificate_provider* provider) {
GPR_ASSERT(options != nullptr);
GPR_ASSERT(provider != nullptr);
options->set_certificate_provider(
provider->Ref(DEBUG_LOCATION, "set_certificate_provider"));
}
int grpc_tls_credentials_options_set_server_authorization_check_config(
grpc_tls_credentials_options* options,
grpc_tls_server_authorization_check_config* config) {
if (options == nullptr || config == nullptr) {
gpr_log(
GPR_ERROR,
"Invalid nullptr arguments to "
"grpc_tls_credentials_options_set_server_authorization_check_config()");
return 0;
}
options->set_server_authorization_check_config(config->Ref());
return 1;
void grpc_tls_credentials_options_watch_root_certs(
grpc_tls_credentials_options* options) {
GPR_ASSERT(options != nullptr);
options->set_watch_root_cert(true);
}
grpc_tls_key_materials_config* grpc_tls_key_materials_config_create() {
return new grpc_tls_key_materials_config();
void grpc_tls_credentials_options_set_root_cert_name(
grpc_tls_credentials_options* options, const char* root_cert_name) {
GPR_ASSERT(options != nullptr);
options->set_root_cert_name(root_cert_name);
}
int grpc_tls_key_materials_config_set_key_materials(
grpc_tls_key_materials_config* config, const char* root_certs,
const grpc_ssl_pem_key_cert_pair** key_cert_pairs, size_t num) {
if (config == nullptr || key_cert_pairs == nullptr || num == 0) {
gpr_log(GPR_ERROR,
"Invalid arguments to "
"grpc_tls_key_materials_config_set_key_materials()");
return 0;
}
config->set_key_materials(root_certs, key_cert_pairs, num);
return 1;
}
int grpc_tls_key_materials_config_set_version(
grpc_tls_key_materials_config* config, int version) {
if (config == nullptr) {
gpr_log(GPR_ERROR,
"Invalid arguments to "
"grpc_tls_key_materials_config_set_version()");
return 0;
}
config->set_version(version);
return 1;
void grpc_tls_credentials_options_watch_identity_key_cert_pairs(
grpc_tls_credentials_options* options) {
GPR_ASSERT(options != nullptr);
options->set_watch_identity_pair(true);
}
int grpc_tls_key_materials_config_get_version(
grpc_tls_key_materials_config* config) {
if (config == nullptr) {
gpr_log(GPR_ERROR,
"Invalid arguments to "
"grpc_tls_key_materials_config_get_version()");
return -1;
}
return config->version();
void grpc_tls_credentials_options_set_identity_cert_name(
grpc_tls_credentials_options* options, const char* identity_cert_name) {
GPR_ASSERT(options != nullptr);
options->set_identity_cert_name(identity_cert_name);
}
grpc_tls_credential_reload_config* grpc_tls_credential_reload_config_create(
const void* config_user_data,
int (*schedule)(void* config_user_data,
grpc_tls_credential_reload_arg* arg),
void (*cancel)(void* config_user_data, grpc_tls_credential_reload_arg* arg),
void (*destruct)(void* config_user_data)) {
if (schedule == nullptr) {
gpr_log(
GPR_ERROR,
"Schedule API is nullptr in creating TLS credential reload config.");
return nullptr;
}
return new grpc_tls_credential_reload_config(config_user_data, schedule,
cancel, destruct);
void grpc_tls_credentials_options_set_server_authorization_check_config(
grpc_tls_credentials_options* options,
grpc_tls_server_authorization_check_config* config) {
GPR_ASSERT(options != nullptr);
GPR_ASSERT(config != nullptr);
options->set_server_authorization_check_config(config->Ref());
}
grpc_tls_server_authorization_check_config*
@ -243,3 +162,12 @@ grpc_tls_server_authorization_check_config_create(
return new grpc_tls_server_authorization_check_config(
config_user_data, schedule, cancel, destruct);
}
void grpc_tls_server_authorization_check_config_release(
grpc_tls_server_authorization_check_config* config) {
GRPC_API_TRACE(
"grpc_tls_server_authorization_check_config_release(config=%p)", 1,
(config));
grpc_core::ExecCtx exec_ctx;
if (config != nullptr) config->Unref();
}

@ -26,6 +26,8 @@
#include "absl/container/inlined_vector.h"
#include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.h"
#include "src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h"
#include "src/core/lib/security/security_connector/ssl_utils.h"
struct grpc_tls_error_details
@ -41,126 +43,6 @@ struct grpc_tls_error_details
std::string error_details_;
};
/** TLS key materials config. **/
struct grpc_tls_key_materials_config
: public grpc_core::RefCounted<grpc_tls_key_materials_config> {
public:
typedef absl::InlinedVector<grpc_core::PemKeyCertPair, 1> PemKeyCertPairList;
/** Getters for member fields. **/
const char* pem_root_certs() const { return pem_root_certs_.get(); }
const PemKeyCertPairList& pem_key_cert_pair_list() const {
return pem_key_cert_pair_list_;
}
int version() const { return version_; }
/** Setters for member fields. **/
// TODO(ZhenLian): Remove this function
void set_pem_root_certs(grpc_core::UniquePtr<char> pem_root_certs) {
pem_root_certs_ = std::move(pem_root_certs);
}
// The ownerships of |pem_root_certs| remain with the caller.
void set_pem_root_certs(const char* pem_root_certs) {
// make a copy of pem_root_certs.
grpc_core::UniquePtr<char> pem_root_ptr(gpr_strdup(pem_root_certs));
pem_root_certs_ = std::move(pem_root_ptr);
}
void add_pem_key_cert_pair(grpc_core::PemKeyCertPair pem_key_cert_pair) {
pem_key_cert_pair_list_.push_back(std::move(pem_key_cert_pair));
}
// The ownerships of |pem_root_certs| and |pem_key_cert_pairs| remain with the
// caller.
void set_key_materials(const char* pem_root_certs,
const grpc_ssl_pem_key_cert_pair** pem_key_cert_pairs,
size_t num_key_cert_pairs);
// The ownerships of |pem_root_certs| and |pem_key_cert_pair_list| remain with
// the caller.
void set_key_materials(const char* pem_root_certs,
const PemKeyCertPairList& pem_key_cert_pair_list);
void set_version(int version) { version_ = version; }
private:
int version_ = 0;
PemKeyCertPairList pem_key_cert_pair_list_;
grpc_core::UniquePtr<char> pem_root_certs_;
};
/** TLS credential reload config. **/
struct grpc_tls_credential_reload_config
: public grpc_core::RefCounted<grpc_tls_credential_reload_config> {
public:
grpc_tls_credential_reload_config(
const void* config_user_data,
int (*schedule)(void* config_user_data,
grpc_tls_credential_reload_arg* arg),
void (*cancel)(void* config_user_data,
grpc_tls_credential_reload_arg* arg),
void (*destruct)(void* config_user_data));
~grpc_tls_credential_reload_config() override;
void* context() const { return context_; }
void set_context(void* context) { context_ = context; }
int Schedule(grpc_tls_credential_reload_arg* arg) const {
if (schedule_ == nullptr) {
gpr_log(GPR_ERROR, "schedule API is nullptr");
if (arg != nullptr) {
arg->status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL;
arg->error_details->set_error_details(
"schedule API in credential reload config is nullptr");
}
return 1;
}
if (arg != nullptr) {
arg->config = const_cast<grpc_tls_credential_reload_config*>(this);
}
return schedule_(config_user_data_, arg);
}
void Cancel(grpc_tls_credential_reload_arg* arg) const {
if (cancel_ == nullptr) {
gpr_log(GPR_ERROR, "cancel API is nullptr.");
if (arg != nullptr) {
arg->status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL;
arg->error_details->set_error_details(
"cancel API in credential reload config is nullptr");
}
return;
}
if (arg != nullptr) {
arg->config = const_cast<grpc_tls_credential_reload_config*>(this);
}
cancel_(config_user_data_, arg);
}
private:
/** This is a pointer to the wrapped language implementation of
* grpc_tls_credential_reload_config. It is necessary to implement the C
* schedule and cancel functions, given the schedule or cancel function in a
* wrapped language. **/
void* context_ = nullptr;
/** config-specific, read-only user data that works for all channels created
with a credential using the config. */
void* config_user_data_;
/** callback function for invoking credential reload API. The implementation
of this method has to be non-blocking, but can be performed synchronously
or asynchronously.
If processing occurs synchronously, it populates \a arg->key_materials, \a
arg->status, and \a arg->error_details and returns zero.
If processing occurs asynchronously, it returns a non-zero value.
Application then invokes \a arg->cb when processing is completed. Note that
\a arg->cb cannot be invoked before \a schedule returns.
*/
int (*schedule_)(void* config_user_data, grpc_tls_credential_reload_arg* arg);
/** callback function for cancelling a credential reload request scheduled via
an asynchronous \a schedule. \a arg is used to pinpoint an exact reloading
request to be cancelled, and the operation may not have any effect if the
request has already been processed. */
void (*cancel_)(void* config_user_data, grpc_tls_credential_reload_arg* arg);
/** callback function for cleaning up any data associated with credential
reload config. */
void (*destruct_)(void* config_user_data);
};
/** TLS server authorization check config. **/
struct grpc_tls_server_authorization_check_config
: public grpc_core::RefCounted<grpc_tls_server_authorization_check_config> {
@ -175,40 +57,12 @@ struct grpc_tls_server_authorization_check_config
~grpc_tls_server_authorization_check_config() override;
void* context() const { return context_; }
void set_context(void* context) { context_ = context; }
int Schedule(grpc_tls_server_authorization_check_arg* arg) const {
if (schedule_ == nullptr) {
gpr_log(GPR_ERROR, "schedule API is nullptr");
if (arg != nullptr) {
arg->status = GRPC_STATUS_NOT_FOUND;
arg->error_details->set_error_details(
"schedule API in server authorization check config is nullptr");
}
return 1;
}
if (arg != nullptr && context_ != nullptr) {
arg->config =
const_cast<grpc_tls_server_authorization_check_config*>(this);
}
return schedule_(config_user_data_, arg);
}
void Cancel(grpc_tls_server_authorization_check_arg* arg) const {
if (cancel_ == nullptr) {
gpr_log(GPR_ERROR, "cancel API is nullptr.");
if (arg != nullptr) {
arg->status = GRPC_STATUS_NOT_FOUND;
arg->error_details->set_error_details(
"schedule API in server authorization check config is nullptr");
}
return;
}
if (arg != nullptr) {
arg->config =
const_cast<grpc_tls_server_authorization_check_config*>(this);
}
cancel_(config_user_data_, arg);
}
int Schedule(grpc_tls_server_authorization_check_arg* arg) const;
void Cancel(grpc_tls_server_authorization_check_arg* arg) const;
private:
/** This is a pointer to the wrapped language implementation of
@ -241,23 +95,15 @@ struct grpc_tls_server_authorization_check_config
void (*destruct_)(void* config_user_data);
};
/* TLS credentials options. */
// Contains configurable options specified by callers to configure their certain
// security features supported in TLS.
// TODO(ZhenLian): consider making this not ref-counted.
struct grpc_tls_credentials_options
: public grpc_core::RefCounted<grpc_tls_credentials_options> {
public:
~grpc_tls_credentials_options() override {
if (key_materials_config_.get() != nullptr) {
key_materials_config_->Unref();
}
if (credential_reload_config_.get() != nullptr) {
credential_reload_config_->Unref();
}
if (server_authorization_check_config_.get() != nullptr) {
server_authorization_check_config_->Unref();
}
}
~grpc_tls_credentials_options() override = default;
/* Getters for member fields. */
// Getters for member fields.
grpc_ssl_client_certificate_request_type cert_request_type() const {
return cert_request_type_;
}
@ -266,18 +112,26 @@ struct grpc_tls_credentials_options
}
grpc_tls_version min_tls_version() const { return min_tls_version_; }
grpc_tls_version max_tls_version() const { return max_tls_version_; }
grpc_tls_key_materials_config* key_materials_config() const {
return key_materials_config_.get();
}
grpc_tls_credential_reload_config* credential_reload_config() const {
return credential_reload_config_.get();
}
grpc_tls_server_authorization_check_config*
server_authorization_check_config() const {
return server_authorization_check_config_.get();
}
/* Setters for member fields. */
// This will be used by the security connector to get the correct distributor.
// It can be applied to both the Tls*Creds and the Xds*Creds cases.
// For Tls*Creds case, we will get the distributor from the provider;
// For Xds*Creds case, there will be a level of indirection between the
// provider and the distributor, so we will get the distributor directly.
grpc_tls_certificate_distributor* certificate_distributor() {
if (provider_ != nullptr) return provider_->distributor().get();
if (distributor_ != nullptr) return distributor_.get();
return nullptr;
}
bool watch_root_cert() { return watch_root_cert_; }
const std::string& root_cert_name() { return root_cert_name_; }
bool watch_identity_pair() { return watch_identity_pair_; }
const std::string& identity_cert_name() { return identity_cert_name_; }
// Setters for member fields.
void set_cert_request_type(
const grpc_ssl_client_certificate_request_type type) {
cert_request_type_ = type;
@ -292,32 +146,61 @@ struct grpc_tls_credentials_options
void set_max_tls_version(grpc_tls_version max_tls_version) {
max_tls_version_ = max_tls_version;
}
void set_key_materials_config(
grpc_core::RefCountedPtr<grpc_tls_key_materials_config> config) {
key_materials_config_ = std::move(config);
}
void set_credential_reload_config(
grpc_core::RefCountedPtr<grpc_tls_credential_reload_config> config) {
credential_reload_config_ = std::move(config);
}
void set_server_authorization_check_config(
grpc_core::RefCountedPtr<grpc_tls_server_authorization_check_config>
config) {
server_authorization_check_config_ = std::move(config);
}
// Sets the provider in the options.
// This should only be used by C-core API for Tls*Creds case.
void set_certificate_provider(
grpc_core::RefCountedPtr<grpc_tls_certificate_provider> provider) {
provider_ = std::move(provider);
}
// Sets the distributor in the options.
// This should only be used by the xDS code for Xds*Creds case.
void set_certificate_distributor(
grpc_core::RefCountedPtr<grpc_tls_certificate_distributor> distributor) {
distributor_ = std::move(distributor);
}
// If need to watch the updates of root certificates with name
// |root_cert_name|. The default value is false. If used in tls_credentials,
// it should always be set to true unless the root certificates are not
// needed.
void set_watch_root_cert(bool watch) { watch_root_cert_ = watch; }
// Sets the name of root certificates being watched, if |set_watch_root_cert|
// is called. If not set, an empty string will be used as the name.
void set_root_cert_name(std::string root_cert_name) {
root_cert_name_ = std::move(root_cert_name);
}
// If need to watch the updates of identity certificates with name
// |identity_cert_name|.
// The default value is false.
// If used in tls_credentials, it should always be set to true
// unless the identity key-cert pairs are not needed.
void set_watch_identity_pair(bool watch) { watch_identity_pair_ = watch; }
// Sets the name of identity key-cert pairs being watched, if
// |set_watch_identity_pair| is called. If not set, an empty string will
// be used as the name.
void set_identity_cert_name(std::string identity_cert_name) {
identity_cert_name_ = std::move(identity_cert_name);
}
private:
grpc_ssl_client_certificate_request_type cert_request_type_;
grpc_ssl_client_certificate_request_type cert_request_type_ =
GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE;
grpc_tls_server_verification_option server_verification_option_ =
GRPC_TLS_SERVER_VERIFICATION;
grpc_tls_version min_tls_version_ = grpc_tls_version::TLS1_2;
grpc_tls_version max_tls_version_ = grpc_tls_version::TLS1_3;
grpc_core::RefCountedPtr<grpc_tls_key_materials_config> key_materials_config_;
grpc_core::RefCountedPtr<grpc_tls_credential_reload_config>
credential_reload_config_;
grpc_core::RefCountedPtr<grpc_tls_server_authorization_check_config>
server_authorization_check_config_;
grpc_core::RefCountedPtr<grpc_tls_certificate_provider> provider_;
grpc_core::RefCountedPtr<grpc_tls_certificate_distributor> distributor_;
bool watch_root_cert_ = false;
std::string root_cert_name_;
bool watch_identity_pair_ = false;
std::string identity_cert_name_;
};
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_TLS_GRPC_TLS_CREDENTIALS_OPTIONS_H \
*/
#endif // GRPC_CORE_LIB_SECURITY_CREDENTIALS_TLS_GRPC_TLS_CREDENTIALS_OPTIONS_H

@ -40,18 +40,18 @@ bool CredentialOptionSanityCheck(const grpc_tls_credentials_options* options,
gpr_log(GPR_ERROR, "TLS credentials options is nullptr.");
return false;
}
if (options->key_materials_config() == nullptr &&
options->credential_reload_config() == nullptr) {
gpr_log(GPR_ERROR,
"TLS credentials options must specify either key materials or "
"credential reload config.");
return false;
}
// TODO(ZhenLian): remove this when it is also supported on server side.
if (!is_client && options->server_authorization_check_config() != nullptr) {
gpr_log(GPR_INFO,
"Server's credentials options should not contain server "
"authorization check config.");
}
if (options->server_verification_option() != GRPC_TLS_SERVER_VERIFICATION &&
options->server_authorization_check_config() == nullptr) {
gpr_log(GPR_ERROR,
"Should provider custom verifications if bypassing default ones.");
return false;
}
return true;
}
@ -85,14 +85,16 @@ TlsCredentials::create_security_connector(
}
grpc_core::RefCountedPtr<grpc_channel_security_connector> sc =
grpc_core::TlsChannelSecurityConnector::CreateTlsChannelSecurityConnector(
this->Ref(), std::move(call_creds), target_name,
this->Ref(), options_, std::move(call_creds), target_name,
overridden_target_name, ssl_session_cache);
if (sc == nullptr) {
return nullptr;
}
grpc_arg new_arg = grpc_channel_arg_string_create(
(char*)GRPC_ARG_HTTP2_SCHEME, (char*)"https");
*new_args = grpc_channel_args_copy_and_add(args, &new_arg, 1);
if (args != nullptr) {
grpc_arg new_arg = grpc_channel_arg_string_create(
(char*)GRPC_ARG_HTTP2_SCHEME, (char*)"https");
*new_args = grpc_channel_args_copy_and_add(args, &new_arg, 1);
}
return sc;
}
@ -106,9 +108,11 @@ TlsServerCredentials::~TlsServerCredentials() {}
grpc_core::RefCountedPtr<grpc_server_security_connector>
TlsServerCredentials::create_security_connector() {
return grpc_core::TlsServerSecurityConnector::
CreateTlsServerSecurityConnector(this->Ref());
CreateTlsServerSecurityConnector(this->Ref(), options_);
}
/** -- Wrapper APIs declared in grpc_security.h -- **/
grpc_channel_credentials* grpc_tls_credentials_create(
grpc_tls_credentials_options* options) {
if (!CredentialOptionSanityCheck(options, true /* is_client */)) {

@ -38,7 +38,7 @@ class TlsCredentials final : public grpc_channel_credentials {
const char* target_name, const grpc_channel_args* args,
grpc_channel_args** new_args) override;
const grpc_tls_credentials_options& options() const { return *options_; }
grpc_tls_credentials_options* options() const { return options_.get(); }
private:
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options_;
@ -53,7 +53,7 @@ class TlsServerCredentials final : public grpc_server_credentials {
grpc_core::RefCountedPtr<grpc_server_security_connector>
create_security_connector() override;
const grpc_tls_credentials_options& options() const { return *options_; }
grpc_tls_credentials_options* options() const { return options_.get(); }
private:
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options_;

@ -187,6 +187,8 @@ class PemKeyCertPair {
grpc_core::UniquePtr<char> cert_chain_;
};
typedef absl::InlinedVector<grpc_core::PemKeyCertPair, 1> PemKeyCertPairList;
} // namespace grpc_core
#endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_SSL_UTILS_H \

@ -46,7 +46,7 @@ namespace grpc_core {
namespace {
tsi_ssl_pem_key_cert_pair* ConvertToTsiPemKeyCertPair(
const grpc_tls_key_materials_config::PemKeyCertPairList& cert_pair_list) {
const grpc_core::PemKeyCertPairList& cert_pair_list) {
tsi_ssl_pem_key_cert_pair* tsi_pairs = nullptr;
size_t num_key_cert_pairs = cert_pair_list.size();
if (num_key_cert_pairs > 0) {
@ -65,127 +65,120 @@ tsi_ssl_pem_key_cert_pair* ConvertToTsiPemKeyCertPair(
} // namespace
grpc_status_code TlsFetchKeyMaterials(
const grpc_core::RefCountedPtr<grpc_tls_key_materials_config>&
key_materials_config,
const grpc_tls_credentials_options& options, bool is_server,
grpc_ssl_certificate_config_reload_status* status) {
GPR_ASSERT(key_materials_config != nullptr);
GPR_ASSERT(status != nullptr);
bool is_key_materials_empty =
key_materials_config->pem_key_cert_pair_list().empty();
grpc_tls_credential_reload_config* credential_reload_config =
options.credential_reload_config();
/** If there are no key materials and no credential reload config and the
* caller is a server, then return an error. We do not require that a client
* always provision certificates. **/
if (credential_reload_config == nullptr && is_key_materials_empty &&
is_server) {
// -------------------channel security connector-------------------
grpc_core::RefCountedPtr<grpc_channel_security_connector>
TlsChannelSecurityConnector::CreateTlsChannelSecurityConnector(
grpc_core::RefCountedPtr<grpc_channel_credentials> ch_creds,
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options,
grpc_core::RefCountedPtr<grpc_call_credentials> request_metadata_creds,
const char* target_name, const char* overridden_target_name,
tsi_ssl_session_cache* ssl_session_cache) {
if (ch_creds == nullptr) {
gpr_log(GPR_ERROR,
"Either credential reload config or key materials should be "
"provisioned.");
return GRPC_STATUS_FAILED_PRECONDITION;
}
grpc_status_code reload_status = GRPC_STATUS_OK;
/** Use |credential_reload_config| to update |key_materials_config|. **/
if (credential_reload_config != nullptr) {
grpc_tls_credential_reload_arg* arg = new grpc_tls_credential_reload_arg();
arg->key_materials_config = key_materials_config.get();
arg->error_details = new grpc_tls_error_details();
int result = credential_reload_config->Schedule(arg);
if (result) {
/** Credential reloading is performed async. This is not yet supported.
* **/
gpr_log(GPR_ERROR, "Async credential reload is unsupported now.");
*status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
reload_status =
is_key_materials_empty ? GRPC_STATUS_UNIMPLEMENTED : GRPC_STATUS_OK;
} else {
/** Credential reloading is performed sync. **/
*status = arg->status;
if (arg->status == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED) {
/* Key materials is not empty. */
gpr_log(GPR_DEBUG, "Credential does not change after reload.");
} else if (arg->status == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL) {
gpr_log(GPR_ERROR, "Credential reload failed with an error:");
if (arg->error_details != nullptr) {
gpr_log(GPR_ERROR, "%s", arg->error_details->error_details().c_str());
}
reload_status =
is_key_materials_empty ? GRPC_STATUS_INTERNAL : GRPC_STATUS_OK;
}
}
delete arg->error_details;
/** If the credential reload config was constructed via a wrapped language,
* then |arg->context| and |arg->destroy_context| will not be nullptr. In
* this case, we must destroy |arg->context|, which stores the wrapped
* language-version of the credential reload arg. **/
if (arg->destroy_context != nullptr) {
arg->destroy_context(arg->context);
}
delete arg;
"channel_creds is nullptr in "
"TlsChannelSecurityConnectorCreate()");
return nullptr;
}
return reload_status;
}
grpc_error* TlsCheckHostName(const char* peer_name, const tsi_peer* peer) {
/* Check the peer name if specified. */
if (peer_name != nullptr && !grpc_ssl_host_matches_name(peer, peer_name)) {
return GRPC_ERROR_CREATE_FROM_COPIED_STRING(
absl::StrCat("Peer name ", peer_name, " is not in peer certificate")
.c_str());
if (options == nullptr) {
gpr_log(GPR_ERROR,
"options is nullptr in "
"TlsChannelSecurityConnectorCreate()");
return nullptr;
}
return GRPC_ERROR_NONE;
if (target_name == nullptr) {
gpr_log(GPR_ERROR,
"target_name is nullptr in "
"TlsChannelSecurityConnectorCreate()");
return nullptr;
}
grpc_core::RefCountedPtr<TlsChannelSecurityConnector> c =
grpc_core::MakeRefCounted<TlsChannelSecurityConnector>(
std::move(ch_creds), std::move(options),
std::move(request_metadata_creds), target_name,
overridden_target_name, ssl_session_cache);
return c;
}
TlsChannelSecurityConnector::TlsChannelSecurityConnector(
grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds,
grpc_core::RefCountedPtr<grpc_channel_credentials> ch_creds,
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options,
grpc_core::RefCountedPtr<grpc_call_credentials> request_metadata_creds,
const char* target_name, const char* overridden_target_name)
: grpc_channel_security_connector(GRPC_SSL_URL_SCHEME,
std::move(channel_creds),
const char* target_name, const char* overridden_target_name,
tsi_ssl_session_cache* ssl_session_cache)
: grpc_channel_security_connector(GRPC_SSL_URL_SCHEME, std::move(ch_creds),
std::move(request_metadata_creds)),
options_(std::move(options)),
overridden_target_name_(
overridden_target_name == nullptr ? "" : overridden_target_name) {
key_materials_config_ = grpc_tls_key_materials_config_create()->Ref();
overridden_target_name == nullptr ? "" : overridden_target_name),
ssl_session_cache_(ssl_session_cache) {
if (ssl_session_cache_ != nullptr) {
tsi_ssl_session_cache_ref(ssl_session_cache_);
}
check_arg_ = ServerAuthorizationCheckArgCreate(this);
absl::string_view host;
absl::string_view port;
grpc_core::SplitHostPort(target_name, &host, &port);
target_name_ = std::string(host);
// Create a watcher.
auto watcher_ptr = absl::make_unique<TlsChannelCertificateWatcher>(this);
certificate_watcher_ = watcher_ptr.get();
// Register the watcher with the distributor.
grpc_tls_certificate_distributor* distributor =
options_->certificate_distributor();
absl::optional<std::string> watched_root_cert_name;
if (options_->watch_root_cert()) {
watched_root_cert_name = options_->root_cert_name();
}
absl::optional<std::string> watched_identity_cert_name;
if (options_->watch_identity_pair()) {
watched_identity_cert_name = options_->identity_cert_name();
}
distributor->WatchTlsCertificates(std::move(watcher_ptr),
watched_root_cert_name,
watched_identity_cert_name);
}
TlsChannelSecurityConnector::~TlsChannelSecurityConnector() {
if (ssl_session_cache_ != nullptr) {
tsi_ssl_session_cache_unref(ssl_session_cache_);
}
// Cancel all the watchers.
grpc_tls_certificate_distributor* distributor =
options_->certificate_distributor();
distributor->CancelTlsCertificatesWatch(certificate_watcher_);
if (client_handshaker_factory_ != nullptr) {
tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory_);
}
if (key_materials_config_.get() != nullptr) {
key_materials_config_->Unref();
if (check_arg_ != nullptr) {
ServerAuthorizationCheckArgDestroy(check_arg_);
}
ServerAuthorizationCheckArgDestroy(check_arg_);
}
void TlsChannelSecurityConnector::add_handshakers(
const grpc_channel_args* args, grpc_pollset_set* /*interested_parties*/,
grpc_core::HandshakeManager* handshake_mgr) {
if (RefreshHandshakerFactory() != GRPC_SECURITY_OK) {
gpr_log(GPR_ERROR, "Handshaker factory refresh failed.");
return;
}
// Instantiate TSI handshaker.
tsi_handshaker* tsi_hs = nullptr;
tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker(
client_handshaker_factory_,
overridden_target_name_.empty() ? target_name_.c_str()
: overridden_target_name_.c_str(),
&tsi_hs);
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
tsi_result_to_string(result));
grpc_core::MutexLock lock(&mu_);
if (client_handshaker_factory_ != nullptr) {
// Instantiate TSI handshaker.
tsi_handshaker* tsi_hs = nullptr;
tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker(
client_handshaker_factory_,
overridden_target_name_.empty() ? target_name_.c_str()
: overridden_target_name_.c_str(),
&tsi_hs);
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
tsi_result_to_string(result));
return;
}
// Create handshakers.
handshake_mgr->Add(grpc_core::SecurityHandshakerCreate(tsi_hs, this, args));
return;
}
// Create handshakers.
handshake_mgr->Add(grpc_core::SecurityHandshakerCreate(tsi_hs, this, args));
// TODO(ZhenLian): Implement the logic(delegation to
// BlockOnInitialCredentialHandshaker) when certificates are not ready.
gpr_log(GPR_ERROR, "%s not supported yet.",
"Client BlockOnInitialCredentialHandshaker");
}
void TlsChannelSecurityConnector::check_peer(
@ -203,12 +196,9 @@ void TlsChannelSecurityConnector::check_peer(
}
*auth_context =
grpc_ssl_peer_to_auth_context(&peer, GRPC_TLS_TRANSPORT_SECURITY_TYPE);
const TlsCredentials* creds =
static_cast<const TlsCredentials*>(channel_creds());
if (creds->options().server_verification_option() ==
GRPC_TLS_SERVER_VERIFICATION) {
if (options_->server_verification_option() == GRPC_TLS_SERVER_VERIFICATION) {
/* Do the default host name check if specifying the target name. */
error = TlsCheckHostName(target_name, &peer);
error = internal::TlsCheckHostName(target_name, &peer);
if (error != GRPC_ERROR_NONE) {
grpc_core::ExecCtx::Run(DEBUG_LOCATION, on_peer_checked, error);
tsi_peer_destruct(&peer);
@ -217,7 +207,7 @@ void TlsChannelSecurityConnector::check_peer(
}
/* Do the custom server authorization check, if specified by the user. */
const grpc_tls_server_authorization_check_config* config =
creds->options().server_authorization_check_config();
options_->server_authorization_check_config();
/* If server authorization config is not null, use it to perform
* server authorization check. */
if (config != nullptr) {
@ -289,105 +279,86 @@ void TlsChannelSecurityConnector::cancel_check_call_host(
GRPC_ERROR_UNREF(error);
}
grpc_core::RefCountedPtr<grpc_channel_security_connector>
TlsChannelSecurityConnector::CreateTlsChannelSecurityConnector(
grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds,
grpc_core::RefCountedPtr<grpc_call_credentials> request_metadata_creds,
const char* target_name, const char* overridden_target_name,
tsi_ssl_session_cache* ssl_session_cache) {
if (channel_creds == nullptr) {
gpr_log(GPR_ERROR,
"channel_creds is nullptr in "
"TlsChannelSecurityConnectorCreate()");
return nullptr;
void TlsChannelSecurityConnector::TlsChannelCertificateWatcher::
OnCertificatesChanged(
absl::optional<absl::string_view> root_certs,
absl::optional<grpc_core::PemKeyCertPairList> key_cert_pairs) {
GPR_ASSERT(security_connector_ != nullptr);
grpc_core::MutexLock lock(&security_connector_->mu_);
if (root_certs.has_value()) {
security_connector_->pem_root_certs_ = root_certs;
}
if (key_cert_pairs.has_value()) {
security_connector_->pem_key_cert_pair_list_ = std::move(key_cert_pairs);
}
bool root_being_watched = security_connector_->options_->watch_root_cert();
bool root_has_value = security_connector_->pem_root_certs_.has_value();
bool identity_being_watched =
security_connector_->options_->watch_identity_pair();
bool identity_has_value =
security_connector_->pem_key_cert_pair_list_.has_value();
if ((root_being_watched && root_has_value && identity_being_watched &&
identity_has_value) ||
(root_being_watched && root_has_value && !identity_being_watched) ||
(!root_being_watched && identity_being_watched && identity_has_value)) {
if (security_connector_->UpdateHandshakerFactoryLocked() !=
GRPC_SECURITY_OK) {
gpr_log(GPR_ERROR, "Update handshaker factory failed.");
}
}
if (target_name == nullptr) {
}
// TODO(ZhenLian): implement the logic to signal waiting handshakers once
// BlockOnInitialCredentialHandshaker is implemented.
void TlsChannelSecurityConnector::TlsChannelCertificateWatcher::OnError(
grpc_error* root_cert_error, grpc_error* identity_cert_error) {
if (root_cert_error != GRPC_ERROR_NONE) {
gpr_log(GPR_ERROR,
"target_name is nullptr in "
"TlsChannelSecurityConnectorCreate()");
return nullptr;
"TlsChannelCertificateWatcher getting root_cert_error: %s",
grpc_error_string(root_cert_error));
}
grpc_core::RefCountedPtr<TlsChannelSecurityConnector> c =
grpc_core::MakeRefCounted<TlsChannelSecurityConnector>(
std::move(channel_creds), std::move(request_metadata_creds),
target_name, overridden_target_name);
if (c->InitializeHandshakerFactory(ssl_session_cache) != GRPC_SECURITY_OK) {
gpr_log(GPR_ERROR, "Could not initialize client handshaker factory.");
return nullptr;
if (identity_cert_error != GRPC_ERROR_NONE) {
gpr_log(GPR_ERROR,
"TlsChannelCertificateWatcher getting identity_cert_error: %s",
grpc_error_string(identity_cert_error));
}
return c;
GRPC_ERROR_UNREF(root_cert_error);
GRPC_ERROR_UNREF(identity_cert_error);
}
grpc_security_status TlsChannelSecurityConnector::ReplaceHandshakerFactory(
tsi_ssl_session_cache* ssl_session_cache) {
const TlsCredentials* creds =
static_cast<const TlsCredentials*>(channel_creds());
// TODO(ZhenLian): implement the logic to signal waiting handshakers once
// BlockOnInitialCredentialHandshaker is implemented.
grpc_security_status
TlsChannelSecurityConnector::UpdateHandshakerFactoryLocked() {
bool skip_server_certificate_verification =
creds->options().server_verification_option() ==
options_->server_verification_option() ==
GRPC_TLS_SKIP_ALL_SERVER_VERIFICATION;
/* Free the client handshaker factory if exists. */
if (client_handshaker_factory_) {
if (client_handshaker_factory_ != nullptr) {
tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory_);
}
tsi_ssl_pem_key_cert_pair* pem_key_cert_pair = ConvertToTsiPemKeyCertPair(
key_materials_config_->pem_key_cert_pair_list());
std::string pem_root_certs;
if (pem_root_certs_.has_value()) {
// TODO(ZhenLian): update the underlying TSI layer to use C++ types like
// std::string and absl::string_view to avoid making another copy here.
pem_root_certs = std::string(*pem_root_certs_);
}
tsi_ssl_pem_key_cert_pair* pem_key_cert_pair = nullptr;
if (pem_key_cert_pair_list_.has_value()) {
pem_key_cert_pair = ConvertToTsiPemKeyCertPair(*pem_key_cert_pair_list_);
}
grpc_security_status status = grpc_ssl_tsi_client_handshaker_factory_init(
pem_key_cert_pair, key_materials_config_->pem_root_certs(),
pem_key_cert_pair,
pem_root_certs.empty() ? nullptr : pem_root_certs.c_str(),
skip_server_certificate_verification,
grpc_get_tsi_tls_version(creds->options().min_tls_version()),
grpc_get_tsi_tls_version(creds->options().max_tls_version()),
ssl_session_cache, &client_handshaker_factory_);
grpc_get_tsi_tls_version(options_->min_tls_version()),
grpc_get_tsi_tls_version(options_->max_tls_version()), ssl_session_cache_,
&client_handshaker_factory_);
/* Free memory. */
grpc_tsi_ssl_pem_key_cert_pairs_destroy(pem_key_cert_pair, 1);
return status;
}
grpc_security_status TlsChannelSecurityConnector::InitializeHandshakerFactory(
tsi_ssl_session_cache* ssl_session_cache) {
grpc_core::MutexLock lock(&mu_);
const TlsCredentials* creds =
static_cast<const TlsCredentials*>(channel_creds());
grpc_tls_key_materials_config* key_materials_config =
creds->options().key_materials_config();
// key_materials_config_->set_key_materials will handle the copying of the key
// materials users provided
if (key_materials_config != nullptr) {
key_materials_config_->set_key_materials(
key_materials_config->pem_root_certs(),
key_materials_config->pem_key_cert_pair_list());
}
grpc_ssl_certificate_config_reload_status reload_status =
GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
/** If |creds->options()| has a credential reload config, then the call to
* |TlsFetchKeyMaterials| will use it to update the root cert and
* pem-key-cert-pair list stored in |key_materials_config_|. **/
if (TlsFetchKeyMaterials(key_materials_config_, creds->options(), false,
&reload_status) != GRPC_STATUS_OK) {
/* Raise an error if key materials are not populated. */
return GRPC_SECURITY_ERROR;
}
return ReplaceHandshakerFactory(ssl_session_cache);
}
grpc_security_status TlsChannelSecurityConnector::RefreshHandshakerFactory() {
grpc_core::MutexLock lock(&mu_);
const TlsCredentials* creds =
static_cast<const TlsCredentials*>(channel_creds());
grpc_ssl_certificate_config_reload_status reload_status =
GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
/** If |creds->options()| has a credential reload config, then the call to
* |TlsFetchKeyMaterials| will use it to update the root cert and
* pem-key-cert-pair list stored in |key_materials_config_|. **/
if (TlsFetchKeyMaterials(key_materials_config_, creds->options(), false,
&reload_status) != GRPC_STATUS_OK) {
return GRPC_SECURITY_ERROR;
}
if (reload_status != GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW) {
// Re-use existing handshaker factory.
return GRPC_SECURITY_OK;
} else {
return ReplaceHandshakerFactory(nullptr);
if (pem_key_cert_pair != nullptr) {
grpc_tsi_ssl_pem_key_cert_pairs_destroy(pem_key_cert_pair, 1);
}
return status;
}
void TlsChannelSecurityConnector::ServerAuthorizationCheckDone(
@ -457,40 +428,86 @@ void TlsChannelSecurityConnector::ServerAuthorizationCheckArgDestroy(
delete arg;
}
// -------------------server security connector-------------------
grpc_core::RefCountedPtr<grpc_server_security_connector>
TlsServerSecurityConnector::CreateTlsServerSecurityConnector(
grpc_core::RefCountedPtr<grpc_server_credentials> server_creds,
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options) {
if (server_creds == nullptr) {
gpr_log(GPR_ERROR,
"server_creds is nullptr in "
"TlsServerSecurityConnectorCreate()");
return nullptr;
}
if (options == nullptr) {
gpr_log(GPR_ERROR,
"options is nullptr in "
"TlsServerSecurityConnectorCreate()");
return nullptr;
}
grpc_core::RefCountedPtr<TlsServerSecurityConnector> c =
grpc_core::MakeRefCounted<TlsServerSecurityConnector>(
std::move(server_creds), std::move(options));
return c;
}
TlsServerSecurityConnector::TlsServerSecurityConnector(
grpc_core::RefCountedPtr<grpc_server_credentials> server_creds)
grpc_core::RefCountedPtr<grpc_server_credentials> server_creds,
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options)
: grpc_server_security_connector(GRPC_SSL_URL_SCHEME,
std::move(server_creds)) {
key_materials_config_ = grpc_tls_key_materials_config_create()->Ref();
std::move(server_creds)),
options_(std::move(options)) {
// Create a watcher.
auto watcher_ptr = absl::make_unique<TlsServerCertificateWatcher>(this);
certificate_watcher_ = watcher_ptr.get();
// Register the watcher with the distributor.
grpc_tls_certificate_distributor* distributor =
options_->certificate_distributor();
absl::optional<std::string> watched_root_cert_name;
if (options_->watch_root_cert()) {
watched_root_cert_name = options_->root_cert_name();
}
absl::optional<std::string> watched_identity_cert_name;
if (options_->watch_identity_pair()) {
watched_identity_cert_name = options_->identity_cert_name();
}
distributor->WatchTlsCertificates(std::move(watcher_ptr),
watched_root_cert_name,
watched_identity_cert_name);
}
TlsServerSecurityConnector::~TlsServerSecurityConnector() {
// Cancel all the watchers.
grpc_tls_certificate_distributor* distributor =
options_->certificate_distributor();
distributor->CancelTlsCertificatesWatch(certificate_watcher_);
if (server_handshaker_factory_ != nullptr) {
tsi_ssl_server_handshaker_factory_unref(server_handshaker_factory_);
}
if (key_materials_config_.get() != nullptr) {
key_materials_config_->Unref();
}
}
void TlsServerSecurityConnector::add_handshakers(
const grpc_channel_args* args, grpc_pollset_set* /*interested_parties*/,
grpc_core::HandshakeManager* handshake_mgr) {
/* Refresh handshaker factory if needed. */
if (RefreshHandshakerFactory() != GRPC_SECURITY_OK) {
gpr_log(GPR_ERROR, "Handshaker factory refresh failed.");
return;
}
/* Create a TLS TSI handshaker for server. */
tsi_handshaker* tsi_hs = nullptr;
tsi_result result = tsi_ssl_server_handshaker_factory_create_handshaker(
server_handshaker_factory_, &tsi_hs);
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
tsi_result_to_string(result));
grpc_core::MutexLock lock(&mu_);
if (server_handshaker_factory_ != nullptr) {
// Instantiate TSI handshaker.
tsi_handshaker* tsi_hs = nullptr;
tsi_result result = tsi_ssl_server_handshaker_factory_create_handshaker(
server_handshaker_factory_, &tsi_hs);
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
tsi_result_to_string(result));
return;
}
// Create handshakers.
handshake_mgr->Add(grpc_core::SecurityHandshakerCreate(tsi_hs, this, args));
return;
}
handshake_mgr->Add(grpc_core::SecurityHandshakerCreate(tsi_hs, this, args));
// TODO(ZhenLian): Implement the logic(delegation to
// BlockOnInitialCredentialHandshaker) when certificates are not ready.
gpr_log(GPR_ERROR, "%s not supported yet.",
"Server BlockOnInitialCredentialHandshaker");
}
void TlsServerSecurityConnector::check_peer(
@ -510,43 +527,79 @@ int TlsServerSecurityConnector::cmp(
static_cast<const grpc_server_security_connector*>(other));
}
grpc_core::RefCountedPtr<grpc_server_security_connector>
TlsServerSecurityConnector::CreateTlsServerSecurityConnector(
grpc_core::RefCountedPtr<grpc_server_credentials> server_creds) {
if (server_creds == nullptr) {
void TlsServerSecurityConnector::TlsServerCertificateWatcher::
OnCertificatesChanged(
absl::optional<absl::string_view> root_certs,
absl::optional<grpc_core::PemKeyCertPairList> key_cert_pairs) {
GPR_ASSERT(security_connector_ != nullptr);
grpc_core::MutexLock lock(&security_connector_->mu_);
if (root_certs.has_value()) {
security_connector_->pem_root_certs_ = root_certs;
}
if (key_cert_pairs.has_value()) {
security_connector_->pem_key_cert_pair_list_ = std::move(key_cert_pairs);
}
bool root_being_watched = security_connector_->options_->watch_root_cert();
bool root_has_value = security_connector_->pem_root_certs_.has_value();
bool identity_being_watched =
security_connector_->options_->watch_identity_pair();
bool identity_has_value =
security_connector_->pem_key_cert_pair_list_.has_value();
if ((root_being_watched && root_has_value && identity_being_watched &&
identity_has_value) ||
(root_being_watched && root_has_value && !identity_being_watched) ||
(!root_being_watched && identity_being_watched && identity_has_value)) {
if (security_connector_->UpdateHandshakerFactoryLocked() !=
GRPC_SECURITY_OK) {
gpr_log(GPR_ERROR, "Update handshaker factory failed.");
}
}
}
// TODO(ZhenLian): implement the logic to signal waiting handshakers once
// BlockOnInitialCredentialHandshaker is implemented.
void TlsServerSecurityConnector::TlsServerCertificateWatcher::OnError(
grpc_error* root_cert_error, grpc_error* identity_cert_error) {
if (root_cert_error != GRPC_ERROR_NONE) {
gpr_log(GPR_ERROR,
"server_creds is nullptr in "
"TlsServerSecurityConnectorCreate()");
return nullptr;
"TlsServerCertificateWatcher getting root_cert_error: %s",
grpc_error_string(root_cert_error));
}
grpc_core::RefCountedPtr<TlsServerSecurityConnector> c =
grpc_core::MakeRefCounted<TlsServerSecurityConnector>(
std::move(server_creds));
if (c->InitializeHandshakerFactory() != GRPC_SECURITY_OK) {
gpr_log(GPR_ERROR, "Could not initialize server handshaker factory.");
return nullptr;
if (identity_cert_error != GRPC_ERROR_NONE) {
gpr_log(GPR_ERROR,
"TlsServerCertificateWatcher getting identity_cert_error: %s",
grpc_error_string(identity_cert_error));
}
return c;
GRPC_ERROR_UNREF(root_cert_error);
GRPC_ERROR_UNREF(identity_cert_error);
}
grpc_security_status TlsServerSecurityConnector::ReplaceHandshakerFactory() {
const TlsServerCredentials* creds =
static_cast<const TlsServerCredentials*>(server_creds());
// TODO(ZhenLian): implement the logic to signal waiting handshakers once
// BlockOnInitialCredentialHandshaker is implemented.
grpc_security_status
TlsServerSecurityConnector::UpdateHandshakerFactoryLocked() {
/* Free the server handshaker factory if exists. */
if (server_handshaker_factory_) {
if (server_handshaker_factory_ != nullptr) {
tsi_ssl_server_handshaker_factory_unref(server_handshaker_factory_);
}
GPR_ASSERT(!key_materials_config_->pem_key_cert_pair_list().empty());
tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs = ConvertToTsiPemKeyCertPair(
key_materials_config_->pem_key_cert_pair_list());
size_t num_key_cert_pairs =
key_materials_config_->pem_key_cert_pair_list().size();
// The identity certs on the server side shouldn't be empty.
GPR_ASSERT(pem_key_cert_pair_list_.has_value());
GPR_ASSERT(!(*pem_key_cert_pair_list_).empty());
std::string pem_root_certs;
if (pem_root_certs_.has_value()) {
// TODO(ZhenLian): update the underlying TSI layer to use C++ types like
// std::string and absl::string_view to avoid making another copy here.
pem_root_certs = std::string(*pem_root_certs_);
}
tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs = nullptr;
pem_key_cert_pairs = ConvertToTsiPemKeyCertPair(*pem_key_cert_pair_list_);
size_t num_key_cert_pairs = (*pem_key_cert_pair_list_).size();
grpc_security_status status = grpc_ssl_tsi_server_handshaker_factory_init(
pem_key_cert_pairs, num_key_cert_pairs,
key_materials_config_->pem_root_certs(),
creds->options().cert_request_type(),
grpc_get_tsi_tls_version(creds->options().min_tls_version()),
grpc_get_tsi_tls_version(creds->options().max_tls_version()),
pem_root_certs.empty() ? nullptr : pem_root_certs.c_str(),
options_->cert_request_type(),
grpc_get_tsi_tls_version(options_->min_tls_version()),
grpc_get_tsi_tls_version(options_->max_tls_version()),
&server_handshaker_factory_);
/* Free memory. */
grpc_tsi_ssl_pem_key_cert_pairs_destroy(pem_key_cert_pairs,
@ -554,53 +607,18 @@ grpc_security_status TlsServerSecurityConnector::ReplaceHandshakerFactory() {
return status;
}
grpc_security_status TlsServerSecurityConnector::InitializeHandshakerFactory() {
grpc_core::MutexLock lock(&mu_);
const TlsServerCredentials* creds =
static_cast<const TlsServerCredentials*>(server_creds());
grpc_tls_key_materials_config* key_materials_config =
creds->options().key_materials_config();
if (key_materials_config != nullptr) {
key_materials_config_->set_key_materials(
key_materials_config->pem_root_certs(),
key_materials_config->pem_key_cert_pair_list());
}
grpc_ssl_certificate_config_reload_status reload_status =
GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
/** If |creds->options()| has a credential reload config, then the call to
* |TlsFetchKeyMaterials| will use it to update the root cert and
* pem-key-cert-pair list stored in |key_materials_config_|. Otherwise, it
* will return |GRPC_STATUS_OK| if |key_materials_config_| already has
* credentials, and an error code if not. **/
if (TlsFetchKeyMaterials(key_materials_config_, creds->options(), true,
&reload_status) != GRPC_STATUS_OK) {
/* Raise an error if key materials are not populated. */
return GRPC_SECURITY_ERROR;
}
return ReplaceHandshakerFactory();
}
namespace internal {
grpc_security_status TlsServerSecurityConnector::RefreshHandshakerFactory() {
grpc_core::MutexLock lock(&mu_);
const TlsServerCredentials* creds =
static_cast<const TlsServerCredentials*>(server_creds());
grpc_ssl_certificate_config_reload_status reload_status =
GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
/** If |creds->options()| has a credential reload config, then the call to
* |TlsFetchKeyMaterials| will use it to update the root cert and
* pem-key-cert-pair list stored in |key_materials_config_|. Otherwise, it
* will return |GRPC_STATUS_OK| if |key_materials_config_| already has
* credentials, and an error code if not. **/
if (TlsFetchKeyMaterials(key_materials_config_, creds->options(), true,
&reload_status) != GRPC_STATUS_OK) {
return GRPC_SECURITY_ERROR;
}
if (reload_status != GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW) {
/* At this point, we should have key materials populated. */
return GRPC_SECURITY_OK;
} else {
return ReplaceHandshakerFactory();
grpc_error* TlsCheckHostName(const char* peer_name, const tsi_peer* peer) {
/* Check the peer name if specified. */
if (peer_name != nullptr && !grpc_ssl_host_matches_name(peer, peer_name)) {
return GRPC_ERROR_CREATE_FROM_COPIED_STRING(
absl::StrCat("Peer name ", peer_name, " is not in peer certificate")
.c_str());
}
return GRPC_ERROR_NONE;
}
} // namespace internal
} // namespace grpc_core

@ -23,13 +23,14 @@
#include "src/core/lib/gprpp/sync.h"
#include "src/core/lib/security/context/security_context.h"
#include "src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h"
#include "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h"
#define GRPC_TLS_TRANSPORT_SECURITY_TYPE "tls"
namespace grpc_core {
// TLS channel security connector.
// Channel security connector using TLS as transport security protocol.
class TlsChannelSecurityConnector final
: public grpc_channel_security_connector {
public:
@ -37,14 +38,18 @@ class TlsChannelSecurityConnector final
static grpc_core::RefCountedPtr<grpc_channel_security_connector>
CreateTlsChannelSecurityConnector(
grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds,
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options,
grpc_core::RefCountedPtr<grpc_call_credentials> request_metadata_creds,
const char* target_name, const char* overridden_target_name,
tsi_ssl_session_cache* ssl_session_cache);
TlsChannelSecurityConnector(
grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds,
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options,
grpc_core::RefCountedPtr<grpc_call_credentials> request_metadata_creds,
const char* target_name, const char* overridden_target_name);
const char* target_name, const char* overridden_target_name,
tsi_ssl_session_cache* ssl_session_cache);
~TlsChannelSecurityConnector() override;
void add_handshakers(const grpc_channel_args* args,
@ -64,15 +69,45 @@ class TlsChannelSecurityConnector final
void cancel_check_call_host(grpc_closure* on_call_host_checked,
grpc_error* error) override;
private:
// Initialize SSL TSI client handshaker factory.
grpc_security_status InitializeHandshakerFactory(
tsi_ssl_session_cache* ssl_session_cache);
tsi_ssl_client_handshaker_factory* ClientHandshakerFactoryForTesting() {
grpc_core::MutexLock lock(&mu_);
return client_handshaker_factory_;
};
// A util function to create a new client handshaker factory to replace
// the existing one if exists.
grpc_security_status ReplaceHandshakerFactory(
tsi_ssl_session_cache* ssl_session_cache);
const absl::optional<absl::string_view>& RootCertsForTesting() {
grpc_core::MutexLock lock(&mu_);
return pem_root_certs_;
}
const absl::optional<grpc_core::PemKeyCertPairList>&
KeyCertPairListForTesting() {
grpc_core::MutexLock lock(&mu_);
return pem_key_cert_pair_list_;
}
private:
// A watcher that watches certificate updates from
// grpc_tls_certificate_distributor. It will never outlive
// |security_connector_|.
class TlsChannelCertificateWatcher : public grpc_tls_certificate_distributor::
TlsCertificatesWatcherInterface {
public:
explicit TlsChannelCertificateWatcher(
TlsChannelSecurityConnector* security_connector)
: security_connector_(security_connector) {}
void OnCertificatesChanged(
absl::optional<absl::string_view> root_certs,
absl::optional<grpc_core::PemKeyCertPairList> key_cert_pairs) override;
void OnError(grpc_error* root_cert_error,
grpc_error* identity_cert_error) override;
private:
TlsChannelSecurityConnector* security_connector_ = nullptr;
};
// Updates |client_handshaker_factory_| when the certificates that
// |certificate_watcher_| is watching get updated.
grpc_security_status UpdateHandshakerFactoryLocked();
// gRPC-provided callback executed by application, which servers to bring the
// control back to gRPC core.
@ -91,29 +126,32 @@ class TlsChannelSecurityConnector final
static void ServerAuthorizationCheckArgDestroy(
grpc_tls_server_authorization_check_arg* arg);
// A util function to refresh SSL TSI client handshaker factory with a valid
// credential.
grpc_security_status RefreshHandshakerFactory();
grpc_core::Mutex mu_;
grpc_closure* on_peer_checked_;
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options_;
grpc_tls_certificate_distributor::TlsCertificatesWatcherInterface*
certificate_watcher_ = nullptr;
grpc_closure* on_peer_checked_ = nullptr;
std::string target_name_;
std::string overridden_target_name_;
tsi_ssl_client_handshaker_factory* client_handshaker_factory_ = nullptr;
grpc_tls_server_authorization_check_arg* check_arg_;
grpc_core::RefCountedPtr<grpc_tls_key_materials_config> key_materials_config_;
grpc_tls_server_authorization_check_arg* check_arg_ = nullptr;
tsi_ssl_session_cache* ssl_session_cache_ = nullptr;
absl::optional<absl::string_view> pem_root_certs_;
absl::optional<grpc_core::PemKeyCertPairList> pem_key_cert_pair_list_;
};
// TLS server security connector.
// Server security connector using TLS as transport security protocol.
class TlsServerSecurityConnector final : public grpc_server_security_connector {
public:
// static factory method to create a TLS server security connector.
static grpc_core::RefCountedPtr<grpc_server_security_connector>
CreateTlsServerSecurityConnector(
grpc_core::RefCountedPtr<grpc_server_credentials> server_creds);
grpc_core::RefCountedPtr<grpc_server_credentials> server_creds,
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options);
explicit TlsServerSecurityConnector(
grpc_core::RefCountedPtr<grpc_server_credentials> server_creds);
TlsServerSecurityConnector(
grpc_core::RefCountedPtr<grpc_server_credentials> server_creds,
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options);
~TlsServerSecurityConnector() override;
void add_handshakers(const grpc_channel_args* args,
@ -126,58 +164,65 @@ class TlsServerSecurityConnector final : public grpc_server_security_connector {
int cmp(const grpc_security_connector* other) const override;
private:
// Initialize SSL TSI server handshaker factory.
grpc_security_status InitializeHandshakerFactory();
tsi_ssl_server_handshaker_factory* ServerHandshakerFactoryForTesting() {
grpc_core::MutexLock lock(&mu_);
return server_handshaker_factory_;
};
// A util function to create a new server handshaker factory to replace the
// existing once if exists.
grpc_security_status ReplaceHandshakerFactory();
const absl::optional<absl::string_view>& RootCertsForTesting() {
grpc_core::MutexLock lock(&mu_);
return pem_root_certs_;
}
// A util function to refresh SSL TSI server handshaker factory with a valid
// credential.
grpc_security_status RefreshHandshakerFactory();
const absl::optional<grpc_core::PemKeyCertPairList>&
KeyCertPairListForTesting() {
grpc_core::MutexLock lock(&mu_);
return pem_key_cert_pair_list_;
}
private:
// A watcher that watches certificate updates from
// grpc_tls_certificate_distributor. It will never outlive
// |security_connector_|.
class TlsServerCertificateWatcher : public grpc_tls_certificate_distributor::
TlsCertificatesWatcherInterface {
public:
explicit TlsServerCertificateWatcher(
TlsServerSecurityConnector* security_connector)
: security_connector_(security_connector) {}
void OnCertificatesChanged(
absl::optional<absl::string_view> root_certs,
absl::optional<grpc_core::PemKeyCertPairList> key_cert_pairs) override;
void OnError(grpc_error* root_cert_error,
grpc_error* identity_cert_error) override;
private:
TlsServerSecurityConnector* security_connector_ = nullptr;
};
// Updates |server_handshaker_factory_| when the certificates that
// |certificate_watcher_| is watching get updated.
grpc_security_status UpdateHandshakerFactoryLocked();
grpc_core::Mutex mu_;
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options_;
grpc_tls_certificate_distributor::TlsCertificatesWatcherInterface*
certificate_watcher_ = nullptr;
tsi_ssl_server_handshaker_factory* server_handshaker_factory_ = nullptr;
grpc_core::RefCountedPtr<grpc_tls_key_materials_config> key_materials_config_;
absl::optional<absl::string_view> pem_root_certs_;
absl::optional<grpc_core::PemKeyCertPairList> pem_key_cert_pair_list_;
};
// ---- Functions below are exposed for testing only -----------------------
/** The |TlsFetchKeyMaterials| API ensures that |key_materials_config| has a
* non-empty pem-key-cert pair list. This is done as follows:
* - if |options| is equipped with a credential reload config, then this
* methods uses credential reloading to populate |key_materials_config|, and
* afterwards it populates |reload_status| with the status of this operation.
* In particular, any data stored in |key_materials_config| is overwritten.
* - if |options| has no credential reload config, then:
* - if |key_materials_config| already has a non-empty pem-key-cert pair
* list or is called by a client, then the method returns |GRPC_STATUS_OK|.
* - if |key_materials_config| has an empty pem-key-cert pair list and is
* called by a server, then the method return an error code.
*
* The arguments are detailed below:
* - key_materials_config: a key materials config that will be populated by the
* method on success; the caller should not pass in nullptr. Any data held by
* the config will be overwritten.
* - options: the TLS credentials options whose credential reloading config
* will be used to populate |key_materials_config|.
* - is_server: true denotes that this method is called by a server, and
* false denotes that this method is called by a client.
* - status: the status of the credential reloading after the method
* returns; the caller should not pass in nullptr. **/
grpc_status_code TlsFetchKeyMaterials(
const grpc_core::RefCountedPtr<grpc_tls_key_materials_config>&
key_materials_config,
const grpc_tls_credentials_options& options, bool is_server,
grpc_ssl_certificate_config_reload_status* status);
namespace internal {
// TlsCheckHostName checks if |peer_name| matches the identity information
// contained in |peer|. This is AKA hostname check.
grpc_error* TlsCheckHostName(const char* peer_name, const tsi_peer* peer);
} // namespace internal
} // namespace grpc_core
#endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_TLS_TLS_SECURITY_CONNECTOR_H \
*/
#endif // GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_TLS_TLS_SECURITY_CONNECTOR_H

@ -295,7 +295,7 @@ std::shared_ptr<ChannelCredentials> LocalCredentials(
// Builds TLS Credentials given TLS options.
std::shared_ptr<ChannelCredentials> TlsCredentials(
const TlsCredentialsOptions& options) {
const TlsChannelCredentialsOptions& options) {
return internal::WrapChannelCredentials(
grpc_tls_credentials_create(options.c_credentials_options()));
}

@ -0,0 +1,45 @@
//
// 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/grpc_security.h>
#include <grpc/support/alloc.h>
#include <grpcpp/security/tls_certificate_provider.h>
#include "absl/container/inlined_vector.h"
namespace grpc {
namespace experimental {
StaticDataCertificateProvider::StaticDataCertificateProvider(
const std::string& root_certificate,
const std::vector<IdentityKeyCertPair>& identity_key_cert_pairs) {
GPR_ASSERT(!root_certificate.empty() || !identity_key_cert_pairs.empty());
grpc_tls_identity_pairs* pairs_core = grpc_tls_identity_pairs_create();
for (const IdentityKeyCertPair& pair : identity_key_cert_pairs) {
grpc_tls_identity_pairs_add_pair(pairs_core, pair.private_key.c_str(),
pair.certificate_chain.c_str());
}
c_provider_ = grpc_tls_certificate_provider_static_data_create(
root_certificate.c_str(), pairs_core);
GPR_ASSERT(c_provider_ != nullptr);
};
StaticDataCertificateProvider::~StaticDataCertificateProvider() {
grpc_tls_certificate_provider_release(c_provider_);
};
} // namespace experimental
} // namespace grpc

@ -16,178 +16,22 @@
*
*/
#include <grpc/grpc_security.h>
#include <grpc/support/alloc.h>
#include <grpcpp/security/tls_credentials_options.h>
#include "absl/container/inlined_vector.h"
#include "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h"
#include "src/cpp/common/tls_credentials_options_util.h"
namespace grpc {
namespace experimental {
/** TLS key materials config API implementation **/
void TlsKeyMaterialsConfig::set_pem_root_certs(
const std::string& pem_root_certs) {
pem_root_certs_ = pem_root_certs;
}
void TlsKeyMaterialsConfig::add_pem_key_cert_pair(
const PemKeyCertPair& pem_key_cert_pair) {
pem_key_cert_pair_list_.push_back(pem_key_cert_pair);
}
void TlsKeyMaterialsConfig::set_key_materials(
const std::string& pem_root_certs,
const std::vector<PemKeyCertPair>& pem_key_cert_pair_list) {
pem_key_cert_pair_list_ = pem_key_cert_pair_list;
pem_root_certs_ = pem_root_certs;
}
/** TLS credential reload arg API implementation **/
TlsCredentialReloadArg::TlsCredentialReloadArg(
grpc_tls_credential_reload_arg* arg)
: c_arg_(arg) {
if (c_arg_ != nullptr && c_arg_->context != nullptr) {
gpr_log(GPR_ERROR, "c_arg context has already been set");
}
c_arg_->context = static_cast<void*>(this);
c_arg_->destroy_context = &TlsCredentialReloadArgDestroyContext;
}
TlsCredentialReloadArg::~TlsCredentialReloadArg() {}
void* TlsCredentialReloadArg::cb_user_data() const {
return c_arg_->cb_user_data;
}
bool TlsCredentialReloadArg::is_pem_key_cert_pair_list_empty() const {
return c_arg_->key_materials_config->pem_key_cert_pair_list().empty();
}
grpc_ssl_certificate_config_reload_status TlsCredentialReloadArg::status()
const {
return c_arg_->status;
}
std::string TlsCredentialReloadArg::error_details() const {
return c_arg_->error_details->error_details();
}
void TlsCredentialReloadArg::set_cb_user_data(void* cb_user_data) {
c_arg_->cb_user_data = cb_user_data;
}
void TlsCredentialReloadArg::set_pem_root_certs(
const std::string& pem_root_certs) {
::grpc_core::UniquePtr<char> c_pem_root_certs(
gpr_strdup(pem_root_certs.c_str()));
c_arg_->key_materials_config->set_pem_root_certs(std::move(c_pem_root_certs));
}
namespace {
::grpc_core::PemKeyCertPair ConvertToCorePemKeyCertPair(
const TlsKeyMaterialsConfig::PemKeyCertPair& pem_key_cert_pair) {
grpc_ssl_pem_key_cert_pair* ssl_pair =
(grpc_ssl_pem_key_cert_pair*)gpr_malloc(
sizeof(grpc_ssl_pem_key_cert_pair));
ssl_pair->private_key = gpr_strdup(pem_key_cert_pair.private_key.c_str());
ssl_pair->cert_chain = gpr_strdup(pem_key_cert_pair.cert_chain.c_str());
return ::grpc_core::PemKeyCertPair(ssl_pair);
}
} // namespace
void TlsCredentialReloadArg::add_pem_key_cert_pair(
const TlsKeyMaterialsConfig::PemKeyCertPair& pem_key_cert_pair) {
c_arg_->key_materials_config->add_pem_key_cert_pair(
ConvertToCorePemKeyCertPair(pem_key_cert_pair));
}
void TlsCredentialReloadArg::set_key_materials(
const std::string& pem_root_certs,
std::vector<TlsKeyMaterialsConfig::PemKeyCertPair> pem_key_cert_pair_list) {
/** Initialize the |key_materials_config| field of |c_arg_|, if it has not
* already been done. **/
if (c_arg_->key_materials_config == nullptr) {
c_arg_->key_materials_config = grpc_tls_key_materials_config_create();
}
/** Convert |pem_key_cert_pair_list| to an inlined vector of ssl pairs. **/
::absl::InlinedVector<::grpc_core::PemKeyCertPair, 1>
c_pem_key_cert_pair_list;
for (const auto& key_cert_pair : pem_key_cert_pair_list) {
c_pem_key_cert_pair_list.emplace_back(
ConvertToCorePemKeyCertPair(key_cert_pair));
}
/** Populate the key materials config field of |c_arg_|. **/
c_arg_->key_materials_config->set_key_materials(pem_root_certs.c_str(),
c_pem_key_cert_pair_list);
}
void TlsCredentialReloadArg::set_key_materials_config(
const std::shared_ptr<TlsKeyMaterialsConfig>& key_materials_config) {
if (key_materials_config == nullptr) {
c_arg_->key_materials_config = nullptr;
return;
}
::absl::InlinedVector<::grpc_core::PemKeyCertPair, 1>
c_pem_key_cert_pair_list;
for (const auto& key_cert_pair :
key_materials_config->pem_key_cert_pair_list()) {
grpc_ssl_pem_key_cert_pair* ssl_pair =
(grpc_ssl_pem_key_cert_pair*)gpr_malloc(
sizeof(grpc_ssl_pem_key_cert_pair));
ssl_pair->private_key = gpr_strdup(key_cert_pair.private_key.c_str());
ssl_pair->cert_chain = gpr_strdup(key_cert_pair.cert_chain.c_str());
::grpc_core::PemKeyCertPair c_pem_key_cert_pair =
::grpc_core::PemKeyCertPair(ssl_pair);
c_pem_key_cert_pair_list.emplace_back(std::move(c_pem_key_cert_pair));
}
::grpc_core::UniquePtr<char> c_pem_root_certs(
gpr_strdup(key_materials_config->pem_root_certs().c_str()));
if (c_arg_->key_materials_config == nullptr) {
c_arg_->key_materials_config = grpc_tls_key_materials_config_create();
}
c_arg_->key_materials_config->set_key_materials(
key_materials_config->pem_root_certs().c_str(), c_pem_key_cert_pair_list);
c_arg_->key_materials_config->set_version(key_materials_config->version());
}
void TlsCredentialReloadArg::set_status(
grpc_ssl_certificate_config_reload_status status) {
c_arg_->status = status;
}
void TlsCredentialReloadArg::set_error_details(
const std::string& error_details) {
c_arg_->error_details->set_error_details(error_details.c_str());
}
void TlsCredentialReloadArg::OnCredentialReloadDoneCallback() {
if (c_arg_->cb == nullptr) {
gpr_log(GPR_ERROR, "credential reload arg callback API is nullptr");
return;
}
c_arg_->cb(c_arg_);
}
/** gRPC TLS credential reload config API implementation **/
TlsCredentialReloadConfig::TlsCredentialReloadConfig(
std::shared_ptr<TlsCredentialReloadInterface> credential_reload_interface)
: credential_reload_interface_(std::move(credential_reload_interface)) {
c_config_ = grpc_tls_credential_reload_config_create(
nullptr, &TlsCredentialReloadConfigCSchedule,
&TlsCredentialReloadConfigCCancel, nullptr);
c_config_->set_context(static_cast<void*>(this));
}
TlsCredentialReloadConfig::~TlsCredentialReloadConfig() {}
/** gRPC TLS server authorization check arg API implementation **/
TlsServerAuthorizationCheckArg::TlsServerAuthorizationCheckArg(
grpc_tls_server_authorization_check_arg* arg)
: c_arg_(arg) {
if (c_arg_ != nullptr && c_arg_->context != nullptr) {
GPR_ASSERT(c_arg_ != nullptr);
if (c_arg_->context != nullptr) {
gpr_log(GPR_ERROR, "c_arg context has already been set");
}
c_arg_->context = static_cast<void*>(this);
@ -265,7 +109,6 @@ void TlsServerAuthorizationCheckArg::OnServerAuthorizationCheckDoneCallback() {
c_arg_->cb(c_arg_);
}
/** gRPC TLS server authorization check config API implementation. **/
TlsServerAuthorizationCheckConfig::TlsServerAuthorizationCheckConfig(
std::shared_ptr<TlsServerAuthorizationCheckInterface>
server_authorization_check_interface)
@ -277,67 +120,66 @@ TlsServerAuthorizationCheckConfig::TlsServerAuthorizationCheckConfig(
c_config_->set_context(static_cast<void*>(this));
}
TlsServerAuthorizationCheckConfig::~TlsServerAuthorizationCheckConfig() {}
/** gRPC TLS credential options API implementation **/
TlsCredentialsOptions::TlsCredentialsOptions(
grpc_tls_server_verification_option server_verification_option,
std::shared_ptr<TlsKeyMaterialsConfig> key_materials_config,
std::shared_ptr<TlsCredentialReloadConfig> credential_reload_config,
std::shared_ptr<TlsServerAuthorizationCheckConfig>
server_authorization_check_config)
: TlsCredentialsOptions(
GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, server_verification_option,
std::move(key_materials_config), std::move(credential_reload_config),
std::move(server_authorization_check_config)) {}
TlsCredentialsOptions::TlsCredentialsOptions(
grpc_ssl_client_certificate_request_type cert_request_type,
std::shared_ptr<TlsKeyMaterialsConfig> key_materials_config,
std::shared_ptr<TlsCredentialReloadConfig> credential_reload_config)
: TlsCredentialsOptions(cert_request_type, GRPC_TLS_SERVER_VERIFICATION,
std::move(key_materials_config),
std::move(credential_reload_config), nullptr) {}
TlsServerAuthorizationCheckConfig::~TlsServerAuthorizationCheckConfig() {
grpc_tls_server_authorization_check_config_release(c_config_);
}
TlsCredentialsOptions::TlsCredentialsOptions(
grpc_ssl_client_certificate_request_type cert_request_type,
grpc_tls_server_verification_option server_verification_option,
std::shared_ptr<TlsKeyMaterialsConfig> key_materials_config,
std::shared_ptr<TlsCredentialReloadConfig> credential_reload_config,
std::shared_ptr<TlsServerAuthorizationCheckConfig>
server_authorization_check_config)
: cert_request_type_(cert_request_type),
server_verification_option_(server_verification_option),
key_materials_config_(std::move(key_materials_config)),
credential_reload_config_(std::move(credential_reload_config)),
server_authorization_check_config_(
std::move(server_authorization_check_config)) {
std::shared_ptr<CertificateProviderInterface> certificate_provider)
: certificate_provider_(std::move(certificate_provider)) {
c_credentials_options_ = grpc_tls_credentials_options_create();
grpc_tls_credentials_options_set_cert_request_type(c_credentials_options_,
cert_request_type_);
if (key_materials_config_ != nullptr) {
grpc_tls_credentials_options_set_key_materials_config(
c_credentials_options_,
ConvertToCKeyMaterialsConfig(key_materials_config_));
}
if (credential_reload_config_ != nullptr) {
grpc_tls_credentials_options_set_credential_reload_config(
c_credentials_options_, credential_reload_config_->c_config());
if (certificate_provider_ != nullptr) {
grpc_tls_credentials_options_set_certificate_provider(
c_credentials_options_, certificate_provider_->c_provider());
}
if (server_authorization_check_config_ != nullptr) {
}
void TlsCredentialsOptions::watch_root_certs() {
grpc_tls_credentials_options_watch_root_certs(c_credentials_options_);
}
void TlsCredentialsOptions::set_root_cert_name(
const std::string& root_cert_name) {
grpc_tls_credentials_options_set_root_cert_name(c_credentials_options_,
root_cert_name.c_str());
}
void TlsCredentialsOptions::watch_identity_key_cert_pairs() {
grpc_tls_credentials_options_watch_identity_key_cert_pairs(
c_credentials_options_);
}
void TlsCredentialsOptions::set_identity_cert_name(
const std::string& identity_cert_name) {
grpc_tls_credentials_options_set_identity_cert_name(
c_credentials_options_, identity_cert_name.c_str());
}
void TlsChannelCredentialsOptions::set_server_verification_option(
grpc_tls_server_verification_option server_verification_option) {
grpc_tls_credentials_options* options = c_credentials_options();
GPR_ASSERT(options != nullptr);
grpc_tls_credentials_options_set_server_verification_option(
options, server_verification_option);
}
void TlsChannelCredentialsOptions::set_server_authorization_check_config(
std::shared_ptr<TlsServerAuthorizationCheckConfig> config) {
grpc_tls_credentials_options* options = c_credentials_options();
GPR_ASSERT(options != nullptr);
if (config != nullptr) {
grpc_tls_credentials_options_set_server_authorization_check_config(
c_credentials_options_, server_authorization_check_config_->c_config());
options, config->c_config());
}
grpc_tls_credentials_options_set_server_verification_option(
c_credentials_options_, server_verification_option);
}
/** Whenever a TlsCredentialsOptions instance is created, the caller takes
* ownership of the c_credentials_options_ pointer (see e.g. the implementation
* of the TlsCredentials API in secure_credentials.cc). For this reason, the
* TlsCredentialsOptions destructor is not responsible for freeing
* c_credentials_options_. **/
TlsCredentialsOptions::~TlsCredentialsOptions() {}
void TlsServerCredentialsOptions::set_cert_request_type(
grpc_ssl_client_certificate_request_type cert_request_type) {
grpc_tls_credentials_options* options = c_credentials_options();
GPR_ASSERT(options != nullptr);
grpc_tls_credentials_options_set_cert_request_type(options,
cert_request_type);
}
} // namespace experimental
} // namespace grpc

@ -19,85 +19,12 @@
#include "absl/container/inlined_vector.h"
#include <grpcpp/security/tls_credentials_options.h>
#include "src/cpp/common/tls_credentials_options_util.h"
namespace grpc {
namespace experimental {
/** Converts the Cpp key materials to C key materials; this allocates memory for
* the C key materials. Note that the user must free
* the underlying pointer to private key and cert chain duplicates; they are not
* freed when the grpc_core::UniquePtr<char> member variables of PemKeyCertPair
* are unused. Similarly, the user must free the underlying pointer to
* c_pem_root_certs. **/
grpc_tls_key_materials_config* ConvertToCKeyMaterialsConfig(
const std::shared_ptr<TlsKeyMaterialsConfig>& config) {
if (config == nullptr) {
return nullptr;
}
grpc_tls_key_materials_config* c_config =
grpc_tls_key_materials_config_create();
::absl::InlinedVector<::grpc_core::PemKeyCertPair, 1>
c_pem_key_cert_pair_list;
for (const auto& key_cert_pair : config->pem_key_cert_pair_list()) {
grpc_ssl_pem_key_cert_pair* ssl_pair =
(grpc_ssl_pem_key_cert_pair*)gpr_malloc(
sizeof(grpc_ssl_pem_key_cert_pair));
ssl_pair->private_key = gpr_strdup(key_cert_pair.private_key.c_str());
ssl_pair->cert_chain = gpr_strdup(key_cert_pair.cert_chain.c_str());
::grpc_core::PemKeyCertPair c_pem_key_cert_pair =
::grpc_core::PemKeyCertPair(ssl_pair);
c_pem_key_cert_pair_list.push_back(::std::move(c_pem_key_cert_pair));
}
c_config->set_key_materials(config->pem_root_certs().c_str(),
c_pem_key_cert_pair_list);
c_config->set_version(config->version());
return c_config;
}
/** The C schedule and cancel functions for the credential reload config.
* They populate a C credential reload arg with the result of a C++ credential
* reload schedule/cancel API. **/
int TlsCredentialReloadConfigCSchedule(void* /*config_user_data*/,
grpc_tls_credential_reload_arg* arg) {
if (arg == nullptr || arg->config == nullptr ||
arg->config->context() == nullptr) {
gpr_log(GPR_ERROR, "credential reload arg was not properly initialized");
return 1;
}
TlsCredentialReloadConfig* cpp_config =
static_cast<TlsCredentialReloadConfig*>(arg->config->context());
TlsCredentialReloadArg* cpp_arg = new TlsCredentialReloadArg(arg);
int schedule_result = cpp_config->Schedule(cpp_arg);
return schedule_result;
}
void TlsCredentialReloadConfigCCancel(void* /*config_user_data*/,
grpc_tls_credential_reload_arg* arg) {
if (arg == nullptr || arg->config == nullptr ||
arg->config->context() == nullptr) {
gpr_log(GPR_ERROR, "credential reload arg was not properly initialized");
return;
}
if (arg->context == nullptr) {
gpr_log(GPR_ERROR, "credential reload arg schedule has already completed");
return;
}
TlsCredentialReloadConfig* cpp_config =
static_cast<TlsCredentialReloadConfig*>(arg->config->context());
TlsCredentialReloadArg* cpp_arg =
static_cast<TlsCredentialReloadArg*>(arg->context);
cpp_config->Cancel(cpp_arg);
}
void TlsCredentialReloadArgDestroyContext(void* context) {
if (context != nullptr) {
TlsCredentialReloadArg* cpp_arg =
static_cast<TlsCredentialReloadArg*>(context);
delete cpp_arg;
}
}
/** The C schedule and cancel functions for the server authorization check
* config. They populate a C server authorization check arg with the result
* of a C++ server authorization check schedule/cancel API. **/

@ -27,29 +27,15 @@
namespace grpc {
namespace experimental {
/** The following function is exposed for testing purposes. **/
grpc_tls_key_materials_config* ConvertToCKeyMaterialsConfig(
const std::shared_ptr<TlsKeyMaterialsConfig>& config);
/** The following 4 functions convert the user-provided schedule or cancel
/** The following 2 functions convert the user-provided schedule or cancel
* functions into C style schedule or cancel functions. These are internal
* functions, not meant to be accessed by the user. **/
int TlsCredentialReloadConfigCSchedule(void* config_user_data,
grpc_tls_credential_reload_arg* arg);
void TlsCredentialReloadConfigCCancel(void* config_user_data,
grpc_tls_credential_reload_arg* arg);
int TlsServerAuthorizationCheckConfigCSchedule(
void* config_user_data, grpc_tls_server_authorization_check_arg* arg);
void TlsServerAuthorizationCheckConfigCCancel(
void* config_user_data, grpc_tls_server_authorization_check_arg* arg);
/** The following 2 functions cleanup data created in the above C schedule
* functions. **/
void TlsCredentialReloadArgDestroyContext(void* context);
void TlsServerAuthorizationCheckArgDestroyContext(void* context);
} // namespace experimental

@ -145,8 +145,7 @@ std::shared_ptr<ServerCredentials> LocalServerCredentials(
}
std::shared_ptr<ServerCredentials> TlsServerCredentials(
const grpc::experimental::TlsCredentialsOptions& options) {
grpc::GrpcLibraryCodegen init;
const grpc::experimental::TlsServerCredentialsOptions& options) {
return std::shared_ptr<ServerCredentials>(new SecureServerCredentials(
grpc_tls_server_credentials_create(options.c_credentials_options())));
}

@ -488,6 +488,7 @@ CORE_SOURCE_FILES = [
'src/core/lib/security/credentials/plugin/plugin_credentials.cc',
'src/core/lib/security/credentials/ssl/ssl_credentials.cc',
'src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.cc',
'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/xds/xds_credentials.cc',

@ -158,18 +158,22 @@ grpc_alts_credentials_create_type grpc_alts_credentials_create_import;
grpc_alts_server_credentials_create_type grpc_alts_server_credentials_create_import;
grpc_local_credentials_create_type grpc_local_credentials_create_import;
grpc_local_server_credentials_create_type grpc_local_server_credentials_create_import;
grpc_tls_identity_pairs_create_type grpc_tls_identity_pairs_create_import;
grpc_tls_identity_pairs_add_pair_type grpc_tls_identity_pairs_add_pair_import;
grpc_tls_identity_pairs_destroy_type grpc_tls_identity_pairs_destroy_import;
grpc_tls_certificate_provider_static_data_create_type grpc_tls_certificate_provider_static_data_create_import;
grpc_tls_certificate_provider_release_type grpc_tls_certificate_provider_release_import;
grpc_tls_credentials_options_create_type grpc_tls_credentials_options_create_import;
grpc_tls_credentials_options_set_cert_request_type_type grpc_tls_credentials_options_set_cert_request_type_import;
grpc_tls_credentials_options_set_server_verification_option_type grpc_tls_credentials_options_set_server_verification_option_import;
grpc_tls_credentials_options_set_key_materials_config_type grpc_tls_credentials_options_set_key_materials_config_import;
grpc_tls_credentials_options_set_credential_reload_config_type grpc_tls_credentials_options_set_credential_reload_config_import;
grpc_tls_credentials_options_set_certificate_provider_type grpc_tls_credentials_options_set_certificate_provider_import;
grpc_tls_credentials_options_watch_root_certs_type grpc_tls_credentials_options_watch_root_certs_import;
grpc_tls_credentials_options_set_root_cert_name_type grpc_tls_credentials_options_set_root_cert_name_import;
grpc_tls_credentials_options_watch_identity_key_cert_pairs_type grpc_tls_credentials_options_watch_identity_key_cert_pairs_import;
grpc_tls_credentials_options_set_identity_cert_name_type grpc_tls_credentials_options_set_identity_cert_name_import;
grpc_tls_credentials_options_set_server_authorization_check_config_type grpc_tls_credentials_options_set_server_authorization_check_config_import;
grpc_tls_key_materials_config_create_type grpc_tls_key_materials_config_create_import;
grpc_tls_key_materials_config_set_key_materials_type grpc_tls_key_materials_config_set_key_materials_import;
grpc_tls_key_materials_config_set_version_type grpc_tls_key_materials_config_set_version_import;
grpc_tls_key_materials_config_get_version_type grpc_tls_key_materials_config_get_version_import;
grpc_tls_credential_reload_config_create_type grpc_tls_credential_reload_config_create_import;
grpc_tls_server_authorization_check_config_create_type grpc_tls_server_authorization_check_config_create_import;
grpc_tls_server_authorization_check_config_release_type grpc_tls_server_authorization_check_config_release_import;
grpc_xds_credentials_create_type grpc_xds_credentials_create_import;
grpc_raw_byte_buffer_create_type grpc_raw_byte_buffer_create_import;
grpc_raw_compressed_byte_buffer_create_type grpc_raw_compressed_byte_buffer_create_import;
@ -432,18 +436,22 @@ void grpc_rb_load_imports(HMODULE library) {
grpc_alts_server_credentials_create_import = (grpc_alts_server_credentials_create_type) GetProcAddress(library, "grpc_alts_server_credentials_create");
grpc_local_credentials_create_import = (grpc_local_credentials_create_type) GetProcAddress(library, "grpc_local_credentials_create");
grpc_local_server_credentials_create_import = (grpc_local_server_credentials_create_type) GetProcAddress(library, "grpc_local_server_credentials_create");
grpc_tls_identity_pairs_create_import = (grpc_tls_identity_pairs_create_type) GetProcAddress(library, "grpc_tls_identity_pairs_create");
grpc_tls_identity_pairs_add_pair_import = (grpc_tls_identity_pairs_add_pair_type) GetProcAddress(library, "grpc_tls_identity_pairs_add_pair");
grpc_tls_identity_pairs_destroy_import = (grpc_tls_identity_pairs_destroy_type) GetProcAddress(library, "grpc_tls_identity_pairs_destroy");
grpc_tls_certificate_provider_static_data_create_import = (grpc_tls_certificate_provider_static_data_create_type) GetProcAddress(library, "grpc_tls_certificate_provider_static_data_create");
grpc_tls_certificate_provider_release_import = (grpc_tls_certificate_provider_release_type) GetProcAddress(library, "grpc_tls_certificate_provider_release");
grpc_tls_credentials_options_create_import = (grpc_tls_credentials_options_create_type) GetProcAddress(library, "grpc_tls_credentials_options_create");
grpc_tls_credentials_options_set_cert_request_type_import = (grpc_tls_credentials_options_set_cert_request_type_type) GetProcAddress(library, "grpc_tls_credentials_options_set_cert_request_type");
grpc_tls_credentials_options_set_server_verification_option_import = (grpc_tls_credentials_options_set_server_verification_option_type) GetProcAddress(library, "grpc_tls_credentials_options_set_server_verification_option");
grpc_tls_credentials_options_set_key_materials_config_import = (grpc_tls_credentials_options_set_key_materials_config_type) GetProcAddress(library, "grpc_tls_credentials_options_set_key_materials_config");
grpc_tls_credentials_options_set_credential_reload_config_import = (grpc_tls_credentials_options_set_credential_reload_config_type) GetProcAddress(library, "grpc_tls_credentials_options_set_credential_reload_config");
grpc_tls_credentials_options_set_certificate_provider_import = (grpc_tls_credentials_options_set_certificate_provider_type) GetProcAddress(library, "grpc_tls_credentials_options_set_certificate_provider");
grpc_tls_credentials_options_watch_root_certs_import = (grpc_tls_credentials_options_watch_root_certs_type) GetProcAddress(library, "grpc_tls_credentials_options_watch_root_certs");
grpc_tls_credentials_options_set_root_cert_name_import = (grpc_tls_credentials_options_set_root_cert_name_type) GetProcAddress(library, "grpc_tls_credentials_options_set_root_cert_name");
grpc_tls_credentials_options_watch_identity_key_cert_pairs_import = (grpc_tls_credentials_options_watch_identity_key_cert_pairs_type) GetProcAddress(library, "grpc_tls_credentials_options_watch_identity_key_cert_pairs");
grpc_tls_credentials_options_set_identity_cert_name_import = (grpc_tls_credentials_options_set_identity_cert_name_type) GetProcAddress(library, "grpc_tls_credentials_options_set_identity_cert_name");
grpc_tls_credentials_options_set_server_authorization_check_config_import = (grpc_tls_credentials_options_set_server_authorization_check_config_type) GetProcAddress(library, "grpc_tls_credentials_options_set_server_authorization_check_config");
grpc_tls_key_materials_config_create_import = (grpc_tls_key_materials_config_create_type) GetProcAddress(library, "grpc_tls_key_materials_config_create");
grpc_tls_key_materials_config_set_key_materials_import = (grpc_tls_key_materials_config_set_key_materials_type) GetProcAddress(library, "grpc_tls_key_materials_config_set_key_materials");
grpc_tls_key_materials_config_set_version_import = (grpc_tls_key_materials_config_set_version_type) GetProcAddress(library, "grpc_tls_key_materials_config_set_version");
grpc_tls_key_materials_config_get_version_import = (grpc_tls_key_materials_config_get_version_type) GetProcAddress(library, "grpc_tls_key_materials_config_get_version");
grpc_tls_credential_reload_config_create_import = (grpc_tls_credential_reload_config_create_type) GetProcAddress(library, "grpc_tls_credential_reload_config_create");
grpc_tls_server_authorization_check_config_create_import = (grpc_tls_server_authorization_check_config_create_type) GetProcAddress(library, "grpc_tls_server_authorization_check_config_create");
grpc_tls_server_authorization_check_config_release_import = (grpc_tls_server_authorization_check_config_release_type) GetProcAddress(library, "grpc_tls_server_authorization_check_config_release");
grpc_xds_credentials_create_import = (grpc_xds_credentials_create_type) GetProcAddress(library, "grpc_xds_credentials_create");
grpc_raw_byte_buffer_create_import = (grpc_raw_byte_buffer_create_type) GetProcAddress(library, "grpc_raw_byte_buffer_create");
grpc_raw_compressed_byte_buffer_create_import = (grpc_raw_compressed_byte_buffer_create_type) GetProcAddress(library, "grpc_raw_compressed_byte_buffer_create");

@ -449,42 +449,54 @@ extern grpc_local_credentials_create_type grpc_local_credentials_create_import;
typedef grpc_server_credentials*(*grpc_local_server_credentials_create_type)(grpc_local_connect_type type);
extern grpc_local_server_credentials_create_type grpc_local_server_credentials_create_import;
#define grpc_local_server_credentials_create grpc_local_server_credentials_create_import
typedef grpc_tls_identity_pairs*(*grpc_tls_identity_pairs_create_type)();
extern grpc_tls_identity_pairs_create_type grpc_tls_identity_pairs_create_import;
#define grpc_tls_identity_pairs_create grpc_tls_identity_pairs_create_import
typedef void(*grpc_tls_identity_pairs_add_pair_type)(grpc_tls_identity_pairs* pairs, const char* private_key, const char* cert_chain);
extern grpc_tls_identity_pairs_add_pair_type grpc_tls_identity_pairs_add_pair_import;
#define grpc_tls_identity_pairs_add_pair grpc_tls_identity_pairs_add_pair_import
typedef void(*grpc_tls_identity_pairs_destroy_type)(grpc_tls_identity_pairs* pairs);
extern grpc_tls_identity_pairs_destroy_type grpc_tls_identity_pairs_destroy_import;
#define grpc_tls_identity_pairs_destroy grpc_tls_identity_pairs_destroy_import
typedef grpc_tls_certificate_provider*(*grpc_tls_certificate_provider_static_data_create_type)(const char* root_certificate, grpc_tls_identity_pairs* pem_key_cert_pairs);
extern grpc_tls_certificate_provider_static_data_create_type grpc_tls_certificate_provider_static_data_create_import;
#define grpc_tls_certificate_provider_static_data_create grpc_tls_certificate_provider_static_data_create_import
typedef void(*grpc_tls_certificate_provider_release_type)(grpc_tls_certificate_provider* provider);
extern grpc_tls_certificate_provider_release_type grpc_tls_certificate_provider_release_import;
#define grpc_tls_certificate_provider_release grpc_tls_certificate_provider_release_import
typedef grpc_tls_credentials_options*(*grpc_tls_credentials_options_create_type)(void);
extern grpc_tls_credentials_options_create_type grpc_tls_credentials_options_create_import;
#define grpc_tls_credentials_options_create grpc_tls_credentials_options_create_import
typedef int(*grpc_tls_credentials_options_set_cert_request_type_type)(grpc_tls_credentials_options* options, grpc_ssl_client_certificate_request_type type);
typedef void(*grpc_tls_credentials_options_set_cert_request_type_type)(grpc_tls_credentials_options* options, grpc_ssl_client_certificate_request_type type);
extern grpc_tls_credentials_options_set_cert_request_type_type grpc_tls_credentials_options_set_cert_request_type_import;
#define grpc_tls_credentials_options_set_cert_request_type grpc_tls_credentials_options_set_cert_request_type_import
typedef int(*grpc_tls_credentials_options_set_server_verification_option_type)(grpc_tls_credentials_options* options, grpc_tls_server_verification_option server_verification_option);
typedef void(*grpc_tls_credentials_options_set_server_verification_option_type)(grpc_tls_credentials_options* options, grpc_tls_server_verification_option server_verification_option);
extern grpc_tls_credentials_options_set_server_verification_option_type grpc_tls_credentials_options_set_server_verification_option_import;
#define grpc_tls_credentials_options_set_server_verification_option grpc_tls_credentials_options_set_server_verification_option_import
typedef int(*grpc_tls_credentials_options_set_key_materials_config_type)(grpc_tls_credentials_options* options, grpc_tls_key_materials_config* config);
extern grpc_tls_credentials_options_set_key_materials_config_type grpc_tls_credentials_options_set_key_materials_config_import;
#define grpc_tls_credentials_options_set_key_materials_config grpc_tls_credentials_options_set_key_materials_config_import
typedef int(*grpc_tls_credentials_options_set_credential_reload_config_type)(grpc_tls_credentials_options* options, grpc_tls_credential_reload_config* config);
extern grpc_tls_credentials_options_set_credential_reload_config_type grpc_tls_credentials_options_set_credential_reload_config_import;
#define grpc_tls_credentials_options_set_credential_reload_config grpc_tls_credentials_options_set_credential_reload_config_import
typedef int(*grpc_tls_credentials_options_set_server_authorization_check_config_type)(grpc_tls_credentials_options* options, grpc_tls_server_authorization_check_config* config);
typedef void(*grpc_tls_credentials_options_set_certificate_provider_type)(grpc_tls_credentials_options* options, grpc_tls_certificate_provider* provider);
extern grpc_tls_credentials_options_set_certificate_provider_type grpc_tls_credentials_options_set_certificate_provider_import;
#define grpc_tls_credentials_options_set_certificate_provider grpc_tls_credentials_options_set_certificate_provider_import
typedef void(*grpc_tls_credentials_options_watch_root_certs_type)(grpc_tls_credentials_options* options);
extern grpc_tls_credentials_options_watch_root_certs_type grpc_tls_credentials_options_watch_root_certs_import;
#define grpc_tls_credentials_options_watch_root_certs grpc_tls_credentials_options_watch_root_certs_import
typedef void(*grpc_tls_credentials_options_set_root_cert_name_type)(grpc_tls_credentials_options* options, const char* root_cert_name);
extern grpc_tls_credentials_options_set_root_cert_name_type grpc_tls_credentials_options_set_root_cert_name_import;
#define grpc_tls_credentials_options_set_root_cert_name grpc_tls_credentials_options_set_root_cert_name_import
typedef void(*grpc_tls_credentials_options_watch_identity_key_cert_pairs_type)(grpc_tls_credentials_options* options);
extern grpc_tls_credentials_options_watch_identity_key_cert_pairs_type grpc_tls_credentials_options_watch_identity_key_cert_pairs_import;
#define grpc_tls_credentials_options_watch_identity_key_cert_pairs grpc_tls_credentials_options_watch_identity_key_cert_pairs_import
typedef void(*grpc_tls_credentials_options_set_identity_cert_name_type)(grpc_tls_credentials_options* options, const char* identity_cert_name);
extern grpc_tls_credentials_options_set_identity_cert_name_type grpc_tls_credentials_options_set_identity_cert_name_import;
#define grpc_tls_credentials_options_set_identity_cert_name grpc_tls_credentials_options_set_identity_cert_name_import
typedef void(*grpc_tls_credentials_options_set_server_authorization_check_config_type)(grpc_tls_credentials_options* options, grpc_tls_server_authorization_check_config* config);
extern grpc_tls_credentials_options_set_server_authorization_check_config_type grpc_tls_credentials_options_set_server_authorization_check_config_import;
#define grpc_tls_credentials_options_set_server_authorization_check_config grpc_tls_credentials_options_set_server_authorization_check_config_import
typedef grpc_tls_key_materials_config*(*grpc_tls_key_materials_config_create_type)(void);
extern grpc_tls_key_materials_config_create_type grpc_tls_key_materials_config_create_import;
#define grpc_tls_key_materials_config_create grpc_tls_key_materials_config_create_import
typedef int(*grpc_tls_key_materials_config_set_key_materials_type)(grpc_tls_key_materials_config* config, const char* pem_root_certs, const grpc_ssl_pem_key_cert_pair** pem_key_cert_pairs, size_t num_key_cert_pairs);
extern grpc_tls_key_materials_config_set_key_materials_type grpc_tls_key_materials_config_set_key_materials_import;
#define grpc_tls_key_materials_config_set_key_materials grpc_tls_key_materials_config_set_key_materials_import
typedef int(*grpc_tls_key_materials_config_set_version_type)(grpc_tls_key_materials_config* config, int version);
extern grpc_tls_key_materials_config_set_version_type grpc_tls_key_materials_config_set_version_import;
#define grpc_tls_key_materials_config_set_version grpc_tls_key_materials_config_set_version_import
typedef int(*grpc_tls_key_materials_config_get_version_type)(grpc_tls_key_materials_config* config);
extern grpc_tls_key_materials_config_get_version_type grpc_tls_key_materials_config_get_version_import;
#define grpc_tls_key_materials_config_get_version grpc_tls_key_materials_config_get_version_import
typedef grpc_tls_credential_reload_config*(*grpc_tls_credential_reload_config_create_type)(const void* config_user_data, int (*schedule)(void* config_user_data, grpc_tls_credential_reload_arg* arg), void (*cancel)(void* config_user_data, grpc_tls_credential_reload_arg* arg), void (*destruct)(void* config_user_data));
extern grpc_tls_credential_reload_config_create_type grpc_tls_credential_reload_config_create_import;
#define grpc_tls_credential_reload_config_create grpc_tls_credential_reload_config_create_import
typedef grpc_tls_server_authorization_check_config*(*grpc_tls_server_authorization_check_config_create_type)(const void* config_user_data, int (*schedule)(void* config_user_data, grpc_tls_server_authorization_check_arg* arg), void (*cancel)(void* config_user_data, grpc_tls_server_authorization_check_arg* arg), void (*destruct)(void* config_user_data));
extern grpc_tls_server_authorization_check_config_create_type grpc_tls_server_authorization_check_config_create_import;
#define grpc_tls_server_authorization_check_config_create grpc_tls_server_authorization_check_config_create_import
typedef void(*grpc_tls_server_authorization_check_config_release_type)(grpc_tls_server_authorization_check_config* config);
extern grpc_tls_server_authorization_check_config_release_type grpc_tls_server_authorization_check_config_release_import;
#define grpc_tls_server_authorization_check_config_release grpc_tls_server_authorization_check_config_release_import
typedef grpc_channel_credentials*(*grpc_xds_credentials_create_type)(grpc_channel_credentials* fallback_credentials);
extern grpc_xds_credentials_create_type grpc_xds_credentials_create_import;
#define grpc_xds_credentials_create grpc_xds_credentials_create_import

@ -50,10 +50,14 @@ struct fullstack_secure_fixture_data {
for (size_t ind = 0; ind < thd_list.size(); ind++) {
thd_list[ind].Join();
}
grpc_tls_certificate_provider_release(client_provider);
grpc_tls_certificate_provider_release(server_provider);
}
std::string localaddr;
grpc_tls_version tls_version;
ThreadList thd_list;
grpc_tls_certificate_provider* client_provider = nullptr;
grpc_tls_certificate_provider* server_provider = nullptr;
};
static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack(
@ -65,9 +69,35 @@ static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack(
memset(&f, 0, sizeof(f));
ffd->localaddr = grpc_core::JoinHostPort("localhost", port);
ffd->tls_version = tls_version;
grpc_slice root_slice, cert_slice, key_slice;
GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file",
grpc_load_file(CA_CERT_PATH, 1, &root_slice)));
std::string root_cert =
std::string(grpc_core::StringViewFromSlice(root_slice));
GPR_ASSERT(GRPC_LOG_IF_ERROR(
"load_file", grpc_load_file(SERVER_CERT_PATH, 1, &cert_slice)));
std::string identity_cert =
std::string(grpc_core::StringViewFromSlice(cert_slice));
GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file",
grpc_load_file(SERVER_KEY_PATH, 1, &key_slice)));
std::string private_key =
std::string(grpc_core::StringViewFromSlice(key_slice));
grpc_tls_identity_pairs* client_pairs = grpc_tls_identity_pairs_create();
grpc_tls_identity_pairs_add_pair(client_pairs, private_key.c_str(),
identity_cert.c_str());
ffd->client_provider = grpc_tls_certificate_provider_static_data_create(
root_cert.c_str(), client_pairs);
grpc_tls_identity_pairs* server_pairs = grpc_tls_identity_pairs_create();
grpc_tls_identity_pairs_add_pair(server_pairs, private_key.c_str(),
identity_cert.c_str());
ffd->server_provider = grpc_tls_certificate_provider_static_data_create(
root_cert.c_str(), server_pairs);
f.fixture_data = ffd;
f.cq = grpc_completion_queue_create_for_next(nullptr);
f.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr);
grpc_slice_unref(root_slice);
grpc_slice_unref(cert_slice);
grpc_slice_unref(key_slice);
return f;
}
@ -151,82 +181,6 @@ static int server_authz_check_async(
return 1;
}
// Synchronous implementation of schedule field in
// grpc_tls_credential_reload_config instance that is a part of client-side
// grpc_tls_credentials_options instance.
static int client_cred_reload_sync(void* /*config_user_data*/,
grpc_tls_credential_reload_arg* arg) {
if (!arg->key_materials_config->pem_key_cert_pair_list().empty()) {
arg->status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
return 0;
}
grpc_slice ca_slice, cert_slice, key_slice;
GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file",
grpc_load_file(CA_CERT_PATH, 1, &ca_slice)));
GPR_ASSERT(GRPC_LOG_IF_ERROR(
"load_file", grpc_load_file(SERVER_CERT_PATH, 1, &cert_slice)));
GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file",
grpc_load_file(SERVER_KEY_PATH, 1, &key_slice)));
const char* ca_cert =
reinterpret_cast<const char*> GRPC_SLICE_START_PTR(ca_slice);
const char* server_cert =
reinterpret_cast<const char*> GRPC_SLICE_START_PTR(cert_slice);
const char* server_key =
reinterpret_cast<const char*> GRPC_SLICE_START_PTR(key_slice);
grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {server_key, server_cert};
if (arg->key_materials_config->pem_key_cert_pair_list().empty()) {
const auto* pem_key_cert_pair_ptr = &pem_key_cert_pair;
grpc_tls_key_materials_config_set_key_materials(
arg->key_materials_config, ca_cert, &pem_key_cert_pair_ptr, 1);
}
// new credential has been reloaded.
arg->status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW;
grpc_slice_unref(cert_slice);
grpc_slice_unref(key_slice);
grpc_slice_unref(ca_slice);
return 0;
}
// Synchronous implementation of schedule field in
// grpc_tls_credential_reload_config instance that is a part of server-side
// grpc_tls_credentials_options instance.
static int server_cred_reload_sync(void* /*config_user_data*/,
grpc_tls_credential_reload_arg* arg) {
if (!arg->key_materials_config->pem_key_cert_pair_list().empty()) {
arg->status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
return 0;
}
grpc_slice ca_slice, cert_slice, key_slice;
GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file",
grpc_load_file(CA_CERT_PATH, 1, &ca_slice)));
GPR_ASSERT(GRPC_LOG_IF_ERROR(
"load_file", grpc_load_file(SERVER_CERT_PATH, 1, &cert_slice)));
GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file",
grpc_load_file(SERVER_KEY_PATH, 1, &key_slice)));
const char* ca_cert =
reinterpret_cast<const char*> GRPC_SLICE_START_PTR(ca_slice);
const char* server_cert =
reinterpret_cast<const char*> GRPC_SLICE_START_PTR(cert_slice);
const char* server_key =
reinterpret_cast<const char*> GRPC_SLICE_START_PTR(key_slice);
grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {server_key, server_cert};
GPR_ASSERT(arg != nullptr);
GPR_ASSERT(arg->key_materials_config != nullptr);
GPR_ASSERT(arg->key_materials_config->pem_key_cert_pair_list().data() !=
nullptr);
if (arg->key_materials_config->pem_key_cert_pair_list().empty()) {
const auto* pem_key_cert_pair_ptr = &pem_key_cert_pair;
grpc_tls_key_materials_config_set_key_materials(
arg->key_materials_config, ca_cert, &pem_key_cert_pair_ptr, 1);
}
// new credential has been reloaded.
arg->status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW;
grpc_slice_unref(cert_slice);
grpc_slice_unref(key_slice);
grpc_slice_unref(ca_slice);
return 0;
}
// Create a TLS channel credential.
static grpc_channel_credentials* create_tls_channel_credentials(
fullstack_secure_fixture_data* ffd) {
@ -234,12 +188,11 @@ static grpc_channel_credentials* create_tls_channel_credentials(
options->set_server_verification_option(GRPC_TLS_SERVER_VERIFICATION);
options->set_min_tls_version(ffd->tls_version);
options->set_max_tls_version(ffd->tls_version);
/* Set credential reload config. */
grpc_tls_credential_reload_config* reload_config =
grpc_tls_credential_reload_config_create(nullptr, client_cred_reload_sync,
nullptr, nullptr);
grpc_tls_credentials_options_set_credential_reload_config(options,
reload_config);
// Set credential provider.
grpc_tls_credentials_options_set_certificate_provider(options,
ffd->client_provider);
grpc_tls_credentials_options_watch_root_certs(options);
grpc_tls_credentials_options_watch_identity_key_cert_pairs(options);
/* Set server authorization check config. */
grpc_tls_server_authorization_check_config* check_config =
grpc_tls_server_authorization_check_config_create(
@ -248,6 +201,7 @@ static grpc_channel_credentials* create_tls_channel_credentials(
options, check_config);
/* Create TLS channel credentials. */
grpc_channel_credentials* creds = grpc_tls_credentials_create(options);
grpc_tls_server_authorization_check_config_release(check_config);
return creds;
}
@ -257,12 +211,11 @@ static grpc_server_credentials* create_tls_server_credentials(
grpc_tls_credentials_options* options = grpc_tls_credentials_options_create();
options->set_min_tls_version(ffd->tls_version);
options->set_max_tls_version(ffd->tls_version);
/* Set credential reload config. */
grpc_tls_credential_reload_config* reload_config =
grpc_tls_credential_reload_config_create(nullptr, server_cred_reload_sync,
nullptr, nullptr);
grpc_tls_credentials_options_set_credential_reload_config(options,
reload_config);
// Set credential provider.
grpc_tls_credentials_options_set_certificate_provider(options,
ffd->server_provider);
grpc_tls_credentials_options_watch_root_certs(options);
grpc_tls_credentials_options_watch_identity_key_cert_pairs(options);
/* Set client certificate request type. */
grpc_tls_credentials_options_set_cert_request_type(
options, GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY);

@ -279,6 +279,10 @@ grpc_cc_test(
srcs = ["tls_security_connector_test.cc"],
data = [
"//src/core/tsi/test_creds:ca.pem",
"//src/core/tsi/test_creds:multi-domain.key",
"//src/core/tsi/test_creds:multi-domain.pem",
"//src/core/tsi/test_creds:server0.key",
"//src/core/tsi/test_creds:server0.pem",
"//src/core/tsi/test_creds:server1.key",
"//src/core/tsi/test_creds:server1.pem",
],

@ -53,8 +53,8 @@ class GrpcTlsCertificateDistributorTest : public ::testing::Test {
// Forward declaration.
class TlsCertificatesTestWatcher;
static grpc_tls_certificate_distributor::PemKeyCertPairList MakeCertKeyPairs(
const char* private_key, const char* certs) {
static grpc_core::PemKeyCertPairList MakeCertKeyPairs(const char* private_key,
const char* certs) {
if (strcmp(private_key, "") == 0 && strcmp(certs, "") == 0) {
return {};
}
@ -63,7 +63,7 @@ class GrpcTlsCertificateDistributorTest : public ::testing::Test {
gpr_malloc(sizeof(grpc_ssl_pem_key_cert_pair)));
ssl_pair->private_key = gpr_strdup(private_key);
ssl_pair->cert_chain = gpr_strdup(certs);
grpc_tls_certificate_distributor::PemKeyCertPairList pem_key_cert_pairs;
grpc_core::PemKeyCertPairList pem_key_cert_pairs;
pem_key_cert_pairs.emplace_back(ssl_pair);
return pem_key_cert_pairs;
}
@ -74,10 +74,8 @@ class GrpcTlsCertificateDistributorTest : public ::testing::Test {
// if the status updates are correct.
struct CredentialInfo {
std::string root_certs;
grpc_tls_certificate_distributor::PemKeyCertPairList key_cert_pairs;
CredentialInfo(
std::string root,
grpc_tls_certificate_distributor::PemKeyCertPairList key_cert)
grpc_core::PemKeyCertPairList key_cert_pairs;
CredentialInfo(std::string root, grpc_core::PemKeyCertPairList key_cert)
: root_certs(std::move(root)), key_cert_pairs(std::move(key_cert)) {}
bool operator==(const CredentialInfo& other) const {
return root_certs == other.root_certs &&
@ -130,13 +128,12 @@ class GrpcTlsCertificateDistributorTest : public ::testing::Test {
void OnCertificatesChanged(
absl::optional<absl::string_view> root_certs,
absl::optional<grpc_tls_certificate_distributor::PemKeyCertPairList>
key_cert_pairs) override {
absl::optional<grpc_core::PemKeyCertPairList> key_cert_pairs) override {
std::string updated_root;
if (root_certs.has_value()) {
updated_root = std::string(*root_certs);
}
grpc_tls_certificate_distributor::PemKeyCertPairList updated_identity;
grpc_core::PemKeyCertPairList updated_identity;
if (key_cert_pairs.has_value()) {
updated_identity = std::move(*key_cert_pairs);
}

@ -33,56 +33,6 @@
namespace testing {
static void SetKeyMaterials(grpc_tls_key_materials_config* config) {
grpc_slice ca_slice, cert_slice, key_slice;
GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file",
grpc_load_file(CA_CERT_PATH, 1, &ca_slice)));
GPR_ASSERT(GRPC_LOG_IF_ERROR(
"load_file", grpc_load_file(SERVER_CERT_PATH, 1, &cert_slice)));
GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file",
grpc_load_file(SERVER_KEY_PATH, 1, &key_slice)));
const char* ca_cert =
reinterpret_cast<const char*> GRPC_SLICE_START_PTR(ca_slice);
const char* server_cert =
reinterpret_cast<const char*> GRPC_SLICE_START_PTR(cert_slice);
const char* server_key =
reinterpret_cast<const char*> GRPC_SLICE_START_PTR(key_slice);
grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {server_key, server_cert};
const auto* pem_key_cert_pair_ptr = &pem_key_cert_pair;
grpc_tls_key_materials_config_set_key_materials(config, ca_cert,
&pem_key_cert_pair_ptr, 1);
grpc_slice_unref(cert_slice);
grpc_slice_unref(key_slice);
grpc_slice_unref(ca_slice);
}
TEST(GrpcTlsCredentialsOptionsTest, SetKeyMaterials) {
grpc_tls_key_materials_config* config =
grpc_tls_key_materials_config_create();
SetKeyMaterials(config);
grpc_slice ca_slice, cert_slice, key_slice;
GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file",
grpc_load_file(CA_CERT_PATH, 1, &ca_slice)));
GPR_ASSERT(GRPC_LOG_IF_ERROR(
"load_file", grpc_load_file(SERVER_CERT_PATH, 1, &cert_slice)));
GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file",
grpc_load_file(SERVER_KEY_PATH, 1, &key_slice)));
const char* ca_cert =
reinterpret_cast<const char*> GRPC_SLICE_START_PTR(ca_slice);
const char* server_cert =
reinterpret_cast<const char*> GRPC_SLICE_START_PTR(cert_slice);
const char* server_key =
reinterpret_cast<const char*> GRPC_SLICE_START_PTR(key_slice);
EXPECT_STREQ(config->pem_root_certs(), ca_cert);
EXPECT_EQ(config->pem_key_cert_pair_list().size(), 1);
EXPECT_STREQ(config->pem_key_cert_pair_list()[0].private_key(), server_key);
EXPECT_STREQ(config->pem_key_cert_pair_list()[0].cert_chain(), server_cert);
grpc_slice_unref(cert_slice);
grpc_slice_unref(key_slice);
grpc_slice_unref(ca_slice);
delete config;
}
TEST(GrpcTlsCredentialsOptionsTest, ErrorDetails) {
grpc_tls_error_details error_details;
EXPECT_STREQ(error_details.error_details().c_str(), "");

@ -27,253 +27,282 @@
#include <string.h>
#include "src/core/lib/iomgr/load_file.h"
#include "src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h"
#include "src/core/lib/security/credentials/tls/tls_credentials.h"
#include "src/core/tsi/transport_security.h"
#include "test/core/util/test_config.h"
#define CA_CERT_PATH "src/core/tsi/test_creds/ca.pem"
#define SERVER_CERT_PATH "src/core/tsi/test_creds/server1.pem"
#define SERVER_KEY_PATH "src/core/tsi/test_creds/server1.key"
namespace {
enum CredReloadResult { FAIL, SUCCESS, UNCHANGED, ASYNC };
void SetKeyMaterials(grpc_tls_key_materials_config* config) {
grpc_slice ca_slice, cert_slice, key_slice;
GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file",
grpc_load_file(CA_CERT_PATH, 1, &ca_slice)));
GPR_ASSERT(GRPC_LOG_IF_ERROR(
"load_file", grpc_load_file(SERVER_CERT_PATH, 1, &cert_slice)));
GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file",
grpc_load_file(SERVER_KEY_PATH, 1, &key_slice)));
const char* ca_cert =
reinterpret_cast<const char*> GRPC_SLICE_START_PTR(ca_slice);
const char* server_cert =
reinterpret_cast<const char*> GRPC_SLICE_START_PTR(cert_slice);
const char* server_key =
reinterpret_cast<const char*> GRPC_SLICE_START_PTR(key_slice);
grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {server_key, server_cert};
const auto* pem_key_cert_pair_ptr = &pem_key_cert_pair;
grpc_tls_key_materials_config_set_key_materials(config, ca_cert,
&pem_key_cert_pair_ptr, 1);
grpc_slice_unref(cert_slice);
grpc_slice_unref(key_slice);
grpc_slice_unref(ca_slice);
}
int CredReloadSuccess(void* /*config_user_data*/,
grpc_tls_credential_reload_arg* arg) {
SetKeyMaterials(arg->key_materials_config);
arg->status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW;
return 0;
}
int CredReloadFail(void* /*config_user_data*/,
grpc_tls_credential_reload_arg* arg) {
arg->status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL;
return 0;
}
int CredReloadUnchanged(void* /*config_user_data*/,
grpc_tls_credential_reload_arg* arg) {
arg->status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
return 0;
}
int CredReloadAsync(void* /*config_user_data*/,
grpc_tls_credential_reload_arg* /*arg*/) {
return 1;
}
} // namespace
#define CLIENT_CERT_PATH "src/core/tsi/test_creds/multi-domain.pem"
#define SERVER_CERT_PATH_0 "src/core/tsi/test_creds/server0.pem"
#define SERVER_KEY_PATH_0 "src/core/tsi/test_creds/server0.key"
#define SERVER_CERT_PATH_1 "src/core/tsi/test_creds/server1.pem"
#define SERVER_KEY_PATH_1 "src/core/tsi/test_creds/server1.key"
namespace grpc {
namespace testing {
constexpr const char* kRootCertName = "root_cert_name";
constexpr const char* kIdentityCertName = "identity_cert_name";
constexpr const char* kErrorMessage = "error_message";
constexpr const char* kTargetName = "some_target";
class TlsSecurityConnectorTest : public ::testing::Test {
protected:
TlsSecurityConnectorTest() {}
void SetUp() override {
options_ = grpc_tls_credentials_options_create()->Ref();
config_ = grpc_tls_key_materials_config_create()->Ref();
}
void TearDown() override { config_->Unref(); }
// Set credential reload config in options.
void SetOptions(CredReloadResult type) {
grpc_tls_credential_reload_config* reload_config = nullptr;
switch (type) {
case SUCCESS:
reload_config = grpc_tls_credential_reload_config_create(
nullptr, CredReloadSuccess, nullptr, nullptr);
break;
case FAIL:
reload_config = grpc_tls_credential_reload_config_create(
nullptr, CredReloadFail, nullptr, nullptr);
break;
case UNCHANGED:
reload_config = grpc_tls_credential_reload_config_create(
nullptr, CredReloadUnchanged, nullptr, nullptr);
break;
case ASYNC:
reload_config = grpc_tls_credential_reload_config_create(
nullptr, CredReloadAsync, nullptr, nullptr);
break;
default:
break;
}
grpc_tls_credentials_options_set_credential_reload_config(options_.get(),
reload_config);
grpc_slice ca_slice_1, ca_slice_0, cert_slice_1, key_slice_1, cert_slice_0,
key_slice_0;
GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file",
grpc_load_file(CA_CERT_PATH, 1, &ca_slice_1)));
GPR_ASSERT(GRPC_LOG_IF_ERROR(
"load_file", grpc_load_file(CLIENT_CERT_PATH, 1, &ca_slice_0)));
GPR_ASSERT(GRPC_LOG_IF_ERROR(
"load_file", grpc_load_file(SERVER_CERT_PATH_1, 1, &cert_slice_1)));
GPR_ASSERT(GRPC_LOG_IF_ERROR(
"load_file", grpc_load_file(SERVER_KEY_PATH_1, 1, &key_slice_1)));
GPR_ASSERT(GRPC_LOG_IF_ERROR(
"load_file", grpc_load_file(SERVER_CERT_PATH_0, 1, &cert_slice_0)));
GPR_ASSERT(GRPC_LOG_IF_ERROR(
"load_file", grpc_load_file(SERVER_KEY_PATH_0, 1, &key_slice_0)));
root_cert_1_ = std::string(grpc_core::StringViewFromSlice(ca_slice_1));
root_cert_0_ = std::string(grpc_core::StringViewFromSlice(ca_slice_0));
std::string identity_key_1 =
std::string(grpc_core::StringViewFromSlice(key_slice_1));
std::string identity_key_0 =
std::string(grpc_core::StringViewFromSlice(key_slice_0));
std::string identity_cert_1 =
std::string(grpc_core::StringViewFromSlice(cert_slice_1));
std::string identity_cert_0 =
std::string(grpc_core::StringViewFromSlice(cert_slice_0));
grpc_ssl_pem_key_cert_pair* ssl_pair_1 =
static_cast<grpc_ssl_pem_key_cert_pair*>(
gpr_malloc(sizeof(grpc_ssl_pem_key_cert_pair)));
ssl_pair_1->private_key = gpr_strdup(identity_key_1.c_str());
ssl_pair_1->cert_chain = gpr_strdup(identity_cert_1.c_str());
identity_pairs_1_.emplace_back(ssl_pair_1);
grpc_ssl_pem_key_cert_pair* ssl_pair_0 =
static_cast<grpc_ssl_pem_key_cert_pair*>(
gpr_malloc(sizeof(grpc_ssl_pem_key_cert_pair)));
ssl_pair_0->private_key = gpr_strdup(identity_key_0.c_str());
ssl_pair_0->cert_chain = gpr_strdup(identity_cert_0.c_str());
identity_pairs_0_.emplace_back(ssl_pair_0);
grpc_slice_unref(ca_slice_1);
grpc_slice_unref(ca_slice_0);
grpc_slice_unref(cert_slice_1);
grpc_slice_unref(key_slice_1);
grpc_slice_unref(cert_slice_0);
grpc_slice_unref(key_slice_0);
}
// Set key materials config.
void SetKeyMaterialsConfig() { SetKeyMaterials(config_.get()); }
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options_;
grpc_core::RefCountedPtr<grpc_tls_key_materials_config> config_;
};
TEST_F(TlsSecurityConnectorTest, NoKeysAndConfig) {
grpc_ssl_certificate_config_reload_status reload_status;
grpc_status_code status =
TlsFetchKeyMaterials(config_, *options_, true, &reload_status);
EXPECT_EQ(status, GRPC_STATUS_FAILED_PRECONDITION);
options_->Unref();
}
void TearDown() override {}
TEST_F(TlsSecurityConnectorTest, NoKeysAndConfigAsAClient) {
grpc_ssl_certificate_config_reload_status reload_status;
grpc_status_code status =
TlsFetchKeyMaterials(config_, *options_, false, &reload_status);
EXPECT_EQ(status, GRPC_STATUS_OK);
options_->Unref();
}
TEST_F(TlsSecurityConnectorTest, NoKeySuccessReload) {
grpc_ssl_certificate_config_reload_status reload_status;
SetOptions(SUCCESS);
grpc_status_code status =
TlsFetchKeyMaterials(config_, *options_, true, &reload_status);
EXPECT_EQ(status, GRPC_STATUS_OK);
EXPECT_EQ(reload_status, GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW);
options_->Unref();
}
TEST_F(TlsSecurityConnectorTest, NoKeyFailReload) {
grpc_ssl_certificate_config_reload_status reload_status;
SetOptions(FAIL);
grpc_status_code status =
TlsFetchKeyMaterials(config_, *options_, true, &reload_status);
EXPECT_EQ(status, GRPC_STATUS_INTERNAL);
EXPECT_EQ(reload_status, GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL);
options_->Unref();
}
TEST_F(TlsSecurityConnectorTest, NoKeyAsyncReload) {
grpc_ssl_certificate_config_reload_status reload_status =
GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
SetOptions(ASYNC);
grpc_status_code status =
TlsFetchKeyMaterials(config_, *options_, true, &reload_status);
EXPECT_EQ(status, GRPC_STATUS_UNIMPLEMENTED);
EXPECT_EQ(reload_status, GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED);
options_->Unref();
}
TEST_F(TlsSecurityConnectorTest, NoKeyUnchangedReload) {
grpc_ssl_certificate_config_reload_status reload_status =
GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
SetOptions(UNCHANGED);
grpc_status_code status =
TlsFetchKeyMaterials(config_, *options_, true, &reload_status);
EXPECT_EQ(status, GRPC_STATUS_OK);
EXPECT_EQ(reload_status, GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED);
options_->Unref();
}
std::string root_cert_1_;
std::string root_cert_0_;
grpc_core::PemKeyCertPairList identity_pairs_1_;
grpc_core::PemKeyCertPairList identity_pairs_0_;
};
TEST_F(TlsSecurityConnectorTest, WithKeyNoReload) {
grpc_ssl_certificate_config_reload_status reload_status =
GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
SetKeyMaterialsConfig();
grpc_status_code status =
TlsFetchKeyMaterials(config_, *options_, true, &reload_status);
EXPECT_EQ(status, GRPC_STATUS_OK);
options_->Unref();
}
class TlsTestCertificateProvider : public ::grpc_tls_certificate_provider {
public:
explicit TlsTestCertificateProvider(
grpc_core::RefCountedPtr<grpc_tls_certificate_distributor> distributor)
: distributor_(std::move(distributor)) {}
~TlsTestCertificateProvider() override {}
grpc_core::RefCountedPtr<grpc_tls_certificate_distributor> distributor()
const override {
return distributor_;
}
TEST_F(TlsSecurityConnectorTest, WithKeySuccessReload) {
grpc_ssl_certificate_config_reload_status reload_status;
SetOptions(SUCCESS);
SetKeyMaterialsConfig();
grpc_status_code status =
TlsFetchKeyMaterials(config_, *options_, true, &reload_status);
EXPECT_EQ(status, GRPC_STATUS_OK);
EXPECT_EQ(reload_status, GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW);
options_->Unref();
}
private:
grpc_core::RefCountedPtr<grpc_tls_certificate_distributor> distributor_;
};
TEST_F(TlsSecurityConnectorTest, WithKeyFailReload) {
grpc_ssl_certificate_config_reload_status reload_status;
SetOptions(FAIL);
SetKeyMaterialsConfig();
grpc_status_code status =
TlsFetchKeyMaterials(config_, *options_, true, &reload_status);
EXPECT_EQ(status, GRPC_STATUS_OK);
EXPECT_EQ(reload_status, GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL);
options_->Unref();
// Tests for ChannelSecurityConnector.
TEST_F(TlsSecurityConnectorTest,
RootAndIdentityCertsObtainedWhenCreateChannelSecurityConnector) {
grpc_core::RefCountedPtr<grpc_tls_certificate_distributor> distributor =
grpc_core::MakeRefCounted<grpc_tls_certificate_distributor>();
distributor->SetKeyMaterials(kRootCertName, root_cert_0_, absl::nullopt);
distributor->SetKeyMaterials(kIdentityCertName, absl::nullopt,
identity_pairs_0_);
grpc_core::RefCountedPtr<::grpc_tls_certificate_provider> provider =
grpc_core::MakeRefCounted<TlsTestCertificateProvider>(distributor);
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options =
grpc_core::MakeRefCounted<grpc_tls_credentials_options>();
options->set_certificate_provider(provider);
options->set_watch_root_cert(true);
options->set_watch_identity_pair(true);
options->set_root_cert_name(kRootCertName);
options->set_identity_cert_name(kIdentityCertName);
grpc_core::RefCountedPtr<TlsCredentials> credential =
grpc_core::MakeRefCounted<TlsCredentials>(options);
grpc_channel_args* new_args = nullptr;
grpc_core::RefCountedPtr<grpc_channel_security_connector> connector =
credential->create_security_connector(nullptr, kTargetName, nullptr,
&new_args);
EXPECT_NE(connector, nullptr);
grpc_core::TlsChannelSecurityConnector* tls_connector =
static_cast<grpc_core::TlsChannelSecurityConnector*>(connector.get());
EXPECT_NE(tls_connector->ClientHandshakerFactoryForTesting(), nullptr);
EXPECT_EQ(tls_connector->RootCertsForTesting(), root_cert_0_);
EXPECT_EQ(tls_connector->KeyCertPairListForTesting(), identity_pairs_0_);
distributor->SetKeyMaterials(kRootCertName, root_cert_1_, absl::nullopt);
distributor->SetKeyMaterials(kIdentityCertName, absl::nullopt,
identity_pairs_1_);
EXPECT_NE(tls_connector->ClientHandshakerFactoryForTesting(), nullptr);
EXPECT_EQ(tls_connector->RootCertsForTesting(), root_cert_1_);
EXPECT_EQ(tls_connector->KeyCertPairListForTesting(), identity_pairs_1_);
grpc_channel_args_destroy(new_args);
}
TEST_F(TlsSecurityConnectorTest, WithKeyAsyncReload) {
grpc_ssl_certificate_config_reload_status reload_status =
GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
SetOptions(ASYNC);
SetKeyMaterialsConfig();
grpc_status_code status =
TlsFetchKeyMaterials(config_, *options_, true, &reload_status);
EXPECT_EQ(status, GRPC_STATUS_OK);
EXPECT_EQ(reload_status, GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED);
options_->Unref();
// Note that on client side, we don't have tests watching identity certs only,
// because in TLS, the trust certs should always be presented. If we don't
// provide, it will try to load certs from some default system locations, and
// will hence fail on some systems.
TEST_F(TlsSecurityConnectorTest,
RootCertsObtainedWhenCreateChannelSecurityConnector) {
grpc_core::RefCountedPtr<grpc_tls_certificate_distributor> distributor =
grpc_core::MakeRefCounted<grpc_tls_certificate_distributor>();
distributor->SetKeyMaterials(kRootCertName, root_cert_0_, absl::nullopt);
distributor->SetKeyMaterials(kIdentityCertName, absl::nullopt,
identity_pairs_0_);
grpc_core::RefCountedPtr<::grpc_tls_certificate_provider> provider =
grpc_core::MakeRefCounted<TlsTestCertificateProvider>(distributor);
// Create options only watching for root certificates.
grpc_core::RefCountedPtr<grpc_tls_credentials_options> root_options =
grpc_core::MakeRefCounted<grpc_tls_credentials_options>();
root_options->set_certificate_provider(provider);
root_options->set_watch_root_cert(true);
root_options->set_root_cert_name(kRootCertName);
grpc_core::RefCountedPtr<TlsCredentials> root_credential =
grpc_core::MakeRefCounted<TlsCredentials>(root_options);
grpc_channel_args* root_new_args = nullptr;
grpc_core::RefCountedPtr<grpc_channel_security_connector> root_connector =
root_credential->create_security_connector(nullptr, "some_target",
nullptr, &root_new_args);
EXPECT_NE(root_connector, nullptr);
grpc_core::TlsChannelSecurityConnector* tls_root_connector =
static_cast<grpc_core::TlsChannelSecurityConnector*>(
root_connector.get());
EXPECT_NE(tls_root_connector->ClientHandshakerFactoryForTesting(), nullptr);
EXPECT_EQ(tls_root_connector->RootCertsForTesting(), root_cert_0_);
distributor->SetKeyMaterials(kRootCertName, root_cert_1_, absl::nullopt);
EXPECT_NE(tls_root_connector->ClientHandshakerFactoryForTesting(), nullptr);
EXPECT_EQ(tls_root_connector->RootCertsForTesting(), root_cert_1_);
grpc_channel_args_destroy(root_new_args);
}
TEST_F(TlsSecurityConnectorTest, WithKeyUnchangedReload) {
grpc_ssl_certificate_config_reload_status reload_status =
GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
SetOptions(UNCHANGED);
SetKeyMaterialsConfig();
grpc_status_code status =
TlsFetchKeyMaterials(config_, *options_, true, &reload_status);
EXPECT_EQ(status, GRPC_STATUS_OK);
EXPECT_EQ(reload_status, GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED);
options_->Unref();
TEST_F(TlsSecurityConnectorTest,
CertPartiallyObtainedWhenCreateChannelSecurityConnector) {
grpc_core::RefCountedPtr<grpc_tls_certificate_distributor> distributor =
grpc_core::MakeRefCounted<grpc_tls_certificate_distributor>();
distributor->SetKeyMaterials(kRootCertName, root_cert_0_, absl::nullopt);
grpc_core::RefCountedPtr<::grpc_tls_certificate_provider> provider =
grpc_core::MakeRefCounted<TlsTestCertificateProvider>(distributor);
// Registered the options watching both certs, but only root certs are
// available at distributor right now.
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options =
grpc_core::MakeRefCounted<grpc_tls_credentials_options>();
options->set_certificate_provider(provider);
options->set_watch_root_cert(true);
options->set_watch_identity_pair(true);
options->set_root_cert_name(kRootCertName);
options->set_identity_cert_name(kIdentityCertName);
grpc_core::RefCountedPtr<TlsCredentials> credential =
grpc_core::MakeRefCounted<TlsCredentials>(options);
grpc_channel_args* new_args = nullptr;
grpc_core::RefCountedPtr<grpc_channel_security_connector> connector =
credential->create_security_connector(nullptr, kTargetName, nullptr,
&new_args);
EXPECT_NE(connector, nullptr);
grpc_core::TlsChannelSecurityConnector* tls_connector =
static_cast<grpc_core::TlsChannelSecurityConnector*>(connector.get());
// The client_handshaker_factory_ shouldn't be updated.
EXPECT_EQ(tls_connector->ClientHandshakerFactoryForTesting(), nullptr);
EXPECT_EQ(tls_connector->RootCertsForTesting(), root_cert_0_);
// After updating the root certs, the client_handshaker_factory_ should be
// updated.
distributor->SetKeyMaterials(kIdentityCertName, absl::nullopt,
identity_pairs_0_);
EXPECT_NE(tls_connector->ClientHandshakerFactoryForTesting(), nullptr);
EXPECT_EQ(tls_connector->RootCertsForTesting(), root_cert_0_);
EXPECT_EQ(tls_connector->KeyCertPairListForTesting(), identity_pairs_0_);
grpc_channel_args_destroy(new_args);
}
TEST_F(TlsSecurityConnectorTest, CreateChannelSecurityConnectorSuccess) {
SetOptions(SUCCESS);
auto cred = std::unique_ptr<grpc_channel_credentials>(
grpc_tls_credentials_create(options_.get()));
const char* target_name = "some_target";
TEST_F(TlsSecurityConnectorTest,
DistributorHasErrorForChannelSecurityConnector) {
grpc_core::RefCountedPtr<grpc_tls_certificate_distributor> distributor =
grpc_core::MakeRefCounted<grpc_tls_certificate_distributor>();
distributor->SetKeyMaterials(kRootCertName, root_cert_0_, absl::nullopt);
distributor->SetKeyMaterials(kIdentityCertName, absl::nullopt,
identity_pairs_0_);
grpc_core::RefCountedPtr<::grpc_tls_certificate_provider> provider =
grpc_core::MakeRefCounted<TlsTestCertificateProvider>(distributor);
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options =
grpc_core::MakeRefCounted<grpc_tls_credentials_options>();
options->set_certificate_provider(provider);
options->set_watch_root_cert(true);
options->set_watch_identity_pair(true);
options->set_root_cert_name(kRootCertName);
options->set_identity_cert_name(kIdentityCertName);
grpc_core::RefCountedPtr<TlsCredentials> credential =
grpc_core::MakeRefCounted<TlsCredentials>(options);
grpc_channel_args* new_args = nullptr;
auto connector =
cred->create_security_connector(nullptr, target_name, nullptr, &new_args);
grpc_core::RefCountedPtr<grpc_channel_security_connector> connector =
credential->create_security_connector(nullptr, kTargetName, nullptr,
&new_args);
EXPECT_NE(connector, nullptr);
grpc_core::TlsChannelSecurityConnector* tls_connector =
static_cast<grpc_core::TlsChannelSecurityConnector*>(connector.get());
EXPECT_NE(tls_connector->ClientHandshakerFactoryForTesting(), nullptr);
EXPECT_EQ(tls_connector->RootCertsForTesting(), root_cert_0_);
EXPECT_EQ(tls_connector->KeyCertPairListForTesting(), identity_pairs_0_);
// Calling SetErrorForCert on distributor shouldn't invalidate the previous
// valid credentials.
distributor->SetErrorForCert(
kRootCertName, GRPC_ERROR_CREATE_FROM_STATIC_STRING(kErrorMessage),
absl::nullopt);
distributor->SetErrorForCert(
kIdentityCertName, absl::nullopt,
GRPC_ERROR_CREATE_FROM_STATIC_STRING(kErrorMessage));
EXPECT_NE(tls_connector->ClientHandshakerFactoryForTesting(), nullptr);
EXPECT_EQ(tls_connector->RootCertsForTesting(), root_cert_0_);
EXPECT_EQ(tls_connector->KeyCertPairListForTesting(), identity_pairs_0_);
grpc_channel_args_destroy(new_args);
}
TEST_F(TlsSecurityConnectorTest,
CreateChannelSecurityConnectorFailNoTargetName) {
SetOptions(SUCCESS);
auto cred = std::unique_ptr<grpc_channel_credentials>(
grpc_tls_credentials_create(options_.get()));
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options =
grpc_core::MakeRefCounted<grpc_tls_credentials_options>();
grpc_core::RefCountedPtr<TlsCredentials> credential =
grpc_core::MakeRefCounted<TlsCredentials>(options);
grpc_channel_args* new_args = nullptr;
grpc_core::RefCountedPtr<grpc_channel_security_connector> connector =
credential->create_security_connector(nullptr, nullptr, nullptr,
&new_args);
EXPECT_EQ(connector, nullptr);
}
TEST_F(TlsSecurityConnectorTest,
CreateChannelSecurityConnectorFailNoCredentials) {
auto connector =
cred->create_security_connector(nullptr, nullptr, nullptr, &new_args);
grpc_core::TlsChannelSecurityConnector::CreateTlsChannelSecurityConnector(
nullptr, grpc_core::MakeRefCounted<grpc_tls_credentials_options>(),
nullptr, kTargetName, nullptr, nullptr);
EXPECT_EQ(connector, nullptr);
}
TEST_F(TlsSecurityConnectorTest, CreateChannelSecurityConnectorFailInit) {
SetOptions(FAIL);
auto cred = std::unique_ptr<grpc_channel_credentials>(
grpc_tls_credentials_create(options_.get()));
grpc_channel_args* new_args = nullptr;
TEST_F(TlsSecurityConnectorTest, CreateChannelSecurityConnectorFailNoOptions) {
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options =
grpc_core::MakeRefCounted<grpc_tls_credentials_options>();
grpc_core::RefCountedPtr<TlsCredentials> credential =
grpc_core::MakeRefCounted<TlsCredentials>(options);
auto connector =
cred->create_security_connector(nullptr, nullptr, nullptr, &new_args);
grpc_core::TlsChannelSecurityConnector::CreateTlsChannelSecurityConnector(
credential, nullptr, nullptr, kTargetName, nullptr, nullptr);
EXPECT_EQ(connector, nullptr);
}
@ -284,11 +313,10 @@ TEST_F(TlsSecurityConnectorTest, TlsCheckHostNameSuccess) {
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, target_name,
&peer.properties[0]) == TSI_OK);
grpc_error* error = grpc_core::TlsCheckHostName(target_name, &peer);
grpc_error* error = grpc_core::internal::TlsCheckHostName(target_name, &peer);
tsi_peer_destruct(&peer);
EXPECT_EQ(error, GRPC_ERROR_NONE);
GRPC_ERROR_UNREF(error);
options_->Unref();
}
TEST_F(TlsSecurityConnectorTest, TlsCheckHostNameFail) {
@ -299,26 +327,176 @@ TEST_F(TlsSecurityConnectorTest, TlsCheckHostNameFail) {
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, another_name,
&peer.properties[0]) == TSI_OK);
grpc_error* error = grpc_core::TlsCheckHostName(target_name, &peer);
grpc_error* error = grpc_core::internal::TlsCheckHostName(target_name, &peer);
tsi_peer_destruct(&peer);
EXPECT_NE(error, GRPC_ERROR_NONE);
GRPC_ERROR_UNREF(error);
options_->Unref();
}
TEST_F(TlsSecurityConnectorTest, CreateServerSecurityConnectorSuccess) {
SetOptions(SUCCESS);
auto cred = std::unique_ptr<grpc_server_credentials>(
grpc_tls_server_credentials_create(options_.get()));
auto connector = cred->create_security_connector();
// Tests for ServerSecurityConnector.
TEST_F(TlsSecurityConnectorTest,
RootAndIdentityCertsObtainedWhenCreateServerSecurityConnector) {
grpc_core::RefCountedPtr<grpc_tls_certificate_distributor> distributor =
grpc_core::MakeRefCounted<grpc_tls_certificate_distributor>();
distributor->SetKeyMaterials(kRootCertName, root_cert_0_, absl::nullopt);
distributor->SetKeyMaterials(kIdentityCertName, absl::nullopt,
identity_pairs_0_);
grpc_core::RefCountedPtr<::grpc_tls_certificate_provider> provider =
grpc_core::MakeRefCounted<TlsTestCertificateProvider>(distributor);
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options =
grpc_core::MakeRefCounted<grpc_tls_credentials_options>();
options->set_certificate_provider(provider);
options->set_watch_root_cert(true);
options->set_watch_identity_pair(true);
options->set_root_cert_name(kRootCertName);
options->set_identity_cert_name(kIdentityCertName);
grpc_core::RefCountedPtr<TlsServerCredentials> credential =
grpc_core::MakeRefCounted<TlsServerCredentials>(options);
grpc_core::RefCountedPtr<grpc_server_security_connector> connector =
credential->create_security_connector();
EXPECT_NE(connector, nullptr);
grpc_core::TlsServerSecurityConnector* tls_connector =
static_cast<grpc_core::TlsServerSecurityConnector*>(connector.get());
EXPECT_NE(tls_connector->ServerHandshakerFactoryForTesting(), nullptr);
EXPECT_EQ(tls_connector->RootCertsForTesting(), root_cert_0_);
EXPECT_EQ(tls_connector->KeyCertPairListForTesting(), identity_pairs_0_);
distributor->SetKeyMaterials(kRootCertName, root_cert_1_, absl::nullopt);
distributor->SetKeyMaterials(kIdentityCertName, absl::nullopt,
identity_pairs_1_);
EXPECT_NE(tls_connector->ServerHandshakerFactoryForTesting(), nullptr);
EXPECT_EQ(tls_connector->RootCertsForTesting(), root_cert_1_);
EXPECT_EQ(tls_connector->KeyCertPairListForTesting(), identity_pairs_1_);
}
// Note that on server side, we don't have tests watching root certs only,
// because in TLS, the identity certs should always be presented. If we don't
// provide, it will try to load certs from some default system locations, and
// will hence fail on some systems.
TEST_F(TlsSecurityConnectorTest,
IdentityCertsObtainedWhenCreateServerSecurityConnector) {
grpc_core::RefCountedPtr<grpc_tls_certificate_distributor> distributor =
grpc_core::MakeRefCounted<grpc_tls_certificate_distributor>();
distributor->SetKeyMaterials(kRootCertName, root_cert_0_, absl::nullopt);
distributor->SetKeyMaterials(kIdentityCertName, absl::nullopt,
identity_pairs_0_);
grpc_core::RefCountedPtr<::grpc_tls_certificate_provider> provider =
grpc_core::MakeRefCounted<TlsTestCertificateProvider>(distributor);
// Create options only watching for identity certificates.
grpc_core::RefCountedPtr<grpc_tls_credentials_options> identity_options =
grpc_core::MakeRefCounted<grpc_tls_credentials_options>();
identity_options->set_certificate_provider(provider);
identity_options->set_watch_identity_pair(true);
identity_options->set_identity_cert_name(kIdentityCertName);
grpc_core::RefCountedPtr<TlsServerCredentials> identity_credential =
grpc_core::MakeRefCounted<TlsServerCredentials>(identity_options);
grpc_core::RefCountedPtr<grpc_server_security_connector> identity_connector =
identity_credential->create_security_connector();
EXPECT_NE(identity_connector, nullptr);
grpc_core::TlsServerSecurityConnector* tls_identity_connector =
static_cast<grpc_core::TlsServerSecurityConnector*>(
identity_connector.get());
EXPECT_NE(tls_identity_connector->ServerHandshakerFactoryForTesting(),
nullptr);
EXPECT_EQ(tls_identity_connector->KeyCertPairListForTesting(),
identity_pairs_0_);
distributor->SetKeyMaterials(kIdentityCertName, absl::nullopt,
identity_pairs_1_);
EXPECT_NE(tls_identity_connector->ServerHandshakerFactoryForTesting(),
nullptr);
EXPECT_EQ(tls_identity_connector->KeyCertPairListForTesting(),
identity_pairs_1_);
}
TEST_F(TlsSecurityConnectorTest,
CertPartiallyObtainedWhenCreateServerSecurityConnector) {
grpc_core::RefCountedPtr<grpc_tls_certificate_distributor> distributor =
grpc_core::MakeRefCounted<grpc_tls_certificate_distributor>();
distributor->SetKeyMaterials(kIdentityCertName, absl::nullopt,
identity_pairs_0_);
grpc_core::RefCountedPtr<::grpc_tls_certificate_provider> provider =
grpc_core::MakeRefCounted<TlsTestCertificateProvider>(distributor);
// Registered the options watching both certs, but only root certs are
// available at distributor right now.
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options =
grpc_core::MakeRefCounted<grpc_tls_credentials_options>();
options->set_certificate_provider(provider);
options->set_watch_root_cert(true);
options->set_watch_identity_pair(true);
options->set_root_cert_name(kRootCertName);
options->set_identity_cert_name(kIdentityCertName);
grpc_core::RefCountedPtr<TlsServerCredentials> credential =
grpc_core::MakeRefCounted<TlsServerCredentials>(options);
grpc_core::RefCountedPtr<grpc_server_security_connector> connector =
credential->create_security_connector();
EXPECT_NE(connector, nullptr);
grpc_core::TlsServerSecurityConnector* tls_connector =
static_cast<grpc_core::TlsServerSecurityConnector*>(connector.get());
// The server_handshaker_factory_ shouldn't be updated.
EXPECT_EQ(tls_connector->ServerHandshakerFactoryForTesting(), nullptr);
EXPECT_EQ(tls_connector->KeyCertPairListForTesting(), identity_pairs_0_);
// After updating the root certs, the server_handshaker_factory_ should be
// updated.
distributor->SetKeyMaterials(kRootCertName, root_cert_0_, absl::nullopt);
EXPECT_NE(tls_connector->ServerHandshakerFactoryForTesting(), nullptr);
EXPECT_EQ(tls_connector->RootCertsForTesting(), root_cert_0_);
EXPECT_EQ(tls_connector->KeyCertPairListForTesting(), identity_pairs_0_);
}
TEST_F(TlsSecurityConnectorTest,
DistributorHasErrorForServerSecurityConnector) {
grpc_core::RefCountedPtr<grpc_tls_certificate_distributor> distributor =
grpc_core::MakeRefCounted<grpc_tls_certificate_distributor>();
distributor->SetKeyMaterials(kRootCertName, root_cert_0_, absl::nullopt);
distributor->SetKeyMaterials(kIdentityCertName, absl::nullopt,
identity_pairs_0_);
grpc_core::RefCountedPtr<::grpc_tls_certificate_provider> provider =
grpc_core::MakeRefCounted<TlsTestCertificateProvider>(distributor);
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options =
grpc_core::MakeRefCounted<grpc_tls_credentials_options>();
options->set_certificate_provider(provider);
options->set_watch_root_cert(true);
options->set_watch_identity_pair(true);
options->set_root_cert_name(kRootCertName);
options->set_identity_cert_name(kIdentityCertName);
grpc_core::RefCountedPtr<TlsServerCredentials> credential =
grpc_core::MakeRefCounted<TlsServerCredentials>(options);
grpc_core::RefCountedPtr<grpc_server_security_connector> connector =
credential->create_security_connector();
EXPECT_NE(connector, nullptr);
grpc_core::TlsServerSecurityConnector* tls_connector =
static_cast<grpc_core::TlsServerSecurityConnector*>(connector.get());
EXPECT_NE(tls_connector->ServerHandshakerFactoryForTesting(), nullptr);
EXPECT_EQ(tls_connector->RootCertsForTesting(), root_cert_0_);
EXPECT_EQ(tls_connector->KeyCertPairListForTesting(), identity_pairs_0_);
// Calling SetErrorForCert on distributor shouldn't invalidate the previous
// valid credentials.
distributor->SetErrorForCert(
kRootCertName, GRPC_ERROR_CREATE_FROM_STATIC_STRING(kErrorMessage),
absl::nullopt);
distributor->SetErrorForCert(
kIdentityCertName, absl::nullopt,
GRPC_ERROR_CREATE_FROM_STATIC_STRING(kErrorMessage));
EXPECT_NE(tls_connector->ServerHandshakerFactoryForTesting(), nullptr);
EXPECT_EQ(tls_connector->RootCertsForTesting(), root_cert_0_);
EXPECT_EQ(tls_connector->KeyCertPairListForTesting(), identity_pairs_0_);
}
TEST_F(TlsSecurityConnectorTest,
CreateServerSecurityConnectorFailNoCredentials) {
auto connector =
grpc_core::TlsServerSecurityConnector::CreateTlsServerSecurityConnector(
nullptr, grpc_core::MakeRefCounted<grpc_tls_credentials_options>());
EXPECT_EQ(connector, nullptr);
}
TEST_F(TlsSecurityConnectorTest, CreateServerSecurityConnectorFailInit) {
SetOptions(FAIL);
auto cred = std::unique_ptr<grpc_server_credentials>(
grpc_tls_server_credentials_create(options_.get()));
auto connector = cred->create_security_connector();
TEST_F(TlsSecurityConnectorTest, CreateServerSecurityConnectorFailNoOptions) {
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options =
grpc_core::MakeRefCounted<grpc_tls_credentials_options>();
grpc_core::RefCountedPtr<TlsServerCredentials> credential =
grpc_core::MakeRefCounted<TlsServerCredentials>(options);
auto connector =
grpc_core::TlsServerSecurityConnector::CreateTlsServerSecurityConnector(
credential, nullptr);
EXPECT_EQ(connector, nullptr);
}

@ -202,18 +202,22 @@ int main(int argc, char **argv) {
printf("%lx", (unsigned long) grpc_alts_server_credentials_create);
printf("%lx", (unsigned long) grpc_local_credentials_create);
printf("%lx", (unsigned long) grpc_local_server_credentials_create);
printf("%lx", (unsigned long) grpc_tls_identity_pairs_create);
printf("%lx", (unsigned long) grpc_tls_identity_pairs_add_pair);
printf("%lx", (unsigned long) grpc_tls_identity_pairs_destroy);
printf("%lx", (unsigned long) grpc_tls_certificate_provider_static_data_create);
printf("%lx", (unsigned long) grpc_tls_certificate_provider_release);
printf("%lx", (unsigned long) grpc_tls_credentials_options_create);
printf("%lx", (unsigned long) grpc_tls_credentials_options_set_cert_request_type);
printf("%lx", (unsigned long) grpc_tls_credentials_options_set_server_verification_option);
printf("%lx", (unsigned long) grpc_tls_credentials_options_set_key_materials_config);
printf("%lx", (unsigned long) grpc_tls_credentials_options_set_credential_reload_config);
printf("%lx", (unsigned long) grpc_tls_credentials_options_set_certificate_provider);
printf("%lx", (unsigned long) grpc_tls_credentials_options_watch_root_certs);
printf("%lx", (unsigned long) grpc_tls_credentials_options_set_root_cert_name);
printf("%lx", (unsigned long) grpc_tls_credentials_options_watch_identity_key_cert_pairs);
printf("%lx", (unsigned long) grpc_tls_credentials_options_set_identity_cert_name);
printf("%lx", (unsigned long) grpc_tls_credentials_options_set_server_authorization_check_config);
printf("%lx", (unsigned long) grpc_tls_key_materials_config_create);
printf("%lx", (unsigned long) grpc_tls_key_materials_config_set_key_materials);
printf("%lx", (unsigned long) grpc_tls_key_materials_config_set_version);
printf("%lx", (unsigned long) grpc_tls_key_materials_config_get_version);
printf("%lx", (unsigned long) grpc_tls_credential_reload_config_create);
printf("%lx", (unsigned long) grpc_tls_server_authorization_check_config_create);
printf("%lx", (unsigned long) grpc_tls_server_authorization_check_config_release);
printf("%lx", (unsigned long) grpc_xds_credentials_create);
printf("%lx", (unsigned long) grpc_raw_byte_buffer_create);
printf("%lx", (unsigned long) grpc_raw_compressed_byte_buffer_create);

@ -18,6 +18,7 @@
#include <gmock/gmock.h>
#include <grpc/grpc.h>
#include <grpc/grpc_security.h>
#include <grpcpp/security/credentials.h>
#include <grpcpp/security/server_credentials.h>
#include <grpcpp/security/tls_credentials_options.h>
@ -28,45 +29,21 @@
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/tmpfile.h"
#include "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h"
#include "src/cpp/client/secure_credentials.h"
#include "src/cpp/common/tls_credentials_options_util.h"
namespace {
typedef class ::grpc::experimental::TlsKeyMaterialsConfig TlsKeyMaterialsConfig;
typedef class ::grpc::experimental::TlsCredentialReloadArg
TlsCredentialReloadArg;
typedef struct ::grpc::experimental::TlsCredentialReloadInterface
TlsCredentialReloadInterface;
typedef class ::grpc::experimental::TlsServerAuthorizationCheckArg
TlsServerAuthorizationCheckArg;
typedef struct ::grpc::experimental::TlsServerAuthorizationCheckInterface
TlsServerAuthorizationCheckInterface;
static void tls_credential_reload_callback(
grpc_tls_credential_reload_arg* arg) {
GPR_ASSERT(arg != nullptr);
arg->status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
}
constexpr const char* kRootCertName = "root_cert_name";
constexpr const char* kRootCertContents = "root_cert_contents";
constexpr const char* kIdentityCertName = "identity_cert_name";
constexpr const char* kIdentityCertPrivateKey = "identity_private_key";
constexpr const char* kIdentityCertContents = "identity_cert_contents";
class TestTlsCredentialReload : public TlsCredentialReloadInterface {
int Schedule(TlsCredentialReloadArg* arg) override {
GPR_ASSERT(arg != nullptr);
TlsKeyMaterialsConfig::PemKeyCertPair pair = {"private_key3",
"cert_chain3"};
arg->set_pem_root_certs("new_pem_root_certs");
arg->add_pem_key_cert_pair(pair);
arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW);
return 0;
}
void Cancel(TlsCredentialReloadArg* arg) override {
GPR_ASSERT(arg != nullptr);
arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL);
arg->set_error_details("cancelled");
}
};
using ::grpc::experimental::StaticDataCertificateProvider;
using ::grpc::experimental::TlsServerAuthorizationCheckArg;
using ::grpc::experimental::TlsServerAuthorizationCheckConfig;
using ::grpc::experimental::TlsServerAuthorizationCheckInterface;
static void tls_server_authorization_check_callback(
grpc_tls_server_authorization_check_arg* arg) {
@ -104,21 +81,18 @@ class TestTlsServerAuthorizationCheck
namespace grpc {
namespace testing {
namespace {
class CredentialsTest : public ::testing::Test {
protected:
};
TEST_F(CredentialsTest, InvalidGoogleRefreshToken) {
TEST(CredentialsTest, InvalidGoogleRefreshToken) {
std::shared_ptr<CallCredentials> bad1 = GoogleRefreshTokenCredentials("");
EXPECT_EQ(static_cast<CallCredentials*>(nullptr), bad1.get());
}
TEST_F(CredentialsTest, DefaultCredentials) {
TEST(CredentialsTest, DefaultCredentials) {
auto creds = GoogleDefaultCredentials();
}
TEST_F(CredentialsTest, StsCredentialsOptionsCppToCore) {
TEST(CredentialsTest, StsCredentialsOptionsCppToCore) {
grpc::experimental::StsCredentialsOptions options;
options.token_exchange_service_uri = "https://foo.com/exchange";
options.resource = "resource";
@ -143,7 +117,7 @@ TEST_F(CredentialsTest, StsCredentialsOptionsCppToCore) {
EXPECT_EQ(options.actor_token_type, core_opts.actor_token_type);
}
TEST_F(CredentialsTest, StsCredentialsOptionsJson) {
TEST(CredentialsTest, StsCredentialsOptionsJson) {
const char valid_json[] = R"(
{
"token_exchange_service_uri": "https://foo/exchange",
@ -231,7 +205,7 @@ TEST_F(CredentialsTest, StsCredentialsOptionsJson) {
::testing::HasSubstr("token_exchange_service_uri"));
}
TEST_F(CredentialsTest, StsCredentialsOptionsFromEnv) {
TEST(CredentialsTest, StsCredentialsOptionsFromEnv) {
// Unset env and check expected failure.
gpr_unsetenv("STS_CREDENTIALS");
grpc::experimental::StsCredentialsOptions options;
@ -270,173 +244,7 @@ TEST_F(CredentialsTest, StsCredentialsOptionsFromEnv) {
gpr_unsetenv("STS_CREDENTIALS");
}
typedef class ::grpc::experimental::TlsKeyMaterialsConfig TlsKeyMaterialsConfig;
TEST_F(CredentialsTest, TlsKeyMaterialsConfigCppToC) {
std::shared_ptr<TlsKeyMaterialsConfig> config(new TlsKeyMaterialsConfig());
struct TlsKeyMaterialsConfig::PemKeyCertPair pair = {"private_key",
"cert_chain"};
std::vector<TlsKeyMaterialsConfig::PemKeyCertPair> pair_list = {pair};
config->set_key_materials("pem_root_certs", pair_list);
grpc_tls_key_materials_config* c_config =
ConvertToCKeyMaterialsConfig(config);
EXPECT_STREQ("pem_root_certs", c_config->pem_root_certs());
EXPECT_EQ(1, static_cast<int>(c_config->pem_key_cert_pair_list().size()));
EXPECT_STREQ(pair.private_key.c_str(),
c_config->pem_key_cert_pair_list()[0].private_key());
EXPECT_STREQ(pair.cert_chain.c_str(),
c_config->pem_key_cert_pair_list()[0].cert_chain());
delete c_config;
}
TEST_F(CredentialsTest, TlsKeyMaterialsModifiers) {
std::shared_ptr<TlsKeyMaterialsConfig> config(new TlsKeyMaterialsConfig());
TlsKeyMaterialsConfig::PemKeyCertPair pair = {"private_key", "cert_chain"};
config->add_pem_key_cert_pair(pair);
config->set_pem_root_certs("pem_root_certs");
EXPECT_STREQ(config->pem_root_certs().c_str(), "pem_root_certs");
std::vector<TlsKeyMaterialsConfig::PemKeyCertPair> list =
config->pem_key_cert_pair_list();
EXPECT_EQ(static_cast<int>(list.size()), 1);
EXPECT_STREQ(list[0].private_key.c_str(), "private_key");
EXPECT_STREQ(list[0].cert_chain.c_str(), "cert_chain");
}
typedef class ::grpc::experimental::TlsCredentialReloadArg
TlsCredentialReloadArg;
typedef class ::grpc::experimental::TlsCredentialReloadConfig
TlsCredentialReloadConfig;
TEST_F(CredentialsTest, TlsCredentialReloadArgCallback) {
grpc_tls_credential_reload_arg* c_arg = new grpc_tls_credential_reload_arg;
c_arg->key_materials_config = grpc_tls_key_materials_config_create();
c_arg->cb = tls_credential_reload_callback;
c_arg->context = nullptr;
TlsCredentialReloadArg* arg = new TlsCredentialReloadArg(c_arg);
arg->set_pem_root_certs("pem_root_certs");
TlsKeyMaterialsConfig::PemKeyCertPair pair = {"private_key", "cert_chain"};
arg->add_pem_key_cert_pair(pair);
arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW);
arg->OnCredentialReloadDoneCallback();
EXPECT_EQ(arg->status(), GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED);
EXPECT_STREQ(c_arg->key_materials_config->pem_root_certs(), "pem_root_certs");
EXPECT_EQ(c_arg->key_materials_config->pem_key_cert_pair_list().size(), 1);
EXPECT_STREQ(
c_arg->key_materials_config->pem_key_cert_pair_list()[0].private_key(),
"private_key");
EXPECT_STREQ(
c_arg->key_materials_config->pem_key_cert_pair_list()[0].cert_chain(),
"cert_chain");
// Cleanup.
delete arg;
delete c_arg->key_materials_config;
delete c_arg;
}
TEST_F(CredentialsTest, TlsCredentialReloadConfigSchedule) {
std::shared_ptr<TestTlsCredentialReload> test_credential_reload(
new TestTlsCredentialReload());
std::shared_ptr<TlsCredentialReloadConfig> config(
new TlsCredentialReloadConfig(test_credential_reload));
grpc_tls_credential_reload_arg* c_arg = new grpc_tls_credential_reload_arg();
c_arg->error_details = new grpc_tls_error_details();
c_arg->context = nullptr;
TlsCredentialReloadArg* arg = new TlsCredentialReloadArg(c_arg);
struct TlsKeyMaterialsConfig::PemKeyCertPair pair1 = {"private_key1",
"cert_chain1"};
struct TlsKeyMaterialsConfig::PemKeyCertPair pair2 = {"private_key2",
"cert_chain2"};
std::vector<TlsKeyMaterialsConfig::PemKeyCertPair> pair_list = {pair1, pair2};
arg->set_key_materials("pem_root_certs", pair_list);
arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW);
arg->set_error_details("error_details");
int schedule_output = config->Schedule(arg);
EXPECT_EQ(schedule_output, 0);
EXPECT_STREQ(c_arg->key_materials_config->pem_root_certs(),
"new_pem_root_certs");
grpc_tls_key_materials_config::PemKeyCertPairList c_pair_list =
c_arg->key_materials_config->pem_key_cert_pair_list();
EXPECT_TRUE(!arg->is_pem_key_cert_pair_list_empty());
EXPECT_EQ(static_cast<int>(c_pair_list.size()), 3);
EXPECT_STREQ(c_pair_list[0].private_key(), "private_key1");
EXPECT_STREQ(c_pair_list[0].cert_chain(), "cert_chain1");
EXPECT_STREQ(c_pair_list[1].private_key(), "private_key2");
EXPECT_STREQ(c_pair_list[1].cert_chain(), "cert_chain2");
EXPECT_STREQ(c_pair_list[2].private_key(), "private_key3");
EXPECT_STREQ(c_pair_list[2].cert_chain(), "cert_chain3");
EXPECT_EQ(arg->status(), GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW);
EXPECT_STREQ(arg->error_details().c_str(), "error_details");
// Cleanup.
delete c_arg->key_materials_config;
if (c_arg->destroy_context != nullptr) {
c_arg->destroy_context(c_arg->context);
}
delete c_arg->error_details;
delete c_arg;
delete config->c_config();
}
TEST_F(CredentialsTest, TlsCredentialReloadConfigCppToC) {
std::shared_ptr<TestTlsCredentialReload> test_credential_reload(
new TestTlsCredentialReload());
TlsCredentialReloadConfig config(test_credential_reload);
grpc_tls_credential_reload_arg c_arg;
c_arg.error_details = new grpc_tls_error_details();
c_arg.context = nullptr;
c_arg.cb_user_data = static_cast<void*>(nullptr);
grpc_tls_key_materials_config c_key_materials;
std::string test_private_key = "private_key";
std::string test_cert_chain = "cert_chain";
grpc_ssl_pem_key_cert_pair* ssl_pair =
(grpc_ssl_pem_key_cert_pair*)gpr_malloc(
sizeof(grpc_ssl_pem_key_cert_pair));
ssl_pair->private_key = gpr_strdup(test_private_key.c_str());
ssl_pair->cert_chain = gpr_strdup(test_cert_chain.c_str());
::grpc_core::PemKeyCertPair pem_key_cert_pair =
::grpc_core::PemKeyCertPair(ssl_pair);
::absl::InlinedVector<::grpc_core::PemKeyCertPair, 1> pem_key_cert_pair_list;
pem_key_cert_pair_list.push_back(pem_key_cert_pair);
std::string test_pem_root_certs = "pem_root_certs";
c_key_materials.set_key_materials(test_pem_root_certs.c_str(),
pem_key_cert_pair_list);
c_arg.key_materials_config = &c_key_materials;
c_arg.status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
std::string test_error_details = "error_details";
c_arg.error_details->set_error_details(test_error_details.c_str());
grpc_tls_credential_reload_config* c_config = config.c_config();
c_arg.config = c_config;
int c_schedule_output = c_config->Schedule(&c_arg);
EXPECT_EQ(c_schedule_output, 0);
EXPECT_EQ(c_arg.cb_user_data, nullptr);
EXPECT_STREQ(c_arg.key_materials_config->pem_root_certs(),
"new_pem_root_certs");
::absl::InlinedVector<::grpc_core::PemKeyCertPair, 1> pair_list =
c_arg.key_materials_config->pem_key_cert_pair_list();
EXPECT_EQ(static_cast<int>(pair_list.size()), 2);
EXPECT_STREQ(pair_list[0].private_key(), "private_key");
EXPECT_STREQ(pair_list[0].cert_chain(), "cert_chain");
EXPECT_STREQ(pair_list[1].private_key(), "private_key3");
EXPECT_STREQ(pair_list[1].cert_chain(), "cert_chain3");
EXPECT_EQ(c_arg.status, GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW);
EXPECT_STREQ(c_arg.error_details->error_details().c_str(),
test_error_details.c_str());
// Cleanup.
c_arg.destroy_context(c_arg.context);
delete c_arg.error_details;
delete config.c_config();
}
typedef class ::grpc::experimental::TlsServerAuthorizationCheckArg
TlsServerAuthorizationCheckArg;
typedef class ::grpc::experimental::TlsServerAuthorizationCheckConfig
TlsServerAuthorizationCheckConfig;
TEST_F(CredentialsTest, TlsServerAuthorizationCheckArgCallback) {
TEST(CredentialsTest, TlsServerAuthorizationCheckArgCallback) {
grpc_tls_server_authorization_check_arg* c_arg =
new grpc_tls_server_authorization_check_arg;
c_arg->cb = tls_server_authorization_check_callback;
@ -472,7 +280,7 @@ TEST_F(CredentialsTest, TlsServerAuthorizationCheckArgCallback) {
delete c_arg;
}
TEST_F(CredentialsTest, TlsServerAuthorizationCheckConfigSchedule) {
TEST(CredentialsTest, TlsServerAuthorizationCheckConfigSchedule) {
std::shared_ptr<TestTlsServerAuthorizationCheck>
test_server_authorization_check(new TestTlsServerAuthorizationCheck());
TlsServerAuthorizationCheckConfig config(test_server_authorization_check);
@ -511,10 +319,9 @@ TEST_F(CredentialsTest, TlsServerAuthorizationCheckConfigSchedule) {
c_arg->destroy_context(c_arg->context);
}
delete c_arg;
delete config.c_config();
}
TEST_F(CredentialsTest, TlsServerAuthorizationCheckConfigCppToC) {
TEST(CredentialsTest, TlsServerAuthorizationCheckConfigCppToC) {
std::shared_ptr<TestTlsServerAuthorizationCheck>
test_server_authorization_check(new TestTlsServerAuthorizationCheck());
TlsServerAuthorizationCheckConfig config(test_server_authorization_check);
@ -545,174 +352,62 @@ TEST_F(CredentialsTest, TlsServerAuthorizationCheckConfigCppToC) {
delete c_arg.error_details;
gpr_free(const_cast<char*>(c_arg.target_name));
gpr_free(const_cast<char*>(c_arg.peer_cert));
delete config.c_config();
}
typedef class ::grpc::experimental::TlsCredentialsOptions TlsCredentialsOptions;
TEST_F(CredentialsTest, TlsCredentialsOptionsCppToC) {
std::shared_ptr<TlsKeyMaterialsConfig> key_materials_config(
new TlsKeyMaterialsConfig());
struct TlsKeyMaterialsConfig::PemKeyCertPair pair = {"private_key",
"cert_chain"};
std::vector<TlsKeyMaterialsConfig::PemKeyCertPair> pair_list = {pair};
key_materials_config->set_key_materials("pem_root_certs", pair_list);
std::shared_ptr<TestTlsCredentialReload> test_credential_reload(
new TestTlsCredentialReload());
std::shared_ptr<TlsCredentialReloadConfig> credential_reload_config(
new TlsCredentialReloadConfig(test_credential_reload));
std::shared_ptr<TestTlsServerAuthorizationCheck>
test_server_authorization_check(new TestTlsServerAuthorizationCheck());
std::shared_ptr<TlsServerAuthorizationCheckConfig>
server_authorization_check_config(new TlsServerAuthorizationCheckConfig(
test_server_authorization_check));
TlsCredentialsOptions options = TlsCredentialsOptions(
GRPC_TLS_SERVER_VERIFICATION, key_materials_config,
credential_reload_config, server_authorization_check_config);
grpc_tls_credentials_options* c_options = options.c_credentials_options();
EXPECT_EQ(c_options->cert_request_type(),
GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE);
EXPECT_EQ(c_options->server_verification_option(),
GRPC_TLS_SERVER_VERIFICATION);
grpc_tls_key_materials_config* c_key_materials_config =
c_options->key_materials_config();
grpc_tls_credential_reload_config* c_credential_reload_config =
c_options->credential_reload_config();
grpc_tls_credential_reload_arg c_credential_reload_arg;
c_credential_reload_arg.cb_user_data = nullptr;
c_credential_reload_arg.key_materials_config =
c_options->key_materials_config();
c_credential_reload_arg.status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
std::string test_error_details = "error_details";
c_credential_reload_arg.error_details = new grpc_tls_error_details();
c_credential_reload_arg.error_details->set_error_details(
test_error_details.c_str());
c_credential_reload_arg.context = nullptr;
grpc_tls_server_authorization_check_config*
c_server_authorization_check_config =
c_options->server_authorization_check_config();
grpc_tls_server_authorization_check_arg c_server_authorization_check_arg;
c_server_authorization_check_arg.cb = tls_server_authorization_check_callback;
c_server_authorization_check_arg.cb_user_data = nullptr;
c_server_authorization_check_arg.success = 0;
c_server_authorization_check_arg.target_name = "target_name";
c_server_authorization_check_arg.peer_cert = "peer_cert";
c_server_authorization_check_arg.status = GRPC_STATUS_UNAUTHENTICATED;
c_server_authorization_check_arg.error_details = new grpc_tls_error_details();
c_server_authorization_check_arg.error_details->set_error_details(
"error_details");
c_server_authorization_check_arg.context = nullptr;
EXPECT_STREQ(c_key_materials_config->pem_root_certs(), "pem_root_certs");
EXPECT_EQ(
static_cast<int>(c_key_materials_config->pem_key_cert_pair_list().size()),
1);
EXPECT_STREQ(
c_key_materials_config->pem_key_cert_pair_list()[0].private_key(),
"private_key");
EXPECT_STREQ(c_key_materials_config->pem_key_cert_pair_list()[0].cert_chain(),
"cert_chain");
GPR_ASSERT(c_credential_reload_config != nullptr);
int c_credential_reload_schedule_output =
c_credential_reload_config->Schedule(&c_credential_reload_arg);
EXPECT_EQ(c_credential_reload_schedule_output, 0);
EXPECT_EQ(c_credential_reload_arg.cb_user_data, nullptr);
EXPECT_STREQ(c_credential_reload_arg.key_materials_config->pem_root_certs(),
"new_pem_root_certs");
::absl::InlinedVector<::grpc_core::PemKeyCertPair, 1> c_pair_list =
c_credential_reload_arg.key_materials_config->pem_key_cert_pair_list();
EXPECT_EQ(static_cast<int>(c_pair_list.size()), 2);
EXPECT_STREQ(c_pair_list[0].private_key(), "private_key");
EXPECT_STREQ(c_pair_list[0].cert_chain(), "cert_chain");
EXPECT_STREQ(c_pair_list[1].private_key(), "private_key3");
EXPECT_STREQ(c_pair_list[1].cert_chain(), "cert_chain3");
EXPECT_EQ(c_credential_reload_arg.status,
GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW);
EXPECT_STREQ(c_credential_reload_arg.error_details->error_details().c_str(),
test_error_details.c_str());
int c_server_authorization_check_schedule_output =
c_server_authorization_check_config->Schedule(
&c_server_authorization_check_arg);
EXPECT_EQ(c_server_authorization_check_schedule_output, 1);
EXPECT_STREQ(
static_cast<char*>(c_server_authorization_check_arg.cb_user_data),
"cb_user_data");
EXPECT_EQ(c_server_authorization_check_arg.success, 1);
EXPECT_STREQ(c_server_authorization_check_arg.target_name,
"sync_target_name");
EXPECT_STREQ(c_server_authorization_check_arg.peer_cert, "sync_peer_cert");
EXPECT_EQ(c_server_authorization_check_arg.status, GRPC_STATUS_OK);
EXPECT_STREQ(
c_server_authorization_check_arg.error_details->error_details().c_str(),
"sync_error_details");
// Cleanup.
c_credential_reload_arg.destroy_context(c_credential_reload_arg.context);
delete c_credential_reload_arg.error_details;
c_server_authorization_check_arg.destroy_context(
c_server_authorization_check_arg.context);
gpr_free(c_server_authorization_check_arg.cb_user_data);
gpr_free(const_cast<char*>(c_server_authorization_check_arg.target_name));
gpr_free(const_cast<char*>(c_server_authorization_check_arg.peer_cert));
delete c_server_authorization_check_arg.error_details;
delete c_options;
}
// This test demonstrates how the TLS credentials will be used.
TEST_F(CredentialsTest, LoadTlsChannelCredentials) {
std::shared_ptr<TestTlsCredentialReload> test_credential_reload(
new TestTlsCredentialReload());
std::shared_ptr<TlsCredentialReloadConfig> credential_reload_config(
new TlsCredentialReloadConfig(test_credential_reload));
std::shared_ptr<TestTlsServerAuthorizationCheck>
test_server_authorization_check(new TestTlsServerAuthorizationCheck());
std::shared_ptr<TlsServerAuthorizationCheckConfig>
server_authorization_check_config(new TlsServerAuthorizationCheckConfig(
test_server_authorization_check));
TlsCredentialsOptions options = TlsCredentialsOptions(
GRPC_TLS_SERVER_VERIFICATION, nullptr, credential_reload_config,
TEST(
CredentialsTest,
TlsChannelCredentialsWithStaticDataCertificateProviderLoadingRootAndIdentity) {
experimental::IdentityKeyCertPair key_cert_pair;
key_cert_pair.private_key = kIdentityCertPrivateKey;
key_cert_pair.certificate_chain = kIdentityCertContents;
std::vector<experimental::IdentityKeyCertPair> identity_key_cert_pairs;
identity_key_cert_pairs.emplace_back(key_cert_pair);
auto certificate_provider = std::make_shared<StaticDataCertificateProvider>(
kRootCertContents, identity_key_cert_pairs);
auto test_server_authorization_check =
std::make_shared<TestTlsServerAuthorizationCheck>();
auto server_authorization_check_config =
std::make_shared<TlsServerAuthorizationCheckConfig>(
test_server_authorization_check);
grpc::experimental::TlsChannelCredentialsOptions options(
certificate_provider);
options.watch_root_certs();
options.set_root_cert_name(kRootCertName);
options.watch_identity_key_cert_pairs();
options.set_identity_cert_name(kIdentityCertName);
options.set_server_verification_option(GRPC_TLS_SERVER_VERIFICATION);
options.set_server_authorization_check_config(
server_authorization_check_config);
std::shared_ptr<grpc::ChannelCredentials> channel_credentials =
grpc::experimental::TlsCredentials(options);
auto channel_credentials = grpc::experimental::TlsCredentials(options);
GPR_ASSERT(channel_credentials.get() != nullptr);
}
TEST_F(CredentialsTest, TlsCredentialReloadConfigErrorMessages) {
std::shared_ptr<TlsCredentialReloadConfig> config(
new TlsCredentialReloadConfig(nullptr));
grpc_tls_credential_reload_arg* c_arg = new grpc_tls_credential_reload_arg;
c_arg->error_details = new grpc_tls_error_details();
c_arg->context = nullptr;
TlsCredentialReloadArg* arg = new TlsCredentialReloadArg(c_arg);
int schedule_output = config->Schedule(arg);
EXPECT_EQ(schedule_output, 1);
EXPECT_EQ(arg->status(), GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL);
EXPECT_STREQ(arg->error_details().c_str(),
"the interface of the credential reload config is nullptr");
arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED);
config->Cancel(arg);
EXPECT_EQ(arg->status(), GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL);
EXPECT_STREQ(arg->error_details().c_str(),
"the interface of the credential reload config is nullptr");
// Cleanup.
if (c_arg->destroy_context != nullptr) {
c_arg->destroy_context(c_arg->context);
}
delete c_arg->error_details;
delete c_arg;
delete config->c_config();
// ChannelCredentials should always have root credential presented.
// Otherwise the system root certificates will be loaded, which will cause
// failure in some tests under MacOS/Windows.
TEST(CredentialsTest,
TlsChannelCredentialsWithStaticDataCertificateProviderLoadingRootOnly) {
auto certificate_provider =
std::make_shared<StaticDataCertificateProvider>(kRootCertContents);
auto test_server_authorization_check =
std::make_shared<TestTlsServerAuthorizationCheck>();
auto server_authorization_check_config =
std::make_shared<TlsServerAuthorizationCheckConfig>(
test_server_authorization_check);
GPR_ASSERT(certificate_provider != nullptr);
GPR_ASSERT(certificate_provider->c_provider() != nullptr);
grpc::experimental::TlsChannelCredentialsOptions options(
certificate_provider);
options.watch_root_certs();
options.set_root_cert_name(kRootCertName);
options.set_server_verification_option(GRPC_TLS_SERVER_VERIFICATION);
options.set_server_authorization_check_config(
server_authorization_check_config);
auto channel_credentials = grpc::experimental::TlsCredentials(options);
GPR_ASSERT(channel_credentials.get() != nullptr);
}
TEST_F(CredentialsTest, TlsServerAuthorizationCheckConfigErrorMessages) {
TEST(CredentialsTest, TlsServerAuthorizationCheckConfigErrorMessages) {
std::shared_ptr<TlsServerAuthorizationCheckConfig> config(
new TlsServerAuthorizationCheckConfig(nullptr));
grpc_tls_server_authorization_check_arg* c_arg =
@ -742,9 +437,9 @@ TEST_F(CredentialsTest, TlsServerAuthorizationCheckConfigErrorMessages) {
c_arg->destroy_context(c_arg->context);
}
delete c_arg;
delete config->c_config();
}
} // namespace
} // namespace testing
} // namespace grpc

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

@ -0,0 +1,98 @@
//
// 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 <gmock/gmock.h>
#include <grpc/grpc.h>
#include <grpc/grpc_security.h>
#include <grpcpp/security/server_credentials.h>
#include <grpcpp/security/tls_credentials_options.h>
#include <gtest/gtest.h>
#include <memory>
#include "src/cpp/client/secure_credentials.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
namespace {
constexpr const char* kRootCertName = "root_cert_name";
constexpr const char* kRootCertContents = "root_cert_contents";
constexpr const char* kIdentityCertName = "identity_cert_name";
constexpr const char* kIdentityCertPrivateKey = "identity_private_key";
constexpr const char* kIdentityCertContents = "identity_cert_contents";
using ::grpc::experimental::StaticDataCertificateProvider;
} // namespace
namespace grpc {
namespace testing {
namespace {
TEST(
CredentialsTest,
TlsServerCredentialsWithStaticDataCertificateProviderLoadingRootAndIdentity) {
experimental::IdentityKeyCertPair key_cert_pair;
key_cert_pair.private_key = kIdentityCertPrivateKey;
key_cert_pair.certificate_chain = kIdentityCertContents;
std::vector<experimental::IdentityKeyCertPair> identity_key_cert_pairs;
identity_key_cert_pairs.emplace_back(key_cert_pair);
auto certificate_provider = std::make_shared<StaticDataCertificateProvider>(
kRootCertContents, identity_key_cert_pairs);
grpc::experimental::TlsServerCredentialsOptions options(certificate_provider);
options.watch_root_certs();
options.set_root_cert_name(kRootCertName);
options.watch_identity_key_cert_pairs();
options.set_identity_cert_name(kIdentityCertName);
options.set_cert_request_type(
GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY);
auto server_credentials = grpc::experimental::TlsServerCredentials(options);
GPR_ASSERT(server_credentials.get() != nullptr);
}
// ServerCredentials should always have identity credential presented.
// Otherwise gRPC stack will fail.
TEST(CredentialsTest,
TlsServerCredentialsWithStaticDataCertificateProviderLoadingIdentityOnly) {
experimental::IdentityKeyCertPair key_cert_pair;
key_cert_pair.private_key = kIdentityCertPrivateKey;
key_cert_pair.certificate_chain = kIdentityCertContents;
std::vector<experimental::IdentityKeyCertPair> identity_key_cert_pairs;
// Adding two key_cert_pair(s) should still work.
identity_key_cert_pairs.emplace_back(key_cert_pair);
identity_key_cert_pairs.emplace_back(key_cert_pair);
auto certificate_provider =
std::make_shared<StaticDataCertificateProvider>(identity_key_cert_pairs);
grpc::experimental::TlsServerCredentialsOptions options(certificate_provider);
options.watch_identity_key_cert_pairs();
options.set_identity_cert_name(kIdentityCertName);
options.set_cert_request_type(
GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY);
auto server_credentials = grpc::experimental::TlsServerCredentials(options);
GPR_ASSERT(server_credentials.get() != nullptr);
}
} // namespace
} // namespace testing
} // namespace grpc
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
grpc::testing::TestEnvironment env(argc, argv);
int ret = RUN_ALL_TESTS();
return ret;
}

@ -1010,6 +1010,7 @@ include/grpcpp/security/auth_context.h \
include/grpcpp/security/auth_metadata_processor.h \
include/grpcpp/security/credentials.h \
include/grpcpp/security/server_credentials.h \
include/grpcpp/security/tls_certificate_provider.h \
include/grpcpp/security/tls_credentials_options.h \
include/grpcpp/server.h \
include/grpcpp/server_builder.h \

@ -1010,6 +1010,7 @@ include/grpcpp/security/auth_context.h \
include/grpcpp/security/auth_metadata_processor.h \
include/grpcpp/security/credentials.h \
include/grpcpp/security/server_credentials.h \
include/grpcpp/security/tls_certificate_provider.h \
include/grpcpp/security/tls_credentials_options.h \
include/grpcpp/server.h \
include/grpcpp/server_builder.h \
@ -1882,7 +1883,6 @@ src/core/lib/security/authorization/evaluate_args.cc \
src/core/lib/security/authorization/evaluate_args.h \
src/core/lib/security/authorization/mock_cel/activation.h \
src/core/lib/security/authorization/mock_cel/cel_value.h \
src/core/lib/security/certificate_provider.h \
src/core/lib/security/context/security_context.cc \
src/core/lib/security/context/security_context.h \
src/core/lib/security/credentials/alts/alts_credentials.cc \
@ -1929,6 +1929,8 @@ src/core/lib/security/credentials/ssl/ssl_credentials.cc \
src/core/lib/security/credentials/ssl/ssl_credentials.h \
src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.cc \
src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.h \
src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc \
src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h \
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 \
@ -2126,6 +2128,7 @@ src/cpp/common/secure_auth_context.cc \
src/cpp/common/secure_auth_context.h \
src/cpp/common/secure_channel_arguments.cc \
src/cpp/common/secure_create_auth_context.cc \
src/cpp/common/tls_certificate_provider.cc \
src/cpp/common/tls_credentials_options.cc \
src/cpp/common/tls_credentials_options_util.cc \
src/cpp/common/tls_credentials_options_util.h \

@ -1725,7 +1725,6 @@ src/core/lib/security/authorization/evaluate_args.cc \
src/core/lib/security/authorization/evaluate_args.h \
src/core/lib/security/authorization/mock_cel/activation.h \
src/core/lib/security/authorization/mock_cel/cel_value.h \
src/core/lib/security/certificate_provider.h \
src/core/lib/security/context/security_context.cc \
src/core/lib/security/context/security_context.h \
src/core/lib/security/credentials/alts/alts_credentials.cc \
@ -1772,6 +1771,8 @@ src/core/lib/security/credentials/ssl/ssl_credentials.cc \
src/core/lib/security/credentials/ssl/ssl_credentials.h \
src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.cc \
src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.h \
src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc \
src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h \
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 \

@ -5833,6 +5833,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": "test_cpp_server_credentials_test",
"platforms": [
"linux",
"mac",
"posix",
"windows"
],
"uses_polling": true
},
{
"args": [],
"benchmark": false,

Loading…
Cancel
Save