diff --git a/BUILD b/BUILD index 47b30c5c2d8..ef0ce65bb24 100644 --- a/BUILD +++ b/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", diff --git a/BUILD.gn b/BUILD.gn new file mode 100644 index 00000000000..1538101dcbb --- /dev/null +++ b/BUILD.gn @@ -0,0 +1,1656 @@ +# GRPC Fuchsia GN build file + +# This file has been automatically generated from a template file. +# Please look at the templates directory instead. +# This file can be regenerated from the template by running +# tools/buildgen/generate_projects.sh + +# 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. + +config("grpc_config") { + include_dirs = [ + ".", + "include/", + ] + defines = [ + "GRPC_USE_PROTO_LITE", + "GPR_SUPPORT_CHANNELS_FROM_FD", + "PB_FIELD_16BIT", + ] +} + + + + source_set("address_sorting") { + sources = [ + "third_party/address_sorting/address_sorting.c", + "third_party/address_sorting/address_sorting_internal.h", + "third_party/address_sorting/address_sorting_posix.c", + "third_party/address_sorting/address_sorting_windows.c", + "third_party/address_sorting/include/address_sorting/address_sorting.h", + ] + deps = [ + ] + + public_configs = [ + ":grpc_config", + ] + include_dirs = [ + "third_party/address_sorting/include", + ] + } + + + + source_set("gpr") { + sources = [ + "include/grpc/impl/codegen/atm.h", + "include/grpc/impl/codegen/atm_gcc_atomic.h", + "include/grpc/impl/codegen/atm_gcc_sync.h", + "include/grpc/impl/codegen/atm_windows.h", + "include/grpc/impl/codegen/byte_buffer.h", + "include/grpc/impl/codegen/byte_buffer_reader.h", + "include/grpc/impl/codegen/compression_types.h", + "include/grpc/impl/codegen/connectivity_state.h", + "include/grpc/impl/codegen/fork.h", + "include/grpc/impl/codegen/gpr_slice.h", + "include/grpc/impl/codegen/gpr_types.h", + "include/grpc/impl/codegen/grpc_types.h", + "include/grpc/impl/codegen/log.h", + "include/grpc/impl/codegen/port_platform.h", + "include/grpc/impl/codegen/propagation_bits.h", + "include/grpc/impl/codegen/slice.h", + "include/grpc/impl/codegen/status.h", + "include/grpc/impl/codegen/sync.h", + "include/grpc/impl/codegen/sync_abseil.h", + "include/grpc/impl/codegen/sync_custom.h", + "include/grpc/impl/codegen/sync_generic.h", + "include/grpc/impl/codegen/sync_posix.h", + "include/grpc/impl/codegen/sync_windows.h", + "include/grpc/support/alloc.h", + "include/grpc/support/atm.h", + "include/grpc/support/atm_gcc_atomic.h", + "include/grpc/support/atm_gcc_sync.h", + "include/grpc/support/atm_windows.h", + "include/grpc/support/cpu.h", + "include/grpc/support/log.h", + "include/grpc/support/log_windows.h", + "include/grpc/support/port_platform.h", + "include/grpc/support/string_util.h", + "include/grpc/support/sync.h", + "include/grpc/support/sync_abseil.h", + "include/grpc/support/sync_custom.h", + "include/grpc/support/sync_generic.h", + "include/grpc/support/sync_posix.h", + "include/grpc/support/sync_windows.h", + "include/grpc/support/thd_id.h", + "include/grpc/support/time.h", + "src/core/ext/upb-generated/google/api/annotations.upb.c", + "src/core/ext/upb-generated/google/api/annotations.upb.h", + "src/core/ext/upb-generated/google/api/expr/v1alpha1/checked.upb.c", + "src/core/ext/upb-generated/google/api/expr/v1alpha1/checked.upb.h", + "src/core/ext/upb-generated/google/api/expr/v1alpha1/syntax.upb.c", + "src/core/ext/upb-generated/google/api/expr/v1alpha1/syntax.upb.h", + "src/core/ext/upb-generated/google/api/http.upb.c", + "src/core/ext/upb-generated/google/api/http.upb.h", + "src/core/ext/upb-generated/google/protobuf/any.upb.c", + "src/core/ext/upb-generated/google/protobuf/any.upb.h", + "src/core/ext/upb-generated/google/protobuf/duration.upb.c", + "src/core/ext/upb-generated/google/protobuf/duration.upb.h", + "src/core/ext/upb-generated/google/protobuf/empty.upb.c", + "src/core/ext/upb-generated/google/protobuf/empty.upb.h", + "src/core/ext/upb-generated/google/protobuf/struct.upb.c", + "src/core/ext/upb-generated/google/protobuf/struct.upb.h", + "src/core/ext/upb-generated/google/protobuf/timestamp.upb.c", + "src/core/ext/upb-generated/google/protobuf/timestamp.upb.h", + "src/core/ext/upb-generated/google/protobuf/wrappers.upb.c", + "src/core/ext/upb-generated/google/protobuf/wrappers.upb.h", + "src/core/ext/upb-generated/google/rpc/status.upb.c", + "src/core/ext/upb-generated/google/rpc/status.upb.h", + "src/core/lib/gpr/alloc.cc", + "src/core/lib/gpr/alloc.h", + "src/core/lib/gpr/arena.h", + "src/core/lib/gpr/atm.cc", + "src/core/lib/gpr/cpu_iphone.cc", + "src/core/lib/gpr/cpu_linux.cc", + "src/core/lib/gpr/cpu_posix.cc", + "src/core/lib/gpr/cpu_windows.cc", + "src/core/lib/gpr/env.h", + "src/core/lib/gpr/env_linux.cc", + "src/core/lib/gpr/env_posix.cc", + "src/core/lib/gpr/env_windows.cc", + "src/core/lib/gpr/log.cc", + "src/core/lib/gpr/log_android.cc", + "src/core/lib/gpr/log_linux.cc", + "src/core/lib/gpr/log_posix.cc", + "src/core/lib/gpr/log_windows.cc", + "src/core/lib/gpr/murmur_hash.cc", + "src/core/lib/gpr/murmur_hash.h", + "src/core/lib/gpr/spinlock.h", + "src/core/lib/gpr/string.cc", + "src/core/lib/gpr/string.h", + "src/core/lib/gpr/string_posix.cc", + "src/core/lib/gpr/string_util_windows.cc", + "src/core/lib/gpr/string_windows.cc", + "src/core/lib/gpr/string_windows.h", + "src/core/lib/gpr/sync.cc", + "src/core/lib/gpr/sync_abseil.cc", + "src/core/lib/gpr/sync_posix.cc", + "src/core/lib/gpr/sync_windows.cc", + "src/core/lib/gpr/time.cc", + "src/core/lib/gpr/time_posix.cc", + "src/core/lib/gpr/time_precise.cc", + "src/core/lib/gpr/time_precise.h", + "src/core/lib/gpr/time_windows.cc", + "src/core/lib/gpr/tls.h", + "src/core/lib/gpr/tls_gcc.h", + "src/core/lib/gpr/tls_msvc.h", + "src/core/lib/gpr/tls_pthread.cc", + "src/core/lib/gpr/tls_pthread.h", + "src/core/lib/gpr/tls_stdcpp.h", + "src/core/lib/gpr/tmpfile.h", + "src/core/lib/gpr/tmpfile_msys.cc", + "src/core/lib/gpr/tmpfile_posix.cc", + "src/core/lib/gpr/tmpfile_windows.cc", + "src/core/lib/gpr/useful.h", + "src/core/lib/gpr/wrap_memcpy.cc", + "src/core/lib/gprpp/arena.cc", + "src/core/lib/gprpp/arena.h", + "src/core/lib/gprpp/atomic.h", + "src/core/lib/gprpp/debug_location.h", + "src/core/lib/gprpp/examine_stack.cc", + "src/core/lib/gprpp/examine_stack.h", + "src/core/lib/gprpp/fork.cc", + "src/core/lib/gprpp/fork.h", + "src/core/lib/gprpp/global_config.h", + "src/core/lib/gprpp/global_config_custom.h", + "src/core/lib/gprpp/global_config_env.cc", + "src/core/lib/gprpp/global_config_env.h", + "src/core/lib/gprpp/global_config_generic.h", + "src/core/lib/gprpp/host_port.cc", + "src/core/lib/gprpp/host_port.h", + "src/core/lib/gprpp/manual_constructor.h", + "src/core/lib/gprpp/memory.h", + "src/core/lib/gprpp/mpscq.cc", + "src/core/lib/gprpp/mpscq.h", + "src/core/lib/gprpp/stat.h", + "src/core/lib/gprpp/stat_posix.cc", + "src/core/lib/gprpp/stat_windows.cc", + "src/core/lib/gprpp/status_helper.cc", + "src/core/lib/gprpp/status_helper.h", + "src/core/lib/gprpp/sync.h", + "src/core/lib/gprpp/thd.h", + "src/core/lib/gprpp/thd_posix.cc", + "src/core/lib/gprpp/thd_windows.cc", + "src/core/lib/gprpp/time_util.cc", + "src/core/lib/gprpp/time_util.h", + "src/core/lib/profiling/basic_timers.cc", + "src/core/lib/profiling/stap_timers.cc", + "src/core/lib/profiling/timers.h", + ] + deps = [ + ":absl/base:base", + ":absl/memory:memory", + ":absl/status:status", + ":absl/strings:cord", + ":absl/strings:str_format", + ":absl/strings:strings", + ":absl/synchronization:synchronization", + ":absl/time:time", + ":absl/types:optional", + ":upb", + ] + + public_configs = [ + ":grpc_config", + ] + } + + + + source_set("grpc") { + sources = [ + "include/grpc/byte_buffer.h", + "include/grpc/byte_buffer_reader.h", + "include/grpc/census.h", + "include/grpc/compression.h", + "include/grpc/event_engine/endpoint_config.h", + "include/grpc/event_engine/event_engine.h", + "include/grpc/event_engine/port.h", + "include/grpc/event_engine/slice_allocator.h", + "include/grpc/fork.h", + "include/grpc/grpc.h", + "include/grpc/grpc_posix.h", + "include/grpc/grpc_security.h", + "include/grpc/grpc_security_constants.h", + "include/grpc/load_reporting.h", + "include/grpc/slice.h", + "include/grpc/slice_buffer.h", + "include/grpc/status.h", + "include/grpc/support/workaround_list.h", + "src/core/ext/filters/census/grpc_context.cc", + "src/core/ext/filters/client_channel/backend_metric.cc", + "src/core/ext/filters/client_channel/backend_metric.h", + "src/core/ext/filters/client_channel/backup_poller.cc", + "src/core/ext/filters/client_channel/backup_poller.h", + "src/core/ext/filters/client_channel/channel_connectivity.cc", + "src/core/ext/filters/client_channel/client_channel.cc", + "src/core/ext/filters/client_channel/client_channel.h", + "src/core/ext/filters/client_channel/client_channel_channelz.cc", + "src/core/ext/filters/client_channel/client_channel_channelz.h", + "src/core/ext/filters/client_channel/client_channel_factory.cc", + "src/core/ext/filters/client_channel/client_channel_factory.h", + "src/core/ext/filters/client_channel/client_channel_plugin.cc", + "src/core/ext/filters/client_channel/config_selector.cc", + "src/core/ext/filters/client_channel/config_selector.h", + "src/core/ext/filters/client_channel/connector.h", + "src/core/ext/filters/client_channel/dynamic_filters.cc", + "src/core/ext/filters/client_channel/dynamic_filters.h", + "src/core/ext/filters/client_channel/global_subchannel_pool.cc", + "src/core/ext/filters/client_channel/global_subchannel_pool.h", + "src/core/ext/filters/client_channel/health/health_check_client.cc", + "src/core/ext/filters/client_channel/health/health_check_client.h", + "src/core/ext/filters/client_channel/http_connect_handshaker.cc", + "src/core/ext/filters/client_channel/http_connect_handshaker.h", + "src/core/ext/filters/client_channel/http_proxy.cc", + "src/core/ext/filters/client_channel/http_proxy.h", + "src/core/ext/filters/client_channel/lb_policy.cc", + "src/core/ext/filters/client_channel/lb_policy.h", + "src/core/ext/filters/client_channel/lb_policy/address_filtering.cc", + "src/core/ext/filters/client_channel/lb_policy/address_filtering.h", + "src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc", + "src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h", + "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc", + "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h", + "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc", + "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h", + "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc", + "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h", + "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h", + "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc", + "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc", + "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h", + "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc", + "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h", + "src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc", + "src/core/ext/filters/client_channel/lb_policy/priority/priority.cc", + "src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc", + "src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.h", + "src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc", + "src/core/ext/filters/client_channel/lb_policy/subchannel_list.h", + "src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc", + "src/core/ext/filters/client_channel/lb_policy/xds/cds.cc", + "src/core/ext/filters/client_channel/lb_policy/xds/xds.h", + "src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h", + "src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc", + "src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc", + "src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc", + "src/core/ext/filters/client_channel/lb_policy_factory.h", + "src/core/ext/filters/client_channel/lb_policy_registry.cc", + "src/core/ext/filters/client_channel/lb_policy_registry.h", + "src/core/ext/filters/client_channel/local_subchannel_pool.cc", + "src/core/ext/filters/client_channel/local_subchannel_pool.h", + "src/core/ext/filters/client_channel/proxy_mapper.h", + "src/core/ext/filters/client_channel/proxy_mapper_registry.cc", + "src/core/ext/filters/client_channel/proxy_mapper_registry.h", + "src/core/ext/filters/client_channel/resolver.cc", + "src/core/ext/filters/client_channel/resolver.h", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_event_engine.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_event_engine.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc", + "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc", + "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h", + "src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc", + "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc", + "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h", + "src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc", + "src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc", + "src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc", + "src/core/ext/filters/client_channel/resolver/xds/xds_resolver.h", + "src/core/ext/filters/client_channel/resolver_factory.h", + "src/core/ext/filters/client_channel/resolver_registry.cc", + "src/core/ext/filters/client_channel/resolver_registry.h", + "src/core/ext/filters/client_channel/resolver_result_parsing.cc", + "src/core/ext/filters/client_channel/resolver_result_parsing.h", + "src/core/ext/filters/client_channel/retry_filter.cc", + "src/core/ext/filters/client_channel/retry_filter.h", + "src/core/ext/filters/client_channel/retry_service_config.cc", + "src/core/ext/filters/client_channel/retry_service_config.h", + "src/core/ext/filters/client_channel/retry_throttle.cc", + "src/core/ext/filters/client_channel/retry_throttle.h", + "src/core/ext/filters/client_channel/server_address.cc", + "src/core/ext/filters/client_channel/server_address.h", + "src/core/ext/filters/client_channel/service_config.cc", + "src/core/ext/filters/client_channel/service_config.h", + "src/core/ext/filters/client_channel/service_config_call_data.h", + "src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc", + "src/core/ext/filters/client_channel/service_config_parser.cc", + "src/core/ext/filters/client_channel/service_config_parser.h", + "src/core/ext/filters/client_channel/subchannel.cc", + "src/core/ext/filters/client_channel/subchannel.h", + "src/core/ext/filters/client_channel/subchannel_interface.h", + "src/core/ext/filters/client_channel/subchannel_pool_interface.cc", + "src/core/ext/filters/client_channel/subchannel_pool_interface.h", + "src/core/ext/filters/client_idle/client_idle_filter.cc", + "src/core/ext/filters/deadline/deadline_filter.cc", + "src/core/ext/filters/deadline/deadline_filter.h", + "src/core/ext/filters/fault_injection/fault_injection_filter.cc", + "src/core/ext/filters/fault_injection/fault_injection_filter.h", + "src/core/ext/filters/fault_injection/service_config_parser.cc", + "src/core/ext/filters/fault_injection/service_config_parser.h", + "src/core/ext/filters/http/client/http_client_filter.cc", + "src/core/ext/filters/http/client/http_client_filter.h", + "src/core/ext/filters/http/client_authority_filter.cc", + "src/core/ext/filters/http/client_authority_filter.h", + "src/core/ext/filters/http/http_filters_plugin.cc", + "src/core/ext/filters/http/message_compress/message_compress_filter.cc", + "src/core/ext/filters/http/message_compress/message_compress_filter.h", + "src/core/ext/filters/http/message_compress/message_decompress_filter.cc", + "src/core/ext/filters/http/message_compress/message_decompress_filter.h", + "src/core/ext/filters/http/server/http_server_filter.cc", + "src/core/ext/filters/http/server/http_server_filter.h", + "src/core/ext/filters/max_age/max_age_filter.cc", + "src/core/ext/filters/max_age/max_age_filter.h", + "src/core/ext/filters/message_size/message_size_filter.cc", + "src/core/ext/filters/message_size/message_size_filter.h", + "src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc", + "src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h", + "src/core/ext/filters/workarounds/workaround_utils.cc", + "src/core/ext/filters/workarounds/workaround_utils.h", + "src/core/ext/transport/chttp2/alpn/alpn.cc", + "src/core/ext/transport/chttp2/alpn/alpn.h", + "src/core/ext/transport/chttp2/client/authority.cc", + "src/core/ext/transport/chttp2/client/authority.h", + "src/core/ext/transport/chttp2/client/chttp2_connector.cc", + "src/core/ext/transport/chttp2/client/chttp2_connector.h", + "src/core/ext/transport/chttp2/client/insecure/channel_create.cc", + "src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc", + "src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc", + "src/core/ext/transport/chttp2/server/chttp2_server.cc", + "src/core/ext/transport/chttp2/server/chttp2_server.h", + "src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc", + "src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc", + "src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc", + "src/core/ext/transport/chttp2/transport/bin_decoder.cc", + "src/core/ext/transport/chttp2/transport/bin_decoder.h", + "src/core/ext/transport/chttp2/transport/bin_encoder.cc", + "src/core/ext/transport/chttp2/transport/bin_encoder.h", + "src/core/ext/transport/chttp2/transport/chttp2_plugin.cc", + "src/core/ext/transport/chttp2/transport/chttp2_transport.cc", + "src/core/ext/transport/chttp2/transport/chttp2_transport.h", + "src/core/ext/transport/chttp2/transport/context_list.cc", + "src/core/ext/transport/chttp2/transport/context_list.h", + "src/core/ext/transport/chttp2/transport/flow_control.cc", + "src/core/ext/transport/chttp2/transport/flow_control.h", + "src/core/ext/transport/chttp2/transport/frame.h", + "src/core/ext/transport/chttp2/transport/frame_data.cc", + "src/core/ext/transport/chttp2/transport/frame_data.h", + "src/core/ext/transport/chttp2/transport/frame_goaway.cc", + "src/core/ext/transport/chttp2/transport/frame_goaway.h", + "src/core/ext/transport/chttp2/transport/frame_ping.cc", + "src/core/ext/transport/chttp2/transport/frame_ping.h", + "src/core/ext/transport/chttp2/transport/frame_rst_stream.cc", + "src/core/ext/transport/chttp2/transport/frame_rst_stream.h", + "src/core/ext/transport/chttp2/transport/frame_settings.cc", + "src/core/ext/transport/chttp2/transport/frame_settings.h", + "src/core/ext/transport/chttp2/transport/frame_window_update.cc", + "src/core/ext/transport/chttp2/transport/frame_window_update.h", + "src/core/ext/transport/chttp2/transport/hpack_encoder.cc", + "src/core/ext/transport/chttp2/transport/hpack_encoder.h", + "src/core/ext/transport/chttp2/transport/hpack_parser.cc", + "src/core/ext/transport/chttp2/transport/hpack_parser.h", + "src/core/ext/transport/chttp2/transport/hpack_table.cc", + "src/core/ext/transport/chttp2/transport/hpack_table.h", + "src/core/ext/transport/chttp2/transport/http2_settings.cc", + "src/core/ext/transport/chttp2/transport/http2_settings.h", + "src/core/ext/transport/chttp2/transport/huffsyms.cc", + "src/core/ext/transport/chttp2/transport/huffsyms.h", + "src/core/ext/transport/chttp2/transport/incoming_metadata.cc", + "src/core/ext/transport/chttp2/transport/incoming_metadata.h", + "src/core/ext/transport/chttp2/transport/internal.h", + "src/core/ext/transport/chttp2/transport/parsing.cc", + "src/core/ext/transport/chttp2/transport/stream_lists.cc", + "src/core/ext/transport/chttp2/transport/stream_map.cc", + "src/core/ext/transport/chttp2/transport/stream_map.h", + "src/core/ext/transport/chttp2/transport/varint.cc", + "src/core/ext/transport/chttp2/transport/varint.h", + "src/core/ext/transport/chttp2/transport/writing.cc", + "src/core/ext/transport/inproc/inproc_plugin.cc", + "src/core/ext/transport/inproc/inproc_transport.cc", + "src/core/ext/transport/inproc/inproc_transport.h", + "src/core/ext/upb-generated/envoy/admin/v3/config_dump.upb.c", + "src/core/ext/upb-generated/envoy/admin/v3/config_dump.upb.h", + "src/core/ext/upb-generated/envoy/annotations/deprecation.upb.c", + "src/core/ext/upb-generated/envoy/annotations/deprecation.upb.h", + "src/core/ext/upb-generated/envoy/annotations/resource.upb.c", + "src/core/ext/upb-generated/envoy/annotations/resource.upb.h", + "src/core/ext/upb-generated/envoy/config/accesslog/v3/accesslog.upb.c", + "src/core/ext/upb-generated/envoy/config/accesslog/v3/accesslog.upb.h", + "src/core/ext/upb-generated/envoy/config/bootstrap/v3/bootstrap.upb.c", + "src/core/ext/upb-generated/envoy/config/bootstrap/v3/bootstrap.upb.h", + "src/core/ext/upb-generated/envoy/config/cluster/v3/circuit_breaker.upb.c", + "src/core/ext/upb-generated/envoy/config/cluster/v3/circuit_breaker.upb.h", + "src/core/ext/upb-generated/envoy/config/cluster/v3/cluster.upb.c", + "src/core/ext/upb-generated/envoy/config/cluster/v3/cluster.upb.h", + "src/core/ext/upb-generated/envoy/config/cluster/v3/filter.upb.c", + "src/core/ext/upb-generated/envoy/config/cluster/v3/filter.upb.h", + "src/core/ext/upb-generated/envoy/config/cluster/v3/outlier_detection.upb.c", + "src/core/ext/upb-generated/envoy/config/cluster/v3/outlier_detection.upb.h", + "src/core/ext/upb-generated/envoy/config/core/v3/address.upb.c", + "src/core/ext/upb-generated/envoy/config/core/v3/address.upb.h", + "src/core/ext/upb-generated/envoy/config/core/v3/backoff.upb.c", + "src/core/ext/upb-generated/envoy/config/core/v3/backoff.upb.h", + "src/core/ext/upb-generated/envoy/config/core/v3/base.upb.c", + "src/core/ext/upb-generated/envoy/config/core/v3/base.upb.h", + "src/core/ext/upb-generated/envoy/config/core/v3/config_source.upb.c", + "src/core/ext/upb-generated/envoy/config/core/v3/config_source.upb.h", + "src/core/ext/upb-generated/envoy/config/core/v3/event_service_config.upb.c", + "src/core/ext/upb-generated/envoy/config/core/v3/event_service_config.upb.h", + "src/core/ext/upb-generated/envoy/config/core/v3/extension.upb.c", + "src/core/ext/upb-generated/envoy/config/core/v3/extension.upb.h", + "src/core/ext/upb-generated/envoy/config/core/v3/grpc_service.upb.c", + "src/core/ext/upb-generated/envoy/config/core/v3/grpc_service.upb.h", + "src/core/ext/upb-generated/envoy/config/core/v3/health_check.upb.c", + "src/core/ext/upb-generated/envoy/config/core/v3/health_check.upb.h", + "src/core/ext/upb-generated/envoy/config/core/v3/http_uri.upb.c", + "src/core/ext/upb-generated/envoy/config/core/v3/http_uri.upb.h", + "src/core/ext/upb-generated/envoy/config/core/v3/protocol.upb.c", + "src/core/ext/upb-generated/envoy/config/core/v3/protocol.upb.h", + "src/core/ext/upb-generated/envoy/config/core/v3/proxy_protocol.upb.c", + "src/core/ext/upb-generated/envoy/config/core/v3/proxy_protocol.upb.h", + "src/core/ext/upb-generated/envoy/config/core/v3/socket_option.upb.c", + "src/core/ext/upb-generated/envoy/config/core/v3/socket_option.upb.h", + "src/core/ext/upb-generated/envoy/config/core/v3/substitution_format_string.upb.c", + "src/core/ext/upb-generated/envoy/config/core/v3/substitution_format_string.upb.h", + "src/core/ext/upb-generated/envoy/config/endpoint/v3/endpoint.upb.c", + "src/core/ext/upb-generated/envoy/config/endpoint/v3/endpoint.upb.h", + "src/core/ext/upb-generated/envoy/config/endpoint/v3/endpoint_components.upb.c", + "src/core/ext/upb-generated/envoy/config/endpoint/v3/endpoint_components.upb.h", + "src/core/ext/upb-generated/envoy/config/endpoint/v3/load_report.upb.c", + "src/core/ext/upb-generated/envoy/config/endpoint/v3/load_report.upb.h", + "src/core/ext/upb-generated/envoy/config/listener/v3/api_listener.upb.c", + "src/core/ext/upb-generated/envoy/config/listener/v3/api_listener.upb.h", + "src/core/ext/upb-generated/envoy/config/listener/v3/listener.upb.c", + "src/core/ext/upb-generated/envoy/config/listener/v3/listener.upb.h", + "src/core/ext/upb-generated/envoy/config/listener/v3/listener_components.upb.c", + "src/core/ext/upb-generated/envoy/config/listener/v3/listener_components.upb.h", + "src/core/ext/upb-generated/envoy/config/listener/v3/udp_listener_config.upb.c", + "src/core/ext/upb-generated/envoy/config/listener/v3/udp_listener_config.upb.h", + "src/core/ext/upb-generated/envoy/config/metrics/v3/stats.upb.c", + "src/core/ext/upb-generated/envoy/config/metrics/v3/stats.upb.h", + "src/core/ext/upb-generated/envoy/config/overload/v3/overload.upb.c", + "src/core/ext/upb-generated/envoy/config/overload/v3/overload.upb.h", + "src/core/ext/upb-generated/envoy/config/rbac/v3/rbac.upb.c", + "src/core/ext/upb-generated/envoy/config/rbac/v3/rbac.upb.h", + "src/core/ext/upb-generated/envoy/config/route/v3/route.upb.c", + "src/core/ext/upb-generated/envoy/config/route/v3/route.upb.h", + "src/core/ext/upb-generated/envoy/config/route/v3/route_components.upb.c", + "src/core/ext/upb-generated/envoy/config/route/v3/route_components.upb.h", + "src/core/ext/upb-generated/envoy/config/route/v3/scoped_route.upb.c", + "src/core/ext/upb-generated/envoy/config/route/v3/scoped_route.upb.h", + "src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.c", + "src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.h", + "src/core/ext/upb-generated/envoy/extensions/clusters/aggregate/v3/cluster.upb.c", + "src/core/ext/upb-generated/envoy/extensions/clusters/aggregate/v3/cluster.upb.h", + "src/core/ext/upb-generated/envoy/extensions/filters/common/fault/v3/fault.upb.c", + "src/core/ext/upb-generated/envoy/extensions/filters/common/fault/v3/fault.upb.h", + "src/core/ext/upb-generated/envoy/extensions/filters/http/fault/v3/fault.upb.c", + "src/core/ext/upb-generated/envoy/extensions/filters/http/fault/v3/fault.upb.h", + "src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c", + "src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.h", + "src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c", + "src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h", + "src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c", + "src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.h", + "src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.c", + "src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.h", + "src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/secret.upb.c", + "src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/secret.upb.h", + "src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/tls.upb.c", + "src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/tls.upb.h", + "src/core/ext/upb-generated/envoy/service/cluster/v3/cds.upb.c", + "src/core/ext/upb-generated/envoy/service/cluster/v3/cds.upb.h", + "src/core/ext/upb-generated/envoy/service/discovery/v3/ads.upb.c", + "src/core/ext/upb-generated/envoy/service/discovery/v3/ads.upb.h", + "src/core/ext/upb-generated/envoy/service/discovery/v3/discovery.upb.c", + "src/core/ext/upb-generated/envoy/service/discovery/v3/discovery.upb.h", + "src/core/ext/upb-generated/envoy/service/endpoint/v3/eds.upb.c", + "src/core/ext/upb-generated/envoy/service/endpoint/v3/eds.upb.h", + "src/core/ext/upb-generated/envoy/service/listener/v3/lds.upb.c", + "src/core/ext/upb-generated/envoy/service/listener/v3/lds.upb.h", + "src/core/ext/upb-generated/envoy/service/load_stats/v3/lrs.upb.c", + "src/core/ext/upb-generated/envoy/service/load_stats/v3/lrs.upb.h", + "src/core/ext/upb-generated/envoy/service/route/v3/rds.upb.c", + "src/core/ext/upb-generated/envoy/service/route/v3/rds.upb.h", + "src/core/ext/upb-generated/envoy/service/route/v3/srds.upb.c", + "src/core/ext/upb-generated/envoy/service/route/v3/srds.upb.h", + "src/core/ext/upb-generated/envoy/service/status/v3/csds.upb.c", + "src/core/ext/upb-generated/envoy/service/status/v3/csds.upb.h", + "src/core/ext/upb-generated/envoy/type/matcher/v3/metadata.upb.c", + "src/core/ext/upb-generated/envoy/type/matcher/v3/metadata.upb.h", + "src/core/ext/upb-generated/envoy/type/matcher/v3/node.upb.c", + "src/core/ext/upb-generated/envoy/type/matcher/v3/node.upb.h", + "src/core/ext/upb-generated/envoy/type/matcher/v3/number.upb.c", + "src/core/ext/upb-generated/envoy/type/matcher/v3/number.upb.h", + "src/core/ext/upb-generated/envoy/type/matcher/v3/path.upb.c", + "src/core/ext/upb-generated/envoy/type/matcher/v3/path.upb.h", + "src/core/ext/upb-generated/envoy/type/matcher/v3/regex.upb.c", + "src/core/ext/upb-generated/envoy/type/matcher/v3/regex.upb.h", + "src/core/ext/upb-generated/envoy/type/matcher/v3/string.upb.c", + "src/core/ext/upb-generated/envoy/type/matcher/v3/string.upb.h", + "src/core/ext/upb-generated/envoy/type/matcher/v3/struct.upb.c", + "src/core/ext/upb-generated/envoy/type/matcher/v3/struct.upb.h", + "src/core/ext/upb-generated/envoy/type/matcher/v3/value.upb.c", + "src/core/ext/upb-generated/envoy/type/matcher/v3/value.upb.h", + "src/core/ext/upb-generated/envoy/type/metadata/v3/metadata.upb.c", + "src/core/ext/upb-generated/envoy/type/metadata/v3/metadata.upb.h", + "src/core/ext/upb-generated/envoy/type/tracing/v3/custom_tag.upb.c", + "src/core/ext/upb-generated/envoy/type/tracing/v3/custom_tag.upb.h", + "src/core/ext/upb-generated/envoy/type/v3/http.upb.c", + "src/core/ext/upb-generated/envoy/type/v3/http.upb.h", + "src/core/ext/upb-generated/envoy/type/v3/percent.upb.c", + "src/core/ext/upb-generated/envoy/type/v3/percent.upb.h", + "src/core/ext/upb-generated/envoy/type/v3/range.upb.c", + "src/core/ext/upb-generated/envoy/type/v3/range.upb.h", + "src/core/ext/upb-generated/envoy/type/v3/semantic_version.upb.c", + "src/core/ext/upb-generated/envoy/type/v3/semantic_version.upb.h", + "src/core/ext/upb-generated/src/proto/grpc/gcp/altscontext.upb.c", + "src/core/ext/upb-generated/src/proto/grpc/gcp/altscontext.upb.h", + "src/core/ext/upb-generated/src/proto/grpc/gcp/handshaker.upb.c", + "src/core/ext/upb-generated/src/proto/grpc/gcp/handshaker.upb.h", + "src/core/ext/upb-generated/src/proto/grpc/gcp/transport_security_common.upb.c", + "src/core/ext/upb-generated/src/proto/grpc/gcp/transport_security_common.upb.h", + "src/core/ext/upb-generated/src/proto/grpc/health/v1/health.upb.c", + "src/core/ext/upb-generated/src/proto/grpc/health/v1/health.upb.h", + "src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.c", + "src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.h", + "src/core/ext/upb-generated/udpa/annotations/migrate.upb.c", + "src/core/ext/upb-generated/udpa/annotations/migrate.upb.h", + "src/core/ext/upb-generated/udpa/annotations/security.upb.c", + "src/core/ext/upb-generated/udpa/annotations/security.upb.h", + "src/core/ext/upb-generated/udpa/annotations/sensitive.upb.c", + "src/core/ext/upb-generated/udpa/annotations/sensitive.upb.h", + "src/core/ext/upb-generated/udpa/annotations/status.upb.c", + "src/core/ext/upb-generated/udpa/annotations/status.upb.h", + "src/core/ext/upb-generated/udpa/annotations/versioning.upb.c", + "src/core/ext/upb-generated/udpa/annotations/versioning.upb.h", + "src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.c", + "src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.h", + "src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.c", + "src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.h", + "src/core/ext/upb-generated/validate/validate.upb.c", + "src/core/ext/upb-generated/validate/validate.upb.h", + "src/core/ext/upb-generated/xds/core/v3/authority.upb.c", + "src/core/ext/upb-generated/xds/core/v3/authority.upb.h", + "src/core/ext/upb-generated/xds/core/v3/collection_entry.upb.c", + "src/core/ext/upb-generated/xds/core/v3/collection_entry.upb.h", + "src/core/ext/upb-generated/xds/core/v3/context_params.upb.c", + "src/core/ext/upb-generated/xds/core/v3/context_params.upb.h", + "src/core/ext/upb-generated/xds/core/v3/resource.upb.c", + "src/core/ext/upb-generated/xds/core/v3/resource.upb.h", + "src/core/ext/upb-generated/xds/core/v3/resource_locator.upb.c", + "src/core/ext/upb-generated/xds/core/v3/resource_locator.upb.h", + "src/core/ext/upb-generated/xds/core/v3/resource_name.upb.c", + "src/core/ext/upb-generated/xds/core/v3/resource_name.upb.h", + "src/core/ext/upbdefs-generated/envoy/admin/v3/config_dump.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/admin/v3/config_dump.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/annotations/deprecation.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/annotations/deprecation.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/annotations/resource.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/annotations/resource.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/config/accesslog/v3/accesslog.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/config/accesslog/v3/accesslog.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/config/bootstrap/v3/bootstrap.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/config/bootstrap/v3/bootstrap.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/config/cluster/v3/circuit_breaker.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/config/cluster/v3/circuit_breaker.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/config/cluster/v3/cluster.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/config/cluster/v3/cluster.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/config/cluster/v3/filter.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/config/cluster/v3/filter.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/config/cluster/v3/outlier_detection.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/config/cluster/v3/outlier_detection.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/config/core/v3/address.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/config/core/v3/address.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/config/core/v3/backoff.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/config/core/v3/backoff.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/config/core/v3/base.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/config/core/v3/base.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/config/core/v3/config_source.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/config/core/v3/config_source.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/config/core/v3/event_service_config.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/config/core/v3/event_service_config.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/config/core/v3/extension.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/config/core/v3/extension.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/config/core/v3/grpc_service.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/config/core/v3/grpc_service.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/config/core/v3/health_check.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/config/core/v3/health_check.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/config/core/v3/http_uri.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/config/core/v3/http_uri.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/config/core/v3/protocol.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/config/core/v3/protocol.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/config/core/v3/proxy_protocol.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/config/core/v3/proxy_protocol.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/config/core/v3/socket_option.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/config/core/v3/socket_option.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/config/core/v3/substitution_format_string.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/config/core/v3/substitution_format_string.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/config/endpoint/v3/endpoint.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/config/endpoint/v3/endpoint.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/config/endpoint/v3/endpoint_components.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/config/endpoint/v3/endpoint_components.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/config/endpoint/v3/load_report.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/config/endpoint/v3/load_report.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/config/listener/v3/api_listener.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/config/listener/v3/api_listener.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/config/listener/v3/listener.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/config/listener/v3/listener.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/config/listener/v3/listener_components.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/config/listener/v3/listener_components.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/config/listener/v3/udp_listener_config.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/config/listener/v3/udp_listener_config.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/config/metrics/v3/stats.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/config/metrics/v3/stats.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/config/overload/v3/overload.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/config/overload/v3/overload.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/config/route/v3/route.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/config/route/v3/route.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/config/route/v3/route_components.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/config/route/v3/route_components.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/config/route/v3/scoped_route.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/config/route/v3/scoped_route.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/config/trace/v3/http_tracer.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/config/trace/v3/http_tracer.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/extensions/filters/common/fault/v3/fault.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/extensions/filters/common/fault/v3/fault.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/extensions/filters/http/fault/v3/fault.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/extensions/filters/http/fault/v3/fault.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/cert.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/cert.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/common.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/common.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/secret.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/secret.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/service/cluster/v3/cds.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/service/cluster/v3/cds.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/service/discovery/v3/ads.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/service/discovery/v3/ads.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/service/discovery/v3/discovery.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/service/discovery/v3/discovery.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/service/endpoint/v3/eds.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/service/endpoint/v3/eds.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/service/listener/v3/lds.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/service/listener/v3/lds.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/service/load_stats/v3/lrs.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/service/load_stats/v3/lrs.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/service/route/v3/rds.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/service/route/v3/rds.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/service/route/v3/srds.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/service/route/v3/srds.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/service/status/v3/csds.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/service/status/v3/csds.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/type/matcher/v3/metadata.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/type/matcher/v3/metadata.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/type/matcher/v3/node.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/type/matcher/v3/node.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/type/matcher/v3/number.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/type/matcher/v3/number.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/type/matcher/v3/path.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/type/matcher/v3/path.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/type/matcher/v3/regex.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/type/matcher/v3/regex.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/type/matcher/v3/string.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/type/matcher/v3/string.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/type/matcher/v3/struct.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/type/matcher/v3/struct.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/type/matcher/v3/value.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/type/matcher/v3/value.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/type/metadata/v3/metadata.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/type/metadata/v3/metadata.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/type/tracing/v3/custom_tag.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/type/tracing/v3/custom_tag.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/type/v3/http.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/type/v3/http.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/type/v3/percent.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/type/v3/percent.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/type/v3/range.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/type/v3/range.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/type/v3/semantic_version.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/type/v3/semantic_version.upbdefs.h", + "src/core/ext/upbdefs-generated/google/api/annotations.upbdefs.c", + "src/core/ext/upbdefs-generated/google/api/annotations.upbdefs.h", + "src/core/ext/upbdefs-generated/google/api/http.upbdefs.c", + "src/core/ext/upbdefs-generated/google/api/http.upbdefs.h", + "src/core/ext/upbdefs-generated/google/protobuf/any.upbdefs.c", + "src/core/ext/upbdefs-generated/google/protobuf/any.upbdefs.h", + "src/core/ext/upbdefs-generated/google/protobuf/duration.upbdefs.c", + "src/core/ext/upbdefs-generated/google/protobuf/duration.upbdefs.h", + "src/core/ext/upbdefs-generated/google/protobuf/empty.upbdefs.c", + "src/core/ext/upbdefs-generated/google/protobuf/empty.upbdefs.h", + "src/core/ext/upbdefs-generated/google/protobuf/struct.upbdefs.c", + "src/core/ext/upbdefs-generated/google/protobuf/struct.upbdefs.h", + "src/core/ext/upbdefs-generated/google/protobuf/timestamp.upbdefs.c", + "src/core/ext/upbdefs-generated/google/protobuf/timestamp.upbdefs.h", + "src/core/ext/upbdefs-generated/google/protobuf/wrappers.upbdefs.c", + "src/core/ext/upbdefs-generated/google/protobuf/wrappers.upbdefs.h", + "src/core/ext/upbdefs-generated/google/rpc/status.upbdefs.c", + "src/core/ext/upbdefs-generated/google/rpc/status.upbdefs.h", + "src/core/ext/upbdefs-generated/udpa/annotations/migrate.upbdefs.c", + "src/core/ext/upbdefs-generated/udpa/annotations/migrate.upbdefs.h", + "src/core/ext/upbdefs-generated/udpa/annotations/security.upbdefs.c", + "src/core/ext/upbdefs-generated/udpa/annotations/security.upbdefs.h", + "src/core/ext/upbdefs-generated/udpa/annotations/sensitive.upbdefs.c", + "src/core/ext/upbdefs-generated/udpa/annotations/sensitive.upbdefs.h", + "src/core/ext/upbdefs-generated/udpa/annotations/status.upbdefs.c", + "src/core/ext/upbdefs-generated/udpa/annotations/status.upbdefs.h", + "src/core/ext/upbdefs-generated/udpa/annotations/versioning.upbdefs.c", + "src/core/ext/upbdefs-generated/udpa/annotations/versioning.upbdefs.h", + "src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.c", + "src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.h", + "src/core/ext/upbdefs-generated/validate/validate.upbdefs.c", + "src/core/ext/upbdefs-generated/validate/validate.upbdefs.h", + "src/core/ext/upbdefs-generated/xds/core/v3/authority.upbdefs.c", + "src/core/ext/upbdefs-generated/xds/core/v3/authority.upbdefs.h", + "src/core/ext/upbdefs-generated/xds/core/v3/collection_entry.upbdefs.c", + "src/core/ext/upbdefs-generated/xds/core/v3/collection_entry.upbdefs.h", + "src/core/ext/upbdefs-generated/xds/core/v3/context_params.upbdefs.c", + "src/core/ext/upbdefs-generated/xds/core/v3/context_params.upbdefs.h", + "src/core/ext/upbdefs-generated/xds/core/v3/resource.upbdefs.c", + "src/core/ext/upbdefs-generated/xds/core/v3/resource.upbdefs.h", + "src/core/ext/upbdefs-generated/xds/core/v3/resource_locator.upbdefs.c", + "src/core/ext/upbdefs-generated/xds/core/v3/resource_locator.upbdefs.h", + "src/core/ext/upbdefs-generated/xds/core/v3/resource_name.upbdefs.c", + "src/core/ext/upbdefs-generated/xds/core/v3/resource_name.upbdefs.h", + "src/core/ext/xds/certificate_provider_factory.h", + "src/core/ext/xds/certificate_provider_registry.cc", + "src/core/ext/xds/certificate_provider_registry.h", + "src/core/ext/xds/certificate_provider_store.cc", + "src/core/ext/xds/certificate_provider_store.h", + "src/core/ext/xds/file_watcher_certificate_provider_factory.cc", + "src/core/ext/xds/file_watcher_certificate_provider_factory.h", + "src/core/ext/xds/xds_api.cc", + "src/core/ext/xds/xds_api.h", + "src/core/ext/xds/xds_bootstrap.cc", + "src/core/ext/xds/xds_bootstrap.h", + "src/core/ext/xds/xds_certificate_provider.cc", + "src/core/ext/xds/xds_certificate_provider.h", + "src/core/ext/xds/xds_channel_args.h", + "src/core/ext/xds/xds_client.cc", + "src/core/ext/xds/xds_client.h", + "src/core/ext/xds/xds_client_stats.cc", + "src/core/ext/xds/xds_client_stats.h", + "src/core/ext/xds/xds_http_fault_filter.cc", + "src/core/ext/xds/xds_http_fault_filter.h", + "src/core/ext/xds/xds_http_filters.cc", + "src/core/ext/xds/xds_http_filters.h", + "src/core/ext/xds/xds_server_config_fetcher.cc", + "src/core/lib/address_utils/parse_address.cc", + "src/core/lib/address_utils/parse_address.h", + "src/core/lib/address_utils/sockaddr_utils.cc", + "src/core/lib/address_utils/sockaddr_utils.h", + "src/core/lib/avl/avl.cc", + "src/core/lib/avl/avl.h", + "src/core/lib/backoff/backoff.cc", + "src/core/lib/backoff/backoff.h", + "src/core/lib/channel/channel_args.cc", + "src/core/lib/channel/channel_args.h", + "src/core/lib/channel/channel_stack.cc", + "src/core/lib/channel/channel_stack.h", + "src/core/lib/channel/channel_stack_builder.cc", + "src/core/lib/channel/channel_stack_builder.h", + "src/core/lib/channel/channel_trace.cc", + "src/core/lib/channel/channel_trace.h", + "src/core/lib/channel/channelz.cc", + "src/core/lib/channel/channelz.h", + "src/core/lib/channel/channelz_registry.cc", + "src/core/lib/channel/channelz_registry.h", + "src/core/lib/channel/connected_channel.cc", + "src/core/lib/channel/connected_channel.h", + "src/core/lib/channel/context.h", + "src/core/lib/channel/handshaker.cc", + "src/core/lib/channel/handshaker.h", + "src/core/lib/channel/handshaker_factory.h", + "src/core/lib/channel/handshaker_registry.cc", + "src/core/lib/channel/handshaker_registry.h", + "src/core/lib/channel/status_util.cc", + "src/core/lib/channel/status_util.h", + "src/core/lib/compression/algorithm_metadata.h", + "src/core/lib/compression/compression.cc", + "src/core/lib/compression/compression_args.cc", + "src/core/lib/compression/compression_args.h", + "src/core/lib/compression/compression_internal.cc", + "src/core/lib/compression/compression_internal.h", + "src/core/lib/compression/message_compress.cc", + "src/core/lib/compression/message_compress.h", + "src/core/lib/compression/stream_compression.cc", + "src/core/lib/compression/stream_compression.h", + "src/core/lib/compression/stream_compression_gzip.cc", + "src/core/lib/compression/stream_compression_gzip.h", + "src/core/lib/compression/stream_compression_identity.cc", + "src/core/lib/compression/stream_compression_identity.h", + "src/core/lib/debug/stats.cc", + "src/core/lib/debug/stats.h", + "src/core/lib/debug/stats_data.cc", + "src/core/lib/debug/stats_data.h", + "src/core/lib/debug/trace.cc", + "src/core/lib/debug/trace.h", + "src/core/lib/event_engine/endpoint_config.cc", + "src/core/lib/event_engine/endpoint_config_internal.h", + "src/core/lib/event_engine/event_engine.cc", + "src/core/lib/event_engine/slice_allocator.cc", + "src/core/lib/event_engine/sockaddr.cc", + "src/core/lib/event_engine/sockaddr.h", + "src/core/lib/gprpp/atomic.h", + "src/core/lib/gprpp/dual_ref_counted.h", + "src/core/lib/gprpp/orphanable.h", + "src/core/lib/gprpp/ref_counted.h", + "src/core/lib/gprpp/ref_counted_ptr.h", + "src/core/lib/http/format_request.cc", + "src/core/lib/http/format_request.h", + "src/core/lib/http/httpcli.cc", + "src/core/lib/http/httpcli.h", + "src/core/lib/http/httpcli_security_connector.cc", + "src/core/lib/http/parser.cc", + "src/core/lib/http/parser.h", + "src/core/lib/iomgr/block_annotate.h", + "src/core/lib/iomgr/buffer_list.cc", + "src/core/lib/iomgr/buffer_list.h", + "src/core/lib/iomgr/call_combiner.cc", + "src/core/lib/iomgr/call_combiner.h", + "src/core/lib/iomgr/cfstream_handle.cc", + "src/core/lib/iomgr/cfstream_handle.h", + "src/core/lib/iomgr/closure.h", + "src/core/lib/iomgr/combiner.cc", + "src/core/lib/iomgr/combiner.h", + "src/core/lib/iomgr/dualstack_socket_posix.cc", + "src/core/lib/iomgr/dynamic_annotations.h", + "src/core/lib/iomgr/endpoint.cc", + "src/core/lib/iomgr/endpoint.h", + "src/core/lib/iomgr/endpoint_cfstream.cc", + "src/core/lib/iomgr/endpoint_cfstream.h", + "src/core/lib/iomgr/endpoint_pair.h", + "src/core/lib/iomgr/endpoint_pair_event_engine.cc", + "src/core/lib/iomgr/endpoint_pair_posix.cc", + "src/core/lib/iomgr/endpoint_pair_uv.cc", + "src/core/lib/iomgr/endpoint_pair_windows.cc", + "src/core/lib/iomgr/error.cc", + "src/core/lib/iomgr/error.h", + "src/core/lib/iomgr/error_cfstream.cc", + "src/core/lib/iomgr/error_cfstream.h", + "src/core/lib/iomgr/error_internal.h", + "src/core/lib/iomgr/ev_apple.cc", + "src/core/lib/iomgr/ev_apple.h", + "src/core/lib/iomgr/ev_epoll1_linux.cc", + "src/core/lib/iomgr/ev_epoll1_linux.h", + "src/core/lib/iomgr/ev_epollex_linux.cc", + "src/core/lib/iomgr/ev_epollex_linux.h", + "src/core/lib/iomgr/ev_poll_posix.cc", + "src/core/lib/iomgr/ev_poll_posix.h", + "src/core/lib/iomgr/ev_posix.cc", + "src/core/lib/iomgr/ev_posix.h", + "src/core/lib/iomgr/ev_windows.cc", + "src/core/lib/iomgr/event_engine/closure.cc", + "src/core/lib/iomgr/event_engine/closure.h", + "src/core/lib/iomgr/event_engine/endpoint.cc", + "src/core/lib/iomgr/event_engine/endpoint.h", + "src/core/lib/iomgr/event_engine/iomgr.cc", + "src/core/lib/iomgr/event_engine/iomgr.h", + "src/core/lib/iomgr/event_engine/pollset.cc", + "src/core/lib/iomgr/event_engine/pollset.h", + "src/core/lib/iomgr/event_engine/promise.h", + "src/core/lib/iomgr/event_engine/resolved_address_internal.cc", + "src/core/lib/iomgr/event_engine/resolved_address_internal.h", + "src/core/lib/iomgr/event_engine/resolver.cc", + "src/core/lib/iomgr/event_engine/tcp.cc", + "src/core/lib/iomgr/event_engine/timer.cc", + "src/core/lib/iomgr/exec_ctx.cc", + "src/core/lib/iomgr/exec_ctx.h", + "src/core/lib/iomgr/executor.cc", + "src/core/lib/iomgr/executor.h", + "src/core/lib/iomgr/executor/mpmcqueue.cc", + "src/core/lib/iomgr/executor/mpmcqueue.h", + "src/core/lib/iomgr/executor/threadpool.cc", + "src/core/lib/iomgr/executor/threadpool.h", + "src/core/lib/iomgr/fork_posix.cc", + "src/core/lib/iomgr/fork_windows.cc", + "src/core/lib/iomgr/gethostname.h", + "src/core/lib/iomgr/gethostname_fallback.cc", + "src/core/lib/iomgr/gethostname_host_name_max.cc", + "src/core/lib/iomgr/gethostname_sysconf.cc", + "src/core/lib/iomgr/grpc_if_nametoindex.h", + "src/core/lib/iomgr/grpc_if_nametoindex_posix.cc", + "src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc", + "src/core/lib/iomgr/internal_errqueue.cc", + "src/core/lib/iomgr/internal_errqueue.h", + "src/core/lib/iomgr/iocp_windows.cc", + "src/core/lib/iomgr/iocp_windows.h", + "src/core/lib/iomgr/iomgr.cc", + "src/core/lib/iomgr/iomgr.h", + "src/core/lib/iomgr/iomgr_custom.cc", + "src/core/lib/iomgr/iomgr_custom.h", + "src/core/lib/iomgr/iomgr_internal.cc", + "src/core/lib/iomgr/iomgr_internal.h", + "src/core/lib/iomgr/iomgr_posix.cc", + "src/core/lib/iomgr/iomgr_posix_cfstream.cc", + "src/core/lib/iomgr/iomgr_uv.cc", + "src/core/lib/iomgr/iomgr_windows.cc", + "src/core/lib/iomgr/is_epollexclusive_available.cc", + "src/core/lib/iomgr/is_epollexclusive_available.h", + "src/core/lib/iomgr/load_file.cc", + "src/core/lib/iomgr/load_file.h", + "src/core/lib/iomgr/lockfree_event.cc", + "src/core/lib/iomgr/lockfree_event.h", + "src/core/lib/iomgr/nameser.h", + "src/core/lib/iomgr/polling_entity.cc", + "src/core/lib/iomgr/polling_entity.h", + "src/core/lib/iomgr/pollset.cc", + "src/core/lib/iomgr/pollset.h", + "src/core/lib/iomgr/pollset_custom.cc", + "src/core/lib/iomgr/pollset_custom.h", + "src/core/lib/iomgr/pollset_set.cc", + "src/core/lib/iomgr/pollset_set.h", + "src/core/lib/iomgr/pollset_set_custom.cc", + "src/core/lib/iomgr/pollset_set_custom.h", + "src/core/lib/iomgr/pollset_set_windows.cc", + "src/core/lib/iomgr/pollset_set_windows.h", + "src/core/lib/iomgr/pollset_uv.cc", + "src/core/lib/iomgr/pollset_uv.h", + "src/core/lib/iomgr/pollset_windows.cc", + "src/core/lib/iomgr/pollset_windows.h", + "src/core/lib/iomgr/port.h", + "src/core/lib/iomgr/python_util.h", + "src/core/lib/iomgr/resolve_address.cc", + "src/core/lib/iomgr/resolve_address.h", + "src/core/lib/iomgr/resolve_address_custom.cc", + "src/core/lib/iomgr/resolve_address_custom.h", + "src/core/lib/iomgr/resolve_address_posix.cc", + "src/core/lib/iomgr/resolve_address_windows.cc", + "src/core/lib/iomgr/resource_quota.cc", + "src/core/lib/iomgr/resource_quota.h", + "src/core/lib/iomgr/sockaddr.h", + "src/core/lib/iomgr/sockaddr_custom.h", + "src/core/lib/iomgr/sockaddr_posix.h", + "src/core/lib/iomgr/sockaddr_windows.h", + "src/core/lib/iomgr/socket_factory_posix.cc", + "src/core/lib/iomgr/socket_factory_posix.h", + "src/core/lib/iomgr/socket_mutator.cc", + "src/core/lib/iomgr/socket_mutator.h", + "src/core/lib/iomgr/socket_utils.h", + "src/core/lib/iomgr/socket_utils_common_posix.cc", + "src/core/lib/iomgr/socket_utils_linux.cc", + "src/core/lib/iomgr/socket_utils_posix.cc", + "src/core/lib/iomgr/socket_utils_posix.h", + "src/core/lib/iomgr/socket_utils_uv.cc", + "src/core/lib/iomgr/socket_utils_windows.cc", + "src/core/lib/iomgr/socket_windows.cc", + "src/core/lib/iomgr/socket_windows.h", + "src/core/lib/iomgr/sys_epoll_wrapper.h", + "src/core/lib/iomgr/tcp_client.cc", + "src/core/lib/iomgr/tcp_client.h", + "src/core/lib/iomgr/tcp_client_cfstream.cc", + "src/core/lib/iomgr/tcp_client_custom.cc", + "src/core/lib/iomgr/tcp_client_posix.cc", + "src/core/lib/iomgr/tcp_client_posix.h", + "src/core/lib/iomgr/tcp_client_windows.cc", + "src/core/lib/iomgr/tcp_custom.cc", + "src/core/lib/iomgr/tcp_custom.h", + "src/core/lib/iomgr/tcp_posix.cc", + "src/core/lib/iomgr/tcp_posix.h", + "src/core/lib/iomgr/tcp_server.cc", + "src/core/lib/iomgr/tcp_server.h", + "src/core/lib/iomgr/tcp_server_custom.cc", + "src/core/lib/iomgr/tcp_server_posix.cc", + "src/core/lib/iomgr/tcp_server_utils_posix.h", + "src/core/lib/iomgr/tcp_server_utils_posix_common.cc", + "src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc", + "src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.cc", + "src/core/lib/iomgr/tcp_server_windows.cc", + "src/core/lib/iomgr/tcp_uv.cc", + "src/core/lib/iomgr/tcp_windows.cc", + "src/core/lib/iomgr/tcp_windows.h", + "src/core/lib/iomgr/time_averaged_stats.cc", + "src/core/lib/iomgr/time_averaged_stats.h", + "src/core/lib/iomgr/timer.cc", + "src/core/lib/iomgr/timer.h", + "src/core/lib/iomgr/timer_custom.cc", + "src/core/lib/iomgr/timer_custom.h", + "src/core/lib/iomgr/timer_generic.cc", + "src/core/lib/iomgr/timer_generic.h", + "src/core/lib/iomgr/timer_heap.cc", + "src/core/lib/iomgr/timer_heap.h", + "src/core/lib/iomgr/timer_manager.cc", + "src/core/lib/iomgr/timer_manager.h", + "src/core/lib/iomgr/timer_uv.cc", + "src/core/lib/iomgr/udp_server.cc", + "src/core/lib/iomgr/udp_server.h", + "src/core/lib/iomgr/unix_sockets_posix.cc", + "src/core/lib/iomgr/unix_sockets_posix.h", + "src/core/lib/iomgr/unix_sockets_posix_noop.cc", + "src/core/lib/iomgr/wakeup_fd_eventfd.cc", + "src/core/lib/iomgr/wakeup_fd_nospecial.cc", + "src/core/lib/iomgr/wakeup_fd_pipe.cc", + "src/core/lib/iomgr/wakeup_fd_pipe.h", + "src/core/lib/iomgr/wakeup_fd_posix.cc", + "src/core/lib/iomgr/wakeup_fd_posix.h", + "src/core/lib/iomgr/work_serializer.cc", + "src/core/lib/iomgr/work_serializer.h", + "src/core/lib/json/json.h", + "src/core/lib/json/json_reader.cc", + "src/core/lib/json/json_util.cc", + "src/core/lib/json/json_util.h", + "src/core/lib/json/json_writer.cc", + "src/core/lib/matchers/matchers.cc", + "src/core/lib/matchers/matchers.h", + "src/core/lib/security/authorization/authorization_engine.h", + "src/core/lib/security/authorization/authorization_policy_provider.h", + "src/core/lib/security/authorization/authorization_policy_provider_vtable.cc", + "src/core/lib/security/authorization/evaluate_args.cc", + "src/core/lib/security/authorization/evaluate_args.h", + "src/core/lib/security/context/security_context.cc", + "src/core/lib/security/context/security_context.h", + "src/core/lib/security/credentials/alts/alts_credentials.cc", + "src/core/lib/security/credentials/alts/alts_credentials.h", + "src/core/lib/security/credentials/alts/check_gcp_environment.cc", + "src/core/lib/security/credentials/alts/check_gcp_environment.h", + "src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc", + "src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc", + "src/core/lib/security/credentials/alts/check_gcp_environment_windows.cc", + "src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc", + "src/core/lib/security/credentials/alts/grpc_alts_credentials_options.cc", + "src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h", + "src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc", + "src/core/lib/security/credentials/composite/composite_credentials.cc", + "src/core/lib/security/credentials/composite/composite_credentials.h", + "src/core/lib/security/credentials/credentials.cc", + "src/core/lib/security/credentials/credentials.h", + "src/core/lib/security/credentials/credentials_metadata.cc", + "src/core/lib/security/credentials/external/aws_external_account_credentials.cc", + "src/core/lib/security/credentials/external/aws_external_account_credentials.h", + "src/core/lib/security/credentials/external/aws_request_signer.cc", + "src/core/lib/security/credentials/external/aws_request_signer.h", + "src/core/lib/security/credentials/external/external_account_credentials.cc", + "src/core/lib/security/credentials/external/external_account_credentials.h", + "src/core/lib/security/credentials/external/file_external_account_credentials.cc", + "src/core/lib/security/credentials/external/file_external_account_credentials.h", + "src/core/lib/security/credentials/external/url_external_account_credentials.cc", + "src/core/lib/security/credentials/external/url_external_account_credentials.h", + "src/core/lib/security/credentials/fake/fake_credentials.cc", + "src/core/lib/security/credentials/fake/fake_credentials.h", + "src/core/lib/security/credentials/google_default/credentials_generic.cc", + "src/core/lib/security/credentials/google_default/google_default_credentials.cc", + "src/core/lib/security/credentials/google_default/google_default_credentials.h", + "src/core/lib/security/credentials/iam/iam_credentials.cc", + "src/core/lib/security/credentials/iam/iam_credentials.h", + "src/core/lib/security/credentials/insecure/insecure_credentials.cc", + "src/core/lib/security/credentials/jwt/json_token.cc", + "src/core/lib/security/credentials/jwt/json_token.h", + "src/core/lib/security/credentials/jwt/jwt_credentials.cc", + "src/core/lib/security/credentials/jwt/jwt_credentials.h", + "src/core/lib/security/credentials/jwt/jwt_verifier.cc", + "src/core/lib/security/credentials/jwt/jwt_verifier.h", + "src/core/lib/security/credentials/local/local_credentials.cc", + "src/core/lib/security/credentials/local/local_credentials.h", + "src/core/lib/security/credentials/oauth2/oauth2_credentials.cc", + "src/core/lib/security/credentials/oauth2/oauth2_credentials.h", + "src/core/lib/security/credentials/plugin/plugin_credentials.cc", + "src/core/lib/security/credentials/plugin/plugin_credentials.h", + "src/core/lib/security/credentials/ssl/ssl_credentials.cc", + "src/core/lib/security/credentials/ssl/ssl_credentials.h", + "src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.cc", + "src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.h", + "src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc", + "src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h", + "src/core/lib/security/credentials/tls/grpc_tls_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", + "src/core/lib/security/credentials/tls/tls_credentials.h", + "src/core/lib/security/credentials/tls/tls_utils.cc", + "src/core/lib/security/credentials/tls/tls_utils.h", + "src/core/lib/security/credentials/xds/xds_credentials.cc", + "src/core/lib/security/credentials/xds/xds_credentials.h", + "src/core/lib/security/security_connector/alts/alts_security_connector.cc", + "src/core/lib/security/security_connector/alts/alts_security_connector.h", + "src/core/lib/security/security_connector/fake/fake_security_connector.cc", + "src/core/lib/security/security_connector/fake/fake_security_connector.h", + "src/core/lib/security/security_connector/insecure/insecure_security_connector.cc", + "src/core/lib/security/security_connector/insecure/insecure_security_connector.h", + "src/core/lib/security/security_connector/load_system_roots.h", + "src/core/lib/security/security_connector/load_system_roots_fallback.cc", + "src/core/lib/security/security_connector/load_system_roots_linux.cc", + "src/core/lib/security/security_connector/load_system_roots_linux.h", + "src/core/lib/security/security_connector/local/local_security_connector.cc", + "src/core/lib/security/security_connector/local/local_security_connector.h", + "src/core/lib/security/security_connector/security_connector.cc", + "src/core/lib/security/security_connector/security_connector.h", + "src/core/lib/security/security_connector/ssl/ssl_security_connector.cc", + "src/core/lib/security/security_connector/ssl/ssl_security_connector.h", + "src/core/lib/security/security_connector/ssl_utils.cc", + "src/core/lib/security/security_connector/ssl_utils.h", + "src/core/lib/security/security_connector/ssl_utils_config.cc", + "src/core/lib/security/security_connector/ssl_utils_config.h", + "src/core/lib/security/security_connector/tls/tls_security_connector.cc", + "src/core/lib/security/security_connector/tls/tls_security_connector.h", + "src/core/lib/security/transport/auth_filters.h", + "src/core/lib/security/transport/client_auth_filter.cc", + "src/core/lib/security/transport/secure_endpoint.cc", + "src/core/lib/security/transport/secure_endpoint.h", + "src/core/lib/security/transport/security_handshaker.cc", + "src/core/lib/security/transport/security_handshaker.h", + "src/core/lib/security/transport/server_auth_filter.cc", + "src/core/lib/security/transport/tsi_error.cc", + "src/core/lib/security/transport/tsi_error.h", + "src/core/lib/security/util/json_util.cc", + "src/core/lib/security/util/json_util.h", + "src/core/lib/slice/b64.cc", + "src/core/lib/slice/b64.h", + "src/core/lib/slice/percent_encoding.cc", + "src/core/lib/slice/percent_encoding.h", + "src/core/lib/slice/slice.cc", + "src/core/lib/slice/slice_buffer.cc", + "src/core/lib/slice/slice_intern.cc", + "src/core/lib/slice/slice_internal.h", + "src/core/lib/slice/slice_string_helpers.cc", + "src/core/lib/slice/slice_string_helpers.h", + "src/core/lib/slice/slice_utils.h", + "src/core/lib/surface/api_trace.cc", + "src/core/lib/surface/api_trace.h", + "src/core/lib/surface/byte_buffer.cc", + "src/core/lib/surface/byte_buffer_reader.cc", + "src/core/lib/surface/call.cc", + "src/core/lib/surface/call.h", + "src/core/lib/surface/call_details.cc", + "src/core/lib/surface/call_log_batch.cc", + "src/core/lib/surface/call_test_only.h", + "src/core/lib/surface/channel.cc", + "src/core/lib/surface/channel.h", + "src/core/lib/surface/channel_init.cc", + "src/core/lib/surface/channel_init.h", + "src/core/lib/surface/channel_ping.cc", + "src/core/lib/surface/channel_stack_type.cc", + "src/core/lib/surface/channel_stack_type.h", + "src/core/lib/surface/completion_queue.cc", + "src/core/lib/surface/completion_queue.h", + "src/core/lib/surface/completion_queue_factory.cc", + "src/core/lib/surface/completion_queue_factory.h", + "src/core/lib/surface/event_string.cc", + "src/core/lib/surface/event_string.h", + "src/core/lib/surface/init.cc", + "src/core/lib/surface/init.h", + "src/core/lib/surface/init_secure.cc", + "src/core/lib/surface/lame_client.cc", + "src/core/lib/surface/lame_client.h", + "src/core/lib/surface/metadata_array.cc", + "src/core/lib/surface/server.cc", + "src/core/lib/surface/server.h", + "src/core/lib/surface/validate_metadata.cc", + "src/core/lib/surface/validate_metadata.h", + "src/core/lib/surface/version.cc", + "src/core/lib/transport/authority_override.cc", + "src/core/lib/transport/authority_override.h", + "src/core/lib/transport/bdp_estimator.cc", + "src/core/lib/transport/bdp_estimator.h", + "src/core/lib/transport/byte_stream.cc", + "src/core/lib/transport/byte_stream.h", + "src/core/lib/transport/connectivity_state.cc", + "src/core/lib/transport/connectivity_state.h", + "src/core/lib/transport/error_utils.cc", + "src/core/lib/transport/error_utils.h", + "src/core/lib/transport/http2_errors.h", + "src/core/lib/transport/metadata.cc", + "src/core/lib/transport/metadata.h", + "src/core/lib/transport/metadata_batch.cc", + "src/core/lib/transport/metadata_batch.h", + "src/core/lib/transport/pid_controller.cc", + "src/core/lib/transport/pid_controller.h", + "src/core/lib/transport/static_metadata.cc", + "src/core/lib/transport/static_metadata.h", + "src/core/lib/transport/status_conversion.cc", + "src/core/lib/transport/status_conversion.h", + "src/core/lib/transport/status_metadata.cc", + "src/core/lib/transport/status_metadata.h", + "src/core/lib/transport/timeout_encoding.cc", + "src/core/lib/transport/timeout_encoding.h", + "src/core/lib/transport/transport.cc", + "src/core/lib/transport/transport.h", + "src/core/lib/transport/transport_impl.h", + "src/core/lib/transport/transport_op_string.cc", + "src/core/lib/uri/uri_parser.cc", + "src/core/lib/uri/uri_parser.h", + "src/core/plugin_registry/grpc_plugin_registry.cc", + "src/core/tsi/alts/crypt/aes_gcm.cc", + "src/core/tsi/alts/crypt/gsec.cc", + "src/core/tsi/alts/crypt/gsec.h", + "src/core/tsi/alts/frame_protector/alts_counter.cc", + "src/core/tsi/alts/frame_protector/alts_counter.h", + "src/core/tsi/alts/frame_protector/alts_crypter.cc", + "src/core/tsi/alts/frame_protector/alts_crypter.h", + "src/core/tsi/alts/frame_protector/alts_frame_protector.cc", + "src/core/tsi/alts/frame_protector/alts_frame_protector.h", + "src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.cc", + "src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.h", + "src/core/tsi/alts/frame_protector/alts_seal_privacy_integrity_crypter.cc", + "src/core/tsi/alts/frame_protector/alts_unseal_privacy_integrity_crypter.cc", + "src/core/tsi/alts/frame_protector/frame_handler.cc", + "src/core/tsi/alts/frame_protector/frame_handler.h", + "src/core/tsi/alts/handshaker/alts_handshaker_client.cc", + "src/core/tsi/alts/handshaker/alts_handshaker_client.h", + "src/core/tsi/alts/handshaker/alts_shared_resource.cc", + "src/core/tsi/alts/handshaker/alts_shared_resource.h", + "src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc", + "src/core/tsi/alts/handshaker/alts_tsi_handshaker.h", + "src/core/tsi/alts/handshaker/alts_tsi_handshaker_private.h", + "src/core/tsi/alts/handshaker/alts_tsi_utils.cc", + "src/core/tsi/alts/handshaker/alts_tsi_utils.h", + "src/core/tsi/alts/handshaker/transport_security_common_api.cc", + "src/core/tsi/alts/handshaker/transport_security_common_api.h", + "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc", + "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h", + "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc", + "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.h", + "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol.h", + "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.cc", + "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.h", + "src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.cc", + "src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.h", + "src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc", + "src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h", + "src/core/tsi/fake_transport_security.cc", + "src/core/tsi/fake_transport_security.h", + "src/core/tsi/local_transport_security.cc", + "src/core/tsi/local_transport_security.h", + "src/core/tsi/ssl/session_cache/ssl_session.h", + "src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc", + "src/core/tsi/ssl/session_cache/ssl_session_cache.cc", + "src/core/tsi/ssl/session_cache/ssl_session_cache.h", + "src/core/tsi/ssl/session_cache/ssl_session_openssl.cc", + "src/core/tsi/ssl_transport_security.cc", + "src/core/tsi/ssl_transport_security.h", + "src/core/tsi/ssl_types.h", + "src/core/tsi/transport_security.cc", + "src/core/tsi/transport_security.h", + "src/core/tsi/transport_security_grpc.cc", + "src/core/tsi/transport_security_grpc.h", + "src/core/tsi/transport_security_interface.h", + "third_party/xxhash/xxhash.h", + ] + deps = [ + "//third_party/zlib", + ":absl/container:flat_hash_map", + ":absl/container:inlined_vector", + ":absl/functional:bind_front", + ":absl/status:statusor", + ":gpr", + "//third_party/boringssl", + ":address_sorting", + "//third_party/cares", + ":address_sorting", + ] + + public_configs = [ + ":grpc_config", + ] + include_dirs = [ + "third_party/cares", + "third_party/address_sorting/include", + ] + } + + + + source_set("grpc++") { + sources = [ + "include/grpc++/alarm.h", + "include/grpc++/channel.h", + "include/grpc++/client_context.h", + "include/grpc++/completion_queue.h", + "include/grpc++/create_channel.h", + "include/grpc++/create_channel_posix.h", + "include/grpc++/ext/health_check_service_server_builder_option.h", + "include/grpc++/generic/async_generic_service.h", + "include/grpc++/generic/generic_stub.h", + "include/grpc++/grpc++.h", + "include/grpc++/health_check_service_interface.h", + "include/grpc++/impl/call.h", + "include/grpc++/impl/channel_argument_option.h", + "include/grpc++/impl/client_unary_call.h", + "include/grpc++/impl/codegen/async_stream.h", + "include/grpc++/impl/codegen/async_unary_call.h", + "include/grpc++/impl/codegen/byte_buffer.h", + "include/grpc++/impl/codegen/call.h", + "include/grpc++/impl/codegen/call_hook.h", + "include/grpc++/impl/codegen/channel_interface.h", + "include/grpc++/impl/codegen/client_context.h", + "include/grpc++/impl/codegen/client_unary_call.h", + "include/grpc++/impl/codegen/completion_queue.h", + "include/grpc++/impl/codegen/completion_queue_tag.h", + "include/grpc++/impl/codegen/config.h", + "include/grpc++/impl/codegen/config_protobuf.h", + "include/grpc++/impl/codegen/core_codegen.h", + "include/grpc++/impl/codegen/core_codegen_interface.h", + "include/grpc++/impl/codegen/create_auth_context.h", + "include/grpc++/impl/codegen/grpc_library.h", + "include/grpc++/impl/codegen/metadata_map.h", + "include/grpc++/impl/codegen/method_handler_impl.h", + "include/grpc++/impl/codegen/proto_utils.h", + "include/grpc++/impl/codegen/rpc_method.h", + "include/grpc++/impl/codegen/rpc_service_method.h", + "include/grpc++/impl/codegen/security/auth_context.h", + "include/grpc++/impl/codegen/serialization_traits.h", + "include/grpc++/impl/codegen/server_context.h", + "include/grpc++/impl/codegen/server_interface.h", + "include/grpc++/impl/codegen/service_type.h", + "include/grpc++/impl/codegen/slice.h", + "include/grpc++/impl/codegen/status.h", + "include/grpc++/impl/codegen/status_code_enum.h", + "include/grpc++/impl/codegen/string_ref.h", + "include/grpc++/impl/codegen/stub_options.h", + "include/grpc++/impl/codegen/sync_stream.h", + "include/grpc++/impl/codegen/time.h", + "include/grpc++/impl/grpc_library.h", + "include/grpc++/impl/method_handler_impl.h", + "include/grpc++/impl/rpc_method.h", + "include/grpc++/impl/rpc_service_method.h", + "include/grpc++/impl/serialization_traits.h", + "include/grpc++/impl/server_builder_option.h", + "include/grpc++/impl/server_builder_plugin.h", + "include/grpc++/impl/server_initializer.h", + "include/grpc++/impl/service_type.h", + "include/grpc++/resource_quota.h", + "include/grpc++/security/auth_context.h", + "include/grpc++/security/auth_metadata_processor.h", + "include/grpc++/security/credentials.h", + "include/grpc++/security/server_credentials.h", + "include/grpc++/server.h", + "include/grpc++/server_builder.h", + "include/grpc++/server_context.h", + "include/grpc++/server_posix.h", + "include/grpc++/support/async_stream.h", + "include/grpc++/support/async_unary_call.h", + "include/grpc++/support/byte_buffer.h", + "include/grpc++/support/channel_arguments.h", + "include/grpc++/support/config.h", + "include/grpc++/support/slice.h", + "include/grpc++/support/status.h", + "include/grpc++/support/status_code_enum.h", + "include/grpc++/support/string_ref.h", + "include/grpc++/support/stub_options.h", + "include/grpc++/support/sync_stream.h", + "include/grpc++/support/time.h", + "include/grpcpp/alarm.h", + "include/grpcpp/channel.h", + "include/grpcpp/client_context.h", + "include/grpcpp/completion_queue.h", + "include/grpcpp/create_channel.h", + "include/grpcpp/create_channel_posix.h", + "include/grpcpp/ext/health_check_service_server_builder_option.h", + "include/grpcpp/generic/async_generic_service.h", + "include/grpcpp/generic/generic_stub.h", + "include/grpcpp/grpcpp.h", + "include/grpcpp/health_check_service_interface.h", + "include/grpcpp/impl/call.h", + "include/grpcpp/impl/channel_argument_option.h", + "include/grpcpp/impl/client_unary_call.h", + "include/grpcpp/impl/codegen/async_generic_service.h", + "include/grpcpp/impl/codegen/async_stream.h", + "include/grpcpp/impl/codegen/async_unary_call.h", + "include/grpcpp/impl/codegen/byte_buffer.h", + "include/grpcpp/impl/codegen/call.h", + "include/grpcpp/impl/codegen/call_hook.h", + "include/grpcpp/impl/codegen/call_op_set.h", + "include/grpcpp/impl/codegen/call_op_set_interface.h", + "include/grpcpp/impl/codegen/callback_common.h", + "include/grpcpp/impl/codegen/channel_interface.h", + "include/grpcpp/impl/codegen/client_callback.h", + "include/grpcpp/impl/codegen/client_context.h", + "include/grpcpp/impl/codegen/client_interceptor.h", + "include/grpcpp/impl/codegen/client_unary_call.h", + "include/grpcpp/impl/codegen/completion_queue.h", + "include/grpcpp/impl/codegen/completion_queue_tag.h", + "include/grpcpp/impl/codegen/config.h", + "include/grpcpp/impl/codegen/config_protobuf.h", + "include/grpcpp/impl/codegen/core_codegen.h", + "include/grpcpp/impl/codegen/core_codegen_interface.h", + "include/grpcpp/impl/codegen/create_auth_context.h", + "include/grpcpp/impl/codegen/delegating_channel.h", + "include/grpcpp/impl/codegen/grpc_library.h", + "include/grpcpp/impl/codegen/intercepted_channel.h", + "include/grpcpp/impl/codegen/interceptor.h", + "include/grpcpp/impl/codegen/interceptor_common.h", + "include/grpcpp/impl/codegen/message_allocator.h", + "include/grpcpp/impl/codegen/metadata_map.h", + "include/grpcpp/impl/codegen/method_handler.h", + "include/grpcpp/impl/codegen/method_handler_impl.h", + "include/grpcpp/impl/codegen/proto_buffer_reader.h", + "include/grpcpp/impl/codegen/proto_buffer_writer.h", + "include/grpcpp/impl/codegen/proto_utils.h", + "include/grpcpp/impl/codegen/rpc_method.h", + "include/grpcpp/impl/codegen/rpc_service_method.h", + "include/grpcpp/impl/codegen/security/auth_context.h", + "include/grpcpp/impl/codegen/serialization_traits.h", + "include/grpcpp/impl/codegen/server_callback.h", + "include/grpcpp/impl/codegen/server_callback_handlers.h", + "include/grpcpp/impl/codegen/server_context.h", + "include/grpcpp/impl/codegen/server_interceptor.h", + "include/grpcpp/impl/codegen/server_interface.h", + "include/grpcpp/impl/codegen/service_type.h", + "include/grpcpp/impl/codegen/slice.h", + "include/grpcpp/impl/codegen/status.h", + "include/grpcpp/impl/codegen/status_code_enum.h", + "include/grpcpp/impl/codegen/string_ref.h", + "include/grpcpp/impl/codegen/stub_options.h", + "include/grpcpp/impl/codegen/sync.h", + "include/grpcpp/impl/codegen/sync_stream.h", + "include/grpcpp/impl/codegen/time.h", + "include/grpcpp/impl/grpc_library.h", + "include/grpcpp/impl/method_handler_impl.h", + "include/grpcpp/impl/rpc_method.h", + "include/grpcpp/impl/rpc_service_method.h", + "include/grpcpp/impl/serialization_traits.h", + "include/grpcpp/impl/server_builder_option.h", + "include/grpcpp/impl/server_builder_plugin.h", + "include/grpcpp/impl/server_initializer.h", + "include/grpcpp/impl/service_type.h", + "include/grpcpp/resource_quota.h", + "include/grpcpp/security/auth_context.h", + "include/grpcpp/security/auth_metadata_processor.h", + "include/grpcpp/security/authorization_policy_provider.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", + "include/grpcpp/server_context.h", + "include/grpcpp/server_posix.h", + "include/grpcpp/support/async_stream.h", + "include/grpcpp/support/async_unary_call.h", + "include/grpcpp/support/byte_buffer.h", + "include/grpcpp/support/channel_arguments.h", + "include/grpcpp/support/client_callback.h", + "include/grpcpp/support/client_interceptor.h", + "include/grpcpp/support/config.h", + "include/grpcpp/support/interceptor.h", + "include/grpcpp/support/message_allocator.h", + "include/grpcpp/support/method_handler.h", + "include/grpcpp/support/proto_buffer_reader.h", + "include/grpcpp/support/proto_buffer_writer.h", + "include/grpcpp/support/server_callback.h", + "include/grpcpp/support/server_interceptor.h", + "include/grpcpp/support/slice.h", + "include/grpcpp/support/status.h", + "include/grpcpp/support/status_code_enum.h", + "include/grpcpp/support/string_ref.h", + "include/grpcpp/support/stub_options.h", + "include/grpcpp/support/sync_stream.h", + "include/grpcpp/support/time.h", + "include/grpcpp/support/validate_service_config.h", + "include/grpcpp/xds_server_builder.h", + "src/cpp/client/channel_cc.cc", + "src/cpp/client/client_callback.cc", + "src/cpp/client/client_context.cc", + "src/cpp/client/client_interceptor.cc", + "src/cpp/client/create_channel.cc", + "src/cpp/client/create_channel_internal.cc", + "src/cpp/client/create_channel_internal.h", + "src/cpp/client/create_channel_posix.cc", + "src/cpp/client/credentials_cc.cc", + "src/cpp/client/insecure_credentials.cc", + "src/cpp/client/secure_credentials.cc", + "src/cpp/client/secure_credentials.h", + "src/cpp/client/xds_credentials.cc", + "src/cpp/codegen/codegen_init.cc", + "src/cpp/common/alarm.cc", + "src/cpp/common/auth_property_iterator.cc", + "src/cpp/common/channel_arguments.cc", + "src/cpp/common/channel_filter.cc", + "src/cpp/common/channel_filter.h", + "src/cpp/common/completion_queue_cc.cc", + "src/cpp/common/core_codegen.cc", + "src/cpp/common/resource_quota_cc.cc", + "src/cpp/common/rpc_method.cc", + "src/cpp/common/secure_auth_context.cc", + "src/cpp/common/secure_auth_context.h", + "src/cpp/common/secure_channel_arguments.cc", + "src/cpp/common/secure_create_auth_context.cc", + "src/cpp/common/tls_certificate_provider.cc", + "src/cpp/common/tls_certificate_verifier.cc", + "src/cpp/common/tls_credentials_options.cc", + "src/cpp/common/validate_service_config.cc", + "src/cpp/common/version_cc.cc", + "src/cpp/server/async_generic_service.cc", + "src/cpp/server/channel_argument_option.cc", + "src/cpp/server/create_default_thread_pool.cc", + "src/cpp/server/dynamic_thread_pool.cc", + "src/cpp/server/dynamic_thread_pool.h", + "src/cpp/server/external_connection_acceptor_impl.cc", + "src/cpp/server/external_connection_acceptor_impl.h", + "src/cpp/server/health/default_health_check_service.cc", + "src/cpp/server/health/default_health_check_service.h", + "src/cpp/server/health/health_check_service.cc", + "src/cpp/server/health/health_check_service_server_builder_option.cc", + "src/cpp/server/insecure_server_credentials.cc", + "src/cpp/server/secure_server_credentials.cc", + "src/cpp/server/secure_server_credentials.h", + "src/cpp/server/server_builder.cc", + "src/cpp/server/server_callback.cc", + "src/cpp/server/server_cc.cc", + "src/cpp/server/server_context.cc", + "src/cpp/server/server_credentials.cc", + "src/cpp/server/server_posix.cc", + "src/cpp/server/thread_pool_interface.h", + "src/cpp/server/xds_server_credentials.cc", + "src/cpp/thread_manager/thread_manager.cc", + "src/cpp/thread_manager/thread_manager.h", + "src/cpp/util/byte_buffer_cc.cc", + "src/cpp/util/status.cc", + "src/cpp/util/string_ref.cc", + "src/cpp/util/time_cc.cc", + ] + deps = [ + "//third_party/protobuf:protobuf_lite", + ":grpc", + ] + + public_configs = [ + ":grpc_config", + ] + } + + # Only compile the plugin for the host architecture. + if (current_toolchain == host_toolchain) { + + + source_set("grpc_plugin_support") { + sources = [ + "include/grpc++/impl/codegen/config_protobuf.h", + "include/grpcpp/impl/codegen/config_protobuf.h", + "src/compiler/config.h", + "src/compiler/config_protobuf.h", + "src/compiler/cpp_generator.cc", + "src/compiler/cpp_generator.h", + "src/compiler/cpp_generator_helpers.h", + "src/compiler/cpp_plugin.h", + "src/compiler/csharp_generator.cc", + "src/compiler/csharp_generator.h", + "src/compiler/csharp_generator_helpers.h", + "src/compiler/generator_helpers.h", + "src/compiler/node_generator.cc", + "src/compiler/node_generator.h", + "src/compiler/node_generator_helpers.h", + "src/compiler/objective_c_generator.cc", + "src/compiler/objective_c_generator.h", + "src/compiler/objective_c_generator_helpers.h", + "src/compiler/php_generator.cc", + "src/compiler/php_generator.h", + "src/compiler/php_generator_helpers.h", + "src/compiler/protobuf_plugin.h", + "src/compiler/python_generator.cc", + "src/compiler/python_generator.h", + "src/compiler/python_generator_helpers.h", + "src/compiler/python_private_generator.h", + "src/compiler/schema_interface.h", + ] + deps = [ + "//third_party/protobuf:protoc_lib", + ] + + public_configs = [ + ":grpc_config", + ] + } + + } + # Only compile the plugin for the host architecture. + if (current_toolchain == host_toolchain) { + + executable("grpc_cpp_plugin") { + sources = [ + "src/compiler/cpp_plugin.cc", + ] + deps = [ + "//third_party/protobuf:protoc_lib", + ":grpc_plugin_support", + ] + + configs += [ + "//third_party/protobuf:protobuf_config", + ] + public_configs = [ ":grpc_config" ] + } + + } + + diff --git a/CMakeLists.txt b/CMakeLists.txt index 350ed0b80bf..180dd9077c9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 ) diff --git a/Makefile b/Makefile index 9354d865335..f3b7fee7bbe 100644 --- a/Makefile +++ b/Makefile @@ -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) diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml index 811a6a32b16..ed957d3bcde 100644 --- a/build_autogenerated.yaml +++ b/build_autogenerated.yaml @@ -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 diff --git a/config.m4 b/config.m4 index 5b84c2af076..f1a5816f3fe 100644 --- a/config.m4 +++ b/config.m4 @@ -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 \ diff --git a/config.w32 b/config.w32 index 07a44ffa314..25b8bcbcf26 100644 --- a/config.w32 +++ b/config.w32 @@ -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 " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 53f6bc7f4cc..260efc2bdf4 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -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', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 0f86f039f72..307c5b8bfcc 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -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', diff --git a/grpc.def b/grpc.def index 8c5d3d17407..caba5e2aab8 100644 --- a/grpc.def +++ b/grpc.def @@ -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 diff --git a/grpc.gemspec b/grpc.gemspec index fe9f1fe072e..c505b8210b7 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -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 ) diff --git a/grpc.gyp b/grpc.gyp index 5d51585ab81..b1d8979c971 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -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', diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h index 2902100f1cb..48f5afe08cf 100644 --- a/include/grpc/grpc_security.h +++ b/include/grpc/grpc_security.h @@ -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); diff --git a/include/grpc/grpc_security_constants.h b/include/grpc/grpc_security_constants.h index 1c3cbc712df..8b071817e6e 100644 --- a/include/grpc/grpc_security_constants.h +++ b/include/grpc/grpc_security_constants.h @@ -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. diff --git a/include/grpcpp/security/tls_certificate_verifier.h b/include/grpcpp/security/tls_certificate_verifier.h new file mode 100644 index 00000000000..0c678c3ba0a --- /dev/null +++ b/include/grpcpp/security/tls_certificate_verifier.h @@ -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 +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +// TODO(yihuazhang): remove the forward declaration here and include +// 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 uri_names() const; + std::vector dns_names() const; + std::vector email_names() const; + std::vector 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 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> + 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 + static std::shared_ptr Create(Args&&... args) { + grpc::internal::GrpcLibraryInitializer g_gli_initializer; + g_gli_initializer.summon(); + auto* external_verifier = new Subclass(std::forward(args)...); + return std::make_shared( + 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 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 + request_map_ ABSL_GUARDED_BY(mu_); +}; + +class HostNameCertificateVerifier : public CertificateVerifier { + public: + HostNameCertificateVerifier(); +}; + +} // namespace experimental +} // namespace grpc + +#endif // GRPCPP_SECURITY_TLS_CERTIFICATE_VERIFIER_H diff --git a/include/grpcpp/security/tls_credentials_options.h b/include/grpcpp/security/tls_credentials_options.h index fb861a50ae4..1bb56232583 100644 --- a/include/grpcpp/security/tls_credentials_options.h +++ b/include/grpcpp/security/tls_credentials_options.h @@ -26,6 +26,7 @@ #include #include #include +#include #include // 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 - 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 - 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 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 certificate_provider_; + std::shared_ptr 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 - 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: }; diff --git a/package.xml b/package.xml index f97b0f2b7a1..c2077068cb4 100644 --- a/package.xml +++ b/package.xml @@ -1104,6 +1104,8 @@ + + diff --git a/src/core/lib/security/credentials/tls/grpc_tls_certificate_verifier.cc b/src/core/lib/security/credentials/tls/grpc_tls_certificate_verifier.cc new file mode 100644 index 00000000000..7ffd3ff9160 --- /dev/null +++ b/src/core/lib/security/credentials/tls/grpc_tls_certificate_verifier.cc @@ -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 + +#include "src/core/lib/security/credentials/tls/grpc_tls_certificate_verifier.h" + +#include +#include +#include + +#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 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(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(callback_arg); + std::function 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(status), error_details); + } + callback(return_status); + } +} + +bool HostNameCertificateVerifier::Verify( + grpc_tls_custom_verification_check_request* request, + std::function, 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 async_cb = + [callback, request, callback_arg](absl::Status async_status) { + callback(request, callback_arg, + static_cast(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(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(); +} diff --git a/src/core/lib/security/credentials/tls/grpc_tls_certificate_verifier.h b/src/core/lib/security/credentials/tls/grpc_tls_certificate_verifier.h new file mode 100644 index 00000000000..9e89268fec9 --- /dev/null +++ b/src/core/lib/security/credentials/tls/grpc_tls_certificate_verifier.h @@ -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 + +#include + +#include "absl/status/status.h" + +#include + +#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 { + 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 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 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> + 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 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 diff --git a/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc b/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc index bf26e707e33..8042cf26686 100644 --- a/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc +++ b/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc @@ -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(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(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(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); } diff --git a/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h b/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h index c3953910c56..edaac0e438c 100644 --- a/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h +++ b/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h @@ -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 { - 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 { - 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 - config) { - server_authorization_check_config_ = std::move(config); + // Sets the verifier in the options. + void set_certificate_verifier( + grpc_core::RefCountedPtr 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 - server_authorization_check_config_; + grpc_core::RefCountedPtr verifier_; + bool check_call_host_ = true; grpc_core::RefCountedPtr provider_; bool watch_root_cert_ = false; std::string root_cert_name_; diff --git a/src/core/lib/security/credentials/tls/tls_credentials.cc b/src/core/lib/security/credentials/tls/tls_credentials.cc index f5b05d8a012..60e60d521c7 100644 --- a/src/core/lib/security/credentials/tls/tls_credentials.cc +++ b/src/core/lib/security/credentials/tls/tls_credentials.cc @@ -28,29 +28,40 @@ #include #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()); } return true; } diff --git a/src/core/lib/security/credentials/xds/xds_credentials.cc b/src/core/lib/security/credentials/xds/xds_credentials.cc index 15b8e900fcb..1026d30a0d6 100644 --- a/src/core/lib/security/credentials/xds/xds_credentials.cc +++ b/src/core/lib/security/credentials/xds/xds_credentials.cc @@ -61,41 +61,39 @@ bool XdsVerifySubjectAlternativeNames( return false; } -class ServerAuthCheck { +class XdsCertificateVerifier : public grpc_tls_certificate_verifier { public: - ServerAuthCheck( + XdsCertificateVerifier( RefCountedPtr 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(config_user_data)->ScheduleImpl(arg); - } - - static void Destroy(void* config_user_data) { - delete static_cast(config_user_data); + bool Verify(grpc_tls_custom_verification_check_request* request, + std::function, + 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 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( - server_auth_check, ServerAuthCheck::Schedule, nullptr, - ServerAuthCheck::Destroy)); + tls_credentials_options->set_verify_server_cert(true); + tls_credentials_options->set_certificate_verifier( + MakeRefCounted(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 diff --git a/src/core/lib/security/security_connector/ssl_utils.cc b/src/core/lib/security/security_connector/ssl_utils.cc index 4fe689de4ac..81972c2b085 100644 --- a/src/core/lib/security/security_connector/ssl_utils.cc +++ b/src/core/lib/security/security_connector/ssl_utils.cc @@ -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; diff --git a/src/core/lib/security/security_connector/tls/tls_security_connector.cc b/src/core/lib/security/security_connector/tls/tls_security_connector.cc index 760c610af7d..2f7dd7de870 100644 --- a/src/core/lib/security/security_connector/tls/tls_security_connector.cc +++ b/src/core/lib/security/security_connector/tls/tls_security_connector.cc @@ -23,6 +23,7 @@ #include #include +#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(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 uri_names; + std::vector dns_names; + std::vector email_names; + std::vector 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(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(request->peer_info.peer_cert)); + } + if (request->peer_info.peer_cert_full_chain != nullptr) { + gpr_free(const_cast(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(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(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 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(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 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(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(arg->target_name)); - gpr_free(const_cast(arg->peer_cert)); - gpr_free(const_cast(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 TlsServerSecurityConnector::CreateTlsServerSecurityConnector( @@ -559,16 +626,63 @@ void TlsServerSecurityConnector::check_peer( RefCountedPtr* 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(other)); + const grpc_security_connector* other_sc) const { + auto* other = reinterpret_cast(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 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 diff --git a/src/core/lib/security/security_connector/tls/tls_security_connector.h b/src/core/lib/security/security_connector/tls/tls_security_connector.h index 67ff420d32f..e286c4a4717 100644 --- a/src/core/lib/security/security_connector/tls/tls_security_connector.h +++ b/src/core/lib/security/security_connector/tls/tls_security_connector.h @@ -21,6 +21,8 @@ #include +#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* 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 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 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 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 pem_root_certs_ ABSL_GUARDED_BY(mu_); absl::optional pem_key_cert_pair_list_ ABSL_GUARDED_BY(mu_); + std::map + 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 root_certs, absl::optional 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 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 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 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 pem_root_certs_ ABSL_GUARDED_BY(mu_); absl::optional pem_key_cert_pair_list_ ABSL_GUARDED_BY(mu_); + std::map + 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 diff --git a/src/cpp/common/tls_certificate_verifier.cc b/src/cpp/common/tls_certificate_verifier.cc new file mode 100644 index 00000000000..9be5e127c25 --- /dev/null +++ b/src/cpp/common/tls_certificate_verifier.cc @@ -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 +#include +#include +#include + +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 TlsCustomVerificationCheckRequest::uri_names() + const { + std::vector 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 TlsCustomVerificationCheckRequest::dns_names() + const { + std::vector 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 TlsCustomVerificationCheckRequest::email_names() + const { + std::vector 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 TlsCustomVerificationCheckRequest::ip_names() + const { + std::vector 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 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(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(callback_arg); + std::function 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(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(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(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( + 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(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(user_data); + delete self; +} + +HostNameCertificateVerifier::HostNameCertificateVerifier() + : CertificateVerifier(grpc_tls_certificate_verifier_host_name_create()) {} + +} // namespace experimental +} // namespace grpc diff --git a/src/cpp/common/tls_credentials_options.cc b/src/cpp/common/tls_credentials_options.cc index 8e672308f8e..49b4275abc3 100644 --- a/src/cpp/common/tls_credentials_options.cc +++ b/src/cpp/common/tls_credentials_options.cc @@ -22,109 +22,9 @@ #include #include -#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(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 - 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(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 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 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( diff --git a/src/cpp/common/tls_credentials_options_util.cc b/src/cpp/common/tls_credentials_options_util.cc deleted file mode 100644 index ebcab262402..00000000000 --- a/src/cpp/common/tls_credentials_options_util.cc +++ /dev/null @@ -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 - -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(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(arg->config->context()); - TlsServerAuthorizationCheckArg* cpp_arg = - static_cast(arg->context); - cpp_config->Cancel(cpp_arg); -} - -void TlsServerAuthorizationCheckArgDestroyContext(void* context) { - if (context != nullptr) { - TlsServerAuthorizationCheckArg* cpp_arg = - static_cast(context); - delete cpp_arg; - } -} - -} // namespace experimental -} // namespace grpc diff --git a/src/cpp/common/tls_credentials_options_util.h b/src/cpp/common/tls_credentials_options_util.h deleted file mode 100644 index d6247219fb7..00000000000 --- a/src/cpp/common/tls_credentials_options_util.h +++ /dev/null @@ -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 -#include - -#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 diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index f25961fea9c..d953bf982b5 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -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', diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c index 874a5e9e9f7..7558727a68c 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c @@ -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"); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index 4667bce7a43..a9535823f87 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -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 diff --git a/test/core/end2end/fixtures/h2_tls.cc b/test/core/end2end/fixtures/h2_tls.cc index 2254e1cfd6d..11f1a3b0aa3 100644 --- a/test/core/end2end/fixtures/h2_tls.cc +++ b/test/core/end2end/fixtures/h2_tls.cc @@ -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 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(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(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) { diff --git a/test/core/security/BUILD b/test/core/security/BUILD index 05659fb0f47..8e85204af28 100644 --- a/test/core/security/BUILD +++ b/test/core/security/BUILD @@ -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"], diff --git a/test/core/security/grpc_tls_certificate_verifier_test.cc b/test/core/security/grpc_tls_certificate_verifier_test.cc new file mode 100644 index 00000000000..73428b9f870 --- /dev/null +++ b/test/core/security/grpc_tls_certificate_verifier_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 +#include + +#include +#include + +#include +#include +#include + +#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(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(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("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("*.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("*.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("*.")}; + 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("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("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("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; +} diff --git a/test/core/security/grpc_tls_credentials_options_test.cc b/test/core/security/grpc_tls_credentials_options_test.cc index 761effd9700..363c450fc93 100644 --- a/test/core/security/grpc_tls_credentials_options_test.cc +++ b/test/core/security/grpc_tls_credentials_options_test.cc @@ -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(); - options->set_server_verification_option(GRPC_TLS_SERVER_VERIFICATION); auto credentials = MakeRefCounted(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(); @@ -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(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(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(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(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(); @@ -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(options); ASSERT_NE(credentials, nullptr); grpc_channel_args* new_args = nullptr; @@ -259,7 +257,6 @@ TEST_F(GrpcTlsCredentialsOptionsTest, MakeRefCounted("", "", 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(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(options); ASSERT_NE(credentials, nullptr); grpc_channel_args* new_args = nullptr; @@ -301,7 +297,6 @@ TEST_F(GrpcTlsCredentialsOptionsTest, MakeRefCounted("", "", 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(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(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(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(); + options->set_verify_server_cert(true); + options->set_certificate_verifier(core_external_verifier.Ref()); + options->set_check_call_host(false); + auto credentials = MakeRefCounted(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(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(); + 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( + root_cert_, PemKeyCertPairList()); + options->set_certificate_provider(std::move(provider)); + options->set_watch_identity_pair(true); + auto credentials = MakeRefCounted(options); + ASSERT_NE(credentials, nullptr); + auto connector = credentials->create_security_connector(nullptr); + ASSERT_NE(connector, nullptr); + TlsServerSecurityConnector* tls_connector = + static_cast(connector.get()); + EXPECT_NE(tls_connector, nullptr); +} + +// +// Tests for HostnameCertificateVerifier. +// + +TEST_F(GrpcTlsCredentialsOptionsTest, + ClientOptionsWithHostnameCertificateVerifier) { + auto options = MakeRefCounted(); + options->set_verify_server_cert(true); + options->set_certificate_verifier(hostname_certificate_verifier_.Ref()); + auto credentials = MakeRefCounted(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(connector.get()); + EXPECT_NE(tls_connector->ClientHandshakerFactoryForTesting(), nullptr); +} + +TEST_F(GrpcTlsCredentialsOptionsTest, + ServerOptionsWithHostnameCertificateVerifier) { + auto options = MakeRefCounted(); + 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( + root_cert_, PemKeyCertPairList()); + options->set_certificate_provider(std::move(provider)); + options->set_watch_identity_pair(true); + auto credentials = MakeRefCounted(options); + ASSERT_NE(credentials, nullptr); + auto connector = credentials->create_security_connector(nullptr); + ASSERT_NE(connector, nullptr); + TlsServerSecurityConnector* tls_connector = + static_cast(connector.get()); + EXPECT_EQ(tls_connector->ServerHandshakerFactoryForTesting(), nullptr); +} + } // namespace testing } // namespace grpc_core diff --git a/test/core/security/tls_security_connector_test.cc b/test/core/security/tls_security_connector_test.cc index ef09559f1fe..2b1cc410ded 100644 --- a/test/core/security/tls_security_connector_test.cc +++ b/test/core/security/tls_security_connector_test.cc @@ -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(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 distributor_; }; -// Tests for ChannelSecurityConnector. +// +// Tests for Certificate Providers in ChannelSecurityConnector. +// + TEST_F(TlsSecurityConnectorTest, RootAndIdentityCertsObtainedWhenCreateChannelSecurityConnector) { grpc_core::RefCountedPtr 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 options = + grpc_core::MakeRefCounted(); + options->set_verify_server_cert(true); + options->set_certificate_verifier(core_external_verifier.Ref()); + options->set_check_call_host(false); + grpc_core::RefCountedPtr credential = + grpc_core::MakeRefCounted(options); + grpc_channel_args* new_args = nullptr; + grpc_core::RefCountedPtr connector = + credential->create_security_connector(nullptr, kTargetName, nullptr, + &new_args); + EXPECT_NE(connector, nullptr); + grpc_core::TlsChannelSecurityConnector* tls_connector = + static_cast(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 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 options = + grpc_core::MakeRefCounted(); + options->set_verify_server_cert(true); + options->set_certificate_verifier(core_external_verifier.Ref()); + options->set_check_call_host(false); + grpc_core::RefCountedPtr credential = + grpc_core::MakeRefCounted(options); + grpc_channel_args* new_args = nullptr; + grpc_core::RefCountedPtr connector = + credential->create_security_connector(nullptr, kTargetName, nullptr, + &new_args); + EXPECT_NE(connector, nullptr); + grpc_core::TlsChannelSecurityConnector* tls_connector = + static_cast(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 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(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(); + options->set_verify_server_cert(true); + options->set_certificate_verifier(core_external_verifier->Ref()); + options->set_check_call_host(false); + grpc_core::RefCountedPtr credential = + grpc_core::MakeRefCounted(options); + grpc_channel_args* new_args = nullptr; + grpc_core::RefCountedPtr connector = + credential->create_security_connector(nullptr, kTargetName, nullptr, + &new_args); + EXPECT_NE(connector, nullptr); + grpc_core::TlsChannelSecurityConnector* tls_connector = + static_cast(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 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(); + options->set_verify_server_cert(true); + options->set_certificate_verifier(core_external_verifier->Ref()); + options->set_check_call_host(false); + grpc_core::RefCountedPtr credential = + grpc_core::MakeRefCounted(options); + grpc_channel_args* new_args = nullptr; + grpc_core::RefCountedPtr connector = + credential->create_security_connector(nullptr, kTargetName, nullptr, + &new_args); + EXPECT_NE(connector, nullptr); + grpc_core::TlsChannelSecurityConnector* tls_connector = + static_cast(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 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(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 options = + grpc_core::MakeRefCounted(); + options->set_verify_server_cert(true); + options->set_certificate_verifier(hostname_certificate_verifier_.Ref()); + options->set_check_call_host(false); + grpc_core::RefCountedPtr credential = + grpc_core::MakeRefCounted(options); + grpc_channel_args* new_args = nullptr; + grpc_core::RefCountedPtr connector = + credential->create_security_connector(nullptr, kTargetName, nullptr, + &new_args); + EXPECT_NE(connector, nullptr); + grpc_core::TlsChannelSecurityConnector* tls_connector = + static_cast(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 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 options = + grpc_core::MakeRefCounted(); + options->set_verify_server_cert(true); + options->set_certificate_verifier(hostname_certificate_verifier_.Ref()); + grpc_core::RefCountedPtr credential = + grpc_core::MakeRefCounted(options); + grpc_channel_args* new_args = nullptr; + grpc_core::RefCountedPtr connector = + credential->create_security_connector(nullptr, kTargetName, nullptr, + &new_args); + EXPECT_NE(connector, nullptr); + grpc_core::TlsChannelSecurityConnector* tls_connector = + static_cast(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 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(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 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 options = + grpc_core::MakeRefCounted(); + 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::PemKeyCertPairList()); + options->set_certificate_provider(std::move(provider)); + options->set_watch_identity_pair(true); + auto credentials = grpc_core::MakeRefCounted(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 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 options = + grpc_core::MakeRefCounted(); + 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::PemKeyCertPairList()); + options->set_certificate_provider(std::move(provider)); + options->set_watch_identity_pair(true); + auto credentials = grpc_core::MakeRefCounted(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 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(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(); + 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::PemKeyCertPairList()); + options->set_certificate_provider(std::move(provider)); + options->set_watch_identity_pair(true); + auto credentials = grpc_core::MakeRefCounted(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 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 options = + grpc_core::MakeRefCounted(); + 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::PemKeyCertPairList()); + options->set_certificate_provider(std::move(provider)); + options->set_watch_identity_pair(true); + auto credentials = grpc_core::MakeRefCounted(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 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(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); diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c index 209264fa56c..e4ab05b19b0 100644 --- a/test/core/surface/public_headers_must_be_c89.c +++ b/test/core/surface/public_headers_must_be_c89.c @@ -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); diff --git a/test/core/util/tls_utils.cc b/test/core/util/tls_utils.cc index e70cdcf1c9c..6c9052cc46a 100644 --- a/test/core/util/tls_utils.cc +++ b/test/core/util/tls_utils.cc @@ -16,6 +16,8 @@ #include "test/core/util/tls_utils.h" +#include + #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(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(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(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(arg); + delete verifier; +} + +} // namespace + +void AsyncExternalVerifier::Destruct(void* user_data) { + auto* self = static_cast(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(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 diff --git a/test/core/util/tls_utils.h b/test/core/util/tls_utils.h index 44687137f4b..b87ad74c03d 100644 --- a/test/core/util/tls_utils.h +++ b/test/core/util/tls_utils.h @@ -14,7 +14,11 @@ // limitations under the License. // +#include + +#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 queue_ ABSL_GUARDED_BY(mu_); +}; + } // namespace testing } // namespace grpc_core diff --git a/test/cpp/client/BUILD b/test/cpp/client/BUILD index 9e443233d14..8aa026362bb 100644 --- a/test/cpp/client/BUILD +++ b/test/cpp/client/BUILD @@ -34,6 +34,7 @@ grpc_cc_test( "//:grpc", "//:grpc++", "//test/core/util:grpc_test_util", + "//test/cpp/util:tls_test_utils", ], ) diff --git a/test/cpp/client/credentials_test.cc b/test/cpp/client/credentials_test.cc index cc140da29e7..0699cb2e589 100644 --- a/test/cpp/client/credentials_test.cc +++ b/test/cpp/client/credentials_test.cc @@ -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(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(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(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(target_name_before_callback)); - gpr_free(const_cast(peer_cert_before_callback)); - gpr_free(const_cast(c_arg->target_name)); - gpr_free(const_cast(c_arg->peer_cert)); - delete c_arg->error_details; - delete arg; - delete c_arg; -} - -TEST(CredentialsTest, TlsServerAuthorizationCheckConfigSchedule) { - std::shared_ptr - 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(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(target_name_before_schedule)); - gpr_free(const_cast(peer_cert_before_schedule)); - gpr_free(const_cast(c_arg->target_name)); - gpr_free(const_cast(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 - 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(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(c_arg.target_name)); - gpr_free(const_cast(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(); - auto server_authorization_check_config = - std::make_shared( - 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( kRootCertContents, identity_key_cert_pairs); - auto test_server_authorization_check = - std::make_shared(); - auto server_authorization_check_config = - std::make_shared( - 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(kRootCertContents); - auto test_server_authorization_check = - std::make_shared(); - auto server_authorization_check_config = - std::make_shared( - 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(identity_key_cert_pairs); - auto test_server_authorization_check = - std::make_shared(); - auto server_authorization_check_config = - std::make_shared( - 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(); - auto server_authorization_check_config = - std::make_shared( - 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(); - auto server_authorization_check_config = - std::make_shared( - 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 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(); + 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(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(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 diff --git a/test/cpp/end2end/xds/BUILD b/test/cpp/end2end/xds/BUILD index 5db4b558a4c..b30451f65d7 100644 --- a/test/cpp/end2end/xds/BUILD +++ b/test/cpp/end2end/xds/BUILD @@ -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", ], ) diff --git a/test/cpp/end2end/xds/xds_end2end_test.cc b/test/cpp/end2end/xds/xds_end2end_test.cc index 5ad594edc57..7627b509bc2 100644 --- a/test/cpp/end2end/xds/xds_end2end_test.cc +++ b/test/cpp/end2end/xds/xds_end2end_test.cc @@ -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 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( - 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( - 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 identity_key_cert_pairs; + identity_key_cert_pairs.emplace_back(key_cert_pair); + auto certificate_provider = std::make_shared( + 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(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( - 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( - 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 identity_key_cert_pairs; + identity_key_cert_pairs.emplace_back(key_cert_pair); + auto certificate_provider = std::make_shared( + 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(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( - 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( - grpc_tls_credentials_create(options)); - grpc_tls_server_authorization_check_config_release(check_config); + auto certificate_provider = + std::make_shared(ReadFile(kCaCertPath)); + grpc::experimental::TlsChannelCredentialsOptions options; + options.set_certificate_provider(std::move(certificate_provider)); + options.watch_root_certs(); + auto verifier = + ExternalCertificateVerifier::Create(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); } diff --git a/test/cpp/security/BUILD b/test/cpp/security/BUILD new file mode 100644 index 00000000000..fc8cc6854f1 --- /dev/null +++ b/test/cpp/security/BUILD @@ -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", + ], +) diff --git a/test/cpp/security/tls_certificate_verifier_test.cc b/test/cpp/security/tls_certificate_verifier_test.cc new file mode 100644 index 00000000000..3049618e081 --- /dev/null +++ b/test/cpp/security/tls_certificate_verifier_test.cc @@ -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 + +#include +#include + +#include +#include +#include +#include + +#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(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(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(true); + TlsCustomVerificationCheckRequest cpp_request(&request); + std::function 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(false); + TlsCustomVerificationCheckRequest cpp_request(&request); + std::function 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(); + 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(); + 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("*.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(); + 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("*.")}; + request.peer_info.san_names.dns_names = dns_names; + request.peer_info.san_names.dns_names_size = 1; + auto verifier = std::make_shared(); + 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; +} diff --git a/test/cpp/server/BUILD b/test/cpp/server/BUILD index f8ba1246ecc..e70883a6d21 100644 --- a/test/cpp/server/BUILD +++ b/test/cpp/server/BUILD @@ -76,6 +76,7 @@ grpc_cc_test( "//:grpc", "//:grpc++", "//test/core/util:grpc_test_util", + "//test/cpp/util:tls_test_utils", ], ) diff --git a/test/cpp/server/credentials_test.cc b/test/cpp/server/credentials_test.cc index f0a6e099960..d0c8ac01f9b 100644 --- a/test/cpp/server/credentials_test.cc +++ b/test/cpp/server/credentials_test.cc @@ -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(true); + auto certificate_provider = std::make_shared( + 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(true); + auto certificate_provider = std::make_shared( + 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 diff --git a/test/cpp/util/BUILD b/test/cpp/util/BUILD index 046fbc8ea2e..61a0e095ce4 100644 --- a/test/cpp/util/BUILD +++ b/test/cpp/util/BUILD @@ -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", + ], +) diff --git a/test/cpp/util/tls_test_utils.cc b/test/cpp/util/tls_test_utils.cc new file mode 100644 index 00000000000..6bf727c8cbe --- /dev/null +++ b/test/cpp/util/tls_test_utils.cc @@ -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 + +#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, + 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 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(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 diff --git a/test/cpp/util/tls_test_utils.h b/test/cpp/util/tls_test_utils.h new file mode 100644 index 00000000000..d9dd29abd12 --- /dev/null +++ b/test/cpp/util/tls_test_utils.h @@ -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 + +#include +#include +#include + +#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 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 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 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 queue_ ABSL_GUARDED_BY(mu_); +}; + +} // namespace testing +} // namespace grpc + +#endif // GRPC_TEST_CPP_UTIL_TLS_TEST_UTILS_H diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index a16be0ab128..f786ae43075 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -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 \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 67381e8f9e5..ffc87e5c43d 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -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 \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index a0517ae5943..c4483ff4018 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -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 \ diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index d62c123f745..d0558a7da3a 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -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,