diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h index 51339291754..e85854a3c8c 100644 --- a/include/grpc/grpc_security.h +++ b/include/grpc/grpc_security.h @@ -848,8 +848,8 @@ 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 returns 1 on success and 0 on failure. - * It is used for experimental purpose for now and subject to change. + * 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, @@ -860,8 +860,7 @@ GRPCAPI void grpc_tls_credentials_options_set_cert_request_type( * hostname check, etc. This should be called only on the client side. If * |server_verification_option| is not GRPC_TLS_SERVER_VERIFICATION, use of a * custom authorization check (grpc_tls_server_authorization_check_config) is - * mandatory. It returns 1 on success and 0 on failure. It is used for - * experimental purpose for now and subject to change. + * 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, @@ -870,7 +869,6 @@ GRPCAPI void grpc_tls_credentials_options_set_server_verification_option( /** * Sets the credential provider in the options. * The |options| will implicitly take a new ref to the |provider|. - * It returns 1 on success and 0 on failure. * It is used for experimental purpose for now and subject to change. */ GRPCAPI void grpc_tls_credentials_options_set_certificate_provider( @@ -879,8 +877,14 @@ GRPCAPI void grpc_tls_credentials_options_set_certificate_provider( /** * If set, gRPC stack will keep watching the root certificates with - * name |root_cert_name|. It returns 1 on success and 0 on failure. It is used - * for experimental purpose for now and subject to change. + * name |root_cert_name|. + * If this is not set on the client side, we will use the root certificates + * stored in the default system location, since client side must provide root + * certificates in TLS. + * 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); @@ -895,8 +899,9 @@ GRPCAPI void grpc_tls_credentials_options_set_root_cert_name( /** * If set, gRPC stack will keep watching the identity key-cert pairs - * with name |identity_cert_name|. It returns 1 on success and 0 on failure. It - * is used for experimental purpose for now and subject to change. + * 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); @@ -912,8 +917,8 @@ GRPCAPI void grpc_tls_credentials_options_set_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 returns 1 on success and 0 on failure. It is used for - * experimental purpose for now and subject to change. + * |config|. + * It is used for experimental purpose for now and subject to change. */ GRPCAPI void grpc_tls_credentials_options_set_server_authorization_check_config( grpc_tls_credentials_options* options, diff --git a/include/grpcpp/security/tls_credentials_options.h b/include/grpcpp/security/tls_credentials_options.h index 6abdcaa7efe..da2b595b553 100644 --- a/include/grpcpp/security/tls_credentials_options.h +++ b/include/grpcpp/security/tls_credentials_options.h @@ -155,13 +155,21 @@ class TlsCredentialsOptions { // // @param certificate_provider the provider which fetches TLS credentials that // will be used in the TLS handshake - explicit TlsCredentialsOptions( - std::shared_ptr certificate_provider); + TlsCredentialsOptions(); // ---- Setters for member fields ---- + // Sets the certificate provider used to store root certs and identity certs. + void set_certificate_provider( + std::shared_ptr certificate_provider); // Watches the updates of root certificates with name |root_cert_name|. - // If used in TLS credentials, it should always be set unless the root - // certificates are not needed(e.g. in the one-side TLS scenario, the server - // is not required to verify the client). + // If used in TLS credentials, setting this field is optional for both the + // client side and the server side. + // If this is not set on the client side, we will use the root certificates + // stored in the default system location, since client side must provide root + // certificates in TLS(no matter single-side TLS or mutual TLS). + // 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 + // (in the one-side TLS scenario, the server is not required to provide root + // certs). We don't support default root certs on server side. void watch_root_certs(); // Sets the name of root certificates being watched, if |watch_root_certs| is // called. If not set, an empty string will be used as the name. @@ -169,9 +177,9 @@ class TlsCredentialsOptions { // @param root_cert_name the name of root certs being set. void set_root_cert_name(const std::string& root_cert_name); // Watches the updates of identity key-cert pairs with name - // |identity_cert_name|. If used in TLS credentials, it should always be set - // unless the identity certificates are not needed(e.g. in the one-side TLS - // scenario, the client is not required to provide certs). + // |identity_cert_name|. If used in TLS credentials, it is required to be set + // on the server side, and optional for the client side(in the one-side + // TLS scenario, the client is not required to provide identity certs). void watch_identity_key_cert_pairs(); // Sets the name of identity key-cert pairs being watched, if // |watch_identity_key_cert_pairs| is called. If not set, an empty string will @@ -192,13 +200,13 @@ class TlsCredentialsOptions { }; // Contains configurable options on the client side. +// Client side doesn't need to always use certificate provider. When the +// certificate provider is not set, we will use the root certificates stored +// in the system default locations, and assume client won't provide any +// identity certificates(single side TLS). // It is used for experimental purposes for now and it is subject to change. class TlsChannelCredentialsOptions final : public TlsCredentialsOptions { public: - explicit TlsChannelCredentialsOptions( - std::shared_ptr certificate_provider) - : TlsCredentialsOptions(std::move(certificate_provider)) {} - // Sets the option to verify the server. // The default is GRPC_TLS_SERVER_VERIFICATION. void set_server_verification_option( @@ -215,9 +223,13 @@ class TlsChannelCredentialsOptions final : public TlsCredentialsOptions { // It is used for experimental purposes for now and it is subject to change. class TlsServerCredentialsOptions final : public TlsCredentialsOptions { public: + // Server side is required to use a provider, because server always needs to + // use identity certs. explicit TlsServerCredentialsOptions( std::shared_ptr certificate_provider) - : TlsCredentialsOptions(std::move(certificate_provider)) {} + : TlsCredentialsOptions() { + set_certificate_provider(certificate_provider); + } // Sets option to request the certificates from the client. // The default is GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE. diff --git a/src/core/lib/security/security_connector/ssl_utils.cc b/src/core/lib/security/security_connector/ssl_utils.cc index f1797d5d80a..06ed5245b7e 100644 --- a/src/core/lib/security/security_connector/ssl_utils.cc +++ b/src/core/lib/security/security_connector/ssl_utils.cc @@ -395,6 +395,9 @@ grpc_security_status grpc_ssl_tsi_client_handshaker_factory_init( const char* root_certs; const tsi_ssl_root_certs_store* root_store; if (pem_root_certs == nullptr) { + gpr_log(GPR_INFO, + "No root certificates specified; use ones stored in system default " + "locations instead"); // Use default root certificates. root_certs = grpc_core::DefaultSslRootStore::GetPemRootCerts(); if (root_certs == nullptr) { 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 a198bb55a8b..025f4bd0879 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 @@ -136,9 +136,20 @@ TlsChannelSecurityConnector::TlsChannelSecurityConnector( if (options_->watch_identity_pair()) { watched_identity_cert_name = options_->identity_cert_name(); } - distributor->WatchTlsCertificates(std::move(watcher_ptr), - watched_root_cert_name, - watched_identity_cert_name); + // We will use the root certs stored in system default locations if not + // watching root certs on the client side. We will handle this case + // differently here, because "watching a default roots without the identity + // certs" is a valid case(and hence we will need to call + // OnCertificatesChanged), but it requires nothing from the provider, and + // hence no need to register the watcher. + bool use_default_roots = !options_->watch_root_cert(); + if (use_default_roots && !options_->watch_identity_pair()) { + watcher_ptr->OnCertificatesChanged(absl::nullopt, absl::nullopt); + } else { + distributor->WatchTlsCertificates(std::move(watcher_ptr), + watched_root_cert_name, + watched_identity_cert_name); + } } TlsChannelSecurityConnector::~TlsChannelSecurityConnector() { @@ -148,7 +159,9 @@ TlsChannelSecurityConnector::~TlsChannelSecurityConnector() { // Cancel all the watchers. grpc_tls_certificate_distributor* distributor = options_->certificate_distributor(); - distributor->CancelTlsCertificatesWatch(certificate_watcher_); + if (distributor != nullptr) { + distributor->CancelTlsCertificatesWatch(certificate_watcher_); + } if (client_handshaker_factory_ != nullptr) { tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory_); } @@ -327,16 +340,12 @@ void TlsChannelSecurityConnector::TlsChannelCertificateWatcher:: if (key_cert_pairs.has_value()) { security_connector_->pem_key_cert_pair_list_ = std::move(key_cert_pairs); } - bool root_being_watched = security_connector_->options_->watch_root_cert(); - bool root_has_value = security_connector_->pem_root_certs_.has_value(); - bool identity_being_watched = - security_connector_->options_->watch_identity_pair(); - bool identity_has_value = + const bool root_ready = !security_connector_->options_->watch_root_cert() || + security_connector_->pem_root_certs_.has_value(); + const bool identity_ready = + !security_connector_->options_->watch_identity_pair() || security_connector_->pem_key_cert_pair_list_.has_value(); - if ((root_being_watched && root_has_value && identity_being_watched && - identity_has_value) || - (root_being_watched && root_has_value && !identity_being_watched) || - (!root_being_watched && identity_being_watched && identity_has_value)) { + if (root_ready && identity_ready) { if (security_connector_->UpdateHandshakerFactoryLocked() != GRPC_SECURITY_OK) { gpr_log(GPR_ERROR, "Update handshaker factory failed."); @@ -383,9 +392,11 @@ TlsChannelSecurityConnector::UpdateHandshakerFactoryLocked() { if (pem_key_cert_pair_list_.has_value()) { pem_key_cert_pair = ConvertToTsiPemKeyCertPair(*pem_key_cert_pair_list_); } + bool use_default_roots = !options_->watch_root_cert(); grpc_security_status status = grpc_ssl_tsi_client_handshaker_factory_init( pem_key_cert_pair, - pem_root_certs.empty() ? nullptr : pem_root_certs.c_str(), + pem_root_certs.empty() || use_default_roots ? nullptr + : pem_root_certs.c_str(), skip_server_certificate_verification, grpc_get_tsi_tls_version(options_->min_tls_version()), grpc_get_tsi_tls_version(options_->max_tls_version()), ssl_session_cache_, @@ -516,6 +527,7 @@ TlsServerSecurityConnector::TlsServerSecurityConnector( if (options_->watch_identity_pair()) { watched_identity_cert_name = options_->identity_cert_name(); } + // Server side won't use default system roots at any time. distributor->WatchTlsCertificates(std::move(watcher_ptr), watched_root_cert_name, watched_identity_cert_name); diff --git a/src/cpp/common/tls_credentials_options.cc b/src/cpp/common/tls_credentials_options.cc index 02bc6d918b1..729e6a4db83 100644 --- a/src/cpp/common/tls_credentials_options.cc +++ b/src/cpp/common/tls_credentials_options.cc @@ -124,10 +124,13 @@ TlsServerAuthorizationCheckConfig::~TlsServerAuthorizationCheckConfig() { grpc_tls_server_authorization_check_config_release(c_config_); } -TlsCredentialsOptions::TlsCredentialsOptions( - std::shared_ptr certificate_provider) - : certificate_provider_(std::move(certificate_provider)) { +TlsCredentialsOptions::TlsCredentialsOptions() { c_credentials_options_ = grpc_tls_credentials_options_create(); +} + +void TlsCredentialsOptions::set_certificate_provider( + std::shared_ptr certificate_provider) { + certificate_provider_ = std::move(certificate_provider); if (certificate_provider_ != nullptr) { grpc_tls_credentials_options_set_certificate_provider( c_credentials_options_, certificate_provider_->c_provider()); diff --git a/test/core/security/grpc_tls_credentials_options_test.cc b/test/core/security/grpc_tls_credentials_options_test.cc index 5e9a4e31544..148e4a07522 100644 --- a/test/core/security/grpc_tls_credentials_options_test.cc +++ b/test/core/security/grpc_tls_credentials_options_test.cc @@ -69,6 +69,21 @@ TEST_F(GrpcTlsCredentialsOptionsTest, ErrorDetails) { EXPECT_STREQ(error_details.error_details().c_str(), "test error details"); } +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; + 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); +} + // Tests for StaticDataCertificateProvider. TEST_F(GrpcTlsCredentialsOptionsTest, ClientOptionsWithStaticDataProviderOnBothCerts) { @@ -135,6 +150,26 @@ TEST_F(GrpcTlsCredentialsOptionsTest, EXPECT_EQ(tls_connector->ClientHandshakerFactoryForTesting(), nullptr); } +TEST_F(GrpcTlsCredentialsOptionsTest, + ClientOptionsWithDefaultRootAndStaticDataProviderOnIdentityCerts) { + auto options = MakeRefCounted(); + auto provider = MakeRefCounted( + "", 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; + 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, ServerOptionsWithStaticDataProviderOnBothCerts) { auto options = MakeRefCounted(); @@ -192,7 +227,7 @@ TEST_F(GrpcTlsCredentialsOptionsTest, EXPECT_EQ(tls_connector->ServerHandshakerFactoryForTesting(), nullptr); } -//// Tests for FileWatcherCertificateProvider. +// Tests for FileWatcherCertificateProvider. TEST_F(GrpcTlsCredentialsOptionsTest, ClientOptionsWithCertWatcherProviderOnBothCerts) { auto options = MakeRefCounted(); @@ -460,6 +495,7 @@ TEST_F(GrpcTlsCredentialsOptionsTest, int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); + GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, CA_CERT_PATH); ::testing::InitGoogleTest(&argc, argv); grpc_init(); int ret = RUN_ALL_TESTS(); diff --git a/test/core/security/tls_security_connector_test.cc b/test/core/security/tls_security_connector_test.cc index c6f744da2ce..aff048f48f9 100644 --- a/test/core/security/tls_security_connector_test.cc +++ b/test/core/security/tls_security_connector_test.cc @@ -146,10 +146,59 @@ TEST_F(TlsSecurityConnectorTest, grpc_channel_args_destroy(new_args); } -// Note that on client side, we don't have tests watching identity certs only, -// because in TLS, the trust certs should always be presented. If we don't -// provide, it will try to load certs from some default system locations, and -// will hence fail on some systems. +TEST_F(TlsSecurityConnectorTest, + SystemRootsWhenCreateChannelSecurityConnector) { + // Create options watching for no certificates. + grpc_core::RefCountedPtr root_options = + grpc_core::MakeRefCounted(); + grpc_core::RefCountedPtr root_credential = + grpc_core::MakeRefCounted(root_options); + grpc_channel_args* root_new_args = nullptr; + grpc_core::RefCountedPtr root_connector = + root_credential->create_security_connector(nullptr, "some_target", + nullptr, &root_new_args); + EXPECT_NE(root_connector, nullptr); + grpc_core::TlsChannelSecurityConnector* tls_root_connector = + static_cast( + root_connector.get()); + EXPECT_NE(tls_root_connector->ClientHandshakerFactoryForTesting(), nullptr); + grpc_channel_args_destroy(root_new_args); +} + +TEST_F(TlsSecurityConnectorTest, + SystemRootsAndIdentityCertsObtainedWhenCreateChannelSecurityConnector) { + grpc_core::RefCountedPtr distributor = + grpc_core::MakeRefCounted(); + distributor->SetKeyMaterials(kIdentityCertName, absl::nullopt, + identity_pairs_0_); + grpc_core::RefCountedPtr<::grpc_tls_certificate_provider> provider = + grpc_core::MakeRefCounted(distributor); + // Create options only watching for identity certificates. + grpc_core::RefCountedPtr root_options = + grpc_core::MakeRefCounted(); + root_options->set_certificate_provider(provider); + root_options->set_watch_identity_pair(true); + root_options->set_identity_cert_name(kIdentityCertName); + grpc_core::RefCountedPtr root_credential = + grpc_core::MakeRefCounted(root_options); + grpc_channel_args* root_new_args = nullptr; + grpc_core::RefCountedPtr root_connector = + root_credential->create_security_connector(nullptr, "some_target", + nullptr, &root_new_args); + EXPECT_NE(root_connector, nullptr); + grpc_core::TlsChannelSecurityConnector* tls_root_connector = + static_cast( + root_connector.get()); + EXPECT_NE(tls_root_connector->ClientHandshakerFactoryForTesting(), nullptr); + EXPECT_EQ(tls_root_connector->KeyCertPairListForTesting(), identity_pairs_0_); + // If we have a root update, we shouldn't receive them in security connector, + // since we claimed to use default system roots. + distributor->SetKeyMaterials(kRootCertName, root_cert_1_, absl::nullopt); + EXPECT_NE(tls_root_connector->ClientHandshakerFactoryForTesting(), nullptr); + EXPECT_NE(tls_root_connector->RootCertsForTesting(), root_cert_1_); + grpc_channel_args_destroy(root_new_args); +} + TEST_F(TlsSecurityConnectorTest, RootCertsObtainedWhenCreateChannelSecurityConnector) { grpc_core::RefCountedPtr distributor = @@ -495,6 +544,7 @@ TEST_F(TlsSecurityConnectorTest, CreateServerSecurityConnectorFailNoOptions) { int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); + GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, CA_CERT_PATH); ::testing::InitGoogleTest(&argc, argv); grpc_init(); int ret = RUN_ALL_TESTS(); diff --git a/test/cpp/client/credentials_test.cc b/test/cpp/client/credentials_test.cc index b2ec888ae53..576ab510c8b 100644 --- a/test/cpp/client/credentials_test.cc +++ b/test/cpp/client/credentials_test.cc @@ -359,6 +359,20 @@ TEST(CredentialsTest, TlsServerAuthorizationCheckConfigCppToC) { gpr_free(const_cast(c_arg.peer_cert)); } +TEST(CredentialsTest, TlsChannelCredentialsWithDefaultRoots) { + 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); + auto channel_credentials = grpc::experimental::TlsCredentials(options); + GPR_ASSERT(channel_credentials.get() != nullptr); +} + TEST( CredentialsTest, TlsChannelCredentialsWithStaticDataCertificateProviderLoadingRootAndIdentity) { @@ -374,8 +388,8 @@ TEST( auto server_authorization_check_config = std::make_shared( test_server_authorization_check); - grpc::experimental::TlsChannelCredentialsOptions options( - certificate_provider); + 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(); @@ -387,9 +401,6 @@ TEST( GPR_ASSERT(channel_credentials.get() != nullptr); } -// ChannelCredentials should always have root credential presented. -// Otherwise the system root certificates will be loaded, which will cause -// failure in some tests under MacOS/Windows. TEST(CredentialsTest, TlsChannelCredentialsWithStaticDataCertificateProviderLoadingRootOnly) { auto certificate_provider = @@ -401,8 +412,8 @@ TEST(CredentialsTest, test_server_authorization_check); GPR_ASSERT(certificate_provider != nullptr); GPR_ASSERT(certificate_provider->c_provider() != nullptr); - grpc::experimental::TlsChannelCredentialsOptions options( - certificate_provider); + 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); @@ -412,13 +423,39 @@ TEST(CredentialsTest, GPR_ASSERT(channel_credentials.get() != nullptr); } +TEST( + CredentialsTest, + TlsChannelCredentialsWithDefaultRootsAndStaticDataCertificateProviderLoadingIdentityOnly) { + experimental::IdentityKeyCertPair key_cert_pair; + key_cert_pair.private_key = kIdentityCertPrivateKey; + key_cert_pair.certificate_chain = kIdentityCertContents; + std::vector identity_key_cert_pairs; + 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); +} + TEST( CredentialsTest, TlsChannelCredentialsWithFileWatcherCertificateProviderLoadingRootAndIdentity) { auto certificate_provider = std::make_shared( SERVER_KEY_PATH, SERVER_CERT_PATH, CA_CERT_PATH, 1); - grpc::experimental::TlsChannelCredentialsOptions options( - certificate_provider); + 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(); @@ -435,15 +472,12 @@ TEST( GPR_ASSERT(channel_credentials.get() != nullptr); } -// ChannelCredentials should always have root credential presented. -// Otherwise the system root certificates will be loaded, which will cause -// failure in some tests under MacOS/Windows. TEST(CredentialsTest, TlsChannelCredentialsWithFileWatcherCertificateProviderLoadingRootOnly) { auto certificate_provider = std::make_shared(CA_CERT_PATH, 1); - grpc::experimental::TlsChannelCredentialsOptions options( - certificate_provider); + 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);