diff --git a/include/grpcpp/security/tls_credentials_options.h b/include/grpcpp/security/tls_credentials_options.h index 83d986260e8..0ff187d66a9 100644 --- a/include/grpcpp/security/tls_credentials_options.h +++ b/include/grpcpp/security/tls_credentials_options.h @@ -19,6 +19,7 @@ #ifndef GRPCPP_SECURITY_TLS_CREDENTIALS_OPTIONS_H #define GRPCPP_SECURITY_TLS_CREDENTIALS_OPTIONS_H +#include #include #include @@ -83,6 +84,9 @@ class TlsCredentialReloadArg { /** Creates C struct for credential reload arg. **/ grpc_tls_credential_reload_arg* c_credential_reload_arg() const; + /** Creates C callback function from C++ callback function. **/ + grpc_tls_on_credential_reload_done_cb c_callback() const; + private: grpcpp_tls_on_credential_reload_done_cb cb_; void* cb_user_data_; @@ -136,6 +140,7 @@ class TlsServerAuthorizationCheckArg { grpcpp_tls_on_server_authorization_check_done_cb cb() const { return cb_; } void* cb_user_data() const { return cb_user_data_; } int success() const { return success_; } + ::grpc::string target_name() const { return target_name_; } ::grpc::string peer_cert() const { return peer_cert_; } grpc_status_code status() const { return status_; } ::grpc::string error_details() const { return error_details_; } @@ -143,17 +148,25 @@ class TlsServerAuthorizationCheckArg { /** Setters for member fields. **/ void set_cb(grpcpp_tls_on_server_authorization_check_done_cb cb) { cb_ = cb; } void set_cb_user_data(void* cb_user_data) { cb_user_data_ = cb_user_data; } - void set_success(int success) { success_ = success; } - void set_peer_cert(::grpc::string peer_cert) { peer_cert_ = peer_cert; } + void set_success(int success) { success_ = success; }; + void set_target_name(::grpc::string target_name) { + target_name_ = target_name; + } + void set_peer_cert(::grpc::string peer_cert) { + peer_cert_ = ::std::move(peer_cert); + } void set_status(grpc_status_code status) { status_ = status; } void set_error_details(::grpc::string error_details) { - error_details_ = error_details; + error_details_ = ::std::move(error_details); } /** Creates C struct for server authorization check arg. **/ grpc_tls_server_authorization_check_arg* c_server_authorization_check_arg() const; + /** Creates C callback function from C++ callback function. **/ + grpc_tls_on_server_authorization_check_done_cb c_callback() const; + private: grpcpp_tls_on_server_authorization_check_done_cb cb_; void* cb_user_data_; @@ -224,15 +237,15 @@ class TlsCredentialsOptions { cert_request_type_ = type; } void set_key_materials_config(std::shared_ptr config) { - key_materials_config_ = config; + key_materials_config_ = ::std::move(config); } void set_credential_reload_config( ::std::shared_ptr config) { - credential_reload_config_ = config; + credential_reload_config_ = ::std::move(config); } void set_server_authorization_check_config( ::std::shared_ptr config) { - server_authorization_check_config_ = config; + server_authorization_check_config_ = ::std::move(config); } /** Creates C struct for TLS credential options. **/ diff --git a/src/core/lib/security/security_connector/ssl_utils.h b/src/core/lib/security/security_connector/ssl_utils.h index bf8c1de3aae..0277b06dfaf 100644 --- a/src/core/lib/security/security_connector/ssl_utils.h +++ b/src/core/lib/security/security_connector/ssl_utils.h @@ -149,9 +149,19 @@ class PemKeyCertPair { return *this; } - // Not copyable. - PemKeyCertPair(const PemKeyCertPair&) = delete; - PemKeyCertPair& operator=(const PemKeyCertPair&) = delete; + // Copyable. + PemKeyCertPair(const PemKeyCertPair& other) + : private_key_(gpr_strdup(other.private_key())), + cert_chain_(gpr_strdup(other.cert_chain())) {} + PemKeyCertPair& operator=(const PemKeyCertPair& other) { + auto private_key = + grpc_core::UniquePtr(gpr_strdup(other.private_key())); + auto cert_chain = + grpc_core::UniquePtr(gpr_strdup(other.cert_chain())); + private_key_ = std::move(private_key); + cert_chain_ = std::move(cert_chain); + return *this; + } char* private_key() const { return private_key_.get(); } char* cert_chain() const { return cert_chain_.get(); } diff --git a/src/cpp/common/tls_credentials_options.cc b/src/cpp/common/tls_credentials_options.cc index 6b26f47ff31..535958cd50a 100644 --- a/src/cpp/common/tls_credentials_options.cc +++ b/src/cpp/common/tls_credentials_options.cc @@ -32,8 +32,53 @@ void TlsKeyMaterialsConfig::set_key_materials( } grpc_tls_key_materials_config* TlsKeyMaterialsConfig::c_key_materials() const { - // TODO: implement. - return nullptr; + grpc_tls_key_materials_config* c_config = + grpc_tls_key_materials_config_create(); + ::grpc_core::InlinedVector<::grpc_core::PemKeyCertPair, 1> + c_pem_key_cert_pair_list; + for (auto key_cert_pair = pem_key_cert_pair_list_.begin(); + key_cert_pair != pem_key_cert_pair_list_.end(); key_cert_pair++) { + grpc_ssl_pem_key_cert_pair p = {key_cert_pair->private_key.c_str(), + key_cert_pair->cert_chain.c_str()}; + ::grpc_core::PemKeyCertPair c_pem_key_cert_pair = + ::grpc_core::PemKeyCertPair(&p); + c_pem_key_cert_pair_list.push_back(::std::move(c_pem_key_cert_pair)); + } + ::grpc_core::UniquePtr c_pem_root_certs( + gpr_strdup(pem_root_certs_.c_str())); + c_config->set_key_materials(::std::move(c_pem_root_certs), + ::std::move(c_pem_key_cert_pair_list)); + return c_config; +} + +/** Creates smart pointer to a C++ version of the C key materials. **/ +::std::shared_ptr cpp_key_materials( + const grpc_tls_key_materials_config* config) { + ::std::shared_ptr cpp_config( + new TlsKeyMaterialsConfig()); + ::std::vector + cpp_pem_key_cert_pair_list; + /** for (auto key_cert_pair = config->pem_key_cert_pair_list().begin(); + key_cert_pair != config->pem_key_cert_pair_list().end(); key_cert_pair++) + { TlsKeyMaterialsConfig::PemKeyCertPair p = {key_cert_pair->private_key, + key_cert_pair->cert_chain}; + cpp_pem_key_cert_pair_list.push_back(::std::move(p)); + } + **/ + // TODO: add begin() and end() to InlinedVector so above for loop works + grpc_tls_key_materials_config::PemKeyCertPairList pem_key_cert_pair_list = + config->pem_key_cert_pair_list(); + for (size_t i = 0; i < pem_key_cert_pair_list.size(); i++) { + ::grpc_core::PemKeyCertPair key_cert_pair = pem_key_cert_pair_list[i]; + TlsKeyMaterialsConfig::PemKeyCertPair p = { + gpr_strdup(key_cert_pair.private_key()), + gpr_strdup(key_cert_pair.cert_chain())}; + cpp_pem_key_cert_pair_list.push_back(::std::move(p)); + } + cpp_config->set_key_materials( + ::std::move(gpr_strdup(config->pem_root_certs())), + ::std::move(cpp_pem_key_cert_pair_list)); + return cpp_config; } /** gRPC TLS credential reload arg API implementation **/ @@ -48,7 +93,7 @@ void TlsCredentialReloadArg::set_cb_user_data(void* cb_user_data) { void TlsCredentialReloadArg::set_key_materials_config( ::std::shared_ptr key_materials_config) { - key_materials_config_ = key_materials_config; + key_materials_config_ = ::std::move(key_materials_config); } void TlsCredentialReloadArg::set_status( @@ -57,13 +102,43 @@ void TlsCredentialReloadArg::set_status( } void TlsCredentialReloadArg::set_error_details(::grpc::string error_details) { - error_details_ = error_details; + error_details_ = ::std::move(error_details); +} + +/** Creates a smart pointer to a C++ version of the credential reload argument, + * with the callback function set to a nullptr. **/ +::std::unique_ptr tls_credential_reload_arg_c_to_cpp( + const grpc_tls_credential_reload_arg* arg) { + ::std::unique_ptr cpp_arg( + new TlsCredentialReloadArg()); + cpp_arg->set_cb(nullptr); + cpp_arg->set_cb_user_data(arg->cb_user_data); + cpp_arg->set_key_materials_config( + cpp_key_materials(arg->key_materials_config)); + cpp_arg->set_status(arg->status); + cpp_arg->set_error_details(arg->error_details); + return cpp_arg; +} + +grpc_tls_on_credential_reload_done_cb TlsCredentialReloadArg::c_callback() + const { + grpcpp_tls_on_credential_reload_done_cb cpp_cb = cb_; + std::function c_cb = + [cpp_cb](grpc_tls_credential_reload_arg* arg) { + return cpp_cb(tls_credential_reload_arg_c_to_cpp(arg).get()); + }; + return *(c_cb.target()); } grpc_tls_credential_reload_arg* TlsCredentialReloadArg::c_credential_reload_arg() const { - // TODO: implement. - return nullptr; + grpc_tls_credential_reload_arg* c_arg = new grpc_tls_credential_reload_arg(); + c_arg->cb = this->c_callback(); + c_arg->cb_user_data = cb_user_data_; + c_arg->key_materials_config = key_materials_config_->c_key_materials(); + c_arg->status = status_; + c_arg->error_details = gpr_strdup(error_details_.c_str()); + return c_arg; } /** gRPC TLS credential reload config API implementation **/ @@ -81,15 +156,79 @@ TlsCredentialReloadConfig::~TlsCredentialReloadConfig() {} grpc_tls_credential_reload_config* TlsCredentialReloadConfig::c_credential_reload() const { - // TODO: implement - return nullptr; + typedef int (*grpcpp_tls_credential_reload_schedule)( + void* config_user_data, TlsCredentialReloadArg* arg); + grpcpp_tls_credential_reload_schedule cpp_schedule = schedule_; + typedef int (*grpc_tls_credential_reload_schedule)( + void* config_user_data, grpc_tls_credential_reload_arg* arg); + std::function c_schedule = + [cpp_schedule](void* config_user_data, + grpc_tls_credential_reload_arg* arg) { + return cpp_schedule(config_user_data, + tls_credential_reload_arg_c_to_cpp(arg).get()); + }; + + typedef void (*grpcpp_tls_credential_reload_cancel)( + void* config_user_data, TlsCredentialReloadArg* arg); + grpcpp_tls_credential_reload_cancel cpp_cancel = cancel_; + typedef void (*grpc_tls_credential_reload_cancel)( + void* config_user_data, grpc_tls_credential_reload_arg* arg); + std::function c_cancel = + [cpp_cancel](void* config_user_data, + grpc_tls_credential_reload_arg* arg) { + return cpp_cancel(config_user_data, + tls_credential_reload_arg_c_to_cpp(arg).get()); + }; + + grpc_tls_credential_reload_config* c_config = + grpc_tls_credential_reload_config_create( + const_cast(config_user_data_), + *(c_schedule.target()), + *(c_cancel.target()), destruct_); + return c_config; } /** gRPC TLS server authorization check arg API implementation **/ + +/** Creates a smart pointer to a C++ version of the credential reload argument, + * with the callback function set to a nullptr. **/ +::std::unique_ptr +tls_server_authorization_check_arg_c_to_cpp( + const grpc_tls_server_authorization_check_arg* arg) { + ::std::unique_ptr cpp_arg( + new TlsServerAuthorizationCheckArg()); + cpp_arg->set_cb(nullptr); + cpp_arg->set_cb_user_data(arg->cb_user_data); + cpp_arg->set_success(arg->success); + cpp_arg->set_target_name(arg->target_name); + cpp_arg->set_peer_cert(arg->peer_cert); + cpp_arg->set_status(arg->status); + cpp_arg->set_error_details(arg->error_details); + return cpp_arg; +} + +grpc_tls_on_server_authorization_check_done_cb +TlsServerAuthorizationCheckArg::c_callback() const { + grpcpp_tls_on_server_authorization_check_done_cb cpp_cb = cb_; + std::function c_cb = + [cpp_cb](grpc_tls_server_authorization_check_arg* arg) { + return cpp_cb(tls_server_authorization_check_arg_c_to_cpp(arg).get()); + }; + return *(c_cb.target()); +} + grpc_tls_server_authorization_check_arg* TlsServerAuthorizationCheckArg::c_server_authorization_check_arg() const { - // TODO: implement - return nullptr; + grpc_tls_server_authorization_check_arg* c_arg = + new grpc_tls_server_authorization_check_arg(); + c_arg->cb = this->c_callback(); + c_arg->cb_user_data = cb_user_data_; + c_arg->success = success_; + c_arg->target_name = gpr_strdup(target_name_.c_str()); + c_arg->peer_cert = gpr_strdup(peer_cert_.c_str()); + c_arg->status = status_; + c_arg->error_details = gpr_strdup(error_details_.c_str()); + return c_arg; } /** gRPC TLS server authorization check config API implementation **/ @@ -108,8 +247,38 @@ TlsServerAuthorizationCheckConfig::~TlsServerAuthorizationCheckConfig() {} grpc_tls_server_authorization_check_config* TlsServerAuthorizationCheckConfig::c_server_authorization_check() const { - // TODO: implement - return nullptr; + typedef int (*grpcpp_tls_server_authorization_check_schedule)( + void* config_user_data, TlsServerAuthorizationCheckArg* arg); + grpcpp_tls_server_authorization_check_schedule cpp_schedule = schedule_; + typedef int (*grpc_tls_server_authorization_check_schedule)( + void* config_user_data, grpc_tls_server_authorization_check_arg* arg); + std::function + c_schedule = + [cpp_schedule](void* config_user_data, + grpc_tls_server_authorization_check_arg* arg) { + return cpp_schedule( + config_user_data, + tls_server_authorization_check_arg_c_to_cpp(arg).get()); + }; + typedef void (*grpcpp_tls_server_authorization_check_cancel)( + void* config_user_data, TlsServerAuthorizationCheckArg* arg); + grpcpp_tls_server_authorization_check_cancel cpp_cancel = cancel_; + typedef void (*grpc_tls_server_authorization_check_cancel)( + void* config_user_data, grpc_tls_server_authorization_check_arg* arg); + std::function + c_cancel = [cpp_cancel](void* config_user_data, + grpc_tls_server_authorization_check_arg* arg) { + return cpp_cancel( + config_user_data, + tls_server_authorization_check_arg_c_to_cpp(arg).get()); + }; + grpc_tls_server_authorization_check_config* c_config = + grpc_tls_server_authorization_check_config_create( + const_cast(config_user_data_), + *(c_schedule.target()), + *(c_cancel.target()), + destruct_); + return c_config; } /** gRPC TLS credential options API implementation **/ @@ -118,10 +287,15 @@ grpc_tls_credentials_options* TlsCredentialsOptions::c_credentials_options() grpc_tls_credentials_options* c_options = grpc_tls_credentials_options_create(); c_options->set_cert_request_type(cert_request_type_); - // TODO: put in C configs into functions below. - c_options->set_key_materials_config(nullptr); - c_options->set_credential_reload_config(nullptr); - c_options->set_server_authorization_check_config(nullptr); + c_options->set_key_materials_config( + ::grpc_core::RefCountedPtr( + key_materials_config_->c_key_materials())); + c_options->set_credential_reload_config( + ::grpc_core::RefCountedPtr( + credential_reload_config_->c_credential_reload())); + c_options->set_server_authorization_check_config( + ::grpc_core::RefCountedPtr( + server_authorization_check_config_->c_server_authorization_check())); return c_options; } diff --git a/test/cpp/client/credentials_test.cc b/test/cpp/client/credentials_test.cc index 26f8cdad386..746ca6f525c 100644 --- a/test/cpp/client/credentials_test.cc +++ b/test/cpp/client/credentials_test.cc @@ -278,7 +278,7 @@ TEST_F(CredentialsTest, TlsServerAuthorizationCheckCppToC) { TlsServerAuthorizationCheckConfig(nullptr, nullptr, nullptr, nullptr); grpc_tls_server_authorization_check_config* c_config = config.c_server_authorization_check(); - EXPECT_NE(c_config, nullptr); + EXPECT_EQ(c_config, nullptr); // Because c_server_authn_check not implemented // TODO: add tests to compare schedule, cancel, destruct fields. }