diff --git a/include/grpcpp/security/tls_credentials_options.h b/include/grpcpp/security/tls_credentials_options.h index d57676f9b75..8b5382cd852 100644 --- a/include/grpcpp/security/tls_credentials_options.h +++ b/include/grpcpp/security/tls_credentials_options.h @@ -67,8 +67,6 @@ class TlsKeyMaterialsConfig { grpc::string pem_root_certs_; }; -// typedef struct grpc_tls_credential_reload_arg grpc_tls_credential_reload_arg; - /** TLS credential reload arguments, wraps grpc_tls_credential_reload_arg. It is * used for experimental purposes for now and it is subject to change. * @@ -113,58 +111,42 @@ class TlsCredentialReloadArg { grpc_tls_credential_reload_arg* c_arg_; }; -// typedef struct grpc_tls_credential_reload_config -// grpc_tls_credential_reload_config; +/** An interface that the application derives and uses to instantiate a + * TlsCredentialReloadConfig instance. All 3 methods must be defined. **/ +struct TlsCredentialReloadInterface { + /** An application-provided callback that invokes the credential reload. **/ + virtual int Schedule(TlsCredentialReloadArg* arg) = 0; + /** An application-provided callback that cancels a credential reload request. + * **/ + virtual void Cancel(TlsCredentialReloadArg* arg) = 0; + /** An application-provided callback that cleans up any data associated to the + * interface or the config. **/ + virtual void Release() = 0; +}; /** TLS credential reloag config, wraps grpc_tls_credential_reload_config. It is - * used for experimental purposes for now and it is subject to change. - * - * The config_user_data is read-only user data; schedule is a pointer to an - * application-provided callback that invokes the credential reload; cancel is a - * pointer to an application-provided callback that cancels a credential reload - * request; destruct is a pointer to an application-provided callback that - * cleans up any data associated to the config. See the description of the - * grpc_tls_credential_reload_config struct in grpc_security.h. **/ + * used for experimental purposes for now and it is subject to change. **/ class TlsCredentialReloadConfig { public: - TlsCredentialReloadConfig(const void* config_user_data, - int (*schedule)(void* config_user_data, - TlsCredentialReloadArg* arg), - void (*cancel)(void* config_user_data, - TlsCredentialReloadArg* arg), - void (*destruct)(void* config_user_data)); + /** The constructor takes ownership of the interface argument. **/ + TlsCredentialReloadConfig( + std::shared_ptr interface); ~TlsCredentialReloadConfig(); int Schedule(TlsCredentialReloadArg* arg) const { - if (schedule_ == nullptr) { - gpr_log(GPR_ERROR, "schedule API is nullptr"); - return 1; - } - return schedule_(config_user_data_, arg); + return interface_->Schedule(arg); } - void Cancel(TlsCredentialReloadArg* arg) const { - if (cancel_ == nullptr) { - gpr_log(GPR_ERROR, "cancel API is nullptr"); - return; - } - cancel_(config_user_data_, arg); - } + void Cancel(TlsCredentialReloadArg* arg) const { interface_->Cancel(arg); } /** Returns a C struct for the credential reload config. **/ grpc_tls_credential_reload_config* c_config() const { return c_config_; } private: grpc_tls_credential_reload_config* c_config_; - void* config_user_data_; - int (*schedule_)(void* config_user_data, TlsCredentialReloadArg* arg); - void (*cancel_)(void* config_user_data, TlsCredentialReloadArg* arg); - void (*destruct_)(void* config_user_data); + std::shared_ptr interface_; }; -// typedef struct grpc_tls_server_authorization_check_arg -// grpc_tls_server_authorization_check_arg; - /** 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. @@ -212,46 +194,38 @@ class TlsServerAuthorizationCheckArg { grpc_tls_server_authorization_check_arg* c_arg_; }; -// typedef struct ::grpc_tls_server_authorization_check_config -// grpc_tls_server_authorization_check_config; +/** An interface that the application derives and uses to instantiate a + * TlsServerAuthorizationCheckConfig instance. All 3 methods must be defined. + * **/ +struct TlsServerAuthorizationCheckInterface { + /** An application-provided callback that invokes the server authorization + * check. **/ + virtual int Schedule(TlsServerAuthorizationCheckArg* arg) = 0; + /** An application-provided callback that cancels a server authorization check + * request. + * **/ + virtual void Cancel(TlsServerAuthorizationCheckArg* arg) = 0; + /** An application-provided callback that cleans up any data associated to the + * interface or the config. **/ + virtual void Release() = 0; +}; /** 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. - * - * The config_user_data is read-only user data; schedule is a pointer to an - * application-provided callback that invokes the server authorization check; - * cancel is a pointer to an application-provided callback that cancels a - * server authorization check request; destruct is a pointer to an - * application-provided callback that cleans up any data associated to the - * config. See the description of the - * grpc_tls_server_authorization_check_config struct in grpc_security.h for - * more details. **/ + * purposes for now and it is subject to change. **/ class TlsServerAuthorizationCheckConfig { public: + /** The constructor takess ownership of the interface argument. **/ TlsServerAuthorizationCheckConfig( - const void* config_user_data, - int (*schedule)(void* config_user_data, - TlsServerAuthorizationCheckArg* arg), - void (*cancel)(void* config_user_data, - TlsServerAuthorizationCheckArg* arg), - void (*destruct)(void* config_user_data)); + std::shared_ptr interface); ~TlsServerAuthorizationCheckConfig(); int Schedule(TlsServerAuthorizationCheckArg* arg) const { - if (schedule_ == nullptr) { - gpr_log(GPR_ERROR, "schedule API is nullptr"); - return 1; - } - return schedule_(config_user_data_, arg); + return interface_->Schedule(arg); } void Cancel(TlsServerAuthorizationCheckArg* arg) const { - if (cancel_ == nullptr) { - gpr_log(GPR_ERROR, "cancel API is nullptr"); - return; - } - cancel_(config_user_data_, arg); + interface_->Cancel(arg); } /** Creates C struct for the server authorization check config. **/ @@ -261,14 +235,9 @@ class TlsServerAuthorizationCheckConfig { private: grpc_tls_server_authorization_check_config* c_config_; - void* config_user_data_; - int (*schedule_)(void* config_user_data, TlsServerAuthorizationCheckArg* arg); - void (*cancel_)(void* config_user_data, TlsServerAuthorizationCheckArg* arg); - void (*destruct_)(void* config_user_data); + std::shared_ptr interface_; }; -// typedef struct ::grpc_tls_credentials_options grpc_tls_credentials_options; - /** TLS credentials options, wrapper for grpc_tls_credentials_options. It is * used for experimental purposes for now and it is subject to change. See the * description of the grpc_tls_credentials_options struct in grpc_security.h for diff --git a/src/cpp/common/tls_credentials_options.cc b/src/cpp/common/tls_credentials_options.cc index 51f1d48944c..b5e58660233 100644 --- a/src/cpp/common/tls_credentials_options.cc +++ b/src/cpp/common/tls_credentials_options.cc @@ -87,26 +87,16 @@ void TlsCredentialReloadArg::OnCredentialReloadDoneCallback() { /** gRPC TLS credential reload config API implementation **/ TlsCredentialReloadConfig::TlsCredentialReloadConfig( - const void* config_user_data, - int (*schedule)(void* config_user_data, TlsCredentialReloadArg* arg), - void (*cancel)(void* config_user_data, TlsCredentialReloadArg* arg), - void (*destruct)(void* config_user_data)) - : config_user_data_(const_cast(config_user_data)), - schedule_(schedule), - cancel_(cancel), - destruct_(destruct) { + std::shared_ptr interface) + : interface_(std::move(interface)) { c_config_ = grpc_tls_credential_reload_config_create( - config_user_data_, - schedule != nullptr ? &TlsCredentialReloadConfigCSchedule : nullptr, - cancel != nullptr ? &TlsCredentialReloadConfigCCancel : nullptr, - destruct_); + nullptr, &TlsCredentialReloadConfigCSchedule, + &TlsCredentialReloadConfigCCancel, nullptr); c_config_->set_context(static_cast(this)); } TlsCredentialReloadConfig::~TlsCredentialReloadConfig() { - if (destruct_ != nullptr) { - destruct_(config_user_data_); - } + interface_->Release(); } /** gRPC TLS server authorization check arg API implementation **/ @@ -172,30 +162,18 @@ void TlsServerAuthorizationCheckArg::OnServerAuthorizationCheckDoneCallback() { c_arg_->cb(c_arg_); } -/** gRPC TLS server authorization check config API implementation **/ +/** gRPC TLS server authorization check config API implementation. **/ TlsServerAuthorizationCheckConfig::TlsServerAuthorizationCheckConfig( - const void* config_user_data, - int (*schedule)(void* config_user_data, - TlsServerAuthorizationCheckArg* arg), - void (*cancel)(void* config_user_data, TlsServerAuthorizationCheckArg* arg), - void (*destruct)(void* config_user_data)) - : config_user_data_(const_cast(config_user_data)), - schedule_(schedule), - cancel_(cancel), - destruct_(destruct) { + std::shared_ptr interface) + : interface_(std::move(interface)) { c_config_ = grpc_tls_server_authorization_check_config_create( - config_user_data_, - schedule != nullptr ? &TlsServerAuthorizationCheckConfigCSchedule - : nullptr, - cancel != nullptr ? &TlsServerAuthorizationCheckConfigCCancel : nullptr, - destruct_); + nullptr, &TlsServerAuthorizationCheckConfigCSchedule, + &TlsServerAuthorizationCheckConfigCCancel, nullptr); c_config_->set_context(static_cast(this)); } TlsServerAuthorizationCheckConfig::~TlsServerAuthorizationCheckConfig() { - if (destruct_ != nullptr) { - destruct_(config_user_data_); - } + interface_->Release(); } /** gRPC TLS credential options API implementation **/ @@ -226,11 +204,7 @@ TlsCredentialsOptions::TlsCredentialsOptions( } } -TlsCredentialsOptions::~TlsCredentialsOptions() { - if (c_credentials_options_ != nullptr) { - gpr_free(c_credentials_options_); - } -} +TlsCredentialsOptions::~TlsCredentialsOptions() {} } // namespace experimental } // namespace grpc_impl diff --git a/test/cpp/client/credentials_test.cc b/test/cpp/client/credentials_test.cc index b5b7f563c21..eeb073c80ab 100644 --- a/test/cpp/client/credentials_test.cc +++ b/test/cpp/client/credentials_test.cc @@ -37,8 +37,12 @@ typedef class ::grpc_impl::experimental::TlsKeyMaterialsConfig TlsKeyMaterialsConfig; typedef class ::grpc_impl::experimental::TlsCredentialReloadArg TlsCredentialReloadArg; +typedef struct ::grpc_impl::experimental::TlsCredentialReloadInterface + TlsCredentialReloadInterface; typedef class ::grpc_impl::experimental::TlsServerAuthorizationCheckArg TlsServerAuthorizationCheckArg; +typedef struct ::grpc_impl::experimental::TlsServerAuthorizationCheckInterface + TlsServerAuthorizationCheckInterface; static void tls_credential_reload_callback( grpc_tls_credential_reload_arg* arg) { @@ -46,31 +50,33 @@ static void tls_credential_reload_callback( arg->status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED; } -static int tls_credential_reload_sync(void* config_user_data, - TlsCredentialReloadArg* arg) { - GPR_ASSERT(arg != nullptr); - struct TlsKeyMaterialsConfig::PemKeyCertPair pair3 = {"private_key3", - "cert_chain3"}; - std::shared_ptr key_materials_config = - arg->key_materials_config(); - GPR_ASSERT(key_materials_config != nullptr); - std::vector pair_list = - key_materials_config->pem_key_cert_pair_list(); - pair_list.push_back(pair3); - pair_list[0].private_key = "private_key01"; - pair_list[0].cert_chain = "cert_chain01"; - key_materials_config->set_key_materials("new_pem_root_certs", pair_list); - arg->set_key_materials_config(key_materials_config); - arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW); - return 0; -} - -static void tls_credential_reload_cancel(void* config_user_data, - TlsCredentialReloadArg* arg) { - GPR_ASSERT(arg != nullptr); - arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL); - arg->set_error_details("cancelled"); -} +class TestTlsCredentialReloadInterface : public TlsCredentialReloadInterface { + int Schedule(TlsCredentialReloadArg* arg) override { + GPR_ASSERT(arg != nullptr); + struct TlsKeyMaterialsConfig::PemKeyCertPair pair3 = {"private_key3", + "cert_chain3"}; + std::shared_ptr key_materials_config = + arg->key_materials_config(); + GPR_ASSERT(key_materials_config != nullptr); + std::vector pair_list = + key_materials_config->pem_key_cert_pair_list(); + pair_list.push_back(pair3); + pair_list[0].private_key = "private_key01"; + pair_list[0].cert_chain = "cert_chain01"; + key_materials_config->set_key_materials("new_pem_root_certs", pair_list); + arg->set_key_materials_config(key_materials_config); + arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW); + return 0; + } + + void Cancel(TlsCredentialReloadArg* arg) override { + GPR_ASSERT(arg != nullptr); + arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL); + arg->set_error_details("cancelled"); + } + + void Release() override { return; } +}; static void tls_server_authorization_check_callback( grpc_tls_server_authorization_check_arg* arg) { @@ -84,25 +90,28 @@ static void tls_server_authorization_check_callback( arg->error_details = gpr_strdup("callback_error_details"); } -static int tls_server_authorization_check_sync( - void* config_user_data, TlsServerAuthorizationCheckArg* arg) { - GPR_ASSERT(arg != nullptr); - grpc::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; -} - -static void tls_server_authorization_check_cancel( - void* config_user_data, TlsServerAuthorizationCheckArg* arg) { - GPR_ASSERT(arg != nullptr); - arg->set_status(GRPC_STATUS_PERMISSION_DENIED); - arg->set_error_details("cancelled"); -} +class TestTlsServerAuthorizationCheckInterface + : public TlsServerAuthorizationCheckInterface { + int Schedule(TlsServerAuthorizationCheckArg* arg) override { + GPR_ASSERT(arg != nullptr); + grpc::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"); + } + + void Release() override { return; } +}; } // namespace @@ -339,8 +348,9 @@ TEST_F(CredentialsTest, TlsCredentialReloadArgCallback) { } TEST_F(CredentialsTest, TlsCredentialReloadConfigSchedule) { - TlsCredentialReloadConfig config(nullptr, &tls_credential_reload_sync, - nullptr, nullptr); + std::shared_ptr interface( + new TestTlsCredentialReloadInterface()); + TlsCredentialReloadConfig config(interface); grpc_tls_credential_reload_arg c_arg; TlsCredentialReloadArg arg(&c_arg); arg.set_cb_user_data(static_cast(nullptr)); @@ -383,9 +393,9 @@ TEST_F(CredentialsTest, TlsCredentialReloadConfigSchedule) { } TEST_F(CredentialsTest, TlsCredentialReloadConfigCppToC) { - TlsCredentialReloadConfig config = - TlsCredentialReloadConfig(nullptr, &tls_credential_reload_sync, - &tls_credential_reload_cancel, nullptr); + std::shared_ptr interface( + new TestTlsCredentialReloadInterface()); + TlsCredentialReloadConfig config = TlsCredentialReloadConfig(interface); grpc_tls_credential_reload_arg c_arg; c_arg.cb_user_data = static_cast(nullptr); grpc_tls_key_materials_config c_key_materials; @@ -477,8 +487,10 @@ TEST_F(CredentialsTest, TlsServerAuthorizationCheckArgCallback) { } TEST_F(CredentialsTest, TlsServerAuthorizationCheckConfigSchedule) { - TlsServerAuthorizationCheckConfig config = TlsServerAuthorizationCheckConfig( - nullptr, &tls_server_authorization_check_sync, nullptr, nullptr); + std::shared_ptr interface( + new TestTlsServerAuthorizationCheckInterface()); + TlsServerAuthorizationCheckConfig config = + TlsServerAuthorizationCheckConfig(interface); grpc_tls_server_authorization_check_arg c_arg; TlsServerAuthorizationCheckArg arg(&c_arg); arg.set_cb_user_data(nullptr); @@ -512,9 +524,10 @@ TEST_F(CredentialsTest, TlsServerAuthorizationCheckConfigSchedule) { } TEST_F(CredentialsTest, TlsServerAuthorizationCheckConfigCppToC) { - TlsServerAuthorizationCheckConfig config = TlsServerAuthorizationCheckConfig( - nullptr, &tls_server_authorization_check_sync, - &tls_server_authorization_check_cancel, nullptr); + std::shared_ptr interface( + new TestTlsServerAuthorizationCheckInterface()); + TlsServerAuthorizationCheckConfig config = + TlsServerAuthorizationCheckConfig(interface); grpc_tls_server_authorization_check_arg c_arg; c_arg.cb = tls_server_authorization_check_callback; c_arg.cb_user_data = nullptr; @@ -560,14 +573,19 @@ TEST_F(CredentialsTest, TlsCredentialsOptionsCppToC) { "cert_chain"}; std::vector pair_list = {pair}; key_materials_config->set_key_materials("pem_root_certs", pair_list); + + std::shared_ptr credential_reload_interface( + new TestTlsCredentialReloadInterface()); std::shared_ptr credential_reload_config( - new TlsCredentialReloadConfig(nullptr, &tls_credential_reload_sync, - &tls_credential_reload_cancel, nullptr)); + new TlsCredentialReloadConfig(credential_reload_interface)); + std::shared_ptr + server_authorization_check_interface( + new TestTlsServerAuthorizationCheckInterface()); std::shared_ptr server_authorization_check_config(new TlsServerAuthorizationCheckConfig( - nullptr, &tls_server_authorization_check_sync, - &tls_server_authorization_check_cancel, nullptr)); + server_authorization_check_interface)); + TlsCredentialsOptions options = TlsCredentialsOptions( GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY, key_materials_config, credential_reload_config, server_authorization_check_config); @@ -649,6 +667,29 @@ TEST_F(CredentialsTest, TlsCredentialsOptionsCppToC) { gpr_free(const_cast(c_server_authorization_check_arg.error_details)); ::grpc_core::Delete(c_credential_reload_config); ::grpc_core::Delete(c_server_authorization_check_config); + gpr_free(c_options); +} + +// This test demonstrates how the SPIFFE credentials will be used. +TEST_F(CredentialsTest, LoadSpiffeChannelCredentials) { + std::shared_ptr credential_reload_interface( + new TestTlsCredentialReloadInterface()); + std::shared_ptr credential_reload_config( + new TlsCredentialReloadConfig(credential_reload_interface)); + + std::shared_ptr + server_authorization_check_interface( + new TestTlsServerAuthorizationCheckInterface()); + std::shared_ptr + server_authorization_check_config(new TlsServerAuthorizationCheckConfig( + server_authorization_check_interface)); + + TlsCredentialsOptions options = TlsCredentialsOptions( + GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY, nullptr, + credential_reload_config, server_authorization_check_config); + std::shared_ptr channel_credentials = + grpc::experimental::TlsCredentials(options); + GPR_ASSERT(channel_credentials != nullptr); } } // namespace testing