Support Custom Post-handshake Verification in TlsCredentials (#25631)
* custom verification refactoring - post-handshake verification
This commit is contained in:
parent
9be868488f
commit
2e14f6fa70
9
BUILD
9
BUILD
|
|
@ -325,6 +325,7 @@ GRPCXX_PUBLIC_HDRS = [
|
|||
"include/grpcpp/security/server_credentials.h",
|
||||
"include/grpcpp/security/tls_certificate_provider.h",
|
||||
"include/grpcpp/security/authorization_policy_provider.h",
|
||||
"include/grpcpp/security/tls_certificate_verifier.h",
|
||||
"include/grpcpp/security/tls_credentials_options.h",
|
||||
"include/grpcpp/server.h",
|
||||
"include/grpcpp/server_builder.h",
|
||||
|
|
@ -465,7 +466,6 @@ grpc_cc_library(
|
|||
hdrs = [
|
||||
"src/cpp/client/secure_credentials.h",
|
||||
"src/cpp/common/secure_auth_context.h",
|
||||
"src/cpp/common/tls_credentials_options_util.h",
|
||||
"src/cpp/server/secure_server_credentials.h",
|
||||
],
|
||||
language = "c++",
|
||||
|
|
@ -505,18 +505,18 @@ grpc_cc_library(
|
|||
"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_certificate_verifier.cc",
|
||||
"src/cpp/common/tls_credentials_options.cc",
|
||||
"src/cpp/common/tls_credentials_options_util.cc",
|
||||
"src/cpp/server/insecure_server_credentials.cc",
|
||||
"src/cpp/server/secure_server_credentials.cc",
|
||||
],
|
||||
hdrs = [
|
||||
"src/cpp/client/secure_credentials.h",
|
||||
"src/cpp/common/secure_auth_context.h",
|
||||
"src/cpp/common/tls_credentials_options_util.h",
|
||||
"src/cpp/server/secure_server_credentials.h",
|
||||
],
|
||||
external_deps = [
|
||||
"absl/status",
|
||||
"absl/synchronization",
|
||||
"absl/container:inlined_vector",
|
||||
"absl/strings",
|
||||
|
|
@ -3199,6 +3199,7 @@ grpc_cc_library(
|
|||
"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_certificate_verifier.cc",
|
||||
"src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc",
|
||||
"src/core/lib/security/credentials/tls/tls_credentials.cc",
|
||||
"src/core/lib/security/credentials/tls/tls_utils.cc",
|
||||
|
|
@ -3249,6 +3250,7 @@ grpc_cc_library(
|
|||
"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_certificate_verifier.h",
|
||||
"src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h",
|
||||
"src/core/lib/security/credentials/tls/tls_credentials.h",
|
||||
"src/core/lib/security/credentials/tls/tls_utils.h",
|
||||
|
|
@ -3271,6 +3273,7 @@ grpc_cc_library(
|
|||
],
|
||||
external_deps = [
|
||||
"absl/container:inlined_vector",
|
||||
"absl/functional:bind_front",
|
||||
"absl/strings",
|
||||
"absl/strings:str_format",
|
||||
"absl/time",
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -822,6 +822,7 @@ if(gRPC_BUILD_TESTS)
|
|||
add_dependencies(buildtests_cxx grpc_cli)
|
||||
add_dependencies(buildtests_cxx grpc_tls_certificate_distributor_test)
|
||||
add_dependencies(buildtests_cxx grpc_tls_certificate_provider_test)
|
||||
add_dependencies(buildtests_cxx grpc_tls_certificate_verifier_test)
|
||||
add_dependencies(buildtests_cxx grpc_tls_credentials_options_test)
|
||||
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
|
||||
add_dependencies(buildtests_cxx grpc_tool_test)
|
||||
|
|
@ -952,6 +953,7 @@ if(gRPC_BUILD_TESTS)
|
|||
endif()
|
||||
add_dependencies(buildtests_cxx time_util_test)
|
||||
add_dependencies(buildtests_cxx timer_test)
|
||||
add_dependencies(buildtests_cxx tls_certificate_verifier_test)
|
||||
add_dependencies(buildtests_cxx tls_security_connector_test)
|
||||
add_dependencies(buildtests_cxx tls_test)
|
||||
add_dependencies(buildtests_cxx too_many_pings_test)
|
||||
|
|
@ -1969,6 +1971,7 @@ add_library(grpc
|
|||
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_certificate_verifier.cc
|
||||
src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc
|
||||
src/core/lib/security/credentials/tls/tls_credentials.cc
|
||||
src/core/lib/security/credentials/tls/tls_utils.cc
|
||||
|
|
@ -2818,8 +2821,8 @@ add_library(grpc++
|
|||
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_certificate_verifier.cc
|
||||
src/cpp/common/tls_credentials_options.cc
|
||||
src/cpp/common/tls_credentials_options_util.cc
|
||||
src/cpp/common/validate_service_config.cc
|
||||
src/cpp/common/version_cc.cc
|
||||
src/cpp/server/async_generic_service.cc
|
||||
|
|
@ -3045,6 +3048,7 @@ foreach(_hdr
|
|||
include/grpcpp/security/credentials.h
|
||||
include/grpcpp/security/server_credentials.h
|
||||
include/grpcpp/security/tls_certificate_provider.h
|
||||
include/grpcpp/security/tls_certificate_verifier.h
|
||||
include/grpcpp/security/tls_credentials_options.h
|
||||
include/grpcpp/server.h
|
||||
include/grpcpp/server_builder.h
|
||||
|
|
@ -3694,6 +3698,7 @@ foreach(_hdr
|
|||
include/grpcpp/security/credentials.h
|
||||
include/grpcpp/security/server_credentials.h
|
||||
include/grpcpp/security/tls_certificate_provider.h
|
||||
include/grpcpp/security/tls_certificate_verifier.h
|
||||
include/grpcpp/security/tls_credentials_options.h
|
||||
include/grpcpp/server.h
|
||||
include/grpcpp/server_builder.h
|
||||
|
|
@ -11515,6 +11520,41 @@ target_link_libraries(grpc_tls_certificate_provider_test
|
|||
)
|
||||
|
||||
|
||||
endif()
|
||||
if(gRPC_BUILD_TESTS)
|
||||
|
||||
add_executable(grpc_tls_certificate_verifier_test
|
||||
test/core/security/grpc_tls_certificate_verifier_test.cc
|
||||
third_party/googletest/googletest/src/gtest-all.cc
|
||||
third_party/googletest/googlemock/src/gmock-all.cc
|
||||
)
|
||||
|
||||
target_include_directories(grpc_tls_certificate_verifier_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_XXHASH_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(grpc_tls_certificate_verifier_test
|
||||
${_gRPC_PROTOBUF_LIBRARIES}
|
||||
${_gRPC_ALLTARGETS_LIBRARIES}
|
||||
grpc_test_util
|
||||
)
|
||||
|
||||
|
||||
endif()
|
||||
if(gRPC_BUILD_TESTS)
|
||||
|
||||
|
|
@ -15668,6 +15708,7 @@ if(gRPC_BUILD_TESTS)
|
|||
|
||||
add_executable(test_cpp_client_credentials_test
|
||||
test/cpp/client/credentials_test.cc
|
||||
test/cpp/util/tls_test_utils.cc
|
||||
third_party/googletest/googletest/src/gtest-all.cc
|
||||
third_party/googletest/googlemock/src/gmock-all.cc
|
||||
)
|
||||
|
|
@ -15704,6 +15745,7 @@ if(gRPC_BUILD_TESTS)
|
|||
|
||||
add_executable(test_cpp_server_credentials_test
|
||||
test/cpp/server/credentials_test.cc
|
||||
test/cpp/util/tls_test_utils.cc
|
||||
third_party/googletest/googletest/src/gtest-all.cc
|
||||
third_party/googletest/googlemock/src/gmock-all.cc
|
||||
)
|
||||
|
|
@ -16040,6 +16082,43 @@ target_link_libraries(timer_test
|
|||
)
|
||||
|
||||
|
||||
endif()
|
||||
if(gRPC_BUILD_TESTS)
|
||||
|
||||
add_executable(tls_certificate_verifier_test
|
||||
test/cpp/security/tls_certificate_verifier_test.cc
|
||||
test/cpp/util/tls_test_utils.cc
|
||||
third_party/googletest/googletest/src/gtest-all.cc
|
||||
third_party/googletest/googlemock/src/gmock-all.cc
|
||||
)
|
||||
|
||||
target_include_directories(tls_certificate_verifier_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_XXHASH_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(tls_certificate_verifier_test
|
||||
${_gRPC_PROTOBUF_LIBRARIES}
|
||||
${_gRPC_ALLTARGETS_LIBRARIES}
|
||||
grpc++
|
||||
grpc_test_util
|
||||
)
|
||||
|
||||
|
||||
endif()
|
||||
if(gRPC_BUILD_TESTS)
|
||||
|
||||
|
|
@ -17045,6 +17124,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
|
|||
test/cpp/end2end/test_service_impl.cc
|
||||
test/cpp/end2end/xds/xds_end2end_test.cc
|
||||
test/cpp/end2end/xds/xds_server.cc
|
||||
test/cpp/util/tls_test_utils.cc
|
||||
third_party/googletest/googletest/src/gtest-all.cc
|
||||
third_party/googletest/googlemock/src/gmock-all.cc
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1521,6 +1521,7 @@ LIBGRPC_SRC = \
|
|||
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_certificate_verifier.cc \
|
||||
src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc \
|
||||
src/core/lib/security/credentials/tls/tls_credentials.cc \
|
||||
src/core/lib/security/credentials/tls/tls_utils.cc \
|
||||
|
|
@ -2947,6 +2948,7 @@ 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_certificate_verifier.cc: $(OPENSSL_DEP)
|
||||
src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc: $(OPENSSL_DEP)
|
||||
src/core/lib/security/credentials/tls/tls_credentials.cc: $(OPENSSL_DEP)
|
||||
src/core/lib/security/credentials/tls/tls_utils.cc: $(OPENSSL_DEP)
|
||||
|
|
|
|||
|
|
@ -872,6 +872,7 @@ libs:
|
|||
- 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_certificate_verifier.h
|
||||
- src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h
|
||||
- src/core/lib/security/credentials/tls/tls_credentials.h
|
||||
- src/core/lib/security/credentials/tls/tls_utils.h
|
||||
|
|
@ -1436,6 +1437,7 @@ libs:
|
|||
- 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_certificate_verifier.cc
|
||||
- src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc
|
||||
- src/core/lib/security/credentials/tls/tls_credentials.cc
|
||||
- src/core/lib/security/credentials/tls/tls_utils.cc
|
||||
|
|
@ -2418,6 +2420,7 @@ libs:
|
|||
- include/grpcpp/security/credentials.h
|
||||
- include/grpcpp/security/server_credentials.h
|
||||
- include/grpcpp/security/tls_certificate_provider.h
|
||||
- include/grpcpp/security/tls_certificate_verifier.h
|
||||
- include/grpcpp/security/tls_credentials_options.h
|
||||
- include/grpcpp/server.h
|
||||
- include/grpcpp/server_builder.h
|
||||
|
|
@ -2471,7 +2474,6 @@ libs:
|
|||
- src/cpp/client/secure_credentials.h
|
||||
- src/cpp/common/channel_filter.h
|
||||
- src/cpp/common/secure_auth_context.h
|
||||
- src/cpp/common/tls_credentials_options_util.h
|
||||
- src/cpp/server/dynamic_thread_pool.h
|
||||
- src/cpp/server/external_connection_acceptor_impl.h
|
||||
- src/cpp/server/health/default_health_check_service.h
|
||||
|
|
@ -2521,8 +2523,8 @@ libs:
|
|||
- 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_certificate_verifier.cc
|
||||
- src/cpp/common/tls_credentials_options.cc
|
||||
- src/cpp/common/tls_credentials_options_util.cc
|
||||
- src/cpp/common/validate_service_config.cc
|
||||
- src/cpp/common/version_cc.cc
|
||||
- src/cpp/server/async_generic_service.cc
|
||||
|
|
@ -2802,6 +2804,7 @@ libs:
|
|||
- include/grpcpp/security/credentials.h
|
||||
- include/grpcpp/security/server_credentials.h
|
||||
- include/grpcpp/security/tls_certificate_provider.h
|
||||
- include/grpcpp/security/tls_certificate_verifier.h
|
||||
- include/grpcpp/security/tls_credentials_options.h
|
||||
- include/grpcpp/server.h
|
||||
- include/grpcpp/server_builder.h
|
||||
|
|
@ -6164,6 +6167,15 @@ targets:
|
|||
- test/core/security/grpc_tls_certificate_provider_test.cc
|
||||
deps:
|
||||
- grpc_test_util
|
||||
- name: grpc_tls_certificate_verifier_test
|
||||
gtest: true
|
||||
build: test
|
||||
language: c++
|
||||
headers: []
|
||||
src:
|
||||
- test/core/security/grpc_tls_certificate_verifier_test.cc
|
||||
deps:
|
||||
- grpc_test_util
|
||||
- name: grpc_tls_credentials_options_test
|
||||
gtest: true
|
||||
build: test
|
||||
|
|
@ -7925,9 +7937,11 @@ targets:
|
|||
gtest: true
|
||||
build: test
|
||||
language: c++
|
||||
headers: []
|
||||
headers:
|
||||
- test/cpp/util/tls_test_utils.h
|
||||
src:
|
||||
- test/cpp/client/credentials_test.cc
|
||||
- test/cpp/util/tls_test_utils.cc
|
||||
deps:
|
||||
- grpc++
|
||||
- grpc_test_util
|
||||
|
|
@ -7935,9 +7949,11 @@ targets:
|
|||
gtest: true
|
||||
build: test
|
||||
language: c++
|
||||
headers: []
|
||||
headers:
|
||||
- test/cpp/util/tls_test_utils.h
|
||||
src:
|
||||
- test/cpp/server/credentials_test.cc
|
||||
- test/cpp/util/tls_test_utils.cc
|
||||
deps:
|
||||
- grpc++
|
||||
- grpc_test_util
|
||||
|
|
@ -8040,6 +8056,18 @@ targets:
|
|||
deps:
|
||||
- grpc++
|
||||
- grpc_test_util
|
||||
- name: tls_certificate_verifier_test
|
||||
gtest: true
|
||||
build: test
|
||||
language: c++
|
||||
headers:
|
||||
- test/cpp/util/tls_test_utils.h
|
||||
src:
|
||||
- test/cpp/security/tls_certificate_verifier_test.cc
|
||||
- test/cpp/util/tls_test_utils.cc
|
||||
deps:
|
||||
- grpc++
|
||||
- grpc_test_util
|
||||
- name: tls_security_connector_test
|
||||
gtest: true
|
||||
build: test
|
||||
|
|
@ -8564,6 +8592,7 @@ targets:
|
|||
- test/cpp/end2end/counted_service.h
|
||||
- test/cpp/end2end/test_service_impl.h
|
||||
- test/cpp/end2end/xds/xds_server.h
|
||||
- test/cpp/util/tls_test_utils.h
|
||||
src:
|
||||
- src/proto/grpc/testing/duplicate/echo_duplicate.proto
|
||||
- src/proto/grpc/testing/echo.proto
|
||||
|
|
@ -8603,6 +8632,7 @@ targets:
|
|||
- test/cpp/end2end/test_service_impl.cc
|
||||
- test/cpp/end2end/xds/xds_end2end_test.cc
|
||||
- test/cpp/end2end/xds/xds_server.cc
|
||||
- test/cpp/util/tls_test_utils.cc
|
||||
deps:
|
||||
- grpc++_test_config
|
||||
- grpc++_test_util
|
||||
|
|
|
|||
|
|
@ -574,6 +574,7 @@ if test "$PHP_GRPC" != "no"; then
|
|||
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_certificate_verifier.cc \
|
||||
src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc \
|
||||
src/core/lib/security/credentials/tls/tls_credentials.cc \
|
||||
src/core/lib/security/credentials/tls/tls_utils.cc \
|
||||
|
|
|
|||
|
|
@ -540,6 +540,7 @@ if (PHP_GRPC != "no") {
|
|||
"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_certificate_verifier.cc " +
|
||||
"src\\core\\lib\\security\\credentials\\tls\\grpc_tls_credentials_options.cc " +
|
||||
"src\\core\\lib\\security\\credentials\\tls\\tls_credentials.cc " +
|
||||
"src\\core\\lib\\security\\credentials\\tls\\tls_utils.cc " +
|
||||
|
|
|
|||
|
|
@ -159,6 +159,7 @@ Pod::Spec.new do |s|
|
|||
'include/grpcpp/security/credentials.h',
|
||||
'include/grpcpp/security/server_credentials.h',
|
||||
'include/grpcpp/security/tls_certificate_provider.h',
|
||||
'include/grpcpp/security/tls_certificate_verifier.h',
|
||||
'include/grpcpp/security/tls_credentials_options.h',
|
||||
'include/grpcpp/server.h',
|
||||
'include/grpcpp/server_builder.h',
|
||||
|
|
@ -731,6 +732,7 @@ Pod::Spec.new do |s|
|
|||
'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_certificate_verifier.h',
|
||||
'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h',
|
||||
'src/core/lib/security/credentials/tls/tls_credentials.h',
|
||||
'src/core/lib/security/credentials/tls/tls_utils.h',
|
||||
|
|
@ -845,9 +847,8 @@ Pod::Spec.new do |s|
|
|||
'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_certificate_verifier.cc',
|
||||
'src/cpp/common/tls_credentials_options.cc',
|
||||
'src/cpp/common/tls_credentials_options_util.cc',
|
||||
'src/cpp/common/tls_credentials_options_util.h',
|
||||
'src/cpp/common/validate_service_config.cc',
|
||||
'src/cpp/common/version_cc.cc',
|
||||
'src/cpp/server/async_generic_service.cc',
|
||||
|
|
@ -1424,6 +1425,7 @@ Pod::Spec.new do |s|
|
|||
'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_certificate_verifier.h',
|
||||
'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h',
|
||||
'src/core/lib/security/credentials/tls/tls_credentials.h',
|
||||
'src/core/lib/security/credentials/tls/tls_utils.h',
|
||||
|
|
@ -1514,7 +1516,6 @@ Pod::Spec.new do |s|
|
|||
'src/cpp/client/secure_credentials.h',
|
||||
'src/cpp/common/channel_filter.h',
|
||||
'src/cpp/common/secure_auth_context.h',
|
||||
'src/cpp/common/tls_credentials_options_util.h',
|
||||
'src/cpp/server/dynamic_thread_pool.h',
|
||||
'src/cpp/server/external_connection_acceptor_impl.h',
|
||||
'src/cpp/server/health/default_health_check_service.h',
|
||||
|
|
|
|||
|
|
@ -1204,6 +1204,8 @@ Pod::Spec.new do |s|
|
|||
'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_certificate_verifier.cc',
|
||||
'src/core/lib/security/credentials/tls/grpc_tls_certificate_verifier.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',
|
||||
|
|
@ -1941,6 +1943,7 @@ Pod::Spec.new do |s|
|
|||
'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_certificate_verifier.h',
|
||||
'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h',
|
||||
'src/core/lib/security/credentials/tls/tls_credentials.h',
|
||||
'src/core/lib/security/credentials/tls/tls_utils.h',
|
||||
|
|
|
|||
|
|
@ -149,16 +149,14 @@ EXPORTS
|
|||
grpc_tls_certificate_provider_file_watcher_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_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_server_authorization_check_config_create
|
||||
grpc_tls_server_authorization_check_config_release
|
||||
grpc_tls_credentials_options_set_cert_request_type
|
||||
grpc_tls_credentials_options_set_verify_server_cert
|
||||
grpc_tls_credentials_options_set_check_call_host
|
||||
grpc_xds_credentials_create
|
||||
grpc_xds_server_credentials_create
|
||||
grpc_authorization_policy_provider_static_data_create
|
||||
|
|
|
|||
|
|
@ -1124,6 +1124,8 @@ Gem::Specification.new do |s|
|
|||
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_certificate_verifier.cc )
|
||||
s.files += %w( src/core/lib/security/credentials/tls/grpc_tls_certificate_verifier.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 )
|
||||
|
|
|
|||
|
|
@ -962,6 +962,7 @@
|
|||
'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_certificate_verifier.cc',
|
||||
'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc',
|
||||
'src/core/lib/security/credentials/tls/tls_credentials.cc',
|
||||
'src/core/lib/security/credentials/tls/tls_utils.cc',
|
||||
|
|
@ -1501,8 +1502,8 @@
|
|||
'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_certificate_verifier.cc',
|
||||
'src/cpp/common/tls_credentials_options.cc',
|
||||
'src/cpp/common/tls_credentials_options_util.cc',
|
||||
'src/cpp/common/validate_service_config.cc',
|
||||
'src/cpp/common/version_cc.cc',
|
||||
'src/cpp/server/async_generic_service.cc',
|
||||
|
|
|
|||
|
|
@ -747,61 +747,62 @@ GRPCAPI grpc_server_credentials* grpc_local_server_credentials_create(
|
|||
/** --- TLS channel/server credentials ---
|
||||
* It is used for experimental purpose for now and subject to change. */
|
||||
|
||||
/** Struct for indicating errors. It is used for
|
||||
* experimental purpose for now and subject to change. */
|
||||
typedef struct grpc_tls_error_details grpc_tls_error_details;
|
||||
|
||||
/** 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;
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL API - 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.
|
||||
* behaviors.
|
||||
*/
|
||||
typedef struct grpc_tls_credentials_options grpc_tls_credentials_options;
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL API - 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.
|
||||
* handshake.
|
||||
*/
|
||||
typedef struct grpc_tls_certificate_provider grpc_tls_certificate_provider;
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL API - Subject to change
|
||||
*
|
||||
* 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.
|
||||
* to show local identity.
|
||||
*/
|
||||
typedef struct grpc_tls_identity_pairs grpc_tls_identity_pairs;
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL API - Subject to change
|
||||
*
|
||||
* 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.
|
||||
* data, including identity private key and identity certificate chain.
|
||||
*/
|
||||
GRPCAPI grpc_tls_identity_pairs* grpc_tls_identity_pairs_create();
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL API - Subject to change
|
||||
*
|
||||
* 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.
|
||||
* |private_key| and |cert_chain|.
|
||||
*/
|
||||
GRPCAPI void grpc_tls_identity_pairs_add_pair(grpc_tls_identity_pairs* pairs,
|
||||
const char* private_key,
|
||||
const char* cert_chain);
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL API - Subject to change
|
||||
*
|
||||
* 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.
|
||||
* grpc_tls_identity_pairs object is responsible for its destruction.
|
||||
*/
|
||||
GRPCAPI void grpc_tls_identity_pairs_destroy(grpc_tls_identity_pairs* pairs);
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL API - Subject to change
|
||||
*
|
||||
* 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.
|
||||
|
|
@ -809,13 +810,14 @@ GRPCAPI void grpc_tls_identity_pairs_destroy(grpc_tls_identity_pairs* pairs);
|
|||
* 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);
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL API - Subject to change
|
||||
*
|
||||
* Creates a grpc_tls_certificate_provider that will watch the credential
|
||||
* changes on the file system. This provider will always return the up-to-date
|
||||
* cert data for all the cert names callers set through
|
||||
|
|
@ -833,7 +835,6 @@ grpc_tls_certificate_provider_static_data_create(
|
|||
* - refresh_interval_sec is the refreshing interval that we will check the
|
||||
* files for updates.
|
||||
* It does not take ownership of parameters.
|
||||
* It is used for experimental purpose for now and subject to change.
|
||||
*/
|
||||
GRPCAPI grpc_tls_certificate_provider*
|
||||
grpc_tls_certificate_provider_file_watcher_create(
|
||||
|
|
@ -841,49 +842,34 @@ grpc_tls_certificate_provider_file_watcher_create(
|
|||
const char* root_cert_path, unsigned int refresh_interval_sec);
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL API - Subject to change
|
||||
*
|
||||
* 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.
|
||||
* grpc_tls_certificate_provider object is responsible for its release.
|
||||
*/
|
||||
GRPCAPI void grpc_tls_certificate_provider_release(
|
||||
grpc_tls_certificate_provider* provider);
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL API - Subject to change
|
||||
*
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Sets the options of whether to request and verify client certs. This should
|
||||
* be called only on the server side. 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);
|
||||
|
||||
/**
|
||||
* 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 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);
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL API - Subject to change
|
||||
*
|
||||
* Sets the credential provider in the options.
|
||||
* The |options| will implicitly take a new ref to the |provider|.
|
||||
* 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_certificate_provider* provider);
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL API - Subject to change
|
||||
*
|
||||
* If set, gRPC stack will keep watching the root certificates with
|
||||
* name |root_cert_name|.
|
||||
* If this is not set on the client side, we will use the root certificates
|
||||
|
|
@ -892,151 +878,296 @@ GRPCAPI void grpc_tls_credentials_options_set_certificate_provider(
|
|||
* If this is not set on the server side, we will not watch any root certificate
|
||||
* updates, and assume no root certificates needed for the server(single-side
|
||||
* TLS). Default root certs on the server side is not supported.
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL API - 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 void grpc_tls_credentials_options_set_root_cert_name(
|
||||
grpc_tls_credentials_options* options, const char* root_cert_name);
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL API - Subject to change
|
||||
*
|
||||
* If set, gRPC stack will keep watching the identity key-cert pairs
|
||||
* with name |identity_cert_name|.
|
||||
* This is required on the server side, and optional on the client side.
|
||||
* It is used for experimental purpose for now and subject to change.
|
||||
*/
|
||||
GRPCAPI void grpc_tls_credentials_options_watch_identity_key_cert_pairs(
|
||||
grpc_tls_credentials_options* options);
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL API - 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.
|
||||
* name.
|
||||
*/
|
||||
GRPCAPI void grpc_tls_credentials_options_set_identity_cert_name(
|
||||
grpc_tls_credentials_options* options, const char* identity_cert_name);
|
||||
|
||||
/**
|
||||
* 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 is used for experimental purpose for now and subject to change.
|
||||
* EXPERIMENTAL API - Subject to change
|
||||
*
|
||||
* Sets the options of whether to request and/or verify client certs. This shall
|
||||
* only be called on the server side.
|
||||
*/
|
||||
GRPCAPI void grpc_tls_credentials_options_set_server_authorization_check_config(
|
||||
GRPCAPI void grpc_tls_credentials_options_set_cert_request_type(
|
||||
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. */
|
||||
|
||||
typedef struct grpc_tls_server_authorization_check_arg
|
||||
grpc_tls_server_authorization_check_arg;
|
||||
|
||||
/** callback function provided by gRPC used to handle the result of server
|
||||
authorization check. 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_server_authorization_check_done_cb)(
|
||||
grpc_tls_server_authorization_check_arg* arg);
|
||||
|
||||
/** A struct containing all information necessary to schedule/cancel a server
|
||||
authorization check request.
|
||||
- cb and cb_user_data represent a gRPC-provided callback and an argument
|
||||
passed to it.
|
||||
- success will store the result of server authorization check. That is,
|
||||
if success returns a non-zero value, it means the authorization check
|
||||
passes and if returning zero, it means the check fails.
|
||||
- target_name is the name of an endpoint the channel is connecting to.
|
||||
- peer_cert represents a complete certificate chain including both
|
||||
signing and leaf certificates.
|
||||
- \a subject_alternative_names is an array of size
|
||||
\a subject_alternative_names_size consisting of pointers to strings.
|
||||
- status and error_details contain information
|
||||
about errors occurred when a server authorization check request is
|
||||
scheduled/cancelled.
|
||||
- config is a pointer to the unique
|
||||
grpc_tls_server_authorization_check_config instance that this argument
|
||||
corresponds to.
|
||||
- context is a pointer to a wrapped language implementation of this
|
||||
grpc_tls_server_authorization_check_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 purpose for now and subject to change.
|
||||
*/
|
||||
struct grpc_tls_server_authorization_check_arg {
|
||||
grpc_tls_on_server_authorization_check_done_cb cb;
|
||||
void* cb_user_data;
|
||||
int success;
|
||||
const char* target_name;
|
||||
const char* peer_cert;
|
||||
const char* peer_cert_full_chain;
|
||||
char** subject_alternative_names;
|
||||
size_t subject_alternative_names_size;
|
||||
grpc_status_code status;
|
||||
grpc_tls_error_details* error_details;
|
||||
grpc_tls_server_authorization_check_config* config;
|
||||
void* context;
|
||||
void (*destroy_context)(void* ctx);
|
||||
};
|
||||
|
||||
/** Create a grpc_tls_server_authorization_check_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
|
||||
server authorization check 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->result,
|
||||
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
|
||||
server authorization check request scheduled via an asynchronous schedule
|
||||
API. arg is used to pinpoint an exact check 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_server_authorization_check_config*
|
||||
grpc_tls_server_authorization_check_config_create(
|
||||
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));
|
||||
grpc_ssl_client_certificate_request_type type);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* EXPERIMENTAL API - Subject to change
|
||||
*
|
||||
* Sets the options of whether to verify server certs on the client side.
|
||||
* Passing in a non-zero value indicates verifying the certs.
|
||||
*/
|
||||
GRPCAPI void grpc_tls_server_authorization_check_config_release(
|
||||
grpc_tls_server_authorization_check_config* config);
|
||||
GRPCAPI void grpc_tls_credentials_options_set_verify_server_cert(
|
||||
grpc_tls_credentials_options* options, int verify_server_cert);
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL API - Subject to change
|
||||
*
|
||||
* The read-only request information exposed in a verification call.
|
||||
* Callers should not directly manage the ownership of it. We will make sure it
|
||||
* is always available inside verify() or cancel() call, and will destroy the
|
||||
* object at the end of custom verification.
|
||||
*/
|
||||
typedef struct grpc_tls_custom_verification_check_request {
|
||||
/* The target name of the server when the client initiates the connection. */
|
||||
/* This field will be nullptr if on the server side. */
|
||||
const char* target_name;
|
||||
/* The information contained in the certificate chain sent from the peer. */
|
||||
struct peer_info {
|
||||
/* The Common Name field on the peer leaf certificate. */
|
||||
const char* common_name;
|
||||
/* The list of Subject Alternative Names on the peer leaf certificate. */
|
||||
struct san_names {
|
||||
char** uri_names;
|
||||
size_t uri_names_size;
|
||||
char** dns_names;
|
||||
size_t dns_names_size;
|
||||
char** email_names;
|
||||
size_t email_names_size;
|
||||
char** ip_names;
|
||||
size_t ip_names_size;
|
||||
} san_names;
|
||||
/* The raw peer leaf certificate. */
|
||||
const char* peer_cert;
|
||||
/* The raw peer certificate chain. Note that it is not always guaranteed to
|
||||
* get the peer full chain. For more, please refer to
|
||||
* GRPC_X509_PEM_CERT_CHAIN_PROPERTY_NAME defined in file
|
||||
* grpc_security_constants.h.
|
||||
* TODO(ZhenLian): Consider fixing this in the future. */
|
||||
const char* peer_cert_full_chain;
|
||||
} peer_info;
|
||||
} grpc_tls_custom_verification_check_request;
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL API - Subject to change
|
||||
*
|
||||
* A callback function provided by gRPC as a parameter of the |verify| function
|
||||
* in grpc_tls_certificate_verifier_external. If |verify| is expected to be run
|
||||
* asynchronously, the implementer of |verify| will need to invoke this callback
|
||||
* with |callback_arg| and proper verification status at the end to bring the
|
||||
* control back to gRPC C core.
|
||||
*/
|
||||
typedef void (*grpc_tls_on_custom_verification_check_done_cb)(
|
||||
grpc_tls_custom_verification_check_request* request, void* callback_arg,
|
||||
grpc_status_code status, const char* error_details);
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL API - Subject to change
|
||||
*
|
||||
* The internal verifier type that will be used inside core.
|
||||
*/
|
||||
typedef struct grpc_tls_certificate_verifier grpc_tls_certificate_verifier;
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL API - Subject to change
|
||||
*
|
||||
* A struct containing all the necessary functions a custom external verifier
|
||||
* needs to implement to be able to be converted to an internal verifier.
|
||||
*/
|
||||
typedef struct grpc_tls_certificate_verifier_external {
|
||||
void* user_data;
|
||||
/**
|
||||
* A function pointer containing the verification logic that will be
|
||||
* performed after the TLS handshake is done. It could be processed
|
||||
* synchronously or asynchronously.
|
||||
* - If expected to be processed synchronously, the implementer should
|
||||
* populate the verification result through |sync_status| and
|
||||
* |sync_error_details|, and then return true.
|
||||
* - If expected to be processed asynchronously, the implementer should return
|
||||
* false immediately, and then in the asynchronous thread invoke |callback|
|
||||
* with the verification result. The implementer MUST NOT invoke the async
|
||||
* |callback| in the same thread before |verify| returns, otherwise it can
|
||||
* lead to deadlocks.
|
||||
*
|
||||
* user_data: any argument that is passed in the user_data of
|
||||
* grpc_tls_certificate_verifier_external during construction time
|
||||
* can be retrieved later here.
|
||||
* request: request information exposed to the function implementer.
|
||||
* callback: the callback that the function implementer needs to invoke, if
|
||||
* return a non-zero value. It is usually invoked when the
|
||||
* asynchronous verification is done, and serves to bring the
|
||||
* control back to gRPC.
|
||||
* callback_arg: A pointer to the internal ExternalVerifier instance. This is
|
||||
* mainly used as an argument in |callback|, if want to invoke
|
||||
* |callback| in async mode.
|
||||
* sync_status: indicates if a connection should be allowed. This should only
|
||||
* be used if the verification check is done synchronously.
|
||||
* sync_error_details: the error generated while verifying a connection. This
|
||||
* should only be used if the verification check is done
|
||||
* synchronously. the implementation must allocate the
|
||||
* error string via gpr_malloc() or gpr_strdup().
|
||||
* return: return 0 if |verify| is expected to be executed asynchronously,
|
||||
* otherwise return a non-zero value.
|
||||
*/
|
||||
int (*verify)(void* user_data,
|
||||
grpc_tls_custom_verification_check_request* request,
|
||||
grpc_tls_on_custom_verification_check_done_cb callback,
|
||||
void* callback_arg, grpc_status_code* sync_status,
|
||||
char** sync_error_details);
|
||||
/**
|
||||
* A function pointer that cleans up the caller-specified resources when the
|
||||
* verifier is still running but the whole connection got cancelled. This
|
||||
* could happen when the verifier is doing some async operations, and the
|
||||
* whole handshaker object got destroyed because of connection time limit is
|
||||
* reached, or any other reasons. In such cases, function implementers might
|
||||
* want to be notified, and properly clean up some resources.
|
||||
*
|
||||
* user_data: any argument that is passed in the user_data of
|
||||
* grpc_tls_certificate_verifier_external during construction time
|
||||
* can be retrieved later here.
|
||||
* request: request information exposed to the function implementer. It will
|
||||
* be the same request object that was passed to verify(), and it
|
||||
* tells the cancel() which request to cancel.
|
||||
*/
|
||||
void (*cancel)(void* user_data,
|
||||
grpc_tls_custom_verification_check_request* request);
|
||||
/**
|
||||
* A function pointer that does some additional destruction work when the
|
||||
* verifier is destroyed. This is used when the caller wants to associate some
|
||||
* objects to the lifetime of external_verifier, and destroy them when
|
||||
* external_verifier got destructed. For example, in C++, the class containing
|
||||
* user-specified callback functions should not be destroyed before
|
||||
* external_verifier, since external_verifier will invoke them while being
|
||||
* used.
|
||||
* Note that the caller MUST delete the grpc_tls_certificate_verifier_external
|
||||
* object itself in this function, otherwise it will cause memory leaks. That
|
||||
* also means the user_data has to carries at least a self pointer, for the
|
||||
* callers to later delete it in destruct().
|
||||
*
|
||||
* user_data: any argument that is passed in the user_data of
|
||||
* grpc_tls_certificate_verifier_external during construction time
|
||||
* can be retrieved later here.
|
||||
*/
|
||||
void (*destruct)(void* user_data);
|
||||
} grpc_tls_certificate_verifier_external;
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL API - Subject to change
|
||||
*
|
||||
* Converts an external verifier to an internal verifier.
|
||||
* Note that we will not take the ownership of the external_verifier. Callers
|
||||
* will need to delete external_verifier in its own destruct function.
|
||||
*/
|
||||
grpc_tls_certificate_verifier* grpc_tls_certificate_verifier_external_create(
|
||||
grpc_tls_certificate_verifier_external* external_verifier);
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL API - Subject to change
|
||||
*
|
||||
* Factory function for an internal verifier that will do the default hostname
|
||||
* check.
|
||||
*/
|
||||
grpc_tls_certificate_verifier* grpc_tls_certificate_verifier_host_name_create();
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL API - Subject to change
|
||||
*
|
||||
* Releases a grpc_tls_certificate_verifier object. The creator of the
|
||||
* grpc_tls_certificate_verifier object is responsible for its release.
|
||||
*/
|
||||
void grpc_tls_certificate_verifier_release(
|
||||
grpc_tls_certificate_verifier* verifier);
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL API - Subject to change
|
||||
*
|
||||
* Sets the verifier in options. The |options| will implicitly take a new ref to
|
||||
* the |verifier|. If not set on the client side, we will verify server's
|
||||
* certificates, and check the default hostname. If not set on the server side,
|
||||
* we will verify client's certificates.
|
||||
*/
|
||||
void grpc_tls_credentials_options_set_certificate_verifier(
|
||||
grpc_tls_credentials_options* options,
|
||||
grpc_tls_certificate_verifier* verifier);
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL API - Subject to change
|
||||
*
|
||||
* Sets the options of whether to check the hostname of the peer on a per-call
|
||||
* basis. This is usually used in a combination with virtual hosting at the
|
||||
* client side, where each individual call on a channel can have a different
|
||||
* host associated with it.
|
||||
* This check is intended to verify that the host specified for the individual
|
||||
* call is covered by the cert that the peer presented.
|
||||
* The default is a non-zero value, which indicates performing such checks.
|
||||
*/
|
||||
GRPCAPI void grpc_tls_credentials_options_set_check_call_host(
|
||||
grpc_tls_credentials_options* options, int check_call_host);
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL API - Subject to change
|
||||
*
|
||||
* Performs the verification logic of an internal verifier.
|
||||
* This is typically used when composing the internal verifiers as part of the
|
||||
* custom verification.
|
||||
* If |grpc_tls_certificate_verifier_verify| returns true, inspect the
|
||||
* verification result through request->status and request->error_details.
|
||||
* Otherwise, inspect through the parameter of |callback|.
|
||||
*/
|
||||
int grpc_tls_certificate_verifier_verify(
|
||||
grpc_tls_certificate_verifier* verifier,
|
||||
grpc_tls_custom_verification_check_request* request,
|
||||
grpc_tls_on_custom_verification_check_done_cb callback, void* callback_arg,
|
||||
grpc_status_code* sync_status, char** sync_error_details);
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL API - Subject to change
|
||||
*
|
||||
* Performs the cancellation logic of an internal verifier.
|
||||
* This is typically used when composing the internal verifiers as part of the
|
||||
* custom verification.
|
||||
*/
|
||||
void grpc_tls_certificate_verifier_cancel(
|
||||
grpc_tls_certificate_verifier* verifier,
|
||||
grpc_tls_custom_verification_check_request* request);
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL API - Subject to change
|
||||
*
|
||||
* 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.
|
||||
* security level of the resulting connection is GRPC_PRIVACY_AND_INTEGRITY.
|
||||
*/
|
||||
grpc_channel_credentials* grpc_tls_credentials_create(
|
||||
grpc_tls_credentials_options* options);
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL API - 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 will take the ownership of the |options|.
|
||||
*/
|
||||
grpc_server_credentials* grpc_tls_server_credentials_create(
|
||||
grpc_tls_credentials_options* options);
|
||||
|
|
|
|||
|
|
@ -135,20 +135,6 @@ typedef enum {
|
|||
GRPC_SECURITY_MAX = GRPC_PRIVACY_AND_INTEGRITY,
|
||||
} grpc_security_level;
|
||||
|
||||
typedef enum {
|
||||
/** Default option: performs server certificate verification and hostname
|
||||
verification. */
|
||||
GRPC_TLS_SERVER_VERIFICATION,
|
||||
/** Performs server certificate verification, but skips hostname verification
|
||||
Client is responsible for verifying server's identity via
|
||||
server authorization check callback. */
|
||||
GRPC_TLS_SKIP_HOSTNAME_VERIFICATION,
|
||||
/** Skips both server certificate and hostname verification.
|
||||
Client is responsible for verifying server's identity and
|
||||
server's certificate via server authorization check callback. */
|
||||
GRPC_TLS_SKIP_ALL_SERVER_VERIFICATION
|
||||
} grpc_tls_server_verification_option;
|
||||
|
||||
/**
|
||||
* Type of local connections for which local channel/server credentials will be
|
||||
* applied. It supports UDS and local TCP connections.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,225 @@
|
|||
//
|
||||
// Copyright 2021 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_VERIFIER_H
|
||||
#define GRPCPP_SECURITY_TLS_CERTIFICATE_VERIFIER_H
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <grpc/grpc_security_constants.h>
|
||||
#include <grpc/status.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpcpp/impl/codegen/grpc_library.h>
|
||||
#include <grpcpp/impl/codegen/sync.h>
|
||||
#include <grpcpp/impl/grpc_library.h>
|
||||
#include <grpcpp/support/config.h>
|
||||
#include <grpcpp/support/string_ref.h>
|
||||
|
||||
// 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_custom_verification_check_request
|
||||
grpc_tls_custom_verification_check_request;
|
||||
typedef struct grpc_tls_certificate_verifier grpc_tls_certificate_verifier;
|
||||
typedef struct grpc_tls_certificate_verifier_external
|
||||
grpc_tls_certificate_verifier_external;
|
||||
typedef void (*grpc_tls_on_custom_verification_check_done_cb)(
|
||||
grpc_tls_custom_verification_check_request* request, void* callback_arg,
|
||||
grpc_status_code status, const char* error_details);
|
||||
extern "C" grpc_tls_certificate_verifier*
|
||||
grpc_tls_certificate_verifier_external_create(
|
||||
grpc_tls_certificate_verifier_external* external_verifier);
|
||||
|
||||
namespace grpc {
|
||||
namespace experimental {
|
||||
|
||||
// Contains the verification-related information associated with a connection
|
||||
// request. Users should not directly create or destroy this request object, but
|
||||
// shall interact with it through CertificateVerifier's Verify() and Cancel().
|
||||
class TlsCustomVerificationCheckRequest {
|
||||
public:
|
||||
explicit TlsCustomVerificationCheckRequest(
|
||||
grpc_tls_custom_verification_check_request* request);
|
||||
~TlsCustomVerificationCheckRequest() {}
|
||||
|
||||
grpc::string_ref target_name() const;
|
||||
grpc::string_ref peer_cert() const;
|
||||
grpc::string_ref peer_cert_full_chain() const;
|
||||
grpc::string_ref common_name() const;
|
||||
std::vector<grpc::string_ref> uri_names() const;
|
||||
std::vector<grpc::string_ref> dns_names() const;
|
||||
std::vector<grpc::string_ref> email_names() const;
|
||||
std::vector<grpc::string_ref> ip_names() const;
|
||||
|
||||
grpc_tls_custom_verification_check_request* c_request() { return c_request_; }
|
||||
|
||||
private:
|
||||
grpc_tls_custom_verification_check_request* c_request_ = nullptr;
|
||||
};
|
||||
|
||||
// The base class of all internal verifier implementations, and the ultimate
|
||||
// class that all external verifiers will eventually be transformed into.
|
||||
// To implement a custom verifier, do not extend this class; instead,
|
||||
// implement a subclass of ExternalCertificateVerifier. Note that custom
|
||||
// verifier implementations can compose their functionality with existing
|
||||
// implementations of this interface, such as HostnameVerifier, by delegating
|
||||
// to an instance of that class.
|
||||
class CertificateVerifier {
|
||||
public:
|
||||
explicit CertificateVerifier(grpc_tls_certificate_verifier* v);
|
||||
|
||||
~CertificateVerifier();
|
||||
|
||||
// Verifies a connection request, based on the logic specified in an internal
|
||||
// verifier. The check on each internal verifier could be either synchronous
|
||||
// or asynchronous, and we will need to use return value to know.
|
||||
//
|
||||
// request: the verification information associated with this request
|
||||
// callback: This will only take effect if the verifier is asynchronous.
|
||||
// The function that gRPC will invoke when the verifier has already
|
||||
// completed its asynchronous check. Callers can use this function
|
||||
// to perform any additional checks. The input parameter of the
|
||||
// std::function indicates the status of the verifier check.
|
||||
// sync_status: This will only be useful if the verifier is synchronous.
|
||||
// The status of the verifier as it has already done it's
|
||||
// synchronous check.
|
||||
// return: return true if executed synchronously, otherwise return false
|
||||
bool Verify(TlsCustomVerificationCheckRequest* request,
|
||||
std::function<void(grpc::Status)> callback,
|
||||
grpc::Status* sync_status);
|
||||
|
||||
// Cancels a verification request previously started via Verify().
|
||||
// Used when the connection attempt times out or is cancelled while an async
|
||||
// verification request is pending.
|
||||
//
|
||||
// request: the verification information associated with this request
|
||||
void Cancel(TlsCustomVerificationCheckRequest* request);
|
||||
|
||||
// Gets the core verifier used internally.
|
||||
grpc_tls_certificate_verifier* c_verifier() { return verifier_; };
|
||||
|
||||
private:
|
||||
static void AsyncCheckDone(
|
||||
grpc_tls_custom_verification_check_request* request, void* callback_arg,
|
||||
grpc_status_code status, const char* error_details);
|
||||
|
||||
grpc_tls_certificate_verifier* verifier_ = nullptr;
|
||||
grpc::internal::Mutex mu_;
|
||||
std::map<grpc_tls_custom_verification_check_request*,
|
||||
std::function<void(grpc::Status)>>
|
||||
request_map_ ABSL_GUARDED_BY(mu_);
|
||||
};
|
||||
|
||||
// The base class of all external, user-specified verifiers. Users should
|
||||
// inherit this class to implement a custom verifier.
|
||||
// Note that while implementing the custom verifier that extends this class, it
|
||||
// is possible to compose an existing ExternalCertificateVerifier or
|
||||
// CertificateVerifier, inside the Verify() and Cancel() function of the new
|
||||
// custom verifier.
|
||||
class ExternalCertificateVerifier {
|
||||
public:
|
||||
// A factory method for creating a |CertificateVerifier| from this class. All
|
||||
// the user-implemented verifiers should use this function to be converted to
|
||||
// verifiers compatible with |TlsCredentialsOptions|.
|
||||
// The resulting CertificateVerifier takes ownership of the newly instantiated
|
||||
// Subclass.
|
||||
template <typename Subclass, typename... Args>
|
||||
static std::shared_ptr<CertificateVerifier> Create(Args&&... args) {
|
||||
grpc::internal::GrpcLibraryInitializer g_gli_initializer;
|
||||
g_gli_initializer.summon();
|
||||
auto* external_verifier = new Subclass(std::forward<Args>(args)...);
|
||||
return std::make_shared<CertificateVerifier>(
|
||||
grpc_tls_certificate_verifier_external_create(
|
||||
external_verifier->base_));
|
||||
}
|
||||
|
||||
// The verification logic that will be performed after the TLS handshake
|
||||
// completes. Implementers can choose to do their checks synchronously or
|
||||
// asynchronously.
|
||||
//
|
||||
// request: the verification information associated with this request
|
||||
// callback: This should only be used if your check is done asynchronously.
|
||||
// When the asynchronous work is done, invoke this callback function
|
||||
// with the proper status, indicating the success or the failure of
|
||||
// the check. The implementer MUST NOT invoke this |callback| in the
|
||||
// same thread before Verify() returns, otherwise it can lead to
|
||||
// deadlocks.
|
||||
// sync_status: This should only be used if your check is done synchronously.
|
||||
// Modifies this value to indicate the success or the failure of
|
||||
// the check.
|
||||
// return: return true if your check is done synchronously, otherwise return
|
||||
// false
|
||||
virtual bool Verify(TlsCustomVerificationCheckRequest* request,
|
||||
std::function<void(grpc::Status)> callback,
|
||||
grpc::Status* sync_status) = 0;
|
||||
|
||||
// Cancels a verification request previously started via Verify().
|
||||
// Used when the connection attempt times out or is cancelled while an async
|
||||
// verification request is pending. The implementation should abort whatever
|
||||
// async operation it is waiting for and quickly invoke the callback that was
|
||||
// passed to Verify() with a status indicating the cancellation.
|
||||
//
|
||||
// request: the verification information associated with this request
|
||||
virtual void Cancel(TlsCustomVerificationCheckRequest* request) = 0;
|
||||
|
||||
protected:
|
||||
ExternalCertificateVerifier();
|
||||
|
||||
virtual ~ExternalCertificateVerifier();
|
||||
|
||||
private:
|
||||
struct AsyncRequestState {
|
||||
AsyncRequestState(grpc_tls_on_custom_verification_check_done_cb cb,
|
||||
void* arg,
|
||||
grpc_tls_custom_verification_check_request* request)
|
||||
: callback(cb), callback_arg(arg), cpp_request(request) {}
|
||||
|
||||
grpc_tls_on_custom_verification_check_done_cb callback;
|
||||
void* callback_arg;
|
||||
TlsCustomVerificationCheckRequest cpp_request;
|
||||
};
|
||||
|
||||
static int VerifyInCoreExternalVerifier(
|
||||
void* user_data, grpc_tls_custom_verification_check_request* request,
|
||||
grpc_tls_on_custom_verification_check_done_cb callback,
|
||||
void* callback_arg, grpc_status_code* sync_status,
|
||||
char** sync_error_details);
|
||||
|
||||
static void CancelInCoreExternalVerifier(
|
||||
void* user_data, grpc_tls_custom_verification_check_request* request);
|
||||
|
||||
static void DestructInCoreExternalVerifier(void* user_data);
|
||||
|
||||
// TODO(yihuazhang): after the insecure build is removed, make this an object
|
||||
// member instead of a pointer.
|
||||
grpc_tls_certificate_verifier_external* base_ = nullptr;
|
||||
grpc::internal::Mutex mu_;
|
||||
std::map<grpc_tls_custom_verification_check_request*, AsyncRequestState>
|
||||
request_map_ ABSL_GUARDED_BY(mu_);
|
||||
};
|
||||
|
||||
class HostNameCertificateVerifier : public CertificateVerifier {
|
||||
public:
|
||||
HostNameCertificateVerifier();
|
||||
};
|
||||
|
||||
} // namespace experimental
|
||||
} // namespace grpc
|
||||
|
||||
#endif // GRPCPP_SECURITY_TLS_CERTIFICATE_VERIFIER_H
|
||||
|
|
@ -26,6 +26,7 @@
|
|||
#include <grpc/status.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpcpp/security/tls_certificate_provider.h>
|
||||
#include <grpcpp/security/tls_certificate_verifier.h>
|
||||
#include <grpcpp/support/config.h>
|
||||
|
||||
// TODO(yihuazhang): remove the forward declaration here and include
|
||||
|
|
@ -36,116 +37,11 @@ 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;
|
||||
typedef struct grpc_tls_certificate_verifier grpc_tls_certificate_verifier;
|
||||
|
||||
namespace grpc {
|
||||
namespace experimental {
|
||||
|
||||
/** 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.
|
||||
*
|
||||
* The server authorization check arg contains all the info necessary to
|
||||
* schedule/cancel a server authorization check request. The callback function
|
||||
* must be called after finishing the schedule operation. See the description
|
||||
* of the grpc_tls_server_authorization_check_arg struct in grpc_security.h for
|
||||
* more details. **/
|
||||
class TlsServerAuthorizationCheckArg {
|
||||
public:
|
||||
/** TlsServerAuthorizationCheckArg does not take ownership of the C arg passed
|
||||
* to the constructor. One must remember to free any memory allocated to the
|
||||
* C arg after using the setter functions below. **/
|
||||
explicit TlsServerAuthorizationCheckArg(
|
||||
grpc_tls_server_authorization_check_arg* arg);
|
||||
~TlsServerAuthorizationCheckArg();
|
||||
|
||||
/** Getters for member fields. **/
|
||||
void* cb_user_data() const;
|
||||
int success() const;
|
||||
std::string target_name() const;
|
||||
std::string peer_cert() const;
|
||||
std::string peer_cert_full_chain() const;
|
||||
grpc_status_code status() const;
|
||||
std::string error_details() const;
|
||||
|
||||
/** Setters for member fields. **/
|
||||
void set_cb_user_data(void* cb_user_data);
|
||||
void set_success(int success);
|
||||
void set_target_name(const std::string& target_name);
|
||||
void set_peer_cert(const std::string& peer_cert);
|
||||
void set_peer_cert_full_chain(const std::string& peer_cert_full_chain);
|
||||
void set_status(grpc_status_code status);
|
||||
void set_error_details(const std::string& error_details);
|
||||
|
||||
/** Calls the C arg's callback function. **/
|
||||
void OnServerAuthorizationCheckDoneCallback();
|
||||
|
||||
private:
|
||||
grpc_tls_server_authorization_check_arg* c_arg_;
|
||||
};
|
||||
|
||||
/** An interface that the application derives and uses to instantiate a
|
||||
* TlsServerAuthorizationCheckConfig instance. Refer to the definition of the
|
||||
* grpc_tls_server_authorization_check_config in grpc_tls_credentials_options.h
|
||||
* for more details on the expectations of the member functions of the
|
||||
* interface.
|
||||
* **/
|
||||
struct TlsServerAuthorizationCheckInterface {
|
||||
virtual ~TlsServerAuthorizationCheckInterface() = default;
|
||||
/** A callback that invokes the server authorization check. **/
|
||||
virtual int Schedule(TlsServerAuthorizationCheckArg* arg) = 0;
|
||||
/** A callback that cancels a server authorization check request. **/
|
||||
virtual void Cancel(TlsServerAuthorizationCheckArg* /* arg */) {}
|
||||
};
|
||||
|
||||
/** TLS server authorization check config, wraps
|
||||
* grps_tls_server_authorization_check_config. It is used for experimental
|
||||
* purposes for now and it is subject to change. **/
|
||||
class TlsServerAuthorizationCheckConfig {
|
||||
public:
|
||||
explicit TlsServerAuthorizationCheckConfig(
|
||||
std::shared_ptr<TlsServerAuthorizationCheckInterface>
|
||||
server_authorization_check_interface);
|
||||
~TlsServerAuthorizationCheckConfig();
|
||||
|
||||
int Schedule(TlsServerAuthorizationCheckArg* arg) const {
|
||||
if (server_authorization_check_interface_ == nullptr) {
|
||||
gpr_log(GPR_ERROR, "server authorization check interface is nullptr");
|
||||
if (arg != nullptr) {
|
||||
arg->set_status(GRPC_STATUS_NOT_FOUND);
|
||||
arg->set_error_details(
|
||||
"the interface of the server authorization check config is "
|
||||
"nullptr");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return server_authorization_check_interface_->Schedule(arg);
|
||||
}
|
||||
|
||||
void Cancel(TlsServerAuthorizationCheckArg* arg) const {
|
||||
if (server_authorization_check_interface_ == nullptr) {
|
||||
gpr_log(GPR_ERROR, "server authorization check interface is nullptr");
|
||||
if (arg != nullptr) {
|
||||
arg->set_status(GRPC_STATUS_NOT_FOUND);
|
||||
arg->set_error_details(
|
||||
"the interface of the server authorization check config is "
|
||||
"nullptr");
|
||||
}
|
||||
return;
|
||||
}
|
||||
server_authorization_check_interface_->Cancel(arg);
|
||||
}
|
||||
|
||||
/** Returns C struct for the server authorization check config. **/
|
||||
grpc_tls_server_authorization_check_config* c_config() const {
|
||||
return c_config_;
|
||||
}
|
||||
|
||||
private:
|
||||
grpc_tls_server_authorization_check_config* c_config_;
|
||||
std::shared_ptr<TlsServerAuthorizationCheckInterface>
|
||||
server_authorization_check_interface_;
|
||||
};
|
||||
|
||||
// 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.
|
||||
|
|
@ -187,6 +83,19 @@ class TlsCredentialsOptions {
|
|||
//
|
||||
// @param identity_cert_name the name of identity key-cert pairs being set.
|
||||
void set_identity_cert_name(const std::string& identity_cert_name);
|
||||
// Sets the certificate verifier used to perform post-handshake peer identity
|
||||
// checks.
|
||||
void set_certificate_verifier(
|
||||
std::shared_ptr<CertificateVerifier> certificate_verifier);
|
||||
// Sets the options of whether to check the hostname of the peer on a per-call
|
||||
// basis. This is usually used in a combination with virtual hosting at the
|
||||
// client side, where each individual call on a channel can have a different
|
||||
// host associated with it.
|
||||
// This check is intended to verify that the host specified for the individual
|
||||
// call is covered by the cert that the peer presented.
|
||||
// We will perform such checks by default. This should be disabled if
|
||||
// verifiers other than the host name verifier is used.
|
||||
void set_check_call_host(bool check_call_host);
|
||||
|
||||
// ----- Getters for member fields ----
|
||||
// Get the internal c options. This function shall be used only internally.
|
||||
|
|
@ -196,6 +105,7 @@ class TlsCredentialsOptions {
|
|||
|
||||
private:
|
||||
std::shared_ptr<CertificateProviderInterface> certificate_provider_;
|
||||
std::shared_ptr<CertificateVerifier> certificate_verifier_;
|
||||
grpc_tls_credentials_options* c_credentials_options_ = nullptr;
|
||||
};
|
||||
|
||||
|
|
@ -207,14 +117,9 @@ class TlsCredentialsOptions {
|
|||
// It is used for experimental purposes for now and it is subject to change.
|
||||
class TlsChannelCredentialsOptions final : public TlsCredentialsOptions {
|
||||
public:
|
||||
// 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>
|
||||
authorization_check_config);
|
||||
// Sets the decision of whether to do a crypto check on the server certs.
|
||||
// The default is true.
|
||||
void set_verify_server_certs(bool verify_server_certs);
|
||||
|
||||
private:
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1104,6 +1104,8 @@
|
|||
<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_certificate_verifier.cc" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/security/credentials/tls/grpc_tls_certificate_verifier.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" />
|
||||
|
|
|
|||
|
|
@ -0,0 +1,201 @@
|
|||
//
|
||||
// Copyright 2021 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_verifier.h"
|
||||
|
||||
#include <grpc/support/alloc.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpc/support/string_util.h>
|
||||
|
||||
#include "src/core/lib/gprpp/host_port.h"
|
||||
#include "src/core/lib/gprpp/stat.h"
|
||||
#include "src/core/lib/security/credentials/tls/tls_utils.h"
|
||||
#include "src/core/lib/slice/slice_internal.h"
|
||||
#include "src/core/lib/surface/api_trace.h"
|
||||
|
||||
namespace grpc_core {
|
||||
|
||||
bool ExternalCertificateVerifier::Verify(
|
||||
grpc_tls_custom_verification_check_request* request,
|
||||
std::function<void(absl::Status)> callback, absl::Status* sync_status) {
|
||||
{
|
||||
MutexLock lock(&mu_);
|
||||
request_map_.emplace(request, std::move(callback));
|
||||
}
|
||||
// Invoke the caller-specified verification logic embedded in
|
||||
// external_verifier_.
|
||||
grpc_status_code status_code = GRPC_STATUS_OK;
|
||||
char* error_details = nullptr;
|
||||
bool is_done = external_verifier_->verify(external_verifier_->user_data,
|
||||
request, &OnVerifyDone, this,
|
||||
&status_code, &error_details);
|
||||
if (is_done) {
|
||||
if (status_code != GRPC_STATUS_OK) {
|
||||
*sync_status = absl::Status(static_cast<absl::StatusCode>(status_code),
|
||||
error_details);
|
||||
}
|
||||
MutexLock lock(&mu_);
|
||||
request_map_.erase(request);
|
||||
}
|
||||
gpr_free(error_details);
|
||||
return is_done;
|
||||
}
|
||||
|
||||
void ExternalCertificateVerifier::OnVerifyDone(
|
||||
grpc_tls_custom_verification_check_request* request, void* callback_arg,
|
||||
grpc_status_code status, const char* error_details) {
|
||||
ExecCtx exec_ctx;
|
||||
auto* self = static_cast<ExternalCertificateVerifier*>(callback_arg);
|
||||
std::function<void(absl::Status)> callback;
|
||||
{
|
||||
MutexLock lock(&self->mu_);
|
||||
auto it = self->request_map_.find(request);
|
||||
if (it != self->request_map_.end()) {
|
||||
callback = std::move(it->second);
|
||||
self->request_map_.erase(it);
|
||||
}
|
||||
}
|
||||
if (callback != nullptr) {
|
||||
absl::Status return_status = absl::OkStatus();
|
||||
if (status != GRPC_STATUS_OK) {
|
||||
return_status =
|
||||
absl::Status(static_cast<absl::StatusCode>(status), error_details);
|
||||
}
|
||||
callback(return_status);
|
||||
}
|
||||
}
|
||||
|
||||
bool HostNameCertificateVerifier::Verify(
|
||||
grpc_tls_custom_verification_check_request* request,
|
||||
std::function<void(absl::Status)>, absl::Status* sync_status) {
|
||||
GPR_ASSERT(request != nullptr);
|
||||
// Extract the target name, and remove its port.
|
||||
const char* target_name = request->target_name;
|
||||
if (target_name == nullptr) {
|
||||
*sync_status = absl::Status(absl::StatusCode::kUnauthenticated,
|
||||
"Target name is not specified.");
|
||||
return true; // synchronous check
|
||||
}
|
||||
absl::string_view target_host;
|
||||
absl::string_view ignored_port;
|
||||
SplitHostPort(target_name, &target_host, &ignored_port);
|
||||
if (target_host.empty()) {
|
||||
*sync_status = absl::Status(absl::StatusCode::kUnauthenticated,
|
||||
"Failed to split hostname and port.");
|
||||
return true; // synchronous check
|
||||
}
|
||||
// IPv6 zone-id should not be included in comparisons.
|
||||
const size_t zone_id = target_host.find('%');
|
||||
if (zone_id != absl::string_view::npos) {
|
||||
target_host.remove_suffix(target_host.size() - zone_id);
|
||||
}
|
||||
// Perform the hostname check.
|
||||
// First check the DNS field. We allow prefix or suffix wildcard matching.
|
||||
char** dns_names = request->peer_info.san_names.dns_names;
|
||||
size_t dns_names_size = request->peer_info.san_names.dns_names_size;
|
||||
if (dns_names != nullptr && dns_names_size > 0) {
|
||||
for (size_t i = 0; i < dns_names_size; ++i) {
|
||||
const char* dns_name = dns_names[i];
|
||||
// We are using the target name sent from the client as a matcher to match
|
||||
// against identity name on the peer cert.
|
||||
if (VerifySubjectAlternativeName(dns_name, std::string(target_host))) {
|
||||
return true; // synchronous check
|
||||
}
|
||||
}
|
||||
}
|
||||
// Then check the IP address. We only allow exact matching.
|
||||
char** ip_names = request->peer_info.san_names.ip_names;
|
||||
size_t ip_names_size = request->peer_info.san_names.ip_names_size;
|
||||
if (ip_names != nullptr && ip_names_size > 0) {
|
||||
for (size_t i = 0; i < ip_names_size; ++i) {
|
||||
const char* ip_name = ip_names[i];
|
||||
if (target_host == ip_name) {
|
||||
return true; // synchronous check
|
||||
}
|
||||
}
|
||||
}
|
||||
// If there's no SAN, try the CN.
|
||||
if (dns_names_size == 0) {
|
||||
const char* common_name = request->peer_info.common_name;
|
||||
// We are using the target name sent from the client as a matcher to match
|
||||
// against identity name on the peer cert.
|
||||
if (VerifySubjectAlternativeName(common_name, std::string(target_host))) {
|
||||
return true; // synchronous check
|
||||
}
|
||||
}
|
||||
*sync_status = absl::Status(absl::StatusCode::kUnauthenticated,
|
||||
"Hostname Verification Check failed.");
|
||||
return true; // synchronous check
|
||||
}
|
||||
|
||||
} // namespace grpc_core
|
||||
|
||||
//
|
||||
// Wrapper APIs declared in grpc_security.h
|
||||
//
|
||||
|
||||
int grpc_tls_certificate_verifier_verify(
|
||||
grpc_tls_certificate_verifier* verifier,
|
||||
grpc_tls_custom_verification_check_request* request,
|
||||
grpc_tls_on_custom_verification_check_done_cb callback, void* callback_arg,
|
||||
grpc_status_code* sync_status, char** sync_error_details) {
|
||||
grpc_core::ExecCtx exec_ctx;
|
||||
std::function<void(absl::Status)> async_cb =
|
||||
[callback, request, callback_arg](absl::Status async_status) {
|
||||
callback(request, callback_arg,
|
||||
static_cast<grpc_status_code>(async_status.code()),
|
||||
std::string(async_status.message()).c_str());
|
||||
};
|
||||
absl::Status sync_status_cpp;
|
||||
bool is_done = verifier->Verify(request, async_cb, &sync_status_cpp);
|
||||
if (is_done) {
|
||||
if (!sync_status_cpp.ok()) {
|
||||
*sync_status = static_cast<grpc_status_code>(sync_status_cpp.code());
|
||||
*sync_error_details =
|
||||
gpr_strdup(std::string(sync_status_cpp.message()).c_str());
|
||||
}
|
||||
}
|
||||
return is_done;
|
||||
}
|
||||
|
||||
void grpc_tls_certificate_verifier_cancel(
|
||||
grpc_tls_certificate_verifier* verifier,
|
||||
grpc_tls_custom_verification_check_request* request) {
|
||||
grpc_core::ExecCtx exec_ctx;
|
||||
verifier->Cancel(request);
|
||||
}
|
||||
|
||||
grpc_tls_certificate_verifier* grpc_tls_certificate_verifier_external_create(
|
||||
grpc_tls_certificate_verifier_external* external_verifier) {
|
||||
grpc_core::ExecCtx exec_ctx;
|
||||
return new grpc_core::ExternalCertificateVerifier(external_verifier);
|
||||
}
|
||||
|
||||
grpc_tls_certificate_verifier*
|
||||
grpc_tls_certificate_verifier_host_name_create() {
|
||||
grpc_core::ExecCtx exec_ctx;
|
||||
return new grpc_core::HostNameCertificateVerifier();
|
||||
}
|
||||
|
||||
void grpc_tls_certificate_verifier_release(
|
||||
grpc_tls_certificate_verifier* verifier) {
|
||||
GRPC_API_TRACE("grpc_tls_certificate_verifier_release(verifier=%p)", 1,
|
||||
(verifier));
|
||||
grpc_core::ExecCtx exec_ctx;
|
||||
if (verifier != nullptr) verifier->Unref();
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
//
|
||||
// Copyright 2021 gRPC authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
#ifndef GRPC_CORE_LIB_SECURITY_CREDENTIALS_TLS_GRPC_TLS_CERTIFICATE_VERIFIER_H
|
||||
#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_TLS_GRPC_TLS_CERTIFICATE_VERIFIER_H
|
||||
|
||||
#include <grpc/support/port_platform.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "absl/status/status.h"
|
||||
|
||||
#include <grpc/grpc_security.h>
|
||||
|
||||
#include "src/core/lib/gprpp/ref_counted.h"
|
||||
#include "src/core/lib/gprpp/ref_counted_ptr.h"
|
||||
#include "src/core/lib/gprpp/thd.h"
|
||||
#include "src/core/lib/iomgr/load_file.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"
|
||||
|
||||
// An abstraction of the verifier that all verifier subclasses should extend.
|
||||
struct grpc_tls_certificate_verifier
|
||||
: public grpc_core::RefCounted<grpc_tls_certificate_verifier> {
|
||||
public:
|
||||
grpc_tls_certificate_verifier() = default;
|
||||
|
||||
~grpc_tls_certificate_verifier() override = default;
|
||||
// Verifies the specific request. It can be processed in sync or async mode.
|
||||
// If the caller want it to be processed asynchronously, return false
|
||||
// immediately, and at the end of the async operation, invoke the callback
|
||||
// with the verification results stored in absl::Status. Otherwise, populate
|
||||
// the verification results in |sync_status| and return true. The caller is
|
||||
// expected to populate verification results by setting request.
|
||||
virtual bool Verify(grpc_tls_custom_verification_check_request* request,
|
||||
std::function<void(absl::Status)> callback,
|
||||
absl::Status* sync_status) = 0;
|
||||
// Operations that will be performed when a request is cancelled.
|
||||
// This is only needed when in async mode.
|
||||
virtual void Cancel(grpc_tls_custom_verification_check_request* request) = 0;
|
||||
};
|
||||
|
||||
namespace grpc_core {
|
||||
|
||||
// A verifier that will transform grpc_tls_certificate_verifier_external to a
|
||||
// verifier that extends grpc_tls_certificate_verifier.
|
||||
class ExternalCertificateVerifier : public grpc_tls_certificate_verifier {
|
||||
public:
|
||||
explicit ExternalCertificateVerifier(
|
||||
grpc_tls_certificate_verifier_external* external_verifier)
|
||||
: external_verifier_(external_verifier) {}
|
||||
|
||||
~ExternalCertificateVerifier() override {
|
||||
if (external_verifier_->destruct != nullptr) {
|
||||
external_verifier_->destruct(external_verifier_->user_data);
|
||||
}
|
||||
}
|
||||
|
||||
bool Verify(grpc_tls_custom_verification_check_request* request,
|
||||
std::function<void(absl::Status)> callback,
|
||||
absl::Status* sync_status) override;
|
||||
|
||||
void Cancel(grpc_tls_custom_verification_check_request* request) override {
|
||||
external_verifier_->cancel(external_verifier_->user_data, request);
|
||||
}
|
||||
|
||||
private:
|
||||
grpc_tls_certificate_verifier_external* external_verifier_;
|
||||
|
||||
static void OnVerifyDone(grpc_tls_custom_verification_check_request* request,
|
||||
void* callback_arg, grpc_status_code status,
|
||||
const char* error_details);
|
||||
// Guards members below.
|
||||
Mutex mu_;
|
||||
// stores each check request and its corresponding callback function.
|
||||
std::map<grpc_tls_custom_verification_check_request*,
|
||||
std::function<void(absl::Status)>>
|
||||
request_map_ ABSL_GUARDED_BY(mu_);
|
||||
};
|
||||
|
||||
// An internal verifier that will perform hostname verification check.
|
||||
class HostNameCertificateVerifier : public grpc_tls_certificate_verifier {
|
||||
public:
|
||||
bool Verify(grpc_tls_custom_verification_check_request* request,
|
||||
std::function<void(absl::Status)> callback,
|
||||
absl::Status* sync_status) override;
|
||||
void Cancel(grpc_tls_custom_verification_check_request*) override {}
|
||||
};
|
||||
|
||||
} // namespace grpc_core
|
||||
|
||||
#endif // GRPC_CORE_LIB_SECURITY_CREDENTIALS_TLS_GRPC_TLS_CERTIFICATE_VERIFIER_H
|
||||
|
|
@ -29,61 +29,6 @@
|
|||
|
||||
#include "src/core/lib/surface/api_trace.h"
|
||||
|
||||
/** -- gRPC TLS server authorization check API implementation. -- **/
|
||||
grpc_tls_server_authorization_check_config::
|
||||
grpc_tls_server_authorization_check_config(
|
||||
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))
|
||||
: config_user_data_(const_cast<void*>(config_user_data)),
|
||||
schedule_(schedule),
|
||||
cancel_(cancel),
|
||||
destruct_(destruct) {}
|
||||
|
||||
grpc_tls_server_authorization_check_config::
|
||||
~grpc_tls_server_authorization_check_config() {
|
||||
if (destruct_ != nullptr) {
|
||||
destruct_(config_user_data_);
|
||||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
|
|
@ -98,11 +43,10 @@ void grpc_tls_credentials_options_set_cert_request_type(
|
|||
options->set_cert_request_type(type);
|
||||
}
|
||||
|
||||
void grpc_tls_credentials_options_set_server_verification_option(
|
||||
grpc_tls_credentials_options* options,
|
||||
grpc_tls_server_verification_option server_verification_option) {
|
||||
void grpc_tls_credentials_options_set_verify_server_cert(
|
||||
grpc_tls_credentials_options* options, int verify_server_cert) {
|
||||
GPR_ASSERT(options != nullptr);
|
||||
options->set_server_verification_option(server_verification_option);
|
||||
options->set_verify_server_cert(verify_server_cert);
|
||||
}
|
||||
|
||||
void grpc_tls_credentials_options_set_certificate_provider(
|
||||
|
|
@ -139,39 +83,16 @@ void grpc_tls_credentials_options_set_identity_cert_name(
|
|||
options->set_identity_cert_name(identity_cert_name);
|
||||
}
|
||||
|
||||
void grpc_tls_credentials_options_set_server_authorization_check_config(
|
||||
void grpc_tls_credentials_options_set_certificate_verifier(
|
||||
grpc_tls_credentials_options* options,
|
||||
grpc_tls_server_authorization_check_config* config) {
|
||||
grpc_tls_certificate_verifier* verifier) {
|
||||
GPR_ASSERT(options != nullptr);
|
||||
GPR_ASSERT(config != nullptr);
|
||||
grpc_core::ExecCtx exec_ctx;
|
||||
options->set_server_authorization_check_config(config->Ref());
|
||||
GPR_ASSERT(verifier != nullptr);
|
||||
options->set_certificate_verifier(verifier->Ref());
|
||||
}
|
||||
|
||||
grpc_tls_server_authorization_check_config*
|
||||
grpc_tls_server_authorization_check_config_create(
|
||||
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)) {
|
||||
if (schedule == nullptr) {
|
||||
gpr_log(GPR_ERROR,
|
||||
"Schedule API is nullptr in creating TLS server authorization "
|
||||
"check config.");
|
||||
return nullptr;
|
||||
}
|
||||
grpc_core::ExecCtx exec_ctx;
|
||||
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();
|
||||
void grpc_tls_credentials_options_set_check_call_host(
|
||||
grpc_tls_credentials_options* options, int check_call_host) {
|
||||
GPR_ASSERT(options != nullptr);
|
||||
options->set_check_call_host(check_call_host);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,73 +28,9 @@
|
|||
#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/credentials/tls/grpc_tls_certificate_verifier.h"
|
||||
#include "src/core/lib/security/security_connector/ssl_utils.h"
|
||||
|
||||
struct grpc_tls_error_details
|
||||
: public grpc_core::RefCounted<grpc_tls_error_details> {
|
||||
public:
|
||||
grpc_tls_error_details() : error_details_("") {}
|
||||
void set_error_details(const char* err_details) {
|
||||
error_details_ = err_details;
|
||||
}
|
||||
const std::string& error_details() { return error_details_; }
|
||||
|
||||
private:
|
||||
std::string error_details_;
|
||||
};
|
||||
|
||||
/** TLS server authorization check config. **/
|
||||
struct grpc_tls_server_authorization_check_config
|
||||
: public grpc_core::RefCounted<grpc_tls_server_authorization_check_config> {
|
||||
public:
|
||||
grpc_tls_server_authorization_check_config(
|
||||
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));
|
||||
~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;
|
||||
|
||||
void Cancel(grpc_tls_server_authorization_check_arg* arg) const;
|
||||
|
||||
private:
|
||||
/** This is a pointer to the wrapped language implementation of
|
||||
* grpc_tls_server_authorization_check_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 server authorization check. 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->result, \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_server_authorization_check_arg* arg);
|
||||
|
||||
/** callback function for canceling a server authorization check request. */
|
||||
void (*cancel_)(void* config_user_data,
|
||||
grpc_tls_server_authorization_check_arg* arg);
|
||||
|
||||
/** callback function for cleaning up any data associated with server
|
||||
authorization check config. */
|
||||
void (*destruct_)(void* config_user_data);
|
||||
};
|
||||
|
||||
// Contains configurable options specified by callers to configure their certain
|
||||
// security features supported in TLS.
|
||||
// TODO(ZhenLian): consider making this not ref-counted.
|
||||
|
|
@ -107,15 +43,14 @@ struct grpc_tls_credentials_options
|
|||
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_;
|
||||
}
|
||||
bool verify_server_cert() const { return verify_server_cert_; }
|
||||
grpc_tls_version min_tls_version() const { return min_tls_version_; }
|
||||
grpc_tls_version max_tls_version() const { return max_tls_version_; }
|
||||
grpc_tls_server_authorization_check_config*
|
||||
server_authorization_check_config() const {
|
||||
return server_authorization_check_config_.get();
|
||||
// Returns the verifier set in the options.
|
||||
grpc_tls_certificate_verifier* certificate_verifier() {
|
||||
return verifier_.get();
|
||||
}
|
||||
bool check_call_host() const { return check_call_host_; }
|
||||
// Returns the distributor from provider_ if it is set, nullptr otherwise.
|
||||
grpc_tls_certificate_distributor* certificate_distributor() {
|
||||
if (provider_ != nullptr) return provider_->distributor().get();
|
||||
|
|
@ -131,9 +66,8 @@ struct grpc_tls_credentials_options
|
|||
const grpc_ssl_client_certificate_request_type type) {
|
||||
cert_request_type_ = type;
|
||||
}
|
||||
void set_server_verification_option(
|
||||
const grpc_tls_server_verification_option server_verification_option) {
|
||||
server_verification_option_ = server_verification_option;
|
||||
void set_verify_server_cert(bool verify_server_cert) {
|
||||
verify_server_cert_ = verify_server_cert;
|
||||
}
|
||||
void set_min_tls_version(grpc_tls_version min_tls_version) {
|
||||
min_tls_version_ = min_tls_version;
|
||||
|
|
@ -141,10 +75,14 @@ struct grpc_tls_credentials_options
|
|||
void set_max_tls_version(grpc_tls_version max_tls_version) {
|
||||
max_tls_version_ = max_tls_version;
|
||||
}
|
||||
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 verifier in the options.
|
||||
void set_certificate_verifier(
|
||||
grpc_core::RefCountedPtr<grpc_tls_certificate_verifier> verifier) {
|
||||
verifier_ = std::move(verifier);
|
||||
}
|
||||
// Sets the verifier in the options.
|
||||
void set_check_call_host(bool check_call_host) {
|
||||
check_call_host_ = check_call_host;
|
||||
}
|
||||
// Sets the provider in the options.
|
||||
void set_certificate_provider(
|
||||
|
|
@ -177,12 +115,11 @@ struct grpc_tls_credentials_options
|
|||
private:
|
||||
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;
|
||||
bool verify_server_cert_ = true;
|
||||
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_server_authorization_check_config>
|
||||
server_authorization_check_config_;
|
||||
grpc_core::RefCountedPtr<grpc_tls_certificate_verifier> verifier_;
|
||||
bool check_call_host_ = true;
|
||||
grpc_core::RefCountedPtr<grpc_tls_certificate_provider> provider_;
|
||||
bool watch_root_cert_ = false;
|
||||
std::string root_cert_name_;
|
||||
|
|
|
|||
|
|
@ -28,29 +28,40 @@
|
|||
#include <grpc/support/string_util.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/security/credentials/tls/grpc_tls_certificate_verifier.h"
|
||||
#include "src/core/lib/security/security_connector/tls/tls_security_connector.h"
|
||||
|
||||
#define GRPC_CREDENTIALS_TYPE_TLS "Tls"
|
||||
|
||||
namespace {
|
||||
|
||||
bool CredentialOptionSanityCheck(const grpc_tls_credentials_options* options,
|
||||
bool CredentialOptionSanityCheck(grpc_tls_credentials_options* options,
|
||||
bool is_client) {
|
||||
if (options == nullptr) {
|
||||
gpr_log(GPR_ERROR, "TLS credentials options is nullptr.");
|
||||
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) {
|
||||
// In the following conditions, there won't be any issues, but it might
|
||||
// indicate callers are doing something wrong with the API.
|
||||
if (is_client && options->cert_request_type() !=
|
||||
GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE) {
|
||||
gpr_log(GPR_ERROR,
|
||||
"Should provider custom verifications if bypassing default ones.");
|
||||
return false;
|
||||
"Client's credentials options should not set cert_request_type.");
|
||||
}
|
||||
if (!is_client && !options->verify_server_cert()) {
|
||||
gpr_log(GPR_ERROR,
|
||||
"Server's credentials options should not set verify_server_cert.");
|
||||
}
|
||||
// In the following conditions, there could be severe security issues.
|
||||
if (is_client && options->certificate_verifier() == nullptr) {
|
||||
// If no verifier is specified on the client side, use the hostname verifier
|
||||
// as default. Users who want to bypass all the verifier check should
|
||||
// implement an external verifier instead.
|
||||
gpr_log(GPR_INFO,
|
||||
"No verifier specified on the client side. Using default hostname "
|
||||
"verifier");
|
||||
options->set_certificate_verifier(
|
||||
grpc_core::MakeRefCounted<grpc_core::HostNameCertificateVerifier>());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,41 +61,39 @@ bool XdsVerifySubjectAlternativeNames(
|
|||
return false;
|
||||
}
|
||||
|
||||
class ServerAuthCheck {
|
||||
class XdsCertificateVerifier : public grpc_tls_certificate_verifier {
|
||||
public:
|
||||
ServerAuthCheck(
|
||||
XdsCertificateVerifier(
|
||||
RefCountedPtr<XdsCertificateProvider> xds_certificate_provider,
|
||||
std::string cluster_name)
|
||||
: xds_certificate_provider_(std::move(xds_certificate_provider)),
|
||||
cluster_name_(std::move(cluster_name)) {}
|
||||
|
||||
static int Schedule(void* config_user_data,
|
||||
grpc_tls_server_authorization_check_arg* arg) {
|
||||
return static_cast<ServerAuthCheck*>(config_user_data)->ScheduleImpl(arg);
|
||||
}
|
||||
|
||||
static void Destroy(void* config_user_data) {
|
||||
delete static_cast<ServerAuthCheck*>(config_user_data);
|
||||
bool Verify(grpc_tls_custom_verification_check_request* request,
|
||||
std::function<void(absl::Status)>,
|
||||
absl::Status* sync_status) override {
|
||||
GPR_ASSERT(request != nullptr);
|
||||
if (!XdsVerifySubjectAlternativeNames(
|
||||
request->peer_info.san_names.uri_names,
|
||||
request->peer_info.san_names.uri_names_size,
|
||||
xds_certificate_provider_->GetSanMatchers(cluster_name_)) &&
|
||||
!XdsVerifySubjectAlternativeNames(
|
||||
request->peer_info.san_names.ip_names,
|
||||
request->peer_info.san_names.ip_names_size,
|
||||
xds_certificate_provider_->GetSanMatchers(cluster_name_)) &&
|
||||
!XdsVerifySubjectAlternativeNames(
|
||||
request->peer_info.san_names.dns_names,
|
||||
request->peer_info.san_names.dns_names_size,
|
||||
xds_certificate_provider_->GetSanMatchers(cluster_name_))) {
|
||||
*sync_status = absl::Status(
|
||||
absl::StatusCode::kUnauthenticated,
|
||||
"SANs from certificate did not match SANs from xDS control plane");
|
||||
}
|
||||
return true; /* synchronous check */
|
||||
}
|
||||
void Cancel(grpc_tls_custom_verification_check_request*) override {}
|
||||
|
||||
private:
|
||||
int ScheduleImpl(grpc_tls_server_authorization_check_arg* arg) {
|
||||
if (XdsVerifySubjectAlternativeNames(
|
||||
arg->subject_alternative_names, arg->subject_alternative_names_size,
|
||||
xds_certificate_provider_->GetSanMatchers(cluster_name_))) {
|
||||
arg->success = 1;
|
||||
arg->status = GRPC_STATUS_OK;
|
||||
} else {
|
||||
arg->success = 0;
|
||||
arg->status = GRPC_STATUS_UNAUTHENTICATED;
|
||||
if (arg->error_details) {
|
||||
arg->error_details->set_error_details(
|
||||
"SANs from certificate did not match SANs from xDS control plane");
|
||||
}
|
||||
}
|
||||
return 0; /* synchronous check */
|
||||
}
|
||||
|
||||
RefCountedPtr<XdsCertificateProvider> xds_certificate_provider_;
|
||||
std::string cluster_name_;
|
||||
};
|
||||
|
|
@ -161,14 +159,11 @@ XdsCredentials::create_security_connector(
|
|||
tls_credentials_options->set_watch_identity_pair(true);
|
||||
tls_credentials_options->set_identity_cert_name(cluster_name);
|
||||
}
|
||||
tls_credentials_options->set_server_verification_option(
|
||||
GRPC_TLS_SKIP_HOSTNAME_VERIFICATION);
|
||||
auto* server_auth_check = new ServerAuthCheck(xds_certificate_provider,
|
||||
std::move(cluster_name));
|
||||
tls_credentials_options->set_server_authorization_check_config(
|
||||
MakeRefCounted<grpc_tls_server_authorization_check_config>(
|
||||
server_auth_check, ServerAuthCheck::Schedule, nullptr,
|
||||
ServerAuthCheck::Destroy));
|
||||
tls_credentials_options->set_verify_server_cert(true);
|
||||
tls_credentials_options->set_certificate_verifier(
|
||||
MakeRefCounted<XdsCertificateVerifier>(xds_certificate_provider,
|
||||
std::move(cluster_name)));
|
||||
tls_credentials_options->set_check_call_host(false);
|
||||
// TODO(yashkt): Creating a new TlsCreds object each time we create a
|
||||
// security connector means that the security connector's cmp() method
|
||||
// returns unequal for each instance, which means that every time an LB
|
||||
|
|
|
|||
|
|
@ -196,6 +196,7 @@ bool grpc_ssl_check_call_host(absl::string_view host,
|
|||
if (status != GRPC_SECURITY_OK) {
|
||||
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
||||
"call host does not match SSL server name");
|
||||
gpr_log(GPR_ERROR, "call host does not match SSL server name");
|
||||
}
|
||||
grpc_shallow_peer_destruct(&peer);
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "absl/functional/bind_front.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
|
|
@ -46,6 +47,155 @@ namespace grpc_core {
|
|||
|
||||
namespace {
|
||||
|
||||
char* CopyCoreString(char* src, size_t length) {
|
||||
char* target = static_cast<char*>(gpr_malloc(length + 1));
|
||||
memcpy(target, src, length);
|
||||
target[length] = '\0';
|
||||
return target;
|
||||
}
|
||||
|
||||
void PendingVerifierRequestInit(
|
||||
const char* target_name, tsi_peer peer,
|
||||
grpc_tls_custom_verification_check_request* request) {
|
||||
GPR_ASSERT(request != nullptr);
|
||||
// The verifier holds a ref to the security connector, so it's fine to
|
||||
// directly point this to the name cached in the security connector.
|
||||
request->target_name = target_name;
|
||||
// TODO(ZhenLian): avoid the copy when the underlying core implementation used
|
||||
// the null-terminating string.
|
||||
bool has_common_name = false;
|
||||
bool has_peer_cert = false;
|
||||
bool has_peer_cert_full_chain = false;
|
||||
std::vector<char*> uri_names;
|
||||
std::vector<char*> dns_names;
|
||||
std::vector<char*> email_names;
|
||||
std::vector<char*> ip_names;
|
||||
for (size_t i = 0; i < peer.property_count; ++i) {
|
||||
const tsi_peer_property* prop = &peer.properties[i];
|
||||
if (prop->name == nullptr) continue;
|
||||
if (strcmp(prop->name, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY) == 0) {
|
||||
request->peer_info.common_name =
|
||||
CopyCoreString(prop->value.data, prop->value.length);
|
||||
has_common_name = true;
|
||||
} else if (strcmp(prop->name, TSI_X509_PEM_CERT_PROPERTY) == 0) {
|
||||
request->peer_info.peer_cert =
|
||||
CopyCoreString(prop->value.data, prop->value.length);
|
||||
has_peer_cert = true;
|
||||
} else if (strcmp(prop->name, TSI_X509_PEM_CERT_CHAIN_PROPERTY) == 0) {
|
||||
request->peer_info.peer_cert_full_chain =
|
||||
CopyCoreString(prop->value.data, prop->value.length);
|
||||
has_peer_cert_full_chain = true;
|
||||
} else if (strcmp(prop->name, TSI_X509_URI_PEER_PROPERTY) == 0) {
|
||||
char* uri = CopyCoreString(prop->value.data, prop->value.length);
|
||||
uri_names.emplace_back(uri);
|
||||
} else if (strcmp(prop->name, TSI_X509_DNS_PEER_PROPERTY) == 0) {
|
||||
char* dns = CopyCoreString(prop->value.data, prop->value.length);
|
||||
dns_names.emplace_back(dns);
|
||||
} else if (strcmp(prop->name, TSI_X509_EMAIL_PEER_PROPERTY) == 0) {
|
||||
char* email = CopyCoreString(prop->value.data, prop->value.length);
|
||||
email_names.emplace_back(email);
|
||||
} else if (strcmp(prop->name, TSI_X509_IP_PEER_PROPERTY) == 0) {
|
||||
char* ip = CopyCoreString(prop->value.data, prop->value.length);
|
||||
ip_names.emplace_back(ip);
|
||||
}
|
||||
}
|
||||
if (!has_common_name) {
|
||||
request->peer_info.common_name = nullptr;
|
||||
}
|
||||
if (!has_peer_cert) {
|
||||
request->peer_info.peer_cert = nullptr;
|
||||
}
|
||||
if (!has_peer_cert_full_chain) {
|
||||
request->peer_info.peer_cert_full_chain = nullptr;
|
||||
}
|
||||
request->peer_info.san_names.uri_names_size = uri_names.size();
|
||||
if (!uri_names.empty()) {
|
||||
request->peer_info.san_names.uri_names =
|
||||
new char*[request->peer_info.san_names.uri_names_size];
|
||||
for (size_t i = 0; i < request->peer_info.san_names.uri_names_size; ++i) {
|
||||
// We directly point the char* string stored in vector to the |request|.
|
||||
// That string will be released when the |request| is destroyed.
|
||||
request->peer_info.san_names.uri_names[i] = uri_names[i];
|
||||
}
|
||||
} else {
|
||||
request->peer_info.san_names.uri_names = nullptr;
|
||||
}
|
||||
request->peer_info.san_names.dns_names_size = dns_names.size();
|
||||
if (!dns_names.empty()) {
|
||||
request->peer_info.san_names.dns_names =
|
||||
new char*[request->peer_info.san_names.dns_names_size];
|
||||
for (size_t i = 0; i < request->peer_info.san_names.dns_names_size; ++i) {
|
||||
// We directly point the char* string stored in vector to the |request|.
|
||||
// That string will be released when the |request| is destroyed.
|
||||
request->peer_info.san_names.dns_names[i] = dns_names[i];
|
||||
}
|
||||
} else {
|
||||
request->peer_info.san_names.dns_names = nullptr;
|
||||
}
|
||||
request->peer_info.san_names.email_names_size = email_names.size();
|
||||
if (!email_names.empty()) {
|
||||
request->peer_info.san_names.email_names =
|
||||
new char*[request->peer_info.san_names.email_names_size];
|
||||
for (size_t i = 0; i < request->peer_info.san_names.email_names_size; ++i) {
|
||||
// We directly point the char* string stored in vector to the |request|.
|
||||
// That string will be released when the |request| is destroyed.
|
||||
request->peer_info.san_names.email_names[i] = email_names[i];
|
||||
}
|
||||
} else {
|
||||
request->peer_info.san_names.email_names = nullptr;
|
||||
}
|
||||
request->peer_info.san_names.ip_names_size = ip_names.size();
|
||||
if (!ip_names.empty()) {
|
||||
request->peer_info.san_names.ip_names =
|
||||
new char*[request->peer_info.san_names.ip_names_size];
|
||||
for (size_t i = 0; i < request->peer_info.san_names.ip_names_size; ++i) {
|
||||
// We directly point the char* string stored in vector to the |request|.
|
||||
// That string will be released when the |request| is destroyed.
|
||||
request->peer_info.san_names.ip_names[i] = ip_names[i];
|
||||
}
|
||||
} else {
|
||||
request->peer_info.san_names.ip_names = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void PendingVerifierRequestDestroy(
|
||||
grpc_tls_custom_verification_check_request* request) {
|
||||
GPR_ASSERT(request != nullptr);
|
||||
if (request->peer_info.common_name != nullptr) {
|
||||
gpr_free(const_cast<char*>(request->peer_info.common_name));
|
||||
}
|
||||
if (request->peer_info.san_names.uri_names_size > 0) {
|
||||
for (size_t i = 0; i < request->peer_info.san_names.uri_names_size; ++i) {
|
||||
gpr_free(request->peer_info.san_names.uri_names[i]);
|
||||
}
|
||||
delete[] request->peer_info.san_names.uri_names;
|
||||
}
|
||||
if (request->peer_info.san_names.dns_names_size > 0) {
|
||||
for (size_t i = 0; i < request->peer_info.san_names.dns_names_size; ++i) {
|
||||
gpr_free(request->peer_info.san_names.dns_names[i]);
|
||||
}
|
||||
delete[] request->peer_info.san_names.dns_names;
|
||||
}
|
||||
if (request->peer_info.san_names.email_names_size > 0) {
|
||||
for (size_t i = 0; i < request->peer_info.san_names.email_names_size; ++i) {
|
||||
gpr_free(request->peer_info.san_names.email_names[i]);
|
||||
}
|
||||
delete[] request->peer_info.san_names.email_names;
|
||||
}
|
||||
if (request->peer_info.san_names.ip_names_size > 0) {
|
||||
for (size_t i = 0; i < request->peer_info.san_names.ip_names_size; ++i) {
|
||||
gpr_free(request->peer_info.san_names.ip_names[i]);
|
||||
}
|
||||
delete[] request->peer_info.san_names.ip_names;
|
||||
}
|
||||
if (request->peer_info.peer_cert != nullptr) {
|
||||
gpr_free(const_cast<char*>(request->peer_info.peer_cert));
|
||||
}
|
||||
if (request->peer_info.peer_cert_full_chain != nullptr) {
|
||||
gpr_free(const_cast<char*>(request->peer_info.peer_cert_full_chain));
|
||||
}
|
||||
}
|
||||
|
||||
tsi_ssl_pem_key_cert_pair* ConvertToTsiPemKeyCertPair(
|
||||
const PemKeyCertPairList& cert_pair_list) {
|
||||
tsi_ssl_pem_key_cert_pair* tsi_pairs = nullptr;
|
||||
|
|
@ -116,7 +266,6 @@ TlsChannelSecurityConnector::TlsChannelSecurityConnector(
|
|||
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;
|
||||
SplitHostPort(target_name, &host, &port);
|
||||
|
|
@ -164,9 +313,6 @@ TlsChannelSecurityConnector::~TlsChannelSecurityConnector() {
|
|||
if (client_handshaker_factory_ != nullptr) {
|
||||
tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory_);
|
||||
}
|
||||
if (check_arg_ != nullptr) {
|
||||
ServerAuthorizationCheckArgDestroy(check_arg_);
|
||||
}
|
||||
}
|
||||
|
||||
void TlsChannelSecurityConnector::add_handshakers(
|
||||
|
|
@ -205,121 +351,67 @@ void TlsChannelSecurityConnector::check_peer(
|
|||
}
|
||||
*auth_context =
|
||||
grpc_ssl_peer_to_auth_context(&peer, GRPC_TLS_TRANSPORT_SECURITY_TYPE);
|
||||
if (options_->server_verification_option() == GRPC_TLS_SERVER_VERIFICATION) {
|
||||
/* Do the default host name check if specifying the target name. */
|
||||
error = internal::TlsCheckHostName(target_name, &peer);
|
||||
if (error != GRPC_ERROR_NONE) {
|
||||
ExecCtx::Run(DEBUG_LOCATION, on_peer_checked, error);
|
||||
tsi_peer_destruct(&peer);
|
||||
return;
|
||||
}
|
||||
GPR_ASSERT(options_->certificate_verifier() != nullptr);
|
||||
auto* pending_request = new ChannelPendingVerifierRequest(
|
||||
Ref(), on_peer_checked, peer, target_name);
|
||||
{
|
||||
MutexLock lock(&verifier_request_map_mu_);
|
||||
pending_verifier_requests_.emplace(on_peer_checked, pending_request);
|
||||
}
|
||||
/* Do the custom server authorization check, if specified by the user. */
|
||||
const grpc_tls_server_authorization_check_config* config =
|
||||
options_->server_authorization_check_config();
|
||||
/* If server authorization config is not null, use it to perform
|
||||
* server authorization check. */
|
||||
if (config != nullptr) {
|
||||
const tsi_peer_property* p =
|
||||
tsi_peer_get_property_by_name(&peer, TSI_X509_PEM_CERT_PROPERTY);
|
||||
if (p == nullptr) {
|
||||
error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
||||
"Cannot check peer: missing pem cert property.");
|
||||
} else {
|
||||
char* peer_pem = static_cast<char*>(gpr_zalloc(p->value.length + 1));
|
||||
memcpy(peer_pem, p->value.data, p->value.length);
|
||||
GPR_ASSERT(check_arg_ != nullptr);
|
||||
check_arg_->peer_cert = check_arg_->peer_cert == nullptr
|
||||
? gpr_strdup(peer_pem)
|
||||
: check_arg_->peer_cert;
|
||||
check_arg_->target_name = check_arg_->target_name == nullptr
|
||||
? gpr_strdup(target_name)
|
||||
: check_arg_->target_name;
|
||||
on_peer_checked_ = on_peer_checked;
|
||||
gpr_free(peer_pem);
|
||||
const tsi_peer_property* chain = tsi_peer_get_property_by_name(
|
||||
&peer, TSI_X509_PEM_CERT_CHAIN_PROPERTY);
|
||||
if (chain != nullptr) {
|
||||
char* peer_pem_chain =
|
||||
static_cast<char*>(gpr_zalloc(chain->value.length + 1));
|
||||
memcpy(peer_pem_chain, chain->value.data, chain->value.length);
|
||||
check_arg_->peer_cert_full_chain =
|
||||
check_arg_->peer_cert_full_chain == nullptr
|
||||
? gpr_strdup(peer_pem_chain)
|
||||
: check_arg_->peer_cert_full_chain;
|
||||
gpr_free(peer_pem_chain);
|
||||
}
|
||||
// TODO(zhenlian) - This should be cleaned up as part of the custom
|
||||
// verification changes. Fill in the subject alternative names
|
||||
std::vector<char*> subject_alternative_names;
|
||||
for (size_t i = 0; i < peer.property_count; i++) {
|
||||
const tsi_peer_property* prop = &peer.properties[i];
|
||||
if (strcmp(prop->name,
|
||||
TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) == 0) {
|
||||
char* san = new char[prop->value.length + 1];
|
||||
memcpy(san, prop->value.data, prop->value.length);
|
||||
san[prop->value.length] = '\0';
|
||||
subject_alternative_names.emplace_back(san);
|
||||
}
|
||||
}
|
||||
if (check_arg_->subject_alternative_names != nullptr) {
|
||||
for (size_t i = 0; i < check_arg_->subject_alternative_names_size;
|
||||
++i) {
|
||||
delete[] check_arg_->subject_alternative_names[i];
|
||||
}
|
||||
delete[] check_arg_->subject_alternative_names;
|
||||
}
|
||||
check_arg_->subject_alternative_names_size =
|
||||
subject_alternative_names.size();
|
||||
if (subject_alternative_names.empty()) {
|
||||
check_arg_->subject_alternative_names = nullptr;
|
||||
pending_request->Start();
|
||||
}
|
||||
|
||||
void TlsChannelSecurityConnector::cancel_check_peer(
|
||||
grpc_closure* on_peer_checked, grpc_error_handle error) {
|
||||
if (error != GRPC_ERROR_NONE) {
|
||||
gpr_log(GPR_ERROR,
|
||||
"TlsChannelSecurityConnector::cancel_check_peer error: %s",
|
||||
grpc_error_std_string(error).c_str());
|
||||
GRPC_ERROR_UNREF(error);
|
||||
return;
|
||||
}
|
||||
auto* verifier = options_->certificate_verifier();
|
||||
if (verifier != nullptr) {
|
||||
grpc_tls_custom_verification_check_request* pending_verifier_request =
|
||||
nullptr;
|
||||
{
|
||||
MutexLock lock(&verifier_request_map_mu_);
|
||||
auto it = pending_verifier_requests_.find(on_peer_checked);
|
||||
if (it != pending_verifier_requests_.end()) {
|
||||
pending_verifier_request = it->second->request();
|
||||
} else {
|
||||
check_arg_->subject_alternative_names =
|
||||
new char*[check_arg_->subject_alternative_names_size];
|
||||
for (size_t i = 0; i < check_arg_->subject_alternative_names_size;
|
||||
++i) {
|
||||
check_arg_->subject_alternative_names[i] =
|
||||
subject_alternative_names[i];
|
||||
}
|
||||
gpr_log(GPR_INFO,
|
||||
"TlsChannelSecurityConnector::cancel_check_peer: no "
|
||||
"corresponding pending request found");
|
||||
}
|
||||
int callback_status = config->Schedule(check_arg_);
|
||||
/* Server authorization check is handled asynchronously. */
|
||||
if (callback_status) {
|
||||
tsi_peer_destruct(&peer);
|
||||
return;
|
||||
}
|
||||
/* Server authorization check is handled synchronously. */
|
||||
error = ProcessServerAuthorizationCheckResult(check_arg_);
|
||||
}
|
||||
if (pending_verifier_request != nullptr) {
|
||||
verifier->Cancel(pending_verifier_request);
|
||||
}
|
||||
}
|
||||
ExecCtx::Run(DEBUG_LOCATION, on_peer_checked, error);
|
||||
tsi_peer_destruct(&peer);
|
||||
}
|
||||
|
||||
int TlsChannelSecurityConnector::cmp(
|
||||
const grpc_security_connector* other_sc) const {
|
||||
auto* other = reinterpret_cast<const TlsChannelSecurityConnector*>(other_sc);
|
||||
int c = channel_security_connector_cmp(other);
|
||||
if (c != 0) {
|
||||
return c;
|
||||
}
|
||||
return grpc_ssl_cmp_target_name(
|
||||
if (c != 0) return c;
|
||||
c = grpc_ssl_cmp_target_name(
|
||||
target_name_.c_str(), other->target_name_.c_str(),
|
||||
overridden_target_name_.c_str(), other->overridden_target_name_.c_str());
|
||||
if (c != 0) return c;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool TlsChannelSecurityConnector::check_call_host(
|
||||
absl::string_view host, grpc_auth_context* auth_context,
|
||||
grpc_closure* /*on_call_host_checked*/, grpc_error_handle* error) {
|
||||
if (options_->server_verification_option() ==
|
||||
GRPC_TLS_SKIP_HOSTNAME_VERIFICATION ||
|
||||
options_->server_verification_option() ==
|
||||
GRPC_TLS_SKIP_ALL_SERVER_VERIFICATION) {
|
||||
return true;
|
||||
if (options_->check_call_host()) {
|
||||
return grpc_ssl_check_call_host(host, target_name_.c_str(),
|
||||
overridden_target_name_.c_str(),
|
||||
auth_context, error);
|
||||
}
|
||||
return grpc_ssl_check_call_host(host, target_name_.c_str(),
|
||||
overridden_target_name_.c_str(), auth_context,
|
||||
error);
|
||||
return true;
|
||||
}
|
||||
|
||||
void TlsChannelSecurityConnector::cancel_check_call_host(
|
||||
|
|
@ -369,13 +461,61 @@ void TlsChannelSecurityConnector::TlsChannelCertificateWatcher::OnError(
|
|||
GRPC_ERROR_UNREF(identity_cert_error);
|
||||
}
|
||||
|
||||
TlsChannelSecurityConnector::ChannelPendingVerifierRequest::
|
||||
ChannelPendingVerifierRequest(
|
||||
RefCountedPtr<TlsChannelSecurityConnector> security_connector,
|
||||
grpc_closure* on_peer_checked, tsi_peer peer, const char* target_name)
|
||||
: security_connector_(std::move(security_connector)),
|
||||
on_peer_checked_(on_peer_checked) {
|
||||
PendingVerifierRequestInit(target_name, peer, &request_);
|
||||
tsi_peer_destruct(&peer);
|
||||
}
|
||||
|
||||
TlsChannelSecurityConnector::ChannelPendingVerifierRequest::
|
||||
~ChannelPendingVerifierRequest() {
|
||||
PendingVerifierRequestDestroy(&request_);
|
||||
}
|
||||
|
||||
void TlsChannelSecurityConnector::ChannelPendingVerifierRequest::Start() {
|
||||
absl::Status sync_status;
|
||||
grpc_tls_certificate_verifier* verifier =
|
||||
security_connector_->options_->certificate_verifier();
|
||||
bool is_done = verifier->Verify(
|
||||
&request_,
|
||||
absl::bind_front(&ChannelPendingVerifierRequest::OnVerifyDone, this,
|
||||
true),
|
||||
&sync_status);
|
||||
if (is_done) {
|
||||
OnVerifyDone(false, sync_status);
|
||||
}
|
||||
}
|
||||
|
||||
void TlsChannelSecurityConnector::ChannelPendingVerifierRequest::OnVerifyDone(
|
||||
bool run_callback_inline, absl::Status status) {
|
||||
{
|
||||
MutexLock lock(&security_connector_->verifier_request_map_mu_);
|
||||
security_connector_->pending_verifier_requests_.erase(on_peer_checked_);
|
||||
}
|
||||
grpc_error_handle error = GRPC_ERROR_NONE;
|
||||
if (!status.ok()) {
|
||||
error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(
|
||||
absl::StrCat("Custom verification check failed with error: ",
|
||||
status.ToString())
|
||||
.c_str());
|
||||
}
|
||||
if (run_callback_inline) {
|
||||
Closure::Run(DEBUG_LOCATION, on_peer_checked_, error);
|
||||
} else {
|
||||
ExecCtx::Run(DEBUG_LOCATION, on_peer_checked_, error);
|
||||
}
|
||||
delete this;
|
||||
}
|
||||
|
||||
// TODO(ZhenLian): implement the logic to signal waiting handshakers once
|
||||
// BlockOnInitialCredentialHandshaker is implemented.
|
||||
grpc_security_status
|
||||
TlsChannelSecurityConnector::UpdateHandshakerFactoryLocked() {
|
||||
bool skip_server_certificate_verification =
|
||||
options_->server_verification_option() ==
|
||||
GRPC_TLS_SKIP_ALL_SERVER_VERIFICATION;
|
||||
bool skip_server_certificate_verification = !options_->verify_server_cert();
|
||||
/* Free the client handshaker factory if exists. */
|
||||
if (client_handshaker_factory_ != nullptr) {
|
||||
tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory_);
|
||||
|
|
@ -406,79 +546,6 @@ TlsChannelSecurityConnector::UpdateHandshakerFactoryLocked() {
|
|||
return status;
|
||||
}
|
||||
|
||||
void TlsChannelSecurityConnector::ServerAuthorizationCheckDone(
|
||||
grpc_tls_server_authorization_check_arg* arg) {
|
||||
GPR_ASSERT(arg != nullptr);
|
||||
ExecCtx exec_ctx;
|
||||
grpc_error_handle error = ProcessServerAuthorizationCheckResult(arg);
|
||||
TlsChannelSecurityConnector* connector =
|
||||
static_cast<TlsChannelSecurityConnector*>(arg->cb_user_data);
|
||||
ExecCtx::Run(DEBUG_LOCATION, connector->on_peer_checked_, error);
|
||||
}
|
||||
|
||||
grpc_error_handle
|
||||
TlsChannelSecurityConnector::ProcessServerAuthorizationCheckResult(
|
||||
grpc_tls_server_authorization_check_arg* arg) {
|
||||
grpc_error_handle error = GRPC_ERROR_NONE;
|
||||
/* Server authorization check is cancelled by caller. */
|
||||
if (arg->status == GRPC_STATUS_CANCELLED) {
|
||||
error = GRPC_ERROR_CREATE_FROM_CPP_STRING(
|
||||
absl::StrCat("Server authorization check is cancelled by the caller "
|
||||
"with error: ",
|
||||
arg->error_details->error_details()));
|
||||
} else if (arg->status == GRPC_STATUS_OK) {
|
||||
/* Server authorization check completed successfully but returned check
|
||||
* failure. */
|
||||
if (!arg->success) {
|
||||
error = GRPC_ERROR_CREATE_FROM_CPP_STRING(
|
||||
absl::StrCat("Server authorization check failed with error: ",
|
||||
arg->error_details->error_details()));
|
||||
}
|
||||
/* Server authorization check did not complete correctly. */
|
||||
} else {
|
||||
error = GRPC_ERROR_CREATE_FROM_CPP_STRING(absl::StrCat(
|
||||
"Server authorization check did not finish correctly with error: ",
|
||||
arg->error_details->error_details()));
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
grpc_tls_server_authorization_check_arg*
|
||||
TlsChannelSecurityConnector::ServerAuthorizationCheckArgCreate(
|
||||
void* user_data) {
|
||||
grpc_tls_server_authorization_check_arg* arg =
|
||||
new grpc_tls_server_authorization_check_arg();
|
||||
arg->target_name = nullptr;
|
||||
arg->peer_cert = nullptr;
|
||||
arg->peer_cert_full_chain = nullptr;
|
||||
arg->subject_alternative_names = nullptr;
|
||||
arg->subject_alternative_names_size = 0;
|
||||
arg->error_details = new grpc_tls_error_details();
|
||||
arg->cb = ServerAuthorizationCheckDone;
|
||||
arg->cb_user_data = user_data;
|
||||
arg->status = GRPC_STATUS_OK;
|
||||
return arg;
|
||||
}
|
||||
|
||||
void TlsChannelSecurityConnector::ServerAuthorizationCheckArgDestroy(
|
||||
grpc_tls_server_authorization_check_arg* arg) {
|
||||
if (arg == nullptr) {
|
||||
return;
|
||||
}
|
||||
gpr_free(const_cast<char*>(arg->target_name));
|
||||
gpr_free(const_cast<char*>(arg->peer_cert));
|
||||
gpr_free(const_cast<char*>(arg->peer_cert_full_chain));
|
||||
for (size_t i = 0; i < arg->subject_alternative_names_size; ++i) {
|
||||
delete[] arg->subject_alternative_names[i];
|
||||
}
|
||||
delete[] arg->subject_alternative_names;
|
||||
delete arg->error_details;
|
||||
if (arg->destroy_context != nullptr) {
|
||||
arg->destroy_context(arg->context);
|
||||
}
|
||||
delete arg;
|
||||
}
|
||||
|
||||
// -------------------server security connector-------------------
|
||||
RefCountedPtr<grpc_server_security_connector>
|
||||
TlsServerSecurityConnector::CreateTlsServerSecurityConnector(
|
||||
|
|
@ -559,16 +626,63 @@ void TlsServerSecurityConnector::check_peer(
|
|||
RefCountedPtr<grpc_auth_context>* auth_context,
|
||||
grpc_closure* on_peer_checked) {
|
||||
grpc_error_handle error = grpc_ssl_check_alpn(&peer);
|
||||
if (error != GRPC_ERROR_NONE) {
|
||||
ExecCtx::Run(DEBUG_LOCATION, on_peer_checked, error);
|
||||
tsi_peer_destruct(&peer);
|
||||
return;
|
||||
}
|
||||
*auth_context =
|
||||
grpc_ssl_peer_to_auth_context(&peer, GRPC_TLS_TRANSPORT_SECURITY_TYPE);
|
||||
tsi_peer_destruct(&peer);
|
||||
ExecCtx::Run(DEBUG_LOCATION, on_peer_checked, error);
|
||||
if (options_->certificate_verifier() != nullptr) {
|
||||
auto* pending_request =
|
||||
new ServerPendingVerifierRequest(Ref(), on_peer_checked, peer);
|
||||
{
|
||||
MutexLock lock(&verifier_request_map_mu_);
|
||||
pending_verifier_requests_.emplace(on_peer_checked, pending_request);
|
||||
}
|
||||
pending_request->Start();
|
||||
} else {
|
||||
tsi_peer_destruct(&peer);
|
||||
ExecCtx::Run(DEBUG_LOCATION, on_peer_checked, error);
|
||||
}
|
||||
}
|
||||
|
||||
void TlsServerSecurityConnector::cancel_check_peer(
|
||||
grpc_closure* on_peer_checked, grpc_error_handle error) {
|
||||
if (error != GRPC_ERROR_NONE) {
|
||||
gpr_log(GPR_ERROR,
|
||||
"TlsServerSecurityConnector::cancel_check_peer error: %s",
|
||||
grpc_error_std_string(error).c_str());
|
||||
GRPC_ERROR_UNREF(error);
|
||||
return;
|
||||
}
|
||||
auto* verifier = options_->certificate_verifier();
|
||||
if (verifier != nullptr) {
|
||||
grpc_tls_custom_verification_check_request* pending_verifier_request =
|
||||
nullptr;
|
||||
{
|
||||
MutexLock lock(&verifier_request_map_mu_);
|
||||
auto it = pending_verifier_requests_.find(on_peer_checked);
|
||||
if (it != pending_verifier_requests_.end()) {
|
||||
pending_verifier_request = it->second->request();
|
||||
} else {
|
||||
gpr_log(GPR_INFO,
|
||||
"TlsServerSecurityConnector::cancel_check_peer: no "
|
||||
"corresponding pending request found");
|
||||
}
|
||||
}
|
||||
if (pending_verifier_request != nullptr) {
|
||||
verifier->Cancel(pending_verifier_request);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int TlsServerSecurityConnector::cmp(
|
||||
const grpc_security_connector* other) const {
|
||||
return server_security_connector_cmp(
|
||||
static_cast<const grpc_server_security_connector*>(other));
|
||||
const grpc_security_connector* other_sc) const {
|
||||
auto* other = reinterpret_cast<const TlsServerSecurityConnector*>(other_sc);
|
||||
int c = server_security_connector_cmp(other);
|
||||
if (c != 0) return c;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TlsServerSecurityConnector::TlsServerCertificateWatcher::
|
||||
|
|
@ -617,6 +731,55 @@ void TlsServerSecurityConnector::TlsServerCertificateWatcher::OnError(
|
|||
GRPC_ERROR_UNREF(identity_cert_error);
|
||||
}
|
||||
|
||||
TlsServerSecurityConnector::ServerPendingVerifierRequest::
|
||||
ServerPendingVerifierRequest(
|
||||
RefCountedPtr<TlsServerSecurityConnector> security_connector,
|
||||
grpc_closure* on_peer_checked, tsi_peer peer)
|
||||
: security_connector_(std::move(security_connector)),
|
||||
on_peer_checked_(on_peer_checked) {
|
||||
PendingVerifierRequestInit(nullptr, peer, &request_);
|
||||
tsi_peer_destruct(&peer);
|
||||
}
|
||||
|
||||
TlsServerSecurityConnector::ServerPendingVerifierRequest::
|
||||
~ServerPendingVerifierRequest() {
|
||||
PendingVerifierRequestDestroy(&request_);
|
||||
}
|
||||
|
||||
void TlsServerSecurityConnector::ServerPendingVerifierRequest::Start() {
|
||||
absl::Status sync_status;
|
||||
grpc_tls_certificate_verifier* verifier =
|
||||
security_connector_->options_->certificate_verifier();
|
||||
bool is_done = verifier->Verify(
|
||||
&request_,
|
||||
absl::bind_front(&ServerPendingVerifierRequest::OnVerifyDone, this, true),
|
||||
&sync_status);
|
||||
if (is_done) {
|
||||
OnVerifyDone(false, sync_status);
|
||||
}
|
||||
}
|
||||
|
||||
void TlsServerSecurityConnector::ServerPendingVerifierRequest::OnVerifyDone(
|
||||
bool run_callback_inline, absl::Status status) {
|
||||
{
|
||||
MutexLock lock(&security_connector_->verifier_request_map_mu_);
|
||||
security_connector_->pending_verifier_requests_.erase(on_peer_checked_);
|
||||
}
|
||||
grpc_error_handle error = GRPC_ERROR_NONE;
|
||||
if (!status.ok()) {
|
||||
error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(
|
||||
absl::StrCat("Custom verification check failed with error: ",
|
||||
status.ToString())
|
||||
.c_str());
|
||||
}
|
||||
if (run_callback_inline) {
|
||||
Closure::Run(DEBUG_LOCATION, on_peer_checked_, error);
|
||||
} else {
|
||||
ExecCtx::Run(DEBUG_LOCATION, on_peer_checked_, error);
|
||||
}
|
||||
delete this;
|
||||
}
|
||||
|
||||
// TODO(ZhenLian): implement the logic to signal waiting handshakers once
|
||||
// BlockOnInitialCredentialHandshaker is implemented.
|
||||
grpc_security_status
|
||||
|
|
@ -650,18 +813,4 @@ TlsServerSecurityConnector::UpdateHandshakerFactoryLocked() {
|
|||
return status;
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
grpc_error_handle 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_CPP_STRING(
|
||||
absl::StrCat("Peer name ", peer_name, " is not in peer certificate"));
|
||||
}
|
||||
return GRPC_ERROR_NONE;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // namespace grpc_core
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@
|
|||
|
||||
#include <grpc/support/port_platform.h>
|
||||
|
||||
#include "absl/status/status.h"
|
||||
|
||||
#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"
|
||||
|
|
@ -58,11 +60,8 @@ class TlsChannelSecurityConnector final
|
|||
RefCountedPtr<grpc_auth_context>* auth_context,
|
||||
grpc_closure* on_peer_checked) override;
|
||||
|
||||
void cancel_check_peer(grpc_closure* /*on_peer_checked*/,
|
||||
grpc_error_handle error) override {
|
||||
// TODO(ZhenLian): call verifier->cancel() once the verifier is ready.
|
||||
GRPC_ERROR_UNREF(error);
|
||||
}
|
||||
void cancel_check_peer(grpc_closure* on_peer_checked,
|
||||
grpc_error_handle error) override;
|
||||
|
||||
int cmp(const grpc_security_connector* other_sc) const override;
|
||||
|
||||
|
|
@ -108,43 +107,51 @@ class TlsChannelSecurityConnector final
|
|||
TlsChannelSecurityConnector* security_connector_ = nullptr;
|
||||
};
|
||||
|
||||
// Use "new" to create a new instance, and no need to delete it later, since
|
||||
// it will be self-destroyed in |OnVerifyDone|.
|
||||
class ChannelPendingVerifierRequest {
|
||||
public:
|
||||
ChannelPendingVerifierRequest(
|
||||
RefCountedPtr<TlsChannelSecurityConnector> security_connector,
|
||||
grpc_closure* on_peer_checked, tsi_peer peer, const char* target_name);
|
||||
|
||||
~ChannelPendingVerifierRequest();
|
||||
|
||||
void Start();
|
||||
|
||||
grpc_tls_custom_verification_check_request* request() { return &request_; }
|
||||
|
||||
private:
|
||||
void OnVerifyDone(bool run_callback_inline, absl::Status status);
|
||||
// The request will keep a reference of the security connector to make sure
|
||||
// it won't be destroyed while the request is still ongoing.
|
||||
RefCountedPtr<TlsChannelSecurityConnector> security_connector_;
|
||||
grpc_tls_custom_verification_check_request request_;
|
||||
grpc_closure* on_peer_checked_;
|
||||
};
|
||||
|
||||
// Updates |client_handshaker_factory_| when the certificates that
|
||||
// |certificate_watcher_| is watching get updated.
|
||||
grpc_security_status UpdateHandshakerFactoryLocked()
|
||||
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_);
|
||||
|
||||
// gRPC-provided callback executed by application, which servers to bring the
|
||||
// control back to gRPC core.
|
||||
static void ServerAuthorizationCheckDone(
|
||||
grpc_tls_server_authorization_check_arg* arg);
|
||||
|
||||
// A util function to process server authorization check result.
|
||||
static grpc_error_handle ProcessServerAuthorizationCheckResult(
|
||||
grpc_tls_server_authorization_check_arg* arg);
|
||||
|
||||
// A util function to create a server authorization check arg instance.
|
||||
static grpc_tls_server_authorization_check_arg*
|
||||
ServerAuthorizationCheckArgCreate(void* user_data);
|
||||
|
||||
// A util function to destroy a server authorization check arg instance.
|
||||
static void ServerAuthorizationCheckArgDestroy(
|
||||
grpc_tls_server_authorization_check_arg* arg);
|
||||
|
||||
Mutex mu_;
|
||||
// We need a separate mutex for |pending_verifier_requests_|, otherwise there
|
||||
// would be deadlock errors.
|
||||
Mutex verifier_request_map_mu_;
|
||||
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_;
|
||||
grpc_tls_server_authorization_check_arg* check_arg_ = nullptr;
|
||||
|
||||
Mutex mu_;
|
||||
tsi_ssl_client_handshaker_factory* client_handshaker_factory_
|
||||
ABSL_GUARDED_BY(mu_) = nullptr;
|
||||
tsi_ssl_session_cache* ssl_session_cache_ ABSL_GUARDED_BY(mu_) = nullptr;
|
||||
absl::optional<absl::string_view> pem_root_certs_ ABSL_GUARDED_BY(mu_);
|
||||
absl::optional<PemKeyCertPairList> pem_key_cert_pair_list_
|
||||
ABSL_GUARDED_BY(mu_);
|
||||
std::map<grpc_closure* /*on_peer_checked*/, ChannelPendingVerifierRequest*>
|
||||
pending_verifier_requests_ ABSL_GUARDED_BY(verifier_request_map_mu_);
|
||||
};
|
||||
|
||||
// Server security connector using TLS as transport security protocol.
|
||||
|
|
@ -170,10 +177,7 @@ class TlsServerSecurityConnector final : public grpc_server_security_connector {
|
|||
grpc_closure* on_peer_checked) override;
|
||||
|
||||
void cancel_check_peer(grpc_closure* /*on_peer_checked*/,
|
||||
grpc_error_handle error) override {
|
||||
// TODO(ZhenLian): call verifier->cancel() once the verifier is ready.
|
||||
GRPC_ERROR_UNREF(error);
|
||||
}
|
||||
grpc_error_handle error) override;
|
||||
|
||||
int cmp(const grpc_security_connector* other) const override;
|
||||
|
||||
|
|
@ -205,6 +209,7 @@ class TlsServerSecurityConnector final : public grpc_server_security_connector {
|
|||
void OnCertificatesChanged(
|
||||
absl::optional<absl::string_view> root_certs,
|
||||
absl::optional<PemKeyCertPairList> key_cert_pairs) override;
|
||||
|
||||
void OnError(grpc_error_handle root_cert_error,
|
||||
grpc_error_handle identity_cert_error) override;
|
||||
|
||||
|
|
@ -212,32 +217,50 @@ class TlsServerSecurityConnector final : public grpc_server_security_connector {
|
|||
TlsServerSecurityConnector* security_connector_ = nullptr;
|
||||
};
|
||||
|
||||
// Use "new" to create a new instance, and no need to delete it later, since
|
||||
// it will be self-destroyed in |OnVerifyDone|.
|
||||
class ServerPendingVerifierRequest {
|
||||
public:
|
||||
ServerPendingVerifierRequest(
|
||||
RefCountedPtr<TlsServerSecurityConnector> security_connector,
|
||||
grpc_closure* on_peer_checked, tsi_peer peer);
|
||||
|
||||
~ServerPendingVerifierRequest();
|
||||
|
||||
void Start();
|
||||
|
||||
grpc_tls_custom_verification_check_request* request() { return &request_; }
|
||||
|
||||
private:
|
||||
void OnVerifyDone(bool run_callback_inline, absl::Status status);
|
||||
// The request will keep a reference of the security connector to make sure
|
||||
// it won't be destroyed while the request is still ongoing.
|
||||
RefCountedPtr<TlsServerSecurityConnector> security_connector_;
|
||||
grpc_tls_custom_verification_check_request request_;
|
||||
grpc_closure* on_peer_checked_;
|
||||
};
|
||||
|
||||
// Updates |server_handshaker_factory_| when the certificates that
|
||||
// |certificate_watcher_| is watching get updated.
|
||||
grpc_security_status UpdateHandshakerFactoryLocked()
|
||||
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_);
|
||||
|
||||
Mutex mu_;
|
||||
// We need a separate mutex for |pending_verifier_requests_|, otherwise there
|
||||
// would be deadlock errors.
|
||||
Mutex verifier_request_map_mu_;
|
||||
RefCountedPtr<grpc_tls_credentials_options> options_;
|
||||
grpc_tls_certificate_distributor::TlsCertificatesWatcherInterface*
|
||||
certificate_watcher_ = nullptr;
|
||||
|
||||
Mutex mu_;
|
||||
tsi_ssl_server_handshaker_factory* server_handshaker_factory_
|
||||
ABSL_GUARDED_BY(mu_) = nullptr;
|
||||
absl::optional<absl::string_view> pem_root_certs_ ABSL_GUARDED_BY(mu_);
|
||||
absl::optional<PemKeyCertPairList> pem_key_cert_pair_list_
|
||||
ABSL_GUARDED_BY(mu_);
|
||||
std::map<grpc_closure* /*on_peer_checked*/, ServerPendingVerifierRequest*>
|
||||
pending_verifier_requests_ ABSL_GUARDED_BY(verifier_request_map_mu_);
|
||||
};
|
||||
|
||||
// ---- Functions below are exposed for testing only -----------------------
|
||||
namespace internal {
|
||||
|
||||
// TlsCheckHostName checks if |peer_name| matches the identity information
|
||||
// contained in |peer|. This is AKA hostname check.
|
||||
grpc_error_handle 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
|
||||
|
|
|
|||
|
|
@ -0,0 +1,244 @@
|
|||
//
|
||||
// Copyright 2021 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 "absl/container/inlined_vector.h"
|
||||
#include "absl/status/status.h"
|
||||
|
||||
#include <grpc/grpc_security.h>
|
||||
#include <grpc/support/alloc.h>
|
||||
#include <grpc/support/string_util.h>
|
||||
#include <grpcpp/security/tls_certificate_verifier.h>
|
||||
|
||||
namespace grpc {
|
||||
namespace experimental {
|
||||
|
||||
static internal::GrpcLibraryInitializer g_gli_initializer;
|
||||
|
||||
TlsCustomVerificationCheckRequest::TlsCustomVerificationCheckRequest(
|
||||
grpc_tls_custom_verification_check_request* request)
|
||||
: c_request_(request) {
|
||||
GPR_ASSERT(c_request_ != nullptr);
|
||||
}
|
||||
|
||||
grpc::string_ref TlsCustomVerificationCheckRequest::target_name() const {
|
||||
return c_request_->target_name != nullptr ? c_request_->target_name : "";
|
||||
}
|
||||
|
||||
grpc::string_ref TlsCustomVerificationCheckRequest::peer_cert() const {
|
||||
return c_request_->peer_info.peer_cert != nullptr
|
||||
? c_request_->peer_info.peer_cert
|
||||
: "";
|
||||
}
|
||||
|
||||
grpc::string_ref TlsCustomVerificationCheckRequest::peer_cert_full_chain()
|
||||
const {
|
||||
return c_request_->peer_info.peer_cert_full_chain != nullptr
|
||||
? c_request_->peer_info.peer_cert_full_chain
|
||||
: "";
|
||||
}
|
||||
|
||||
grpc::string_ref TlsCustomVerificationCheckRequest::common_name() const {
|
||||
return c_request_->peer_info.common_name != nullptr
|
||||
? c_request_->peer_info.common_name
|
||||
: "";
|
||||
}
|
||||
|
||||
std::vector<grpc::string_ref> TlsCustomVerificationCheckRequest::uri_names()
|
||||
const {
|
||||
std::vector<grpc::string_ref> uri_names;
|
||||
for (size_t i = 0; i < c_request_->peer_info.san_names.uri_names_size; ++i) {
|
||||
uri_names.emplace_back(c_request_->peer_info.san_names.uri_names[i]);
|
||||
}
|
||||
return uri_names;
|
||||
}
|
||||
|
||||
std::vector<grpc::string_ref> TlsCustomVerificationCheckRequest::dns_names()
|
||||
const {
|
||||
std::vector<grpc::string_ref> dns_names;
|
||||
for (size_t i = 0; i < c_request_->peer_info.san_names.dns_names_size; ++i) {
|
||||
dns_names.emplace_back(c_request_->peer_info.san_names.dns_names[i]);
|
||||
}
|
||||
return dns_names;
|
||||
}
|
||||
|
||||
std::vector<grpc::string_ref> TlsCustomVerificationCheckRequest::email_names()
|
||||
const {
|
||||
std::vector<grpc::string_ref> email_names;
|
||||
for (size_t i = 0; i < c_request_->peer_info.san_names.email_names_size;
|
||||
++i) {
|
||||
email_names.emplace_back(c_request_->peer_info.san_names.email_names[i]);
|
||||
}
|
||||
return email_names;
|
||||
}
|
||||
|
||||
std::vector<grpc::string_ref> TlsCustomVerificationCheckRequest::ip_names()
|
||||
const {
|
||||
std::vector<grpc::string_ref> ip_names;
|
||||
for (size_t i = 0; i < c_request_->peer_info.san_names.ip_names_size; ++i) {
|
||||
ip_names.emplace_back(c_request_->peer_info.san_names.ip_names[i]);
|
||||
}
|
||||
return ip_names;
|
||||
}
|
||||
|
||||
CertificateVerifier::CertificateVerifier(grpc_tls_certificate_verifier* v)
|
||||
: verifier_(v) {
|
||||
g_gli_initializer.summon();
|
||||
}
|
||||
|
||||
CertificateVerifier::~CertificateVerifier() {
|
||||
grpc_tls_certificate_verifier_release(verifier_);
|
||||
}
|
||||
|
||||
bool CertificateVerifier::Verify(TlsCustomVerificationCheckRequest* request,
|
||||
std::function<void(grpc::Status)> callback,
|
||||
grpc::Status* sync_status) {
|
||||
GPR_ASSERT(request != nullptr);
|
||||
GPR_ASSERT(request->c_request() != nullptr);
|
||||
{
|
||||
internal::MutexLock lock(&mu_);
|
||||
request_map_.emplace(request->c_request(), std::move(callback));
|
||||
}
|
||||
grpc_status_code status_code = GRPC_STATUS_OK;
|
||||
char* error_details = nullptr;
|
||||
bool is_done = grpc_tls_certificate_verifier_verify(
|
||||
verifier_, request->c_request(), &AsyncCheckDone, this, &status_code,
|
||||
&error_details);
|
||||
if (is_done) {
|
||||
if (status_code != GRPC_STATUS_OK) {
|
||||
*sync_status = grpc::Status(static_cast<grpc::StatusCode>(status_code),
|
||||
error_details);
|
||||
}
|
||||
internal::MutexLock lock(&mu_);
|
||||
request_map_.erase(request->c_request());
|
||||
}
|
||||
gpr_free(error_details);
|
||||
return is_done;
|
||||
}
|
||||
|
||||
void CertificateVerifier::Cancel(TlsCustomVerificationCheckRequest* request) {
|
||||
GPR_ASSERT(request != nullptr);
|
||||
GPR_ASSERT(request->c_request() != nullptr);
|
||||
grpc_tls_certificate_verifier_cancel(verifier_, request->c_request());
|
||||
}
|
||||
|
||||
void CertificateVerifier::AsyncCheckDone(
|
||||
grpc_tls_custom_verification_check_request* request, void* callback_arg,
|
||||
grpc_status_code status, const char* error_details) {
|
||||
auto* self = static_cast<CertificateVerifier*>(callback_arg);
|
||||
std::function<void(grpc::Status)> callback;
|
||||
{
|
||||
internal::MutexLock lock(&self->mu_);
|
||||
auto it = self->request_map_.find(request);
|
||||
if (it != self->request_map_.end()) {
|
||||
callback = std::move(it->second);
|
||||
self->request_map_.erase(it);
|
||||
}
|
||||
}
|
||||
if (callback != nullptr) {
|
||||
grpc::Status return_status;
|
||||
if (status != GRPC_STATUS_OK) {
|
||||
return_status =
|
||||
grpc::Status(static_cast<grpc::StatusCode>(status), error_details);
|
||||
}
|
||||
callback(return_status);
|
||||
}
|
||||
}
|
||||
|
||||
ExternalCertificateVerifier::ExternalCertificateVerifier() {
|
||||
base_ = new grpc_tls_certificate_verifier_external();
|
||||
base_->user_data = this;
|
||||
base_->verify = VerifyInCoreExternalVerifier;
|
||||
base_->cancel = CancelInCoreExternalVerifier;
|
||||
base_->destruct = DestructInCoreExternalVerifier;
|
||||
}
|
||||
|
||||
ExternalCertificateVerifier::~ExternalCertificateVerifier() { delete base_; }
|
||||
|
||||
int ExternalCertificateVerifier::VerifyInCoreExternalVerifier(
|
||||
void* user_data, grpc_tls_custom_verification_check_request* request,
|
||||
grpc_tls_on_custom_verification_check_done_cb callback, void* callback_arg,
|
||||
grpc_status_code* sync_status, char** sync_error_details) {
|
||||
auto* self = static_cast<ExternalCertificateVerifier*>(user_data);
|
||||
TlsCustomVerificationCheckRequest* cpp_request = nullptr;
|
||||
{
|
||||
internal::MutexLock lock(&self->mu_);
|
||||
auto pair = self->request_map_.emplace(
|
||||
request, AsyncRequestState(callback, callback_arg, request));
|
||||
GPR_ASSERT(pair.second);
|
||||
cpp_request = &pair.first->second.cpp_request;
|
||||
}
|
||||
grpc::Status sync_current_verifier_status;
|
||||
bool is_done = self->Verify(
|
||||
cpp_request,
|
||||
[self, request](grpc::Status status) {
|
||||
grpc_tls_on_custom_verification_check_done_cb callback = nullptr;
|
||||
void* callback_arg = nullptr;
|
||||
{
|
||||
internal::MutexLock lock(&self->mu_);
|
||||
auto it = self->request_map_.find(request);
|
||||
if (it != self->request_map_.end()) {
|
||||
callback = it->second.callback;
|
||||
callback_arg = it->second.callback_arg;
|
||||
self->request_map_.erase(it);
|
||||
}
|
||||
}
|
||||
if (callback != nullptr) {
|
||||
callback(request, callback_arg,
|
||||
static_cast<grpc_status_code>(status.error_code()),
|
||||
status.error_message().c_str());
|
||||
}
|
||||
},
|
||||
&sync_current_verifier_status);
|
||||
if (is_done) {
|
||||
if (!sync_current_verifier_status.ok()) {
|
||||
*sync_status = static_cast<grpc_status_code>(
|
||||
sync_current_verifier_status.error_code());
|
||||
*sync_error_details =
|
||||
gpr_strdup(sync_current_verifier_status.error_message().c_str());
|
||||
}
|
||||
internal::MutexLock lock(&self->mu_);
|
||||
self->request_map_.erase(request);
|
||||
}
|
||||
return is_done;
|
||||
}
|
||||
|
||||
void ExternalCertificateVerifier::CancelInCoreExternalVerifier(
|
||||
void* user_data, grpc_tls_custom_verification_check_request* request) {
|
||||
auto* self = static_cast<ExternalCertificateVerifier*>(user_data);
|
||||
TlsCustomVerificationCheckRequest* cpp_request = nullptr;
|
||||
{
|
||||
internal::MutexLock lock(&self->mu_);
|
||||
auto it = self->request_map_.find(request);
|
||||
if (it != self->request_map_.end()) {
|
||||
cpp_request = &it->second.cpp_request;
|
||||
}
|
||||
}
|
||||
if (cpp_request != nullptr) {
|
||||
self->Cancel(cpp_request);
|
||||
}
|
||||
}
|
||||
|
||||
void ExternalCertificateVerifier::DestructInCoreExternalVerifier(
|
||||
void* user_data) {
|
||||
auto* self = static_cast<ExternalCertificateVerifier*>(user_data);
|
||||
delete self;
|
||||
}
|
||||
|
||||
HostNameCertificateVerifier::HostNameCertificateVerifier()
|
||||
: CertificateVerifier(grpc_tls_certificate_verifier_host_name_create()) {}
|
||||
|
||||
} // namespace experimental
|
||||
} // namespace grpc
|
||||
|
|
@ -22,109 +22,9 @@
|
|||
#include <grpc/support/alloc.h>
|
||||
#include <grpcpp/security/tls_credentials_options.h>
|
||||
|
||||
#include "src/cpp/common/tls_credentials_options_util.h"
|
||||
|
||||
namespace grpc {
|
||||
namespace experimental {
|
||||
|
||||
/** gRPC TLS server authorization check arg API implementation **/
|
||||
TlsServerAuthorizationCheckArg::TlsServerAuthorizationCheckArg(
|
||||
grpc_tls_server_authorization_check_arg* arg)
|
||||
: c_arg_(arg) {
|
||||
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);
|
||||
c_arg_->destroy_context = &TlsServerAuthorizationCheckArgDestroyContext;
|
||||
}
|
||||
|
||||
TlsServerAuthorizationCheckArg::~TlsServerAuthorizationCheckArg() {}
|
||||
|
||||
void* TlsServerAuthorizationCheckArg::cb_user_data() const {
|
||||
return c_arg_->cb_user_data;
|
||||
}
|
||||
|
||||
int TlsServerAuthorizationCheckArg::success() const { return c_arg_->success; }
|
||||
|
||||
std::string TlsServerAuthorizationCheckArg::target_name() const {
|
||||
std::string cpp_target_name(c_arg_->target_name);
|
||||
return cpp_target_name;
|
||||
}
|
||||
|
||||
std::string TlsServerAuthorizationCheckArg::peer_cert() const {
|
||||
std::string cpp_peer_cert(c_arg_->peer_cert);
|
||||
return cpp_peer_cert;
|
||||
}
|
||||
|
||||
std::string TlsServerAuthorizationCheckArg::peer_cert_full_chain() const {
|
||||
std::string cpp_peer_cert_full_chain(c_arg_->peer_cert_full_chain);
|
||||
return cpp_peer_cert_full_chain;
|
||||
}
|
||||
|
||||
grpc_status_code TlsServerAuthorizationCheckArg::status() const {
|
||||
return c_arg_->status;
|
||||
}
|
||||
|
||||
std::string TlsServerAuthorizationCheckArg::error_details() const {
|
||||
return c_arg_->error_details->error_details();
|
||||
}
|
||||
|
||||
void TlsServerAuthorizationCheckArg::set_cb_user_data(void* cb_user_data) {
|
||||
c_arg_->cb_user_data = cb_user_data;
|
||||
}
|
||||
|
||||
void TlsServerAuthorizationCheckArg::set_success(int success) {
|
||||
c_arg_->success = success;
|
||||
}
|
||||
|
||||
void TlsServerAuthorizationCheckArg::set_target_name(
|
||||
const std::string& target_name) {
|
||||
c_arg_->target_name = gpr_strdup(target_name.c_str());
|
||||
}
|
||||
|
||||
void TlsServerAuthorizationCheckArg::set_peer_cert(
|
||||
const std::string& peer_cert) {
|
||||
c_arg_->peer_cert = gpr_strdup(peer_cert.c_str());
|
||||
}
|
||||
|
||||
void TlsServerAuthorizationCheckArg::set_peer_cert_full_chain(
|
||||
const std::string& peer_cert_full_chain) {
|
||||
c_arg_->peer_cert_full_chain = gpr_strdup(peer_cert_full_chain.c_str());
|
||||
}
|
||||
|
||||
void TlsServerAuthorizationCheckArg::set_status(grpc_status_code status) {
|
||||
c_arg_->status = status;
|
||||
}
|
||||
|
||||
void TlsServerAuthorizationCheckArg::set_error_details(
|
||||
const std::string& error_details) {
|
||||
c_arg_->error_details->set_error_details(error_details.c_str());
|
||||
}
|
||||
|
||||
void TlsServerAuthorizationCheckArg::OnServerAuthorizationCheckDoneCallback() {
|
||||
if (c_arg_->cb == nullptr) {
|
||||
gpr_log(GPR_ERROR, "server authorizaton check arg callback API is nullptr");
|
||||
return;
|
||||
}
|
||||
c_arg_->cb(c_arg_);
|
||||
}
|
||||
|
||||
TlsServerAuthorizationCheckConfig::TlsServerAuthorizationCheckConfig(
|
||||
std::shared_ptr<TlsServerAuthorizationCheckInterface>
|
||||
server_authorization_check_interface)
|
||||
: server_authorization_check_interface_(
|
||||
std::move(server_authorization_check_interface)) {
|
||||
c_config_ = grpc_tls_server_authorization_check_config_create(
|
||||
nullptr, &TlsServerAuthorizationCheckConfigCSchedule,
|
||||
&TlsServerAuthorizationCheckConfigCCancel, nullptr);
|
||||
c_config_->set_context(static_cast<void*>(this));
|
||||
}
|
||||
|
||||
TlsServerAuthorizationCheckConfig::~TlsServerAuthorizationCheckConfig() {
|
||||
grpc_tls_server_authorization_check_config_release(c_config_);
|
||||
}
|
||||
|
||||
TlsCredentialsOptions::TlsCredentialsOptions() {
|
||||
c_credentials_options_ = grpc_tls_credentials_options_create();
|
||||
}
|
||||
|
|
@ -159,22 +59,27 @@ void TlsCredentialsOptions::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 TlsCredentialsOptions::set_certificate_verifier(
|
||||
std::shared_ptr<CertificateVerifier> certificate_verifier) {
|
||||
certificate_verifier_ = std::move(certificate_verifier);
|
||||
if (certificate_verifier_ != nullptr) {
|
||||
grpc_tls_credentials_options_set_certificate_verifier(
|
||||
c_credentials_options_, certificate_verifier_->c_verifier());
|
||||
}
|
||||
}
|
||||
|
||||
void TlsChannelCredentialsOptions::set_server_authorization_check_config(
|
||||
std::shared_ptr<TlsServerAuthorizationCheckConfig> config) {
|
||||
void TlsCredentialsOptions::set_check_call_host(bool check_call_host) {
|
||||
grpc_tls_credentials_options* options = c_credentials_options();
|
||||
GPR_ASSERT(options != nullptr);
|
||||
if (config != nullptr) {
|
||||
grpc_tls_credentials_options_set_server_authorization_check_config(
|
||||
options, config->c_config());
|
||||
}
|
||||
grpc_tls_credentials_options_set_check_call_host(options, check_call_host);
|
||||
}
|
||||
|
||||
void TlsChannelCredentialsOptions::set_verify_server_certs(
|
||||
bool verify_server_certs) {
|
||||
grpc_tls_credentials_options* options = c_credentials_options();
|
||||
GPR_ASSERT(options != nullptr);
|
||||
grpc_tls_credentials_options_set_verify_server_cert(options,
|
||||
verify_server_certs);
|
||||
}
|
||||
|
||||
void TlsServerCredentialsOptions::set_cert_request_type(
|
||||
|
|
|
|||
|
|
@ -1,76 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2019 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "src/cpp/common/tls_credentials_options_util.h"
|
||||
|
||||
#include "absl/container/inlined_vector.h"
|
||||
|
||||
#include <grpcpp/security/tls_credentials_options.h>
|
||||
|
||||
namespace grpc {
|
||||
namespace experimental {
|
||||
|
||||
/** 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. **/
|
||||
int TlsServerAuthorizationCheckConfigCSchedule(
|
||||
void* /*config_user_data*/, grpc_tls_server_authorization_check_arg* arg) {
|
||||
if (arg == nullptr || arg->config == nullptr ||
|
||||
arg->config->context() == nullptr) {
|
||||
gpr_log(GPR_ERROR,
|
||||
"server authorization check arg was not properly initialized");
|
||||
return 1;
|
||||
}
|
||||
TlsServerAuthorizationCheckConfig* cpp_config =
|
||||
static_cast<TlsServerAuthorizationCheckConfig*>(arg->config->context());
|
||||
TlsServerAuthorizationCheckArg* cpp_arg =
|
||||
new TlsServerAuthorizationCheckArg(arg);
|
||||
int schedule_result = cpp_config->Schedule(cpp_arg);
|
||||
return schedule_result;
|
||||
}
|
||||
|
||||
void TlsServerAuthorizationCheckConfigCCancel(
|
||||
void* /*config_user_data*/, grpc_tls_server_authorization_check_arg* arg) {
|
||||
if (arg == nullptr || arg->config == nullptr ||
|
||||
arg->config->context() == nullptr) {
|
||||
gpr_log(GPR_ERROR,
|
||||
"server authorization check arg was not properly initialized");
|
||||
return;
|
||||
}
|
||||
if (arg->context == nullptr) {
|
||||
gpr_log(GPR_ERROR,
|
||||
"server authorization check arg schedule has already completed");
|
||||
return;
|
||||
}
|
||||
TlsServerAuthorizationCheckConfig* cpp_config =
|
||||
static_cast<TlsServerAuthorizationCheckConfig*>(arg->config->context());
|
||||
TlsServerAuthorizationCheckArg* cpp_arg =
|
||||
static_cast<TlsServerAuthorizationCheckArg*>(arg->context);
|
||||
cpp_config->Cancel(cpp_arg);
|
||||
}
|
||||
|
||||
void TlsServerAuthorizationCheckArgDestroyContext(void* context) {
|
||||
if (context != nullptr) {
|
||||
TlsServerAuthorizationCheckArg* cpp_arg =
|
||||
static_cast<TlsServerAuthorizationCheckArg*>(context);
|
||||
delete cpp_arg;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace experimental
|
||||
} // namespace grpc
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2019 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GRPC_INTERNAL_CPP_COMMON_TLS_CREDENTIALS_OPTIONS_UTIL_H
|
||||
#define GRPC_INTERNAL_CPP_COMMON_TLS_CREDENTIALS_OPTIONS_UTIL_H
|
||||
|
||||
#include <grpc/grpc_security.h>
|
||||
#include <grpcpp/security/tls_credentials_options.h>
|
||||
|
||||
#include "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h"
|
||||
|
||||
namespace grpc {
|
||||
namespace experimental {
|
||||
|
||||
/** 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 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);
|
||||
|
||||
void TlsServerAuthorizationCheckArgDestroyContext(void* context);
|
||||
|
||||
} // namespace experimental
|
||||
} // namespace grpc
|
||||
|
||||
#endif // GRPC_INTERNAL_CPP_COMMON_TLS_CREDENTIALS_OPTIONS_UTIL_H
|
||||
|
|
@ -549,6 +549,7 @@ CORE_SOURCE_FILES = [
|
|||
'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_certificate_verifier.cc',
|
||||
'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc',
|
||||
'src/core/lib/security/credentials/tls/tls_credentials.cc',
|
||||
'src/core/lib/security/credentials/tls/tls_utils.cc',
|
||||
|
|
|
|||
|
|
@ -172,16 +172,14 @@ grpc_tls_certificate_provider_static_data_create_type grpc_tls_certificate_provi
|
|||
grpc_tls_certificate_provider_file_watcher_create_type grpc_tls_certificate_provider_file_watcher_create_import;
|
||||
grpc_tls_certificate_provider_release_type grpc_tls_certificate_provider_release_import;
|
||||
grpc_tls_credentials_options_create_type grpc_tls_credentials_options_create_import;
|
||||
grpc_tls_credentials_options_set_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_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_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_tls_credentials_options_set_cert_request_type_type grpc_tls_credentials_options_set_cert_request_type_import;
|
||||
grpc_tls_credentials_options_set_verify_server_cert_type grpc_tls_credentials_options_set_verify_server_cert_import;
|
||||
grpc_tls_credentials_options_set_check_call_host_type grpc_tls_credentials_options_set_check_call_host_import;
|
||||
grpc_xds_credentials_create_type grpc_xds_credentials_create_import;
|
||||
grpc_xds_server_credentials_create_type grpc_xds_server_credentials_create_import;
|
||||
grpc_authorization_policy_provider_static_data_create_type grpc_authorization_policy_provider_static_data_create_import;
|
||||
|
|
@ -462,16 +460,14 @@ void grpc_rb_load_imports(HMODULE library) {
|
|||
grpc_tls_certificate_provider_file_watcher_create_import = (grpc_tls_certificate_provider_file_watcher_create_type) GetProcAddress(library, "grpc_tls_certificate_provider_file_watcher_create");
|
||||
grpc_tls_certificate_provider_release_import = (grpc_tls_certificate_provider_release_type) GetProcAddress(library, "grpc_tls_certificate_provider_release");
|
||||
grpc_tls_credentials_options_create_import = (grpc_tls_credentials_options_create_type) GetProcAddress(library, "grpc_tls_credentials_options_create");
|
||||
grpc_tls_credentials_options_set_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_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_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_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_verify_server_cert_import = (grpc_tls_credentials_options_set_verify_server_cert_type) GetProcAddress(library, "grpc_tls_credentials_options_set_verify_server_cert");
|
||||
grpc_tls_credentials_options_set_check_call_host_import = (grpc_tls_credentials_options_set_check_call_host_type) GetProcAddress(library, "grpc_tls_credentials_options_set_check_call_host");
|
||||
grpc_xds_credentials_create_import = (grpc_xds_credentials_create_type) GetProcAddress(library, "grpc_xds_credentials_create");
|
||||
grpc_xds_server_credentials_create_import = (grpc_xds_server_credentials_create_type) GetProcAddress(library, "grpc_xds_server_credentials_create");
|
||||
grpc_authorization_policy_provider_static_data_create_import = (grpc_authorization_policy_provider_static_data_create_type) GetProcAddress(library, "grpc_authorization_policy_provider_static_data_create");
|
||||
|
|
|
|||
|
|
@ -491,12 +491,6 @@ extern grpc_tls_certificate_provider_release_type grpc_tls_certificate_provider_
|
|||
typedef grpc_tls_credentials_options*(*grpc_tls_credentials_options_create_type)(void);
|
||||
extern grpc_tls_credentials_options_create_type grpc_tls_credentials_options_create_import;
|
||||
#define grpc_tls_credentials_options_create grpc_tls_credentials_options_create_import
|
||||
typedef void(*grpc_tls_credentials_options_set_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 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 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
|
||||
|
|
@ -512,15 +506,15 @@ extern grpc_tls_credentials_options_watch_identity_key_cert_pairs_type grpc_tls_
|
|||
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_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 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 void(*grpc_tls_credentials_options_set_verify_server_cert_type)(grpc_tls_credentials_options* options, int verify_server_cert);
|
||||
extern grpc_tls_credentials_options_set_verify_server_cert_type grpc_tls_credentials_options_set_verify_server_cert_import;
|
||||
#define grpc_tls_credentials_options_set_verify_server_cert grpc_tls_credentials_options_set_verify_server_cert_import
|
||||
typedef void(*grpc_tls_credentials_options_set_check_call_host_type)(grpc_tls_credentials_options* options, int check_call_host);
|
||||
extern grpc_tls_credentials_options_set_check_call_host_type grpc_tls_credentials_options_set_check_call_host_import;
|
||||
#define grpc_tls_credentials_options_set_check_call_host grpc_tls_credentials_options_set_check_call_host_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
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/util/port.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
#include "test/core/util/tls_utils.h"
|
||||
|
||||
// For normal TLS connections.
|
||||
#define CA_CERT_PATH "src/core/tsi/test_creds/ca.pem"
|
||||
|
|
@ -47,103 +48,200 @@
|
|||
|
||||
typedef absl::InlinedVector<grpc_core::Thread, 1> ThreadList;
|
||||
|
||||
struct SecurityPrimitives {
|
||||
enum ProviderType { STATIC_PROVIDER = 0, FILE_PROVIDER = 1 } provider_type;
|
||||
enum VerifierType {
|
||||
EXTERNAL_SYNC_VERIFIER = 0,
|
||||
EXTERNAL_ASYNC_VERIFIER = 1,
|
||||
HOSTNAME_VERIFIER = 2
|
||||
} verifier_type;
|
||||
enum TlsVersion { V_12 = 0, V_13 = 1 } tls_version;
|
||||
};
|
||||
|
||||
struct fullstack_secure_fixture_data {
|
||||
~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);
|
||||
grpc_tls_certificate_verifier_release(client_verifier);
|
||||
grpc_tls_certificate_verifier_release(server_verifier);
|
||||
}
|
||||
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;
|
||||
grpc_tls_certificate_verifier* client_verifier = nullptr;
|
||||
grpc_tls_certificate_verifier* server_verifier = nullptr;
|
||||
bool check_call_host = true;
|
||||
};
|
||||
|
||||
static grpc_end2end_test_fixture chttp2_create_fixture_static_data(
|
||||
grpc_channel_args* /*client_args*/, grpc_channel_args* /*server_args*/,
|
||||
grpc_tls_version tls_version) {
|
||||
grpc_end2end_test_fixture f;
|
||||
int port = grpc_pick_unused_port_or_die();
|
||||
fullstack_secure_fixture_data* ffd = new fullstack_secure_fixture_data();
|
||||
memset(&f, 0, sizeof(f));
|
||||
ffd->localaddr = grpc_core::JoinHostPort("localhost", port);
|
||||
ffd->tls_version = tls_version;
|
||||
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;
|
||||
static void SetTlsVersion(fullstack_secure_fixture_data* ffd,
|
||||
SecurityPrimitives::TlsVersion tls_version) {
|
||||
switch (tls_version) {
|
||||
case SecurityPrimitives::TlsVersion::V_12: {
|
||||
ffd->tls_version = grpc_tls_version::TLS1_2;
|
||||
break;
|
||||
}
|
||||
case SecurityPrimitives::TlsVersion::V_13: {
|
||||
ffd->tls_version = grpc_tls_version::TLS1_3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static grpc_end2end_test_fixture chttp2_create_fixture_cert_watcher(
|
||||
grpc_channel_args* /*client_args*/, grpc_channel_args* /*server_args*/,
|
||||
grpc_tls_version tls_version) {
|
||||
static void SetCertificateProvider(
|
||||
fullstack_secure_fixture_data* ffd,
|
||||
SecurityPrimitives::ProviderType provider_type) {
|
||||
switch (provider_type) {
|
||||
case SecurityPrimitives::ProviderType::STATIC_PROVIDER: {
|
||||
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);
|
||||
grpc_slice_unref(root_slice);
|
||||
grpc_slice_unref(cert_slice);
|
||||
grpc_slice_unref(key_slice);
|
||||
break;
|
||||
}
|
||||
case SecurityPrimitives::ProviderType::FILE_PROVIDER: {
|
||||
ffd->client_provider = grpc_tls_certificate_provider_file_watcher_create(
|
||||
SERVER_KEY_PATH, SERVER_CERT_PATH, CA_CERT_PATH, 1);
|
||||
ffd->server_provider = grpc_tls_certificate_provider_file_watcher_create(
|
||||
SERVER_KEY_PATH, SERVER_CERT_PATH, CA_CERT_PATH, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void SetCertificateVerifier(
|
||||
fullstack_secure_fixture_data* ffd,
|
||||
SecurityPrimitives::VerifierType verifier_type) {
|
||||
switch (verifier_type) {
|
||||
case SecurityPrimitives::VerifierType::EXTERNAL_SYNC_VERIFIER: {
|
||||
auto* client_sync_verifier =
|
||||
new grpc_core::testing::SyncExternalVerifier(true);
|
||||
ffd->client_verifier = grpc_tls_certificate_verifier_external_create(
|
||||
client_sync_verifier->base());
|
||||
auto* server_sync_verifier =
|
||||
new grpc_core::testing::SyncExternalVerifier(true);
|
||||
ffd->server_verifier = grpc_tls_certificate_verifier_external_create(
|
||||
server_sync_verifier->base());
|
||||
ffd->check_call_host = false;
|
||||
break;
|
||||
}
|
||||
case SecurityPrimitives::VerifierType::EXTERNAL_ASYNC_VERIFIER: {
|
||||
auto* client_async_verifier =
|
||||
new grpc_core::testing::AsyncExternalVerifier(true);
|
||||
ffd->client_verifier = grpc_tls_certificate_verifier_external_create(
|
||||
client_async_verifier->base());
|
||||
auto* server_async_verifier =
|
||||
new grpc_core::testing::AsyncExternalVerifier(true);
|
||||
ffd->server_verifier = grpc_tls_certificate_verifier_external_create(
|
||||
server_async_verifier->base());
|
||||
ffd->check_call_host = false;
|
||||
break;
|
||||
}
|
||||
case SecurityPrimitives::VerifierType::HOSTNAME_VERIFIER: {
|
||||
ffd->client_verifier = grpc_tls_certificate_verifier_host_name_create();
|
||||
// Hostname verifier couldn't be applied to the server side, so we will
|
||||
// use sync external verifier here.
|
||||
auto* server_async_verifier =
|
||||
new grpc_core::testing::AsyncExternalVerifier(true);
|
||||
ffd->server_verifier = grpc_tls_certificate_verifier_external_create(
|
||||
server_async_verifier->base());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static grpc_end2end_test_fixture chttp2_create_fixture_simple_fullstack(
|
||||
grpc_channel_args*, grpc_channel_args*) {
|
||||
grpc_end2end_test_fixture f;
|
||||
int port = grpc_pick_unused_port_or_die();
|
||||
fullstack_secure_fixture_data* ffd = new fullstack_secure_fixture_data();
|
||||
memset(&f, 0, sizeof(f));
|
||||
ffd->localaddr = grpc_core::JoinHostPort("localhost", port);
|
||||
ffd->tls_version = tls_version;
|
||||
ffd->client_provider = grpc_tls_certificate_provider_file_watcher_create(
|
||||
SERVER_KEY_PATH, SERVER_CERT_PATH, CA_CERT_PATH, 1);
|
||||
ffd->server_provider = grpc_tls_certificate_provider_file_watcher_create(
|
||||
SERVER_KEY_PATH, SERVER_CERT_PATH, CA_CERT_PATH, 1);
|
||||
SetTlsVersion(ffd, SecurityPrimitives::TlsVersion::V_12);
|
||||
SetCertificateProvider(ffd,
|
||||
SecurityPrimitives::ProviderType::STATIC_PROVIDER);
|
||||
SetCertificateVerifier(
|
||||
ffd, SecurityPrimitives::VerifierType::EXTERNAL_SYNC_VERIFIER);
|
||||
f.fixture_data = ffd;
|
||||
f.cq = grpc_completion_queue_create_for_next(nullptr);
|
||||
f.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr);
|
||||
return f;
|
||||
}
|
||||
|
||||
static grpc_end2end_test_fixture chttp2_create_fixture_static_data_tls1_2(
|
||||
grpc_channel_args* client_args, grpc_channel_args* server_args) {
|
||||
return chttp2_create_fixture_static_data(client_args, server_args,
|
||||
grpc_tls_version::TLS1_2);
|
||||
static grpc_end2end_test_fixture chttp2_create_fixture_async_verifier(
|
||||
grpc_channel_args*, grpc_channel_args*) {
|
||||
grpc_end2end_test_fixture f;
|
||||
int port = grpc_pick_unused_port_or_die();
|
||||
fullstack_secure_fixture_data* ffd = new fullstack_secure_fixture_data();
|
||||
memset(&f, 0, sizeof(f));
|
||||
ffd->localaddr = grpc_core::JoinHostPort("localhost", port);
|
||||
SetTlsVersion(ffd, SecurityPrimitives::TlsVersion::V_13);
|
||||
SetCertificateProvider(ffd,
|
||||
SecurityPrimitives::ProviderType::STATIC_PROVIDER);
|
||||
SetCertificateVerifier(
|
||||
ffd, SecurityPrimitives::VerifierType::EXTERNAL_ASYNC_VERIFIER);
|
||||
f.fixture_data = ffd;
|
||||
f.cq = grpc_completion_queue_create_for_next(nullptr);
|
||||
f.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr);
|
||||
return f;
|
||||
}
|
||||
|
||||
static grpc_end2end_test_fixture chttp2_create_fixture_static_data_tls1_3(
|
||||
grpc_channel_args* client_args, grpc_channel_args* server_args) {
|
||||
return chttp2_create_fixture_static_data(client_args, server_args,
|
||||
grpc_tls_version::TLS1_3);
|
||||
static grpc_end2end_test_fixture
|
||||
chttp2_create_fixture_hostname_verifier_cert_watcher(grpc_channel_args*,
|
||||
grpc_channel_args*) {
|
||||
grpc_end2end_test_fixture f;
|
||||
int port = grpc_pick_unused_port_or_die();
|
||||
fullstack_secure_fixture_data* ffd = new fullstack_secure_fixture_data();
|
||||
memset(&f, 0, sizeof(f));
|
||||
ffd->localaddr = grpc_core::JoinHostPort("localhost", port);
|
||||
SetTlsVersion(ffd, SecurityPrimitives::TlsVersion::V_12);
|
||||
SetCertificateProvider(ffd, SecurityPrimitives::ProviderType::FILE_PROVIDER);
|
||||
SetCertificateVerifier(ffd,
|
||||
SecurityPrimitives::VerifierType::HOSTNAME_VERIFIER);
|
||||
f.fixture_data = ffd;
|
||||
f.cq = grpc_completion_queue_create_for_next(nullptr);
|
||||
f.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr);
|
||||
return f;
|
||||
}
|
||||
|
||||
static grpc_end2end_test_fixture chttp2_create_fixture_cert_watcher_tls1_2(
|
||||
grpc_channel_args* client_args, grpc_channel_args* server_args) {
|
||||
return chttp2_create_fixture_cert_watcher(client_args, server_args,
|
||||
grpc_tls_version::TLS1_2);
|
||||
}
|
||||
|
||||
static grpc_end2end_test_fixture chttp2_create_fixture_cert_watcher_tls1_3(
|
||||
grpc_channel_args* client_args, grpc_channel_args* server_args) {
|
||||
return chttp2_create_fixture_cert_watcher(client_args, server_args,
|
||||
grpc_tls_version::TLS1_3);
|
||||
static grpc_end2end_test_fixture
|
||||
chttp2_create_fixture_async_verifier_cert_watcher(grpc_channel_args*,
|
||||
grpc_channel_args*) {
|
||||
grpc_end2end_test_fixture f;
|
||||
int port = grpc_pick_unused_port_or_die();
|
||||
fullstack_secure_fixture_data* ffd = new fullstack_secure_fixture_data();
|
||||
memset(&f, 0, sizeof(f));
|
||||
ffd->localaddr = grpc_core::JoinHostPort("localhost", port);
|
||||
SetTlsVersion(ffd, SecurityPrimitives::TlsVersion::V_12);
|
||||
SetCertificateProvider(ffd, SecurityPrimitives::ProviderType::FILE_PROVIDER);
|
||||
SetCertificateVerifier(
|
||||
ffd, SecurityPrimitives::VerifierType::EXTERNAL_ASYNC_VERIFIER);
|
||||
f.fixture_data = ffd;
|
||||
f.cq = grpc_completion_queue_create_for_next(nullptr);
|
||||
f.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr);
|
||||
return f;
|
||||
}
|
||||
|
||||
static void process_auth_failure(void* state, grpc_auth_context* /*ctx*/,
|
||||
|
|
@ -188,37 +286,12 @@ void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture* f) {
|
|||
delete ffd;
|
||||
}
|
||||
|
||||
// Application-provided callback for server authorization check.
|
||||
static void server_authz_check_cb(void* user_data) {
|
||||
grpc_tls_server_authorization_check_arg* check_arg =
|
||||
static_cast<grpc_tls_server_authorization_check_arg*>(user_data);
|
||||
GPR_ASSERT(check_arg != nullptr);
|
||||
// result = 1 indicates the server authorization check passes.
|
||||
// Normally, the application code should resort to mapping information
|
||||
// between server identity and target name to derive the result.
|
||||
// For this test, we directly return 1 for simplicity.
|
||||
check_arg->success = 1;
|
||||
check_arg->status = GRPC_STATUS_OK;
|
||||
check_arg->cb(check_arg);
|
||||
}
|
||||
|
||||
// Asynchronous implementation of schedule field in
|
||||
// grpc_server_authorization_check_config.
|
||||
static int server_authz_check_async(
|
||||
void* config_user_data, grpc_tls_server_authorization_check_arg* arg) {
|
||||
fullstack_secure_fixture_data* ffd =
|
||||
static_cast<fullstack_secure_fixture_data*>(config_user_data);
|
||||
ffd->thd_list.push_back(
|
||||
grpc_core::Thread("h2_tls_test", &server_authz_check_cb, arg));
|
||||
ffd->thd_list[ffd->thd_list.size() - 1].Start();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Create a TLS channel credential.
|
||||
static grpc_channel_credentials* create_tls_channel_credentials(
|
||||
fullstack_secure_fixture_data* ffd) {
|
||||
grpc_tls_credentials_options* options = grpc_tls_credentials_options_create();
|
||||
options->set_server_verification_option(GRPC_TLS_SERVER_VERIFICATION);
|
||||
grpc_tls_credentials_options_set_verify_server_cert(
|
||||
options, 1 /* = verify server certs */);
|
||||
options->set_min_tls_version(ffd->tls_version);
|
||||
options->set_max_tls_version(ffd->tls_version);
|
||||
// Set credential provider.
|
||||
|
|
@ -226,15 +299,13 @@ static grpc_channel_credentials* create_tls_channel_credentials(
|
|||
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(
|
||||
ffd, server_authz_check_async, nullptr, nullptr);
|
||||
grpc_tls_credentials_options_set_server_authorization_check_config(
|
||||
options, check_config);
|
||||
// Set credential verifier.
|
||||
grpc_tls_credentials_options_set_certificate_verifier(options,
|
||||
ffd->client_verifier);
|
||||
grpc_tls_credentials_options_set_check_call_host(options,
|
||||
ffd->check_call_host);
|
||||
/* Create TLS channel credentials. */
|
||||
grpc_channel_credentials* creds = grpc_tls_credentials_create(options);
|
||||
grpc_tls_server_authorization_check_config_release(check_config);
|
||||
return creds;
|
||||
}
|
||||
|
||||
|
|
@ -249,9 +320,12 @@ static grpc_server_credentials* create_tls_server_credentials(
|
|||
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. */
|
||||
// Set client certificate request type.
|
||||
grpc_tls_credentials_options_set_cert_request_type(
|
||||
options, GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY);
|
||||
// Set credential verifier.
|
||||
grpc_tls_credentials_options_set_certificate_verifier(options,
|
||||
ffd->server_verifier);
|
||||
grpc_server_credentials* creds = grpc_tls_server_credentials_create(options);
|
||||
return creds;
|
||||
}
|
||||
|
|
@ -294,48 +368,37 @@ static void chttp2_init_server(grpc_end2end_test_fixture* f,
|
|||
chttp2_init_server_secure_fullstack(f, server_args, ssl_creds);
|
||||
}
|
||||
|
||||
static grpc_end2end_test_config configs[] = {
|
||||
// client: static data provider + async custom verification
|
||||
// server: static data provider
|
||||
// extra: TLS 1.2
|
||||
{"chttp2/simple_ssl_fullstack_tls1_2",
|
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
|
||||
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
|
||||
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
|
||||
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
|
||||
"foo.test.google.fr", chttp2_create_fixture_static_data_tls1_2,
|
||||
chttp2_init_client, chttp2_init_server, chttp2_tear_down_secure_fullstack},
|
||||
// client: static data provider + async custom verification
|
||||
// server: static data provider
|
||||
// extra: TLS 1.3
|
||||
{"chttp2/simple_ssl_fullstack_tls1_3",
|
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
|
||||
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
|
||||
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
|
||||
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
|
||||
"foo.test.google.fr", chttp2_create_fixture_static_data_tls1_3,
|
||||
chttp2_init_client, chttp2_init_server, chttp2_tear_down_secure_fullstack},
|
||||
// client: certificate watcher provider + async custom verification
|
||||
// server: certificate watcher provider
|
||||
// extra: TLS 1.2
|
||||
{"chttp2/reloading_from_files_ssl_fullstack_tls1_2",
|
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
|
||||
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
|
||||
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
|
||||
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
|
||||
"foo.test.google.fr", chttp2_create_fixture_cert_watcher_tls1_2,
|
||||
chttp2_init_client, chttp2_init_server, chttp2_tear_down_secure_fullstack},
|
||||
// client: certificate watcher provider + async custom verification
|
||||
// server: certificate watcher provider
|
||||
// extra: TLS 1.3
|
||||
{"chttp2/reloading_from_files_ssl_fullstack_tls1_3",
|
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
|
||||
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
|
||||
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
|
||||
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
|
||||
"foo.test.google.fr", chttp2_create_fixture_cert_watcher_tls1_3,
|
||||
chttp2_init_client, chttp2_init_server, chttp2_tear_down_secure_fullstack},
|
||||
static const uint32_t kH2TLSFeatureMask =
|
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
|
||||
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
|
||||
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
|
||||
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER;
|
||||
|
||||
static grpc_end2end_test_config configs[] = {
|
||||
// client: static data provider + sync external verifier
|
||||
// server: static data provider + sync external verifier
|
||||
// extra: TLS 1.2
|
||||
{"chttp2/simple_ssl_fullstack", kH2TLSFeatureMask, "foo.test.google.fr",
|
||||
chttp2_create_fixture_simple_fullstack, chttp2_init_client,
|
||||
chttp2_init_server, chttp2_tear_down_secure_fullstack},
|
||||
// client: static data provider + async external verifier
|
||||
// server: static data provider + async external verifier
|
||||
// extra: TLS 1.3
|
||||
{"chttp2/static_provider_async_verifier_tls1_3", kH2TLSFeatureMask,
|
||||
"foo.test.google.fr", chttp2_create_fixture_async_verifier,
|
||||
chttp2_init_client, chttp2_init_server, chttp2_tear_down_secure_fullstack},
|
||||
// client: certificate watcher provider + hostname verifier
|
||||
// server: certificate watcher provider + sync external verifier
|
||||
// extra: TLS 1.2
|
||||
{"chttp2/cert_watcher_provider_sync_verifier_tls1_2", kH2TLSFeatureMask,
|
||||
"foo.test.google.fr", chttp2_create_fixture_hostname_verifier_cert_watcher,
|
||||
chttp2_init_client, chttp2_init_server, chttp2_tear_down_secure_fullstack},
|
||||
// client: certificate watcher provider + async external verifier
|
||||
// server: certificate watcher provider + async external verifier
|
||||
// extra: TLS 1.3
|
||||
{"chttp2/cert_watcher_provider_async_verifier_tls1_3", kH2TLSFeatureMask,
|
||||
"foo.test.google.fr", chttp2_create_fixture_async_verifier_cert_watcher,
|
||||
chttp2_init_client, chttp2_init_server, chttp2_tear_down_secure_fullstack},
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
|
|
|||
|
|
@ -370,6 +370,19 @@ grpc_cc_test(
|
|||
],
|
||||
)
|
||||
|
||||
grpc_cc_test(
|
||||
name = "grpc_tls_certificate_verifier_test",
|
||||
srcs = ["grpc_tls_certificate_verifier_test.cc"],
|
||||
external_deps = ["gtest"],
|
||||
language = "C++",
|
||||
deps = [
|
||||
"//:gpr",
|
||||
"//:grpc",
|
||||
"//:grpc_secure",
|
||||
"//test/core/util:grpc_test_util",
|
||||
],
|
||||
)
|
||||
|
||||
grpc_cc_test(
|
||||
name = "insecure_security_connector_test",
|
||||
srcs = ["insecure_security_connector_test.cc"],
|
||||
|
|
|
|||
|
|
@ -0,0 +1,265 @@
|
|||
//
|
||||
// Copyright 2021 gRPC authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
#include "src/core/lib/security/credentials/tls/grpc_tls_certificate_verifier.h"
|
||||
|
||||
#include <deque>
|
||||
#include <list>
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <grpc/support/alloc.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpc/support/string_util.h>
|
||||
|
||||
#include "src/core/lib/gpr/tmpfile.h"
|
||||
#include "src/core/lib/iomgr/load_file.h"
|
||||
#include "src/core/lib/security/security_connector/tls/tls_security_connector.h"
|
||||
#include "src/core/lib/slice/slice_internal.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
#include "test/core/util/tls_utils.h"
|
||||
|
||||
namespace grpc_core {
|
||||
|
||||
namespace testing {
|
||||
|
||||
// Unit tests for grpc_tls_certificate_verifier and all its successors.
|
||||
// In these tests, |request_| is not outliving the test itself, so it's fine to
|
||||
// point fields in |request_| directly to the address of local variables. In
|
||||
// actual implementation, these fields are dynamically allocated.
|
||||
class GrpcTlsCertificateVerifierTest : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override { memset(&request_, 0, sizeof(request_)); }
|
||||
|
||||
void TearDown() override {}
|
||||
|
||||
grpc_tls_custom_verification_check_request request_;
|
||||
HostNameCertificateVerifier hostname_certificate_verifier_;
|
||||
};
|
||||
|
||||
TEST_F(GrpcTlsCertificateVerifierTest, SyncExternalVerifierSucceeds) {
|
||||
auto* sync_verifier = new SyncExternalVerifier(true);
|
||||
ExternalCertificateVerifier core_external_verifier(sync_verifier->base());
|
||||
absl::Status sync_status;
|
||||
EXPECT_TRUE(core_external_verifier.Verify(
|
||||
&request_, [](absl::Status) {}, &sync_status));
|
||||
EXPECT_TRUE(sync_status.ok())
|
||||
<< sync_status.code() << " " << sync_status.message();
|
||||
}
|
||||
|
||||
TEST_F(GrpcTlsCertificateVerifierTest, SyncExternalVerifierFails) {
|
||||
auto* sync_verifier = new SyncExternalVerifier(false);
|
||||
ExternalCertificateVerifier core_external_verifier(sync_verifier->base());
|
||||
absl::Status sync_status;
|
||||
EXPECT_TRUE(core_external_verifier.Verify(
|
||||
&request_, [](absl::Status) {}, &sync_status));
|
||||
EXPECT_EQ(sync_status.code(), absl::StatusCode::kUnauthenticated);
|
||||
EXPECT_EQ(sync_status.ToString(),
|
||||
"UNAUTHENTICATED: SyncExternalVerifier failed");
|
||||
}
|
||||
|
||||
TEST_F(GrpcTlsCertificateVerifierTest, AsyncExternalVerifierSucceeds) {
|
||||
absl::Status sync_status;
|
||||
// This is to make sure the callback has already been completed before we
|
||||
// destroy ExternalCertificateVerifier object.
|
||||
gpr_event callback_completed_event;
|
||||
gpr_event_init(&callback_completed_event);
|
||||
auto* async_verifier = new AsyncExternalVerifier(true);
|
||||
ExternalCertificateVerifier core_external_verifier(async_verifier->base());
|
||||
EXPECT_FALSE(core_external_verifier.Verify(
|
||||
&request_,
|
||||
[&callback_completed_event](absl::Status async_status) {
|
||||
EXPECT_TRUE(async_status.ok())
|
||||
<< async_status.code() << " " << async_status.message();
|
||||
gpr_event_set(&callback_completed_event, reinterpret_cast<void*>(1));
|
||||
},
|
||||
&sync_status));
|
||||
void* callback_completed =
|
||||
gpr_event_wait(&callback_completed_event,
|
||||
gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
|
||||
gpr_time_from_seconds(10, GPR_TIMESPAN)));
|
||||
EXPECT_NE(callback_completed, nullptr);
|
||||
}
|
||||
|
||||
TEST_F(GrpcTlsCertificateVerifierTest, AsyncExternalVerifierFails) {
|
||||
absl::Status sync_status;
|
||||
// This is to make sure the callback has already been completed before we
|
||||
// destroy ExternalCertificateVerifier object.
|
||||
gpr_event callback_completed_event;
|
||||
gpr_event_init(&callback_completed_event);
|
||||
auto* async_verifier = new AsyncExternalVerifier(false);
|
||||
ExternalCertificateVerifier core_external_verifier(async_verifier->base());
|
||||
EXPECT_FALSE(core_external_verifier.Verify(
|
||||
&request_,
|
||||
[&callback_completed_event](absl::Status async_status) {
|
||||
gpr_log(GPR_INFO, "Callback is invoked.");
|
||||
EXPECT_EQ(async_status.code(), absl::StatusCode::kUnauthenticated);
|
||||
EXPECT_EQ(async_status.ToString(),
|
||||
"UNAUTHENTICATED: AsyncExternalVerifier failed");
|
||||
gpr_event_set(&callback_completed_event, reinterpret_cast<void*>(1));
|
||||
},
|
||||
&sync_status));
|
||||
void* callback_completed =
|
||||
gpr_event_wait(&callback_completed_event,
|
||||
gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
|
||||
gpr_time_from_seconds(10, GPR_TIMESPAN)));
|
||||
EXPECT_NE(callback_completed, nullptr);
|
||||
}
|
||||
|
||||
TEST_F(GrpcTlsCertificateVerifierTest, HostnameVerifierNullTargetName) {
|
||||
absl::Status sync_status;
|
||||
EXPECT_TRUE(hostname_certificate_verifier_.Verify(
|
||||
&request_, [](absl::Status) {}, &sync_status));
|
||||
EXPECT_EQ(sync_status.code(), absl::StatusCode::kUnauthenticated);
|
||||
EXPECT_EQ(sync_status.ToString(),
|
||||
"UNAUTHENTICATED: Target name is not specified.");
|
||||
}
|
||||
|
||||
TEST_F(GrpcTlsCertificateVerifierTest, HostnameVerifierInvalidTargetName) {
|
||||
absl::Status sync_status;
|
||||
request_.target_name = "[foo.com@443";
|
||||
EXPECT_TRUE(hostname_certificate_verifier_.Verify(
|
||||
&request_, [](absl::Status) {}, &sync_status));
|
||||
EXPECT_EQ(sync_status.code(), absl::StatusCode::kUnauthenticated);
|
||||
EXPECT_EQ(sync_status.ToString(),
|
||||
"UNAUTHENTICATED: Failed to split hostname and port.");
|
||||
}
|
||||
|
||||
TEST_F(GrpcTlsCertificateVerifierTest, HostnameVerifierDNSExactCheckSucceeds) {
|
||||
absl::Status sync_status;
|
||||
request_.target_name = "foo.com:443";
|
||||
char* dns_names[] = {const_cast<char*>("foo.com")};
|
||||
request_.peer_info.san_names.dns_names = dns_names;
|
||||
request_.peer_info.san_names.dns_names_size = 1;
|
||||
EXPECT_TRUE(hostname_certificate_verifier_.Verify(
|
||||
&request_, [](absl::Status) {}, &sync_status));
|
||||
EXPECT_TRUE(sync_status.ok())
|
||||
<< sync_status.code() << " " << sync_status.message();
|
||||
}
|
||||
|
||||
TEST_F(GrpcTlsCertificateVerifierTest,
|
||||
HostnameVerifierDNSWildcardCheckSucceeds) {
|
||||
absl::Status sync_status;
|
||||
request_.target_name = "foo.bar.com:443";
|
||||
char* dns_names[] = {const_cast<char*>("*.bar.com")};
|
||||
request_.peer_info.san_names.dns_names = dns_names;
|
||||
request_.peer_info.san_names.dns_names_size = 1;
|
||||
EXPECT_TRUE(hostname_certificate_verifier_.Verify(
|
||||
&request_, [](absl::Status) {}, &sync_status));
|
||||
EXPECT_TRUE(sync_status.ok())
|
||||
<< sync_status.code() << " " << sync_status.message();
|
||||
}
|
||||
|
||||
TEST_F(GrpcTlsCertificateVerifierTest,
|
||||
HostnameVerifierDNSWildcardCaseInsensitiveCheckSucceeds) {
|
||||
absl::Status sync_status;
|
||||
request_.target_name = "fOo.bar.cOm:443";
|
||||
char* dns_names[] = {const_cast<char*>("*.BaR.Com")};
|
||||
request_.peer_info.san_names.dns_names = dns_names;
|
||||
request_.peer_info.san_names.dns_names_size = 1;
|
||||
EXPECT_TRUE(hostname_certificate_verifier_.Verify(
|
||||
&request_, [](absl::Status) {}, &sync_status));
|
||||
EXPECT_TRUE(sync_status.ok())
|
||||
<< sync_status.code() << " " << sync_status.message();
|
||||
}
|
||||
|
||||
TEST_F(GrpcTlsCertificateVerifierTest,
|
||||
HostnameVerifierDNSTopWildcardCheckFails) {
|
||||
absl::Status sync_status;
|
||||
request_.target_name = "foo.com:443";
|
||||
char* dns_names[] = {const_cast<char*>("*.")};
|
||||
request_.peer_info.san_names.dns_names = dns_names;
|
||||
request_.peer_info.san_names.dns_names_size = 1;
|
||||
EXPECT_TRUE(hostname_certificate_verifier_.Verify(
|
||||
&request_, [](absl::Status) {}, &sync_status));
|
||||
EXPECT_EQ(sync_status.code(), absl::StatusCode::kUnauthenticated);
|
||||
EXPECT_EQ(sync_status.ToString(),
|
||||
"UNAUTHENTICATED: Hostname Verification Check failed.");
|
||||
}
|
||||
|
||||
TEST_F(GrpcTlsCertificateVerifierTest, HostnameVerifierDNSExactCheckFails) {
|
||||
absl::Status sync_status;
|
||||
request_.target_name = "foo.com:443";
|
||||
char* dns_names[] = {const_cast<char*>("bar.com")};
|
||||
request_.peer_info.san_names.dns_names = dns_names;
|
||||
request_.peer_info.san_names.dns_names_size = 1;
|
||||
EXPECT_TRUE(hostname_certificate_verifier_.Verify(
|
||||
&request_, [](absl::Status) {}, &sync_status));
|
||||
EXPECT_EQ(sync_status.code(), absl::StatusCode::kUnauthenticated);
|
||||
EXPECT_EQ(sync_status.ToString(),
|
||||
"UNAUTHENTICATED: Hostname Verification Check failed.");
|
||||
}
|
||||
|
||||
TEST_F(GrpcTlsCertificateVerifierTest, HostnameVerifierIpCheckSucceeds) {
|
||||
absl::Status sync_status;
|
||||
request_.target_name = "192.168.0.1:443";
|
||||
char* ip_names[] = {const_cast<char*>("192.168.0.1")};
|
||||
request_.peer_info.san_names.ip_names = ip_names;
|
||||
request_.peer_info.san_names.ip_names_size = 1;
|
||||
EXPECT_TRUE(hostname_certificate_verifier_.Verify(
|
||||
&request_, [](absl::Status) {}, &sync_status));
|
||||
EXPECT_TRUE(sync_status.ok())
|
||||
<< sync_status.code() << " " << sync_status.message();
|
||||
}
|
||||
|
||||
TEST_F(GrpcTlsCertificateVerifierTest, HostnameVerifierIpCheckFails) {
|
||||
absl::Status sync_status;
|
||||
request_.target_name = "192.168.0.1:443";
|
||||
char* ip_names[] = {const_cast<char*>("192.168.1.1")};
|
||||
request_.peer_info.san_names.ip_names = ip_names;
|
||||
request_.peer_info.san_names.ip_names_size = 1;
|
||||
EXPECT_TRUE(hostname_certificate_verifier_.Verify(
|
||||
&request_, [](absl::Status) {}, &sync_status));
|
||||
EXPECT_EQ(sync_status.code(), absl::StatusCode::kUnauthenticated);
|
||||
EXPECT_EQ(sync_status.ToString(),
|
||||
"UNAUTHENTICATED: Hostname Verification Check failed.");
|
||||
}
|
||||
|
||||
TEST_F(GrpcTlsCertificateVerifierTest,
|
||||
HostnameVerifierCommonNameCheckSucceeds) {
|
||||
absl::Status sync_status;
|
||||
request_.target_name = "foo.com:443";
|
||||
request_.peer_info.common_name = "foo.com";
|
||||
EXPECT_TRUE(hostname_certificate_verifier_.Verify(
|
||||
&request_, [](absl::Status) {}, &sync_status));
|
||||
EXPECT_TRUE(sync_status.ok())
|
||||
<< sync_status.code() << " " << sync_status.message();
|
||||
}
|
||||
|
||||
TEST_F(GrpcTlsCertificateVerifierTest, HostnameVerifierCommonNameCheckFails) {
|
||||
absl::Status sync_status;
|
||||
request_.target_name = "foo.com:443";
|
||||
request_.peer_info.common_name = "bar.com";
|
||||
EXPECT_TRUE(hostname_certificate_verifier_.Verify(
|
||||
&request_, [](absl::Status) {}, &sync_status));
|
||||
EXPECT_EQ(sync_status.code(), absl::StatusCode::kUnauthenticated);
|
||||
EXPECT_EQ(sync_status.ToString(),
|
||||
"UNAUTHENTICATED: Hostname Verification Check failed.");
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
|
||||
} // namespace grpc_core
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
grpc::testing::TestEnvironment env(argc, argv);
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
grpc_init();
|
||||
int ret = RUN_ALL_TESTS();
|
||||
grpc_shutdown();
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -61,18 +61,15 @@ class GrpcTlsCredentialsOptionsTest : public ::testing::Test {
|
|||
std::string root_cert_2_;
|
||||
std::string private_key_2_;
|
||||
std::string cert_chain_2_;
|
||||
HostNameCertificateVerifier hostname_certificate_verifier_;
|
||||
};
|
||||
|
||||
TEST_F(GrpcTlsCredentialsOptionsTest, ErrorDetails) {
|
||||
grpc_tls_error_details error_details;
|
||||
EXPECT_STREQ(error_details.error_details().c_str(), "");
|
||||
error_details.set_error_details("test error details");
|
||||
EXPECT_STREQ(error_details.error_details().c_str(), "test error details");
|
||||
}
|
||||
//
|
||||
// Tests for Default Root Certs.
|
||||
//
|
||||
|
||||
TEST_F(GrpcTlsCredentialsOptionsTest, ClientOptionsOnDefaultRootCerts) {
|
||||
auto options = MakeRefCounted<grpc_tls_credentials_options>();
|
||||
options->set_server_verification_option(GRPC_TLS_SERVER_VERIFICATION);
|
||||
auto credentials = MakeRefCounted<TlsCredentials>(options);
|
||||
ASSERT_NE(credentials, nullptr);
|
||||
grpc_channel_args* new_args = nullptr;
|
||||
|
|
@ -85,7 +82,10 @@ TEST_F(GrpcTlsCredentialsOptionsTest, ClientOptionsOnDefaultRootCerts) {
|
|||
EXPECT_NE(tls_connector->ClientHandshakerFactoryForTesting(), nullptr);
|
||||
}
|
||||
|
||||
//
|
||||
// Tests for StaticDataCertificateProvider.
|
||||
//
|
||||
|
||||
TEST_F(GrpcTlsCredentialsOptionsTest,
|
||||
ClientOptionsWithStaticDataProviderOnBothCerts) {
|
||||
auto options = MakeRefCounted<grpc_tls_credentials_options>();
|
||||
|
|
@ -94,7 +94,6 @@ TEST_F(GrpcTlsCredentialsOptionsTest,
|
|||
options->set_certificate_provider(std::move(provider));
|
||||
options->set_watch_root_cert(true);
|
||||
options->set_watch_identity_pair(true);
|
||||
options->set_server_verification_option(GRPC_TLS_SERVER_VERIFICATION);
|
||||
auto credentials = MakeRefCounted<TlsCredentials>(options);
|
||||
ASSERT_NE(credentials, nullptr);
|
||||
grpc_channel_args* new_args = nullptr;
|
||||
|
|
@ -116,7 +115,6 @@ TEST_F(GrpcTlsCredentialsOptionsTest,
|
|||
root_cert_, PemKeyCertPairList());
|
||||
options->set_certificate_provider(std::move(provider));
|
||||
options->set_watch_root_cert(true);
|
||||
options->set_server_verification_option(GRPC_TLS_SERVER_VERIFICATION);
|
||||
auto credentials = MakeRefCounted<TlsCredentials>(options);
|
||||
ASSERT_NE(credentials, nullptr);
|
||||
grpc_channel_args* new_args = nullptr;
|
||||
|
|
@ -138,7 +136,6 @@ TEST_F(GrpcTlsCredentialsOptionsTest,
|
|||
"", MakeCertKeyPairs(private_key_.c_str(), cert_chain_.c_str()));
|
||||
options->set_certificate_provider(std::move(provider));
|
||||
options->set_watch_root_cert(true);
|
||||
options->set_server_verification_option(GRPC_TLS_SERVER_VERIFICATION);
|
||||
auto credentials = MakeRefCounted<TlsCredentials>(options);
|
||||
ASSERT_NE(credentials, nullptr);
|
||||
grpc_channel_args* new_args = nullptr;
|
||||
|
|
@ -158,7 +155,6 @@ TEST_F(GrpcTlsCredentialsOptionsTest,
|
|||
"", MakeCertKeyPairs(private_key_.c_str(), cert_chain_.c_str()));
|
||||
options->set_certificate_provider(std::move(provider));
|
||||
options->set_watch_identity_pair(true);
|
||||
options->set_server_verification_option(GRPC_TLS_SERVER_VERIFICATION);
|
||||
auto credentials = MakeRefCounted<TlsCredentials>(options);
|
||||
ASSERT_NE(credentials, nullptr);
|
||||
grpc_channel_args* new_args = nullptr;
|
||||
|
|
@ -228,7 +224,10 @@ TEST_F(GrpcTlsCredentialsOptionsTest,
|
|||
EXPECT_EQ(tls_connector->ServerHandshakerFactoryForTesting(), nullptr);
|
||||
}
|
||||
|
||||
//
|
||||
// Tests for FileWatcherCertificateProvider.
|
||||
//
|
||||
|
||||
TEST_F(GrpcTlsCredentialsOptionsTest,
|
||||
ClientOptionsWithCertWatcherProviderOnBothCerts) {
|
||||
auto options = MakeRefCounted<grpc_tls_credentials_options>();
|
||||
|
|
@ -237,7 +236,6 @@ TEST_F(GrpcTlsCredentialsOptionsTest,
|
|||
options->set_certificate_provider(std::move(provider));
|
||||
options->set_watch_root_cert(true);
|
||||
options->set_watch_identity_pair(true);
|
||||
options->set_server_verification_option(GRPC_TLS_SERVER_VERIFICATION);
|
||||
auto credentials = MakeRefCounted<TlsCredentials>(options);
|
||||
ASSERT_NE(credentials, nullptr);
|
||||
grpc_channel_args* new_args = nullptr;
|
||||
|
|
@ -259,7 +257,6 @@ TEST_F(GrpcTlsCredentialsOptionsTest,
|
|||
MakeRefCounted<FileWatcherCertificateProvider>("", "", CA_CERT_PATH, 1);
|
||||
options->set_certificate_provider(std::move(provider));
|
||||
options->set_watch_root_cert(true);
|
||||
options->set_server_verification_option(GRPC_TLS_SERVER_VERIFICATION);
|
||||
auto credentials = MakeRefCounted<TlsCredentials>(options);
|
||||
ASSERT_NE(credentials, nullptr);
|
||||
grpc_channel_args* new_args = nullptr;
|
||||
|
|
@ -281,7 +278,6 @@ TEST_F(GrpcTlsCredentialsOptionsTest,
|
|||
SERVER_KEY_PATH, SERVER_CERT_PATH, "", 1);
|
||||
options->set_certificate_provider(std::move(provider));
|
||||
options->set_watch_root_cert(true);
|
||||
options->set_server_verification_option(GRPC_TLS_SERVER_VERIFICATION);
|
||||
auto credentials = MakeRefCounted<TlsCredentials>(options);
|
||||
ASSERT_NE(credentials, nullptr);
|
||||
grpc_channel_args* new_args = nullptr;
|
||||
|
|
@ -301,7 +297,6 @@ TEST_F(GrpcTlsCredentialsOptionsTest,
|
|||
MakeRefCounted<FileWatcherCertificateProvider>("", "", INVALID_PATH, 1);
|
||||
options->set_certificate_provider(std::move(provider));
|
||||
options->set_watch_root_cert(true);
|
||||
options->set_server_verification_option(GRPC_TLS_SERVER_VERIFICATION);
|
||||
auto credentials = MakeRefCounted<TlsCredentials>(options);
|
||||
ASSERT_NE(credentials, nullptr);
|
||||
grpc_channel_args* new_args = nullptr;
|
||||
|
|
@ -388,8 +383,11 @@ TEST_F(GrpcTlsCredentialsOptionsTest,
|
|||
EXPECT_EQ(tls_connector->ServerHandshakerFactoryForTesting(), nullptr);
|
||||
}
|
||||
|
||||
// The following tests write credential data to temporary files to test the
|
||||
//
|
||||
// Tests writing credential data to temporary files to test the
|
||||
// transition behavior of the provider.
|
||||
//
|
||||
|
||||
TEST_F(GrpcTlsCredentialsOptionsTest,
|
||||
ClientOptionsWithCertWatcherProviderOnCertificateRefreshed) {
|
||||
// Create temporary files and copy cert data into them.
|
||||
|
|
@ -404,7 +402,6 @@ TEST_F(GrpcTlsCredentialsOptionsTest,
|
|||
options->set_certificate_provider(std::move(provider));
|
||||
options->set_watch_root_cert(true);
|
||||
options->set_watch_identity_pair(true);
|
||||
options->set_server_verification_option(GRPC_TLS_SERVER_VERIFICATION);
|
||||
auto credentials = MakeRefCounted<TlsCredentials>(options);
|
||||
ASSERT_NE(credentials, nullptr);
|
||||
grpc_channel_args* new_args = nullptr;
|
||||
|
|
@ -453,7 +450,6 @@ TEST_F(GrpcTlsCredentialsOptionsTest,
|
|||
options->set_certificate_provider(std::move(provider));
|
||||
options->set_watch_root_cert(true);
|
||||
options->set_watch_identity_pair(true);
|
||||
options->set_server_verification_option(GRPC_TLS_SERVER_VERIFICATION);
|
||||
auto credentials = MakeRefCounted<TlsCredentials>(options);
|
||||
ASSERT_NE(credentials, nullptr);
|
||||
grpc_channel_args* new_args = nullptr;
|
||||
|
|
@ -490,6 +486,91 @@ TEST_F(GrpcTlsCredentialsOptionsTest,
|
|||
MakeCertKeyPairs(private_key_.c_str(), cert_chain_.c_str()));
|
||||
}
|
||||
|
||||
//
|
||||
// Tests for ExternalCertificateVerifier.
|
||||
// It will only test the creation of security connector, so the actual verify
|
||||
// logic is not invoked.
|
||||
//
|
||||
|
||||
TEST_F(GrpcTlsCredentialsOptionsTest, ClientOptionsWithExternalVerifier) {
|
||||
auto* sync_verifier_ = new SyncExternalVerifier(true);
|
||||
ExternalCertificateVerifier core_external_verifier(sync_verifier_->base());
|
||||
auto options = MakeRefCounted<grpc_tls_credentials_options>();
|
||||
options->set_verify_server_cert(true);
|
||||
options->set_certificate_verifier(core_external_verifier.Ref());
|
||||
options->set_check_call_host(false);
|
||||
auto credentials = MakeRefCounted<TlsCredentials>(options);
|
||||
ASSERT_NE(credentials, nullptr);
|
||||
grpc_channel_args* new_args = nullptr;
|
||||
auto connector = credentials->create_security_connector(
|
||||
nullptr, "random targets", nullptr, &new_args);
|
||||
grpc_channel_args_destroy(new_args);
|
||||
ASSERT_NE(connector, nullptr);
|
||||
TlsChannelSecurityConnector* tls_connector =
|
||||
static_cast<TlsChannelSecurityConnector*>(connector.get());
|
||||
EXPECT_NE(tls_connector, nullptr);
|
||||
}
|
||||
|
||||
TEST_F(GrpcTlsCredentialsOptionsTest, ServerOptionsWithExternalVerifier) {
|
||||
auto* sync_verifier_ = new SyncExternalVerifier(true);
|
||||
ExternalCertificateVerifier core_external_verifier(sync_verifier_->base());
|
||||
auto options = MakeRefCounted<grpc_tls_credentials_options>();
|
||||
options->set_cert_request_type(GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE);
|
||||
options->set_certificate_verifier(core_external_verifier.Ref());
|
||||
// On server side we have to set the provider providing identity certs.
|
||||
auto provider = MakeRefCounted<StaticDataCertificateProvider>(
|
||||
root_cert_, PemKeyCertPairList());
|
||||
options->set_certificate_provider(std::move(provider));
|
||||
options->set_watch_identity_pair(true);
|
||||
auto credentials = MakeRefCounted<TlsServerCredentials>(options);
|
||||
ASSERT_NE(credentials, nullptr);
|
||||
auto connector = credentials->create_security_connector(nullptr);
|
||||
ASSERT_NE(connector, nullptr);
|
||||
TlsServerSecurityConnector* tls_connector =
|
||||
static_cast<TlsServerSecurityConnector*>(connector.get());
|
||||
EXPECT_NE(tls_connector, nullptr);
|
||||
}
|
||||
|
||||
//
|
||||
// Tests for HostnameCertificateVerifier.
|
||||
//
|
||||
|
||||
TEST_F(GrpcTlsCredentialsOptionsTest,
|
||||
ClientOptionsWithHostnameCertificateVerifier) {
|
||||
auto options = MakeRefCounted<grpc_tls_credentials_options>();
|
||||
options->set_verify_server_cert(true);
|
||||
options->set_certificate_verifier(hostname_certificate_verifier_.Ref());
|
||||
auto credentials = MakeRefCounted<TlsCredentials>(options);
|
||||
ASSERT_NE(credentials, nullptr);
|
||||
grpc_channel_args* new_args = nullptr;
|
||||
auto connector = credentials->create_security_connector(
|
||||
nullptr, "random targets", nullptr, &new_args);
|
||||
grpc_channel_args_destroy(new_args);
|
||||
ASSERT_NE(connector, nullptr);
|
||||
TlsChannelSecurityConnector* tls_connector =
|
||||
static_cast<TlsChannelSecurityConnector*>(connector.get());
|
||||
EXPECT_NE(tls_connector->ClientHandshakerFactoryForTesting(), nullptr);
|
||||
}
|
||||
|
||||
TEST_F(GrpcTlsCredentialsOptionsTest,
|
||||
ServerOptionsWithHostnameCertificateVerifier) {
|
||||
auto options = MakeRefCounted<grpc_tls_credentials_options>();
|
||||
options->set_cert_request_type(GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE);
|
||||
options->set_certificate_verifier(hostname_certificate_verifier_.Ref());
|
||||
// On server side we have to set the provider providing identity certs.
|
||||
auto provider = MakeRefCounted<StaticDataCertificateProvider>(
|
||||
root_cert_, PemKeyCertPairList());
|
||||
options->set_certificate_provider(std::move(provider));
|
||||
options->set_watch_identity_pair(true);
|
||||
auto credentials = MakeRefCounted<TlsServerCredentials>(options);
|
||||
ASSERT_NE(credentials, nullptr);
|
||||
auto connector = credentials->create_security_connector(nullptr);
|
||||
ASSERT_NE(connector, nullptr);
|
||||
TlsServerSecurityConnector* tls_connector =
|
||||
static_cast<TlsServerSecurityConnector*>(connector.get());
|
||||
EXPECT_EQ(tls_connector->ServerHandshakerFactoryForTesting(), nullptr);
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
|
||||
} // namespace grpc_core
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "src/core/lib/security/credentials/tls/tls_credentials.h"
|
||||
#include "src/core/tsi/transport_security.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
#include "test/core/util/tls_utils.h"
|
||||
|
||||
#define CA_CERT_PATH "src/core/tsi/test_creds/ca.pem"
|
||||
#define CLIENT_CERT_PATH "src/core/tsi/test_creds/multi-domain.pem"
|
||||
|
|
@ -41,17 +42,18 @@
|
|||
#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 grpc_core {
|
||||
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";
|
||||
constexpr const char* kTargetName = "foo.bar.com:443";
|
||||
|
||||
class TlsSecurityConnectorTest : public ::testing::Test {
|
||||
protected:
|
||||
TlsSecurityConnectorTest() {}
|
||||
|
||||
void SetUp() override {
|
||||
grpc_slice ca_slice_1, ca_slice_0, cert_slice_1, key_slice_1, cert_slice_0,
|
||||
key_slice_0;
|
||||
|
|
@ -87,12 +89,27 @@ class TlsSecurityConnectorTest : public ::testing::Test {
|
|||
grpc_slice_unref(key_slice_0);
|
||||
}
|
||||
|
||||
void TearDown() override {}
|
||||
static void VerifyExpectedErrorCallback(void* arg, grpc_error_handle error) {
|
||||
const char* expected_error_msg = static_cast<const char*>(arg);
|
||||
if (expected_error_msg == nullptr) {
|
||||
EXPECT_EQ(error, GRPC_ERROR_NONE);
|
||||
} else {
|
||||
EXPECT_EQ(GetErrorMsg(error), expected_error_msg);
|
||||
}
|
||||
}
|
||||
|
||||
static std::string GetErrorMsg(grpc_error_handle error) {
|
||||
std::string error_str;
|
||||
GPR_ASSERT(
|
||||
grpc_error_get_str(error, GRPC_ERROR_STR_DESCRIPTION, &error_str));
|
||||
return error_str;
|
||||
}
|
||||
|
||||
std::string root_cert_1_;
|
||||
std::string root_cert_0_;
|
||||
grpc_core::PemKeyCertPairList identity_pairs_1_;
|
||||
grpc_core::PemKeyCertPairList identity_pairs_0_;
|
||||
grpc_core::HostNameCertificateVerifier hostname_certificate_verifier_;
|
||||
};
|
||||
|
||||
class TlsTestCertificateProvider : public ::grpc_tls_certificate_provider {
|
||||
|
|
@ -110,7 +127,10 @@ class TlsTestCertificateProvider : public ::grpc_tls_certificate_provider {
|
|||
grpc_core::RefCountedPtr<grpc_tls_certificate_distributor> distributor_;
|
||||
};
|
||||
|
||||
// Tests for ChannelSecurityConnector.
|
||||
//
|
||||
// Tests for Certificate Providers in ChannelSecurityConnector.
|
||||
//
|
||||
|
||||
TEST_F(TlsSecurityConnectorTest,
|
||||
RootAndIdentityCertsObtainedWhenCreateChannelSecurityConnector) {
|
||||
grpc_core::RefCountedPtr<grpc_tls_certificate_distributor> distributor =
|
||||
|
|
@ -347,33 +367,84 @@ TEST_F(TlsSecurityConnectorTest, CreateChannelSecurityConnectorFailNoOptions) {
|
|||
EXPECT_EQ(connector, nullptr);
|
||||
}
|
||||
|
||||
TEST_F(TlsSecurityConnectorTest, TlsCheckHostNameSuccess) {
|
||||
const char* target_name = "foo.test.google.fr";
|
||||
//
|
||||
// Tests for Certificate Verifier in ChannelSecurityConnector.
|
||||
//
|
||||
|
||||
TEST_F(TlsSecurityConnectorTest,
|
||||
ChannelSecurityConnectorWithSyncExternalVerifierSucceeds) {
|
||||
auto* sync_verifier_ = new SyncExternalVerifier(true);
|
||||
ExternalCertificateVerifier core_external_verifier(sync_verifier_->base());
|
||||
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options =
|
||||
grpc_core::MakeRefCounted<grpc_tls_credentials_options>();
|
||||
options->set_verify_server_cert(true);
|
||||
options->set_certificate_verifier(core_external_verifier.Ref());
|
||||
options->set_check_call_host(false);
|
||||
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);
|
||||
// Construct a basic TSI Peer.
|
||||
tsi_peer peer;
|
||||
GPR_ASSERT(tsi_construct_peer(1, &peer) == TSI_OK);
|
||||
GPR_ASSERT(tsi_construct_peer(2, &peer) == TSI_OK);
|
||||
GPR_ASSERT(tsi_construct_string_peer_property(TSI_SSL_ALPN_SELECTED_PROTOCOL,
|
||||
"grpc", strlen("grpc"),
|
||||
&peer.properties[0]) == TSI_OK);
|
||||
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_handle error =
|
||||
grpc_core::internal::TlsCheckHostName(target_name, &peer);
|
||||
tsi_peer_destruct(&peer);
|
||||
EXPECT_EQ(error, GRPC_ERROR_NONE);
|
||||
GRPC_ERROR_UNREF(error);
|
||||
TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, "foo.bar.com",
|
||||
&peer.properties[1]) == TSI_OK);
|
||||
grpc_core::RefCountedPtr<grpc_auth_context> auth_context;
|
||||
grpc_core::ExecCtx exec_ctx;
|
||||
grpc_closure* on_peer_checked = GRPC_CLOSURE_CREATE(
|
||||
VerifyExpectedErrorCallback, nullptr, grpc_schedule_on_exec_ctx);
|
||||
tls_connector->check_peer(peer, nullptr, &auth_context, on_peer_checked);
|
||||
grpc_channel_args_destroy(new_args);
|
||||
}
|
||||
|
||||
TEST_F(TlsSecurityConnectorTest, TlsCheckHostNameFail) {
|
||||
const char* target_name = "foo.test.google.fr";
|
||||
const char* another_name = "bar.test.google.fr";
|
||||
TEST_F(TlsSecurityConnectorTest,
|
||||
ChannelSecurityConnectorWithSyncExternalVerifierFails) {
|
||||
auto* sync_verifier_ = new SyncExternalVerifier(false);
|
||||
ExternalCertificateVerifier core_external_verifier(sync_verifier_->base());
|
||||
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options =
|
||||
grpc_core::MakeRefCounted<grpc_tls_credentials_options>();
|
||||
options->set_verify_server_cert(true);
|
||||
options->set_certificate_verifier(core_external_verifier.Ref());
|
||||
options->set_check_call_host(false);
|
||||
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);
|
||||
// Construct a basic TSI Peer.
|
||||
tsi_peer peer;
|
||||
GPR_ASSERT(tsi_construct_peer(1, &peer) == TSI_OK);
|
||||
GPR_ASSERT(tsi_construct_peer(2, &peer) == TSI_OK);
|
||||
GPR_ASSERT(tsi_construct_string_peer_property(TSI_SSL_ALPN_SELECTED_PROTOCOL,
|
||||
"grpc", strlen("grpc"),
|
||||
&peer.properties[0]) == TSI_OK);
|
||||
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_handle error =
|
||||
grpc_core::internal::TlsCheckHostName(target_name, &peer);
|
||||
tsi_peer_destruct(&peer);
|
||||
EXPECT_NE(error, GRPC_ERROR_NONE);
|
||||
GRPC_ERROR_UNREF(error);
|
||||
TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, "foo.bar.com",
|
||||
&peer.properties[1]) == TSI_OK);
|
||||
grpc_core::RefCountedPtr<grpc_auth_context> auth_context;
|
||||
const char* expected_error_msg =
|
||||
"Custom verification check failed with error: UNAUTHENTICATED: "
|
||||
"SyncExternalVerifier failed";
|
||||
grpc_core::ExecCtx exec_ctx;
|
||||
grpc_closure* on_peer_checked = GRPC_CLOSURE_CREATE(
|
||||
VerifyExpectedErrorCallback, const_cast<char*>(expected_error_msg),
|
||||
grpc_schedule_on_exec_ctx);
|
||||
tls_connector->check_peer(peer, nullptr, &auth_context, on_peer_checked);
|
||||
grpc_channel_args_destroy(new_args);
|
||||
}
|
||||
|
||||
TEST_F(TlsSecurityConnectorTest,
|
||||
|
|
@ -477,6 +548,192 @@ TEST_F(TlsSecurityConnectorTest,
|
|||
}
|
||||
|
||||
// Tests for ServerSecurityConnector.
|
||||
TEST_F(TlsSecurityConnectorTest,
|
||||
ChannelSecurityConnectorWithAsyncExternalVerifierSucceeds) {
|
||||
auto* async_verifier = new AsyncExternalVerifier(true);
|
||||
auto* core_external_verifier =
|
||||
new ExternalCertificateVerifier(async_verifier->base());
|
||||
auto options = grpc_core::MakeRefCounted<grpc_tls_credentials_options>();
|
||||
options->set_verify_server_cert(true);
|
||||
options->set_certificate_verifier(core_external_verifier->Ref());
|
||||
options->set_check_call_host(false);
|
||||
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);
|
||||
// Construct a basic TSI Peer.
|
||||
tsi_peer peer;
|
||||
GPR_ASSERT(tsi_construct_peer(2, &peer) == TSI_OK);
|
||||
GPR_ASSERT(tsi_construct_string_peer_property(TSI_SSL_ALPN_SELECTED_PROTOCOL,
|
||||
"grpc", strlen("grpc"),
|
||||
&peer.properties[0]) == TSI_OK);
|
||||
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
|
||||
TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, "foo.bar.com",
|
||||
&peer.properties[1]) == TSI_OK);
|
||||
grpc_core::RefCountedPtr<grpc_auth_context> auth_context;
|
||||
grpc_core::ExecCtx exec_ctx;
|
||||
grpc_closure* on_peer_checked = GRPC_CLOSURE_CREATE(
|
||||
VerifyExpectedErrorCallback, nullptr, grpc_schedule_on_exec_ctx);
|
||||
tls_connector->check_peer(peer, nullptr, &auth_context, on_peer_checked);
|
||||
grpc_channel_args_destroy(new_args);
|
||||
core_external_verifier->Unref();
|
||||
}
|
||||
|
||||
TEST_F(TlsSecurityConnectorTest,
|
||||
ChannelSecurityConnectorWithAsyncExternalVerifierFails) {
|
||||
auto* async_verifier = new AsyncExternalVerifier(false);
|
||||
auto* core_external_verifier =
|
||||
new ExternalCertificateVerifier(async_verifier->base());
|
||||
auto options = grpc_core::MakeRefCounted<grpc_tls_credentials_options>();
|
||||
options->set_verify_server_cert(true);
|
||||
options->set_certificate_verifier(core_external_verifier->Ref());
|
||||
options->set_check_call_host(false);
|
||||
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);
|
||||
// Construct a basic TSI Peer.
|
||||
tsi_peer peer;
|
||||
GPR_ASSERT(tsi_construct_peer(2, &peer) == TSI_OK);
|
||||
GPR_ASSERT(tsi_construct_string_peer_property(TSI_SSL_ALPN_SELECTED_PROTOCOL,
|
||||
"grpc", strlen("grpc"),
|
||||
&peer.properties[0]) == TSI_OK);
|
||||
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
|
||||
TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, "foo.bar.com",
|
||||
&peer.properties[1]) == TSI_OK);
|
||||
grpc_core::RefCountedPtr<grpc_auth_context> auth_context;
|
||||
const char* expected_error_msg =
|
||||
"Custom verification check failed with error: UNAUTHENTICATED: "
|
||||
"AsyncExternalVerifier failed";
|
||||
grpc_core::ExecCtx exec_ctx;
|
||||
grpc_closure* on_peer_checked = GRPC_CLOSURE_CREATE(
|
||||
VerifyExpectedErrorCallback, const_cast<char*>(expected_error_msg),
|
||||
grpc_schedule_on_exec_ctx);
|
||||
tls_connector->check_peer(peer, nullptr, &auth_context, on_peer_checked);
|
||||
grpc_channel_args_destroy(new_args);
|
||||
core_external_verifier->Unref();
|
||||
}
|
||||
|
||||
TEST_F(TlsSecurityConnectorTest,
|
||||
ChannelSecurityConnectorHostnameVerifierSucceeds) {
|
||||
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options =
|
||||
grpc_core::MakeRefCounted<grpc_tls_credentials_options>();
|
||||
options->set_verify_server_cert(true);
|
||||
options->set_certificate_verifier(hostname_certificate_verifier_.Ref());
|
||||
options->set_check_call_host(false);
|
||||
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);
|
||||
// Construct a full TSI Peer.
|
||||
tsi_peer peer;
|
||||
GPR_ASSERT(tsi_construct_peer(7, &peer) == TSI_OK);
|
||||
GPR_ASSERT(tsi_construct_string_peer_property(TSI_SSL_ALPN_SELECTED_PROTOCOL,
|
||||
"grpc", strlen("grpc"),
|
||||
&peer.properties[0]) == TSI_OK);
|
||||
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
|
||||
TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, "foo.bar.com",
|
||||
&peer.properties[1]) == TSI_OK);
|
||||
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
|
||||
TSI_X509_PEM_CERT_PROPERTY, "pem_cert", &peer.properties[2]) ==
|
||||
TSI_OK);
|
||||
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
|
||||
TSI_SECURITY_LEVEL_PEER_PROPERTY,
|
||||
tsi_security_level_to_string(TSI_PRIVACY_AND_INTEGRITY),
|
||||
&peer.properties[3]) == TSI_OK);
|
||||
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
|
||||
TSI_X509_PEM_CERT_CHAIN_PROPERTY, "pem_cert_chain",
|
||||
&peer.properties[4]) == TSI_OK);
|
||||
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
|
||||
TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, "foo.bar.com",
|
||||
&peer.properties[5]) == TSI_OK);
|
||||
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
|
||||
TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, "foo.baz.com",
|
||||
&peer.properties[6]) == TSI_OK);
|
||||
grpc_core::RefCountedPtr<grpc_auth_context> auth_context;
|
||||
grpc_core::ExecCtx exec_ctx;
|
||||
grpc_closure* on_peer_checked = GRPC_CLOSURE_CREATE(
|
||||
VerifyExpectedErrorCallback, nullptr, grpc_schedule_on_exec_ctx);
|
||||
tls_connector->check_peer(peer, nullptr, &auth_context, on_peer_checked);
|
||||
grpc_channel_args_destroy(new_args);
|
||||
}
|
||||
|
||||
TEST_F(TlsSecurityConnectorTest,
|
||||
ChannelSecurityConnectorHostnameVerifierFails) {
|
||||
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options =
|
||||
grpc_core::MakeRefCounted<grpc_tls_credentials_options>();
|
||||
options->set_verify_server_cert(true);
|
||||
options->set_certificate_verifier(hostname_certificate_verifier_.Ref());
|
||||
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);
|
||||
// Construct a full TSI Peer.
|
||||
tsi_peer peer;
|
||||
GPR_ASSERT(tsi_construct_peer(7, &peer) == TSI_OK);
|
||||
GPR_ASSERT(tsi_construct_string_peer_property(TSI_SSL_ALPN_SELECTED_PROTOCOL,
|
||||
"grpc", strlen("grpc"),
|
||||
&peer.properties[0]) == TSI_OK);
|
||||
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
|
||||
TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, "foo.com",
|
||||
&peer.properties[1]) == TSI_OK);
|
||||
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
|
||||
TSI_X509_PEM_CERT_PROPERTY, "pem_cert", &peer.properties[2]) ==
|
||||
TSI_OK);
|
||||
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
|
||||
TSI_SECURITY_LEVEL_PEER_PROPERTY,
|
||||
tsi_security_level_to_string(TSI_PRIVACY_AND_INTEGRITY),
|
||||
&peer.properties[3]) == TSI_OK);
|
||||
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
|
||||
TSI_X509_PEM_CERT_CHAIN_PROPERTY, "pem_cert_chain",
|
||||
&peer.properties[4]) == TSI_OK);
|
||||
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
|
||||
TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, "*.com",
|
||||
&peer.properties[5]) == TSI_OK);
|
||||
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
|
||||
TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, "foo.baz.com",
|
||||
&peer.properties[6]) == TSI_OK);
|
||||
grpc_core::RefCountedPtr<grpc_auth_context> auth_context;
|
||||
const char* expected_error_msg =
|
||||
"Custom verification check failed with error: UNAUTHENTICATED: Hostname "
|
||||
"Verification "
|
||||
"Check failed.";
|
||||
grpc_core::ExecCtx exec_ctx;
|
||||
grpc_closure* on_peer_checked = GRPC_CLOSURE_CREATE(
|
||||
VerifyExpectedErrorCallback, const_cast<char*>(expected_error_msg),
|
||||
grpc_schedule_on_exec_ctx);
|
||||
tls_connector->check_peer(peer, nullptr, &auth_context, on_peer_checked);
|
||||
grpc_channel_args_destroy(new_args);
|
||||
}
|
||||
|
||||
//
|
||||
// Tests for Certificate Providers in ServerSecurityConnector.
|
||||
//
|
||||
|
||||
TEST_F(TlsSecurityConnectorTest,
|
||||
RootAndIdentityCertsObtainedWhenCreateServerSecurityConnector) {
|
||||
grpc_core::RefCountedPtr<grpc_tls_certificate_distributor> distributor =
|
||||
|
|
@ -691,8 +948,147 @@ TEST_F(TlsSecurityConnectorTest,
|
|||
EXPECT_NE(connector->cmp(other_connector.get()), 0);
|
||||
}
|
||||
|
||||
//
|
||||
// Tests for Certificate Verifier in ServerSecurityConnector.
|
||||
//
|
||||
|
||||
TEST_F(TlsSecurityConnectorTest,
|
||||
ServerSecurityConnectorWithSyncExternalVerifierSucceeds) {
|
||||
auto* sync_verifier = new SyncExternalVerifier(true);
|
||||
ExternalCertificateVerifier core_external_verifier(sync_verifier->base());
|
||||
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options =
|
||||
grpc_core::MakeRefCounted<grpc_tls_credentials_options>();
|
||||
options->set_cert_request_type(GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE);
|
||||
options->set_certificate_verifier(core_external_verifier.Ref());
|
||||
auto provider =
|
||||
grpc_core::MakeRefCounted<grpc_core::StaticDataCertificateProvider>(
|
||||
"", grpc_core::PemKeyCertPairList());
|
||||
options->set_certificate_provider(std::move(provider));
|
||||
options->set_watch_identity_pair(true);
|
||||
auto credentials = grpc_core::MakeRefCounted<TlsServerCredentials>(options);
|
||||
auto connector = credentials->create_security_connector(nullptr);
|
||||
// Construct a basic TSI Peer.
|
||||
tsi_peer peer;
|
||||
GPR_ASSERT(tsi_construct_peer(2, &peer) == TSI_OK);
|
||||
GPR_ASSERT(tsi_construct_string_peer_property(TSI_SSL_ALPN_SELECTED_PROTOCOL,
|
||||
"grpc", strlen("grpc"),
|
||||
&peer.properties[0]) == TSI_OK);
|
||||
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
|
||||
TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, "foo.bar.com",
|
||||
&peer.properties[1]) == TSI_OK);
|
||||
grpc_core::RefCountedPtr<grpc_auth_context> auth_context;
|
||||
grpc_core::ExecCtx exec_ctx;
|
||||
grpc_closure* on_peer_checked = GRPC_CLOSURE_CREATE(
|
||||
VerifyExpectedErrorCallback, nullptr, grpc_schedule_on_exec_ctx);
|
||||
connector->check_peer(peer, nullptr, &auth_context, on_peer_checked);
|
||||
}
|
||||
|
||||
TEST_F(TlsSecurityConnectorTest,
|
||||
ServerSecurityConnectorWithSyncExternalVerifierFails) {
|
||||
auto* sync_verifier = new SyncExternalVerifier(false);
|
||||
ExternalCertificateVerifier core_external_verifier(sync_verifier->base());
|
||||
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options =
|
||||
grpc_core::MakeRefCounted<grpc_tls_credentials_options>();
|
||||
options->set_cert_request_type(GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE);
|
||||
options->set_certificate_verifier(core_external_verifier.Ref());
|
||||
auto provider =
|
||||
grpc_core::MakeRefCounted<grpc_core::StaticDataCertificateProvider>(
|
||||
"", grpc_core::PemKeyCertPairList());
|
||||
options->set_certificate_provider(std::move(provider));
|
||||
options->set_watch_identity_pair(true);
|
||||
auto credentials = grpc_core::MakeRefCounted<TlsServerCredentials>(options);
|
||||
auto connector = credentials->create_security_connector(nullptr);
|
||||
// Construct a basic TSI Peer.
|
||||
tsi_peer peer;
|
||||
GPR_ASSERT(tsi_construct_peer(2, &peer) == TSI_OK);
|
||||
GPR_ASSERT(tsi_construct_string_peer_property(TSI_SSL_ALPN_SELECTED_PROTOCOL,
|
||||
"grpc", strlen("grpc"),
|
||||
&peer.properties[0]) == TSI_OK);
|
||||
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
|
||||
TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, "foo.bar.com",
|
||||
&peer.properties[1]) == TSI_OK);
|
||||
grpc_core::RefCountedPtr<grpc_auth_context> auth_context;
|
||||
const char* expected_error_msg =
|
||||
"Custom verification check failed with error: UNAUTHENTICATED: "
|
||||
"SyncExternalVerifier failed";
|
||||
grpc_core::ExecCtx exec_ctx;
|
||||
grpc_closure* on_peer_checked = GRPC_CLOSURE_CREATE(
|
||||
VerifyExpectedErrorCallback, const_cast<char*>(expected_error_msg),
|
||||
grpc_schedule_on_exec_ctx);
|
||||
connector->check_peer(peer, nullptr, &auth_context, on_peer_checked);
|
||||
}
|
||||
|
||||
TEST_F(TlsSecurityConnectorTest,
|
||||
ServerSecurityConnectorWithAsyncExternalVerifierSucceeds) {
|
||||
auto* async_verifier = new AsyncExternalVerifier(true);
|
||||
auto* core_external_verifier =
|
||||
new ExternalCertificateVerifier(async_verifier->base());
|
||||
auto options = grpc_core::MakeRefCounted<grpc_tls_credentials_options>();
|
||||
options->set_cert_request_type(GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE);
|
||||
options->set_certificate_verifier(core_external_verifier->Ref());
|
||||
auto provider =
|
||||
grpc_core::MakeRefCounted<grpc_core::StaticDataCertificateProvider>(
|
||||
"", grpc_core::PemKeyCertPairList());
|
||||
options->set_certificate_provider(std::move(provider));
|
||||
options->set_watch_identity_pair(true);
|
||||
auto credentials = grpc_core::MakeRefCounted<TlsServerCredentials>(options);
|
||||
auto connector = credentials->create_security_connector(nullptr);
|
||||
// Construct a basic TSI Peer.
|
||||
tsi_peer peer;
|
||||
GPR_ASSERT(tsi_construct_peer(2, &peer) == TSI_OK);
|
||||
GPR_ASSERT(tsi_construct_string_peer_property(TSI_SSL_ALPN_SELECTED_PROTOCOL,
|
||||
"grpc", strlen("grpc"),
|
||||
&peer.properties[0]) == TSI_OK);
|
||||
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
|
||||
TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, "foo.bar.com",
|
||||
&peer.properties[1]) == TSI_OK);
|
||||
grpc_core::RefCountedPtr<grpc_auth_context> auth_context;
|
||||
grpc_core::ExecCtx exec_ctx;
|
||||
grpc_closure* on_peer_checked = GRPC_CLOSURE_CREATE(
|
||||
VerifyExpectedErrorCallback, nullptr, grpc_schedule_on_exec_ctx);
|
||||
connector->check_peer(peer, nullptr, &auth_context, on_peer_checked);
|
||||
core_external_verifier->Unref();
|
||||
}
|
||||
|
||||
TEST_F(TlsSecurityConnectorTest,
|
||||
ServerSecurityConnectorWithAsyncExternalVerifierFails) {
|
||||
auto* async_verifier = new AsyncExternalVerifier(false);
|
||||
auto* core_external_verifier =
|
||||
new ExternalCertificateVerifier(async_verifier->base());
|
||||
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options =
|
||||
grpc_core::MakeRefCounted<grpc_tls_credentials_options>();
|
||||
options->set_cert_request_type(GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE);
|
||||
options->set_certificate_verifier(core_external_verifier->Ref());
|
||||
auto provider =
|
||||
grpc_core::MakeRefCounted<grpc_core::StaticDataCertificateProvider>(
|
||||
"", grpc_core::PemKeyCertPairList());
|
||||
options->set_certificate_provider(std::move(provider));
|
||||
options->set_watch_identity_pair(true);
|
||||
auto credentials = grpc_core::MakeRefCounted<TlsServerCredentials>(options);
|
||||
auto connector = credentials->create_security_connector(nullptr);
|
||||
// Construct a basic TSI Peer.
|
||||
tsi_peer peer;
|
||||
GPR_ASSERT(tsi_construct_peer(2, &peer) == TSI_OK);
|
||||
GPR_ASSERT(tsi_construct_string_peer_property(TSI_SSL_ALPN_SELECTED_PROTOCOL,
|
||||
"grpc", strlen("grpc"),
|
||||
&peer.properties[0]) == TSI_OK);
|
||||
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
|
||||
TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, "foo.bar.com",
|
||||
&peer.properties[1]) == TSI_OK);
|
||||
grpc_core::RefCountedPtr<grpc_auth_context> auth_context;
|
||||
const char* expected_error_msg =
|
||||
"Custom verification check failed with error: UNAUTHENTICATED: "
|
||||
"AsyncExternalVerifier failed";
|
||||
grpc_core::ExecCtx exec_ctx;
|
||||
grpc_closure* on_peer_checked = GRPC_CLOSURE_CREATE(
|
||||
VerifyExpectedErrorCallback, const_cast<char*>(expected_error_msg),
|
||||
grpc_schedule_on_exec_ctx);
|
||||
connector->check_peer(peer, nullptr, &auth_context, on_peer_checked);
|
||||
core_external_verifier->Unref();
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
} // namespace grpc
|
||||
} // namespace grpc_core
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
grpc::testing::TestEnvironment env(argc, argv);
|
||||
|
|
|
|||
|
|
@ -216,16 +216,14 @@ int main(int argc, char **argv) {
|
|||
printf("%lx", (unsigned long) grpc_tls_certificate_provider_file_watcher_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_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_server_authorization_check_config_create);
|
||||
printf("%lx", (unsigned long) grpc_tls_server_authorization_check_config_release);
|
||||
printf("%lx", (unsigned long) grpc_tls_credentials_options_set_cert_request_type);
|
||||
printf("%lx", (unsigned long) grpc_tls_credentials_options_set_verify_server_cert);
|
||||
printf("%lx", (unsigned long) grpc_tls_credentials_options_set_check_call_host);
|
||||
printf("%lx", (unsigned long) grpc_xds_credentials_create);
|
||||
printf("%lx", (unsigned long) grpc_xds_server_credentials_create);
|
||||
printf("%lx", (unsigned long) grpc_authorization_policy_provider_static_data_create);
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
#include "test/core/util/tls_utils.h"
|
||||
|
||||
#include <grpc/support/log.h>
|
||||
|
||||
#include "src/core/lib/gpr/tmpfile.h"
|
||||
#include "src/core/lib/iomgr/load_file.h"
|
||||
#include "src/core/lib/slice/slice_internal.h"
|
||||
|
|
@ -71,6 +73,102 @@ std::string GetFileContents(const char* path) {
|
|||
return credential;
|
||||
}
|
||||
|
||||
int SyncExternalVerifier::Verify(void* user_data,
|
||||
grpc_tls_custom_verification_check_request*,
|
||||
grpc_tls_on_custom_verification_check_done_cb,
|
||||
void*, grpc_status_code* sync_status,
|
||||
char** sync_error_details) {
|
||||
auto* self = static_cast<SyncExternalVerifier*>(user_data);
|
||||
if (self->success_) {
|
||||
*sync_status = GRPC_STATUS_OK;
|
||||
return true; // Synchronous call
|
||||
}
|
||||
*sync_status = GRPC_STATUS_UNAUTHENTICATED;
|
||||
*sync_error_details = gpr_strdup("SyncExternalVerifier failed");
|
||||
return true; // Synchronous call
|
||||
}
|
||||
|
||||
void SyncExternalVerifier::Destruct(void* user_data) {
|
||||
auto* self = static_cast<SyncExternalVerifier*>(user_data);
|
||||
delete self;
|
||||
}
|
||||
|
||||
AsyncExternalVerifier::~AsyncExternalVerifier() {
|
||||
// Tell the thread to shut down.
|
||||
{
|
||||
MutexLock lock(&mu_);
|
||||
queue_.push_back(Request{nullptr, nullptr, nullptr, true});
|
||||
}
|
||||
// Wait for thread to exit.
|
||||
thread_.Join();
|
||||
grpc_shutdown();
|
||||
}
|
||||
|
||||
int AsyncExternalVerifier::Verify(
|
||||
void* user_data, grpc_tls_custom_verification_check_request* request,
|
||||
grpc_tls_on_custom_verification_check_done_cb callback, void* callback_arg,
|
||||
grpc_status_code*, char**) {
|
||||
auto* self = static_cast<AsyncExternalVerifier*>(user_data);
|
||||
// Add request to queue to be picked up by worker thread.
|
||||
MutexLock lock(&self->mu_);
|
||||
self->queue_.push_back(Request{request, callback, callback_arg, false});
|
||||
return false; // Asynchronous call
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void DestroyExternalVerifier(void* arg) {
|
||||
auto* verifier = static_cast<AsyncExternalVerifier*>(arg);
|
||||
delete verifier;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void AsyncExternalVerifier::Destruct(void* user_data) {
|
||||
auto* self = static_cast<AsyncExternalVerifier*>(user_data);
|
||||
// Spawn a detached thread to destroy the verifier, to make sure that we don't
|
||||
// try to join the worker thread from within the worker thread.
|
||||
grpc_core::Thread destroy_thread(
|
||||
"DestroyExternalVerifier", DestroyExternalVerifier, self, nullptr,
|
||||
grpc_core::Thread::Options().set_joinable(false));
|
||||
destroy_thread.Start();
|
||||
}
|
||||
|
||||
void AsyncExternalVerifier::WorkerThread(void* arg) {
|
||||
auto* self = static_cast<AsyncExternalVerifier*>(arg);
|
||||
while (true) {
|
||||
// Check queue for work.
|
||||
bool got_request = false;
|
||||
Request request;
|
||||
{
|
||||
MutexLock lock(&self->mu_);
|
||||
if (!self->queue_.empty()) {
|
||||
got_request = true;
|
||||
request = self->queue_.front();
|
||||
self->queue_.pop_front();
|
||||
}
|
||||
}
|
||||
// If nothing found in the queue, sleep for a bit and try again.
|
||||
if (!got_request) {
|
||||
gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(100));
|
||||
continue;
|
||||
}
|
||||
// If we're being told to shut down, return.
|
||||
if (request.shutdown) {
|
||||
return;
|
||||
}
|
||||
// Process the request.
|
||||
if (self->success_) {
|
||||
request.callback(request.request, request.callback_arg, GRPC_STATUS_OK,
|
||||
"");
|
||||
} else {
|
||||
request.callback(request.request, request.callback_arg,
|
||||
GRPC_STATUS_UNAUTHENTICATED,
|
||||
"AsyncExternalVerifier failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
|
||||
} // namespace grpc_core
|
||||
|
|
|
|||
|
|
@ -14,7 +14,11 @@
|
|||
// limitations under the License.
|
||||
//
|
||||
|
||||
#include <deque>
|
||||
|
||||
#include "src/core/lib/gprpp/thd.h"
|
||||
#include "src/core/lib/security/security_connector/ssl_utils.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
namespace grpc_core {
|
||||
|
||||
|
|
@ -43,6 +47,90 @@ PemKeyCertPairList MakeCertKeyPairs(absl::string_view private_key,
|
|||
|
||||
std::string GetFileContents(const char* path);
|
||||
|
||||
// A synchronous external verifier implementation that simply returns
|
||||
// verification results based on users' inputs. Note that it will delete itself
|
||||
// in Destruct(), so create it like
|
||||
// ```
|
||||
// auto* sync_verifier_ = new SyncExternalVerifier(false);
|
||||
// ```
|
||||
// and no need to delete it later. This is basically to keep consistent with the
|
||||
// semantics in AsyncExternalVerifier.
|
||||
class SyncExternalVerifier {
|
||||
public:
|
||||
explicit SyncExternalVerifier(bool success)
|
||||
: success_(success), base_{this, Verify, Cancel, Destruct} {}
|
||||
|
||||
grpc_tls_certificate_verifier_external* base() { return &base_; }
|
||||
|
||||
private:
|
||||
static int Verify(void* user_data,
|
||||
grpc_tls_custom_verification_check_request* request,
|
||||
grpc_tls_on_custom_verification_check_done_cb callback,
|
||||
void* callback_arg, grpc_status_code* sync_status,
|
||||
char** sync_error_details);
|
||||
|
||||
static void Cancel(void*, grpc_tls_custom_verification_check_request*) {}
|
||||
|
||||
static void Destruct(void* user_data);
|
||||
|
||||
bool success_ = false;
|
||||
grpc_tls_certificate_verifier_external base_;
|
||||
};
|
||||
|
||||
// An asynchronous external verifier implementation that runs a thread and
|
||||
// process each request received from the verifier sequentially. Note that it
|
||||
// will delete itself in Destruct(), so create it like
|
||||
// ```
|
||||
// auto* async_verifier = new AsyncExternalVerifier(true, &event);
|
||||
// auto* core_external_verifier =
|
||||
// new ExternalCertificateVerifier(async_verifier->base());
|
||||
// ```
|
||||
// and no need to delete it later.
|
||||
// We delete AsyncExternalVerifier in Destruct() instead of its dtor because we
|
||||
// wanted AsyncExternalVerifier to outlive the underlying core
|
||||
// ExternalCertificateVerifier implementation.
|
||||
class AsyncExternalVerifier {
|
||||
public:
|
||||
explicit AsyncExternalVerifier(bool success)
|
||||
: success_(success),
|
||||
thread_("AsyncExternalVerifierWorkerThread", WorkerThread, this),
|
||||
base_{this, Verify, Cancel, Destruct} {
|
||||
grpc_init();
|
||||
thread_.Start();
|
||||
}
|
||||
|
||||
~AsyncExternalVerifier();
|
||||
|
||||
grpc_tls_certificate_verifier_external* base() { return &base_; }
|
||||
|
||||
private:
|
||||
// A request to pass to the worker thread.
|
||||
struct Request {
|
||||
grpc_tls_custom_verification_check_request* request;
|
||||
grpc_tls_on_custom_verification_check_done_cb callback;
|
||||
void* callback_arg;
|
||||
bool shutdown; // If true, thread will exit.
|
||||
};
|
||||
|
||||
static int Verify(void* user_data,
|
||||
grpc_tls_custom_verification_check_request* request,
|
||||
grpc_tls_on_custom_verification_check_done_cb callback,
|
||||
void* callback_arg, grpc_status_code* sync_status,
|
||||
char** sync_error_details);
|
||||
|
||||
static void Cancel(void*, grpc_tls_custom_verification_check_request*) {}
|
||||
|
||||
static void Destruct(void* user_data);
|
||||
|
||||
static void WorkerThread(void* arg);
|
||||
|
||||
bool success_ = false;
|
||||
grpc_core::Thread thread_;
|
||||
grpc_tls_certificate_verifier_external base_;
|
||||
Mutex mu_;
|
||||
std::deque<Request> queue_ ABSL_GUARDED_BY(mu_);
|
||||
};
|
||||
|
||||
} // namespace testing
|
||||
|
||||
} // namespace grpc_core
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ grpc_cc_test(
|
|||
"//:grpc",
|
||||
"//:grpc++",
|
||||
"//test/core/util:grpc_test_util",
|
||||
"//test/cpp/util:tls_test_utils",
|
||||
],
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
#include "src/core/lib/gpr/env.h"
|
||||
#include "src/core/lib/gpr/tmpfile.h"
|
||||
#include "src/cpp/client/secure_credentials.h"
|
||||
#include "src/cpp/common/tls_credentials_options_util.h"
|
||||
#include "test/cpp/util/tls_test_utils.h"
|
||||
|
||||
#define CA_CERT_PATH "src/core/tsi/test_creds/ca.pem"
|
||||
#define SERVER_CERT_PATH "src/core/tsi/test_creds/server1.pem"
|
||||
|
|
@ -45,44 +45,11 @@ constexpr const char* kIdentityCertName = "identity_cert_name";
|
|||
constexpr const char* kIdentityCertPrivateKey = "identity_private_key";
|
||||
constexpr const char* kIdentityCertContents = "identity_cert_contents";
|
||||
|
||||
using ::grpc::experimental::ExternalCertificateVerifier;
|
||||
using ::grpc::experimental::FileWatcherCertificateProvider;
|
||||
using ::grpc::experimental::HostNameCertificateVerifier;
|
||||
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) {
|
||||
GPR_ASSERT(arg != nullptr);
|
||||
std::string cb_user_data = "cb_user_data";
|
||||
arg->cb_user_data = static_cast<void*>(gpr_strdup(cb_user_data.c_str()));
|
||||
arg->success = 1;
|
||||
arg->target_name = gpr_strdup("callback_target_name");
|
||||
arg->peer_cert = gpr_strdup("callback_peer_cert");
|
||||
arg->status = GRPC_STATUS_OK;
|
||||
arg->error_details->set_error_details("callback_error_details");
|
||||
}
|
||||
|
||||
class TestTlsServerAuthorizationCheck
|
||||
: public TlsServerAuthorizationCheckInterface {
|
||||
int Schedule(TlsServerAuthorizationCheckArg* arg) override {
|
||||
GPR_ASSERT(arg != nullptr);
|
||||
std::string cb_user_data = "cb_user_data";
|
||||
arg->set_cb_user_data(static_cast<void*>(gpr_strdup(cb_user_data.c_str())));
|
||||
arg->set_success(1);
|
||||
arg->set_target_name("sync_target_name");
|
||||
arg->set_peer_cert("sync_peer_cert");
|
||||
arg->set_status(GRPC_STATUS_OK);
|
||||
arg->set_error_details("sync_error_details");
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Cancel(TlsServerAuthorizationCheckArg* arg) override {
|
||||
GPR_ASSERT(arg != nullptr);
|
||||
arg->set_status(GRPC_STATUS_PERMISSION_DENIED);
|
||||
arg->set_error_details("cancelled");
|
||||
}
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace grpc {
|
||||
|
|
@ -297,126 +264,9 @@ TEST(CredentialsTest, StsCredentialsOptionsFromEnv) {
|
|||
gpr_unsetenv("STS_CREDENTIALS");
|
||||
}
|
||||
|
||||
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;
|
||||
c_arg->context = nullptr;
|
||||
c_arg->error_details = new grpc_tls_error_details();
|
||||
TlsServerAuthorizationCheckArg* arg =
|
||||
new TlsServerAuthorizationCheckArg(c_arg);
|
||||
arg->set_cb_user_data(nullptr);
|
||||
arg->set_success(0);
|
||||
arg->set_target_name("target_name");
|
||||
arg->set_peer_cert("peer_cert");
|
||||
arg->set_status(GRPC_STATUS_UNAUTHENTICATED);
|
||||
arg->set_error_details("error_details");
|
||||
const char* target_name_before_callback = c_arg->target_name;
|
||||
const char* peer_cert_before_callback = c_arg->peer_cert;
|
||||
|
||||
arg->OnServerAuthorizationCheckDoneCallback();
|
||||
EXPECT_STREQ(static_cast<char*>(arg->cb_user_data()), "cb_user_data");
|
||||
gpr_free(arg->cb_user_data());
|
||||
EXPECT_EQ(arg->success(), 1);
|
||||
EXPECT_STREQ(arg->target_name().c_str(), "callback_target_name");
|
||||
EXPECT_STREQ(arg->peer_cert().c_str(), "callback_peer_cert");
|
||||
EXPECT_EQ(arg->status(), GRPC_STATUS_OK);
|
||||
EXPECT_STREQ(arg->error_details().c_str(), "callback_error_details");
|
||||
|
||||
// Cleanup.
|
||||
gpr_free(const_cast<char*>(target_name_before_callback));
|
||||
gpr_free(const_cast<char*>(peer_cert_before_callback));
|
||||
gpr_free(const_cast<char*>(c_arg->target_name));
|
||||
gpr_free(const_cast<char*>(c_arg->peer_cert));
|
||||
delete c_arg->error_details;
|
||||
delete arg;
|
||||
delete c_arg;
|
||||
}
|
||||
|
||||
TEST(CredentialsTest, TlsServerAuthorizationCheckConfigSchedule) {
|
||||
std::shared_ptr<TestTlsServerAuthorizationCheck>
|
||||
test_server_authorization_check(new TestTlsServerAuthorizationCheck());
|
||||
TlsServerAuthorizationCheckConfig config(test_server_authorization_check);
|
||||
grpc_tls_server_authorization_check_arg* c_arg =
|
||||
new grpc_tls_server_authorization_check_arg();
|
||||
c_arg->error_details = new grpc_tls_error_details();
|
||||
c_arg->context = nullptr;
|
||||
TlsServerAuthorizationCheckArg* arg =
|
||||
new TlsServerAuthorizationCheckArg(c_arg);
|
||||
arg->set_cb_user_data(nullptr);
|
||||
arg->set_success(0);
|
||||
arg->set_target_name("target_name");
|
||||
arg->set_peer_cert("peer_cert");
|
||||
arg->set_status(GRPC_STATUS_PERMISSION_DENIED);
|
||||
arg->set_error_details("error_details");
|
||||
const char* target_name_before_schedule = c_arg->target_name;
|
||||
const char* peer_cert_before_schedule = c_arg->peer_cert;
|
||||
|
||||
int schedule_output = config.Schedule(arg);
|
||||
EXPECT_EQ(schedule_output, 1);
|
||||
EXPECT_STREQ(static_cast<char*>(arg->cb_user_data()), "cb_user_data");
|
||||
EXPECT_EQ(arg->success(), 1);
|
||||
EXPECT_STREQ(arg->target_name().c_str(), "sync_target_name");
|
||||
EXPECT_STREQ(arg->peer_cert().c_str(), "sync_peer_cert");
|
||||
EXPECT_EQ(arg->status(), GRPC_STATUS_OK);
|
||||
EXPECT_STREQ(arg->error_details().c_str(), "sync_error_details");
|
||||
|
||||
// Cleanup.
|
||||
gpr_free(arg->cb_user_data());
|
||||
gpr_free(const_cast<char*>(target_name_before_schedule));
|
||||
gpr_free(const_cast<char*>(peer_cert_before_schedule));
|
||||
gpr_free(const_cast<char*>(c_arg->target_name));
|
||||
gpr_free(const_cast<char*>(c_arg->peer_cert));
|
||||
delete c_arg->error_details;
|
||||
if (c_arg->destroy_context != nullptr) {
|
||||
c_arg->destroy_context(c_arg->context);
|
||||
}
|
||||
delete c_arg;
|
||||
}
|
||||
|
||||
TEST(CredentialsTest, TlsServerAuthorizationCheckConfigCppToC) {
|
||||
std::shared_ptr<TestTlsServerAuthorizationCheck>
|
||||
test_server_authorization_check(new TestTlsServerAuthorizationCheck());
|
||||
TlsServerAuthorizationCheckConfig config(test_server_authorization_check);
|
||||
grpc_tls_server_authorization_check_arg c_arg;
|
||||
c_arg.cb = tls_server_authorization_check_callback;
|
||||
c_arg.cb_user_data = nullptr;
|
||||
c_arg.success = 0;
|
||||
c_arg.target_name = "target_name";
|
||||
c_arg.peer_cert = "peer_cert";
|
||||
c_arg.status = GRPC_STATUS_UNAUTHENTICATED;
|
||||
c_arg.error_details = new grpc_tls_error_details();
|
||||
c_arg.error_details->set_error_details("error_details");
|
||||
c_arg.config = config.c_config();
|
||||
c_arg.context = nullptr;
|
||||
int c_schedule_output = (c_arg.config)->Schedule(&c_arg);
|
||||
EXPECT_EQ(c_schedule_output, 1);
|
||||
EXPECT_STREQ(static_cast<char*>(c_arg.cb_user_data), "cb_user_data");
|
||||
EXPECT_EQ(c_arg.success, 1);
|
||||
EXPECT_STREQ(c_arg.target_name, "sync_target_name");
|
||||
EXPECT_STREQ(c_arg.peer_cert, "sync_peer_cert");
|
||||
EXPECT_EQ(c_arg.status, GRPC_STATUS_OK);
|
||||
EXPECT_STREQ(c_arg.error_details->error_details().c_str(),
|
||||
"sync_error_details");
|
||||
|
||||
// Cleanup.
|
||||
gpr_free(c_arg.cb_user_data);
|
||||
c_arg.destroy_context(c_arg.context);
|
||||
delete c_arg.error_details;
|
||||
gpr_free(const_cast<char*>(c_arg.target_name));
|
||||
gpr_free(const_cast<char*>(c_arg.peer_cert));
|
||||
}
|
||||
|
||||
TEST(CredentialsTest, TlsChannelCredentialsWithDefaultRoots) {
|
||||
TEST(CredentialsTest, TlsChannelCredentialsWithDefaultRootsAndDefaultVerifier) {
|
||||
grpc::experimental::TlsChannelCredentialsOptions options;
|
||||
options.set_server_verification_option(GRPC_TLS_SERVER_VERIFICATION);
|
||||
auto test_server_authorization_check =
|
||||
std::make_shared<TestTlsServerAuthorizationCheck>();
|
||||
auto server_authorization_check_config =
|
||||
std::make_shared<TlsServerAuthorizationCheckConfig>(
|
||||
test_server_authorization_check);
|
||||
options.set_server_authorization_check_config(
|
||||
server_authorization_check_config);
|
||||
options.set_verify_server_certs(true);
|
||||
auto channel_credentials = grpc::experimental::TlsCredentials(options);
|
||||
GPR_ASSERT(channel_credentials.get() != nullptr);
|
||||
}
|
||||
|
|
@ -431,20 +281,12 @@ TEST(
|
|||
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;
|
||||
options.set_certificate_provider(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);
|
||||
auto channel_credentials = grpc::experimental::TlsCredentials(options);
|
||||
GPR_ASSERT(channel_credentials.get() != nullptr);
|
||||
}
|
||||
|
|
@ -453,20 +295,12 @@ 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;
|
||||
options.set_certificate_provider(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);
|
||||
}
|
||||
|
|
@ -481,18 +315,10 @@ TEST(
|
|||
identity_key_cert_pairs.emplace_back(key_cert_pair);
|
||||
auto certificate_provider =
|
||||
std::make_shared<StaticDataCertificateProvider>(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;
|
||||
options.set_certificate_provider(certificate_provider);
|
||||
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);
|
||||
auto channel_credentials = grpc::experimental::TlsCredentials(options);
|
||||
GPR_ASSERT(channel_credentials.get() != nullptr);
|
||||
}
|
||||
|
|
@ -508,14 +334,6 @@ TEST(
|
|||
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);
|
||||
auto test_server_authorization_check =
|
||||
std::make_shared<TestTlsServerAuthorizationCheck>();
|
||||
auto server_authorization_check_config =
|
||||
std::make_shared<TlsServerAuthorizationCheckConfig>(
|
||||
test_server_authorization_check);
|
||||
options.set_server_authorization_check_config(
|
||||
server_authorization_check_config);
|
||||
auto channel_credentials = grpc::experimental::TlsCredentials(options);
|
||||
GPR_ASSERT(channel_credentials.get() != nullptr);
|
||||
}
|
||||
|
|
@ -528,48 +346,39 @@ TEST(CredentialsTest,
|
|||
options.set_certificate_provider(certificate_provider);
|
||||
options.watch_root_certs();
|
||||
options.set_root_cert_name(kRootCertName);
|
||||
options.set_server_verification_option(GRPC_TLS_SERVER_VERIFICATION);
|
||||
auto test_server_authorization_check =
|
||||
std::make_shared<TestTlsServerAuthorizationCheck>();
|
||||
auto server_authorization_check_config =
|
||||
std::make_shared<TlsServerAuthorizationCheckConfig>(
|
||||
test_server_authorization_check);
|
||||
options.set_server_authorization_check_config(
|
||||
server_authorization_check_config);
|
||||
auto channel_credentials = grpc::experimental::TlsCredentials(options);
|
||||
GPR_ASSERT(channel_credentials.get() != nullptr);
|
||||
}
|
||||
|
||||
TEST(CredentialsTest, TlsServerAuthorizationCheckConfigErrorMessages) {
|
||||
std::shared_ptr<TlsServerAuthorizationCheckConfig> config(
|
||||
new TlsServerAuthorizationCheckConfig(nullptr));
|
||||
grpc_tls_server_authorization_check_arg* c_arg =
|
||||
new grpc_tls_server_authorization_check_arg;
|
||||
c_arg->error_details = new grpc_tls_error_details();
|
||||
c_arg->context = nullptr;
|
||||
TlsServerAuthorizationCheckArg* arg =
|
||||
new TlsServerAuthorizationCheckArg(c_arg);
|
||||
int schedule_output = config->Schedule(arg);
|
||||
TEST(CredentialsTest, TlsChannelCredentialsWithHostNameVerifier) {
|
||||
auto verifier = std::make_shared<HostNameCertificateVerifier>();
|
||||
grpc::experimental::TlsChannelCredentialsOptions options;
|
||||
options.set_verify_server_certs(true);
|
||||
options.set_certificate_verifier(verifier);
|
||||
auto channel_credentials = grpc::experimental::TlsCredentials(options);
|
||||
GPR_ASSERT(channel_credentials.get() != nullptr);
|
||||
}
|
||||
|
||||
EXPECT_EQ(schedule_output, 1);
|
||||
EXPECT_EQ(arg->status(), GRPC_STATUS_NOT_FOUND);
|
||||
EXPECT_STREQ(
|
||||
arg->error_details().c_str(),
|
||||
"the interface of the server authorization check config is nullptr");
|
||||
TEST(CredentialsTest, TlsChannelCredentialsWithSyncExternalVerifier) {
|
||||
auto verifier =
|
||||
ExternalCertificateVerifier::Create<SyncCertificateVerifier>(true);
|
||||
grpc::experimental::TlsChannelCredentialsOptions options;
|
||||
options.set_verify_server_certs(true);
|
||||
options.set_certificate_verifier(verifier);
|
||||
options.set_check_call_host(false);
|
||||
auto channel_credentials = grpc::experimental::TlsCredentials(options);
|
||||
GPR_ASSERT(channel_credentials.get() != nullptr);
|
||||
}
|
||||
|
||||
arg->set_status(GRPC_STATUS_OK);
|
||||
config->Cancel(arg);
|
||||
EXPECT_EQ(arg->status(), GRPC_STATUS_NOT_FOUND);
|
||||
EXPECT_STREQ(
|
||||
arg->error_details().c_str(),
|
||||
"the interface of the server authorization check config is nullptr");
|
||||
|
||||
// Cleanup.
|
||||
delete c_arg->error_details;
|
||||
if (c_arg->destroy_context != nullptr) {
|
||||
c_arg->destroy_context(c_arg->context);
|
||||
}
|
||||
delete c_arg;
|
||||
TEST(CredentialsTest, TlsChannelCredentialsWithAsyncExternalVerifier) {
|
||||
auto verifier =
|
||||
ExternalCertificateVerifier::Create<AsyncCertificateVerifier>(true);
|
||||
grpc::experimental::TlsChannelCredentialsOptions options;
|
||||
options.set_verify_server_certs(true);
|
||||
options.set_certificate_verifier(verifier);
|
||||
options.set_check_call_host(false);
|
||||
auto channel_credentials = grpc::experimental::TlsCredentials(options);
|
||||
GPR_ASSERT(channel_credentials.get() != nullptr);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ grpc_cc_test(
|
|||
"//test/cpp/end2end:test_service_impl",
|
||||
"//test/cpp/util:test_config",
|
||||
"//test/cpp/util:test_util",
|
||||
"//test/cpp/util:tls_test_utils",
|
||||
],
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@
|
|||
#include "test/cpp/end2end/test_service_impl.h"
|
||||
#include "test/cpp/end2end/xds/xds_server.h"
|
||||
#include "test/cpp/util/test_config.h"
|
||||
#include "test/cpp/util/tls_test_utils.h"
|
||||
|
||||
#ifndef DISABLED_XDS_PROTO_IN_CC
|
||||
#include "src/cpp/server/csds/csds.h"
|
||||
|
|
@ -139,6 +140,9 @@ using ::envoy::type::matcher::v3::StringMatcher;
|
|||
using ::envoy::type::v3::FractionalPercent;
|
||||
|
||||
using ClientStats = LrsServiceImpl::ClientStats;
|
||||
using ::grpc::experimental::ExternalCertificateVerifier;
|
||||
using ::grpc::experimental::IdentityKeyCertPair;
|
||||
using ::grpc::experimental::StaticDataCertificateProvider;
|
||||
|
||||
constexpr char kDefaultLocalityRegion[] = "xds_default_locality_region";
|
||||
constexpr char kDefaultLocalityZone[] = "xds_default_locality_zone";
|
||||
|
|
@ -538,34 +542,25 @@ class FakeCertificateProviderFactory
|
|||
FakeCertificateProvider::CertDataMap* g_fake1_cert_data_map = nullptr;
|
||||
FakeCertificateProvider::CertDataMap* g_fake2_cert_data_map = nullptr;
|
||||
|
||||
int ServerAuthCheckSchedule(void* /* config_user_data */,
|
||||
grpc_tls_server_authorization_check_arg* arg) {
|
||||
arg->success = 1;
|
||||
arg->status = GRPC_STATUS_OK;
|
||||
return 0; /* synchronous check */
|
||||
}
|
||||
|
||||
std::shared_ptr<ChannelCredentials> CreateTlsFallbackCredentials() {
|
||||
// TODO(yashykt): Switch to using C++ API once b/173823806 is fixed.
|
||||
grpc_tls_credentials_options* options = grpc_tls_credentials_options_create();
|
||||
grpc_tls_credentials_options_set_server_verification_option(
|
||||
options, GRPC_TLS_SKIP_HOSTNAME_VERIFICATION);
|
||||
grpc_tls_credentials_options_set_certificate_provider(
|
||||
options,
|
||||
grpc_core::MakeRefCounted<grpc_core::StaticDataCertificateProvider>(
|
||||
ReadFile(kCaCertPath),
|
||||
ReadTlsIdentityPair(kServerKeyPath, kServerCertPath))
|
||||
.get());
|
||||
grpc_tls_credentials_options_watch_root_certs(options);
|
||||
grpc_tls_credentials_options_watch_identity_key_cert_pairs(options);
|
||||
grpc_tls_server_authorization_check_config* check_config =
|
||||
grpc_tls_server_authorization_check_config_create(
|
||||
nullptr, ServerAuthCheckSchedule, nullptr, nullptr);
|
||||
grpc_tls_credentials_options_set_server_authorization_check_config(
|
||||
options, check_config);
|
||||
auto channel_creds = std::make_shared<SecureChannelCredentials>(
|
||||
grpc_tls_credentials_create(options));
|
||||
grpc_tls_server_authorization_check_config_release(check_config);
|
||||
IdentityKeyCertPair key_cert_pair;
|
||||
key_cert_pair.private_key = ReadFile(kServerKeyPath);
|
||||
key_cert_pair.certificate_chain = ReadFile(kServerCertPath);
|
||||
std::vector<IdentityKeyCertPair> identity_key_cert_pairs;
|
||||
identity_key_cert_pairs.emplace_back(key_cert_pair);
|
||||
auto certificate_provider = std::make_shared<StaticDataCertificateProvider>(
|
||||
ReadFile(kCaCertPath), identity_key_cert_pairs);
|
||||
grpc::experimental::TlsChannelCredentialsOptions options;
|
||||
options.set_certificate_provider(std::move(certificate_provider));
|
||||
options.watch_root_certs();
|
||||
options.watch_identity_key_cert_pairs();
|
||||
auto verifier =
|
||||
ExternalCertificateVerifier::Create<SyncCertificateVerifier>(true);
|
||||
options.set_certificate_verifier(std::move(verifier));
|
||||
options.set_verify_server_certs(true);
|
||||
options.set_check_call_host(false);
|
||||
auto channel_creds = grpc::experimental::TlsCredentials(options);
|
||||
GPR_ASSERT(channel_creds.get() != nullptr);
|
||||
return channel_creds;
|
||||
}
|
||||
|
||||
|
|
@ -8502,27 +8497,23 @@ class XdsServerSecurityTest : public XdsEnd2endTest {
|
|||
args.SetInt(GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL, 1);
|
||||
std::string uri = absl::StrCat(
|
||||
ipv6_only_ ? "ipv6:[::1]:" : "ipv4:127.0.0.1:", backends_[0]->port());
|
||||
// TODO(yashykt): Switch to using C++ API once b/173823806 is fixed.
|
||||
grpc_tls_credentials_options* options =
|
||||
grpc_tls_credentials_options_create();
|
||||
grpc_tls_credentials_options_set_server_verification_option(
|
||||
options, GRPC_TLS_SKIP_HOSTNAME_VERIFICATION);
|
||||
grpc_tls_credentials_options_set_certificate_provider(
|
||||
options,
|
||||
grpc_core::MakeRefCounted<grpc_core::StaticDataCertificateProvider>(
|
||||
ReadFile(kCaCertPath),
|
||||
ReadTlsIdentityPair(kServerKeyPath, kServerCertPath))
|
||||
.get());
|
||||
grpc_tls_credentials_options_watch_root_certs(options);
|
||||
grpc_tls_credentials_options_watch_identity_key_cert_pairs(options);
|
||||
grpc_tls_server_authorization_check_config* check_config =
|
||||
grpc_tls_server_authorization_check_config_create(
|
||||
nullptr, ServerAuthCheckSchedule, nullptr, nullptr);
|
||||
grpc_tls_credentials_options_set_server_authorization_check_config(
|
||||
options, check_config);
|
||||
auto channel_creds = std::make_shared<SecureChannelCredentials>(
|
||||
grpc_tls_credentials_create(options));
|
||||
grpc_tls_server_authorization_check_config_release(check_config);
|
||||
IdentityKeyCertPair key_cert_pair;
|
||||
key_cert_pair.private_key = ReadFile(kServerKeyPath);
|
||||
key_cert_pair.certificate_chain = ReadFile(kServerCertPath);
|
||||
std::vector<IdentityKeyCertPair> identity_key_cert_pairs;
|
||||
identity_key_cert_pairs.emplace_back(key_cert_pair);
|
||||
auto certificate_provider = std::make_shared<StaticDataCertificateProvider>(
|
||||
ReadFile(kCaCertPath), identity_key_cert_pairs);
|
||||
grpc::experimental::TlsChannelCredentialsOptions options;
|
||||
options.set_certificate_provider(std::move(certificate_provider));
|
||||
options.watch_root_certs();
|
||||
options.watch_identity_key_cert_pairs();
|
||||
auto verifier =
|
||||
ExternalCertificateVerifier::Create<SyncCertificateVerifier>(true);
|
||||
options.set_verify_server_certs(true);
|
||||
options.set_certificate_verifier(std::move(verifier));
|
||||
auto channel_creds = grpc::experimental::TlsCredentials(options);
|
||||
GPR_ASSERT(channel_creds.get() != nullptr);
|
||||
return CreateCustomChannel(uri, channel_creds, args);
|
||||
}
|
||||
|
||||
|
|
@ -8534,26 +8525,17 @@ class XdsServerSecurityTest : public XdsEnd2endTest {
|
|||
args.SetInt(GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL, 1);
|
||||
std::string uri = absl::StrCat(
|
||||
ipv6_only_ ? "ipv6:[::1]:" : "ipv4:127.0.0.1:", backends_[0]->port());
|
||||
// TODO(yashykt): Switch to using C++ API once b/173823806 is fixed.
|
||||
grpc_tls_credentials_options* options =
|
||||
grpc_tls_credentials_options_create();
|
||||
grpc_tls_credentials_options_set_server_verification_option(
|
||||
options, GRPC_TLS_SKIP_HOSTNAME_VERIFICATION);
|
||||
grpc_tls_credentials_options_set_certificate_provider(
|
||||
options,
|
||||
grpc_core::MakeRefCounted<grpc_core::StaticDataCertificateProvider>(
|
||||
ReadFile(kCaCertPath),
|
||||
ReadTlsIdentityPair(kServerKeyPath, kServerCertPath))
|
||||
.get());
|
||||
grpc_tls_credentials_options_watch_root_certs(options);
|
||||
grpc_tls_server_authorization_check_config* check_config =
|
||||
grpc_tls_server_authorization_check_config_create(
|
||||
nullptr, ServerAuthCheckSchedule, nullptr, nullptr);
|
||||
grpc_tls_credentials_options_set_server_authorization_check_config(
|
||||
options, check_config);
|
||||
auto channel_creds = std::make_shared<SecureChannelCredentials>(
|
||||
grpc_tls_credentials_create(options));
|
||||
grpc_tls_server_authorization_check_config_release(check_config);
|
||||
auto certificate_provider =
|
||||
std::make_shared<StaticDataCertificateProvider>(ReadFile(kCaCertPath));
|
||||
grpc::experimental::TlsChannelCredentialsOptions options;
|
||||
options.set_certificate_provider(std::move(certificate_provider));
|
||||
options.watch_root_certs();
|
||||
auto verifier =
|
||||
ExternalCertificateVerifier::Create<SyncCertificateVerifier>(true);
|
||||
options.set_verify_server_certs(true);
|
||||
options.set_certificate_verifier(std::move(verifier));
|
||||
auto channel_creds = grpc::experimental::TlsCredentials(options);
|
||||
GPR_ASSERT(channel_creds.get() != nullptr);
|
||||
return CreateCustomChannel(uri, channel_creds, args);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
# Copyright 2021 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.
|
||||
|
||||
load("//bazel:grpc_build_system.bzl", "grpc_cc_test", "grpc_package")
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
grpc_package(name = "test/cpp/security")
|
||||
|
||||
grpc_cc_test(
|
||||
name = "tls_certificate_verifier_test",
|
||||
srcs = ["tls_certificate_verifier_test.cc"],
|
||||
external_deps = [
|
||||
"gtest",
|
||||
],
|
||||
deps = [
|
||||
"//:gpr",
|
||||
"//:grpc",
|
||||
"//:grpc++",
|
||||
"//test/core/util:grpc_test_util",
|
||||
"//test/cpp/util:tls_test_utils",
|
||||
],
|
||||
)
|
||||
|
|
@ -0,0 +1,161 @@
|
|||
//
|
||||
// Copyright 2021 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 <memory>
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/grpc_security.h>
|
||||
#include <grpcpp/security/server_credentials.h>
|
||||
#include <grpcpp/security/tls_credentials_options.h>
|
||||
|
||||
#include "src/cpp/client/secure_credentials.h"
|
||||
#include "test/core/util/port.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
#include "test/cpp/util/tls_test_utils.h"
|
||||
|
||||
namespace {
|
||||
|
||||
using ::grpc::experimental::ExternalCertificateVerifier;
|
||||
using ::grpc::experimental::HostNameCertificateVerifier;
|
||||
using ::grpc::experimental::TlsCustomVerificationCheckRequest;
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace grpc {
|
||||
namespace testing {
|
||||
namespace {
|
||||
|
||||
TEST(TlsCertificateVerifierTest, SyncCertificateVerifierSucceeds) {
|
||||
grpc_tls_custom_verification_check_request request;
|
||||
auto verifier =
|
||||
ExternalCertificateVerifier::Create<SyncCertificateVerifier>(true);
|
||||
TlsCustomVerificationCheckRequest cpp_request(&request);
|
||||
grpc::Status sync_status;
|
||||
verifier->Verify(&cpp_request, nullptr, &sync_status);
|
||||
EXPECT_TRUE(sync_status.ok())
|
||||
<< sync_status.error_code() << " " << sync_status.error_message();
|
||||
}
|
||||
|
||||
TEST(TlsCertificateVerifierTest, SyncCertificateVerifierFails) {
|
||||
grpc_tls_custom_verification_check_request request;
|
||||
auto verifier =
|
||||
ExternalCertificateVerifier::Create<SyncCertificateVerifier>(false);
|
||||
TlsCustomVerificationCheckRequest cpp_request(&request);
|
||||
grpc::Status sync_status;
|
||||
verifier->Verify(&cpp_request, nullptr, &sync_status);
|
||||
EXPECT_EQ(sync_status.error_code(), grpc::StatusCode::UNAUTHENTICATED);
|
||||
EXPECT_EQ(sync_status.error_message(), "SyncCertificateVerifier failed");
|
||||
}
|
||||
|
||||
TEST(TlsCertificateVerifierTest, AsyncCertificateVerifierSucceeds) {
|
||||
grpc_tls_custom_verification_check_request request;
|
||||
auto verifier =
|
||||
ExternalCertificateVerifier::Create<AsyncCertificateVerifier>(true);
|
||||
TlsCustomVerificationCheckRequest cpp_request(&request);
|
||||
std::function<void(grpc::Status)> callback = [](grpc::Status async_status) {
|
||||
EXPECT_TRUE(async_status.ok())
|
||||
<< async_status.error_code() << " " << async_status.error_message();
|
||||
};
|
||||
grpc::Status sync_status;
|
||||
EXPECT_FALSE(verifier->Verify(&cpp_request, callback, &sync_status));
|
||||
}
|
||||
|
||||
TEST(TlsCertificateVerifierTest, AsyncCertificateVerifierFails) {
|
||||
grpc_tls_custom_verification_check_request request;
|
||||
auto verifier =
|
||||
ExternalCertificateVerifier::Create<AsyncCertificateVerifier>(false);
|
||||
TlsCustomVerificationCheckRequest cpp_request(&request);
|
||||
std::function<void(grpc::Status)> callback = [](grpc::Status async_status) {
|
||||
EXPECT_EQ(async_status.error_code(), grpc::StatusCode::UNAUTHENTICATED);
|
||||
EXPECT_EQ(async_status.error_message(), "AsyncCertificateVerifier failed");
|
||||
};
|
||||
grpc::Status sync_status;
|
||||
EXPECT_FALSE(verifier->Verify(&cpp_request, callback, &sync_status));
|
||||
}
|
||||
|
||||
TEST(TlsCertificateVerifierTest, HostNameCertificateVerifierSucceeds) {
|
||||
grpc_tls_custom_verification_check_request request;
|
||||
memset(&request, 0, sizeof(request));
|
||||
request.target_name = "foo.bar.com";
|
||||
request.peer_info.common_name = "foo.bar.com";
|
||||
auto verifier = std::make_shared<HostNameCertificateVerifier>();
|
||||
TlsCustomVerificationCheckRequest cpp_request(&request);
|
||||
grpc::Status sync_status;
|
||||
verifier->Verify(&cpp_request, nullptr, &sync_status);
|
||||
EXPECT_TRUE(sync_status.ok())
|
||||
<< sync_status.error_code() << " " << sync_status.error_message();
|
||||
}
|
||||
|
||||
TEST(TlsCertificateVerifierTest, HostNameCertificateVerifierFails) {
|
||||
grpc_tls_custom_verification_check_request request;
|
||||
memset(&request, 0, sizeof(request));
|
||||
request.target_name = "foo.bar.com";
|
||||
request.peer_info.common_name = "foo.baz.com";
|
||||
auto verifier = std::make_shared<HostNameCertificateVerifier>();
|
||||
TlsCustomVerificationCheckRequest cpp_request(&request);
|
||||
grpc::Status sync_status;
|
||||
verifier->Verify(&cpp_request, nullptr, &sync_status);
|
||||
EXPECT_EQ(sync_status.error_code(), grpc::StatusCode::UNAUTHENTICATED);
|
||||
EXPECT_EQ(sync_status.error_message(), "Hostname Verification Check failed.");
|
||||
}
|
||||
|
||||
TEST(TlsCertificateVerifierTest,
|
||||
HostNameCertificateVerifierSucceedsMultipleFields) {
|
||||
grpc_tls_custom_verification_check_request request;
|
||||
memset(&request, 0, sizeof(request));
|
||||
request.target_name = "foo.bar.com";
|
||||
request.peer_info.common_name = "foo.baz.com";
|
||||
char* dns_names[] = {const_cast<char*>("*.bar.com")};
|
||||
request.peer_info.san_names.dns_names = dns_names;
|
||||
request.peer_info.san_names.dns_names_size = 1;
|
||||
auto verifier = std::make_shared<HostNameCertificateVerifier>();
|
||||
TlsCustomVerificationCheckRequest cpp_request(&request);
|
||||
grpc::Status sync_status;
|
||||
verifier->Verify(&cpp_request, nullptr, &sync_status);
|
||||
EXPECT_TRUE(sync_status.ok())
|
||||
<< sync_status.error_code() << " " << sync_status.error_message();
|
||||
}
|
||||
|
||||
TEST(TlsCertificateVerifierTest,
|
||||
HostNameCertificateVerifierFailsMultipleFields) {
|
||||
grpc_tls_custom_verification_check_request request;
|
||||
memset(&request, 0, sizeof(request));
|
||||
request.target_name = "foo.bar.com";
|
||||
request.peer_info.common_name = "foo.baz.com";
|
||||
char* dns_names[] = {const_cast<char*>("*.")};
|
||||
request.peer_info.san_names.dns_names = dns_names;
|
||||
request.peer_info.san_names.dns_names_size = 1;
|
||||
auto verifier = std::make_shared<HostNameCertificateVerifier>();
|
||||
TlsCustomVerificationCheckRequest cpp_request(&request);
|
||||
grpc::Status sync_status;
|
||||
verifier->Verify(&cpp_request, nullptr, &sync_status);
|
||||
EXPECT_EQ(sync_status.error_code(), grpc::StatusCode::UNAUTHENTICATED);
|
||||
EXPECT_EQ(sync_status.error_message(), "Hostname Verification Check failed.");
|
||||
}
|
||||
|
||||
} // 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;
|
||||
}
|
||||
|
|
@ -76,6 +76,7 @@ grpc_cc_test(
|
|||
"//:grpc",
|
||||
"//:grpc++",
|
||||
"//test/core/util:grpc_test_util",
|
||||
"//test/cpp/util:tls_test_utils",
|
||||
],
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include "src/cpp/client/secure_credentials.h"
|
||||
#include "test/core/util/port.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
#include "test/cpp/util/tls_test_utils.h"
|
||||
|
||||
#define CA_CERT_PATH "src/core/tsi/test_creds/ca.pem"
|
||||
#define SERVER_CERT_PATH "src/core/tsi/test_creds/server1.pem"
|
||||
|
|
@ -40,6 +41,7 @@ constexpr const char* kIdentityCertName = "identity_cert_name";
|
|||
constexpr const char* kIdentityCertPrivateKey = "identity_private_key";
|
||||
constexpr const char* kIdentityCertContents = "identity_cert_contents";
|
||||
|
||||
using ::grpc::experimental::ExternalCertificateVerifier;
|
||||
using ::grpc::experimental::FileWatcherCertificateProvider;
|
||||
using ::grpc::experimental::StaticDataCertificateProvider;
|
||||
|
||||
|
|
@ -124,6 +126,40 @@ TEST(
|
|||
GPR_ASSERT(server_credentials.get() != nullptr);
|
||||
}
|
||||
|
||||
TEST(CredentialsTest, TlsServerCredentialsWithSyncExternalVerifier) {
|
||||
auto verifier =
|
||||
ExternalCertificateVerifier::Create<SyncCertificateVerifier>(true);
|
||||
auto certificate_provider = std::make_shared<FileWatcherCertificateProvider>(
|
||||
SERVER_KEY_PATH, SERVER_CERT_PATH, CA_CERT_PATH, 1);
|
||||
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);
|
||||
options.set_certificate_verifier(verifier);
|
||||
auto server_credentials = grpc::experimental::TlsServerCredentials(options);
|
||||
GPR_ASSERT(server_credentials.get() != nullptr);
|
||||
}
|
||||
|
||||
TEST(CredentialsTest, TlsServerCredentialsWithAsyncExternalVerifier) {
|
||||
auto verifier =
|
||||
ExternalCertificateVerifier::Create<AsyncCertificateVerifier>(true);
|
||||
auto certificate_provider = std::make_shared<FileWatcherCertificateProvider>(
|
||||
SERVER_KEY_PATH, SERVER_CERT_PATH, CA_CERT_PATH, 1);
|
||||
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);
|
||||
options.set_certificate_verifier(verifier);
|
||||
auto server_credentials = grpc::experimental::TlsServerCredentials(options);
|
||||
GPR_ASSERT(server_credentials.get() != nullptr);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace testing
|
||||
} // namespace grpc
|
||||
|
|
|
|||
|
|
@ -364,3 +364,19 @@ grpc_cc_test(
|
|||
"//test/cpp/util:test_util",
|
||||
],
|
||||
)
|
||||
|
||||
grpc_cc_library(
|
||||
name = "tls_test_utils",
|
||||
srcs = [
|
||||
"tls_test_utils.cc",
|
||||
],
|
||||
hdrs = [
|
||||
"tls_test_utils.h",
|
||||
],
|
||||
deps = [
|
||||
"//:gpr",
|
||||
"//:grpc",
|
||||
"//:grpc++",
|
||||
"//test/core/util:grpc_test_util",
|
||||
],
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,99 @@
|
|||
//
|
||||
// Copyright 2021 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 "test/cpp/util/tls_test_utils.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "src/core/lib/gprpp/thd.h"
|
||||
#include "test/core/util/port.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
using ::grpc::experimental::ExternalCertificateVerifier;
|
||||
using ::grpc::experimental::TlsCustomVerificationCheckRequest;
|
||||
|
||||
namespace grpc {
|
||||
namespace testing {
|
||||
|
||||
bool SyncCertificateVerifier::Verify(TlsCustomVerificationCheckRequest*,
|
||||
std::function<void(grpc::Status)>,
|
||||
grpc::Status* sync_status) {
|
||||
if (!success_) {
|
||||
*sync_status = grpc::Status(grpc::StatusCode::UNAUTHENTICATED,
|
||||
"SyncCertificateVerifier failed");
|
||||
} else {
|
||||
*sync_status = grpc::Status(grpc::StatusCode::OK, "");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
AsyncCertificateVerifier::AsyncCertificateVerifier(bool success)
|
||||
: success_(success),
|
||||
thread_("AsyncCertificateVerifierWorkerThread", WorkerThread, this) {
|
||||
thread_.Start();
|
||||
}
|
||||
|
||||
AsyncCertificateVerifier::~AsyncCertificateVerifier() {
|
||||
// Tell the thread to shut down.
|
||||
{
|
||||
internal::MutexLock lock(&mu_);
|
||||
queue_.push_back(Request{nullptr, nullptr, true});
|
||||
}
|
||||
// Wait for thread to exit.
|
||||
thread_.Join();
|
||||
}
|
||||
|
||||
bool AsyncCertificateVerifier::Verify(
|
||||
TlsCustomVerificationCheckRequest* request,
|
||||
std::function<void(grpc::Status)> callback, grpc::Status*) {
|
||||
internal::MutexLock lock(&mu_);
|
||||
queue_.push_back(Request{request, std::move(callback), false});
|
||||
return false; // Asynchronous call
|
||||
}
|
||||
|
||||
void AsyncCertificateVerifier::WorkerThread(void* arg) {
|
||||
auto* self = static_cast<AsyncCertificateVerifier*>(arg);
|
||||
while (true) {
|
||||
// Check queue for work.
|
||||
bool got_request = false;
|
||||
Request request;
|
||||
{
|
||||
internal::MutexLock lock(&self->mu_);
|
||||
if (!self->queue_.empty()) {
|
||||
got_request = true;
|
||||
request = self->queue_.front();
|
||||
self->queue_.pop_front();
|
||||
}
|
||||
}
|
||||
// If nothing found in the queue, sleep for a bit and try again.
|
||||
if (!got_request) {
|
||||
gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(100));
|
||||
continue;
|
||||
}
|
||||
// If we're being told to shut down, return.
|
||||
if (request.shutdown) return;
|
||||
auto return_status = grpc::Status(grpc::StatusCode::OK, "");
|
||||
// Process the request.
|
||||
if (!self->success_) {
|
||||
return_status = grpc::Status(grpc::StatusCode::UNAUTHENTICATED,
|
||||
"AsyncCertificateVerifier failed");
|
||||
}
|
||||
request.callback(return_status);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
} // namespace grpc
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
//
|
||||
// Copyright 2021 gRPC authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
#ifndef GRPC_TEST_CPP_UTIL_TLS_TEST_UTILS_H
|
||||
#define GRPC_TEST_CPP_UTIL_TLS_TEST_UTILS_H
|
||||
|
||||
#include <deque>
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/grpc_security.h>
|
||||
#include <grpcpp/security/server_credentials.h>
|
||||
|
||||
#include "src/core/lib/gprpp/thd.h"
|
||||
|
||||
namespace grpc {
|
||||
namespace testing {
|
||||
|
||||
class SyncCertificateVerifier
|
||||
: public ::grpc::experimental::ExternalCertificateVerifier {
|
||||
public:
|
||||
explicit SyncCertificateVerifier(bool success) : success_(success) {}
|
||||
|
||||
~SyncCertificateVerifier() override {}
|
||||
|
||||
bool Verify(::grpc::experimental::TlsCustomVerificationCheckRequest* request,
|
||||
std::function<void(grpc::Status)> callback,
|
||||
grpc::Status* sync_status) override;
|
||||
|
||||
void Cancel(
|
||||
::grpc::experimental::TlsCustomVerificationCheckRequest*) override {}
|
||||
|
||||
private:
|
||||
bool success_ = false;
|
||||
};
|
||||
|
||||
class AsyncCertificateVerifier
|
||||
: public ::grpc::experimental::ExternalCertificateVerifier {
|
||||
public:
|
||||
explicit AsyncCertificateVerifier(bool success);
|
||||
|
||||
~AsyncCertificateVerifier() override;
|
||||
|
||||
bool Verify(::grpc::experimental::TlsCustomVerificationCheckRequest* request,
|
||||
std::function<void(grpc::Status)> callback,
|
||||
grpc::Status* sync_status) override;
|
||||
|
||||
void Cancel(
|
||||
::grpc::experimental::TlsCustomVerificationCheckRequest*) override {}
|
||||
|
||||
private:
|
||||
// A request to pass to the worker thread.
|
||||
struct Request {
|
||||
::grpc::experimental::TlsCustomVerificationCheckRequest* request;
|
||||
std::function<void(grpc::Status)> callback;
|
||||
bool shutdown; // If true, thread will exit.
|
||||
};
|
||||
|
||||
static void WorkerThread(void* arg);
|
||||
|
||||
bool success_ = false;
|
||||
grpc_core::Thread thread_;
|
||||
grpc::internal::Mutex mu_;
|
||||
std::deque<Request> queue_ ABSL_GUARDED_BY(mu_);
|
||||
};
|
||||
|
||||
} // namespace testing
|
||||
} // namespace grpc
|
||||
|
||||
#endif // GRPC_TEST_CPP_UTIL_TLS_TEST_UTILS_H
|
||||
|
|
@ -1021,6 +1021,7 @@ include/grpcpp/security/binder_security_policy.h \
|
|||
include/grpcpp/security/credentials.h \
|
||||
include/grpcpp/security/server_credentials.h \
|
||||
include/grpcpp/security/tls_certificate_provider.h \
|
||||
include/grpcpp/security/tls_certificate_verifier.h \
|
||||
include/grpcpp/security/tls_credentials_options.h \
|
||||
include/grpcpp/server.h \
|
||||
include/grpcpp/server_builder.h \
|
||||
|
|
|
|||
|
|
@ -1021,6 +1021,7 @@ include/grpcpp/security/binder_security_policy.h \
|
|||
include/grpcpp/security/credentials.h \
|
||||
include/grpcpp/security/server_credentials.h \
|
||||
include/grpcpp/security/tls_certificate_provider.h \
|
||||
include/grpcpp/security/tls_certificate_verifier.h \
|
||||
include/grpcpp/security/tls_credentials_options.h \
|
||||
include/grpcpp/server.h \
|
||||
include/grpcpp/server_builder.h \
|
||||
|
|
@ -2098,6 +2099,8 @@ 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_certificate_verifier.cc \
|
||||
src/core/lib/security/credentials/tls/grpc_tls_certificate_verifier.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 \
|
||||
|
|
@ -2307,9 +2310,8 @@ 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_certificate_verifier.cc \
|
||||
src/cpp/common/tls_credentials_options.cc \
|
||||
src/cpp/common/tls_credentials_options_util.cc \
|
||||
src/cpp/common/tls_credentials_options_util.h \
|
||||
src/cpp/common/validate_service_config.cc \
|
||||
src/cpp/common/version_cc.cc \
|
||||
src/cpp/server/async_generic_service.cc \
|
||||
|
|
|
|||
|
|
@ -1898,6 +1898,8 @@ 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_certificate_verifier.cc \
|
||||
src/core/lib/security/credentials/tls/grpc_tls_certificate_verifier.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 \
|
||||
|
|
|
|||
|
|
@ -4743,6 +4743,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": "grpc_tls_certificate_verifier_test",
|
||||
"platforms": [
|
||||
"linux",
|
||||
"mac",
|
||||
"posix",
|
||||
"windows"
|
||||
],
|
||||
"uses_polling": true
|
||||
},
|
||||
{
|
||||
"args": [],
|
||||
"benchmark": false,
|
||||
|
|
@ -7075,6 +7099,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": "tls_certificate_verifier_test",
|
||||
"platforms": [
|
||||
"linux",
|
||||
"mac",
|
||||
"posix",
|
||||
"windows"
|
||||
],
|
||||
"uses_polling": true
|
||||
},
|
||||
{
|
||||
"args": [],
|
||||
"benchmark": false,
|
||||
|
|
|
|||
Loading…
Reference in New Issue