Merge pull request #19778 from matthewstevenson88/spiffe1

Add C++ wrapper for SPIFFE credentials v2
pull/20277/head
matthewstevenson88 5 years ago committed by GitHub
commit 0362df725f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      BUILD
  2. 4
      BUILD.gn
  3. 4
      CMakeLists.txt
  4. 6
      Makefile
  5. 4
      build.yaml
  6. 5
      gRPC-C++.podspec
  7. 2
      grpc.gyp
  8. 62
      include/grpc/grpc_security.h
  9. 5
      include/grpcpp/security/credentials.h
  10. 5
      include/grpcpp/security/credentials_impl.h
  11. 6
      include/grpcpp/security/server_credentials.h
  12. 5
      include/grpcpp/security/server_credentials_impl.h
  13. 330
      include/grpcpp/security/tls_credentials_options.h
  14. 64
      src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h
  15. 6
      src/core/lib/security/security_connector/tls/spiffe_security_connector.cc
  16. 7
      src/cpp/client/secure_credentials.cc
  17. 1
      src/cpp/client/secure_credentials.h
  18. 282
      src/cpp/common/tls_credentials_options.cc
  19. 150
      src/cpp/common/tls_credentials_options_util.cc
  20. 58
      src/cpp/common/tls_credentials_options_util.h
  21. 7
      src/cpp/server/secure_server_credentials.cc
  22. 1
      src/cpp/server/secure_server_credentials.h
  23. 543
      test/cpp/client/credentials_test.cc
  24. 1
      tools/doxygen/Doxyfile.c++
  25. 4
      tools/doxygen/Doxyfile.c++.internal

@ -258,6 +258,7 @@ GRPCXX_PUBLIC_HDRS = [
"include/grpcpp/security/credentials_impl.h",
"include/grpcpp/security/server_credentials.h",
"include/grpcpp/security/server_credentials_impl.h",
"include/grpcpp/security/tls_credentials_options.h",
"include/grpcpp/server.h",
"include/grpcpp/server_impl.h",
"include/grpcpp/server_builder.h",
@ -355,12 +356,15 @@ grpc_cc_library(
"src/cpp/common/secure_auth_context.cc",
"src/cpp/common/secure_channel_arguments.cc",
"src/cpp/common/secure_create_auth_context.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",
],
language = "c++",
@ -369,6 +373,7 @@ grpc_cc_library(
deps = [
"gpr",
"grpc",
"grpc_secure",
"grpc++_base",
"grpc++_codegen_base",
"grpc++_codegen_base_src",

@ -1164,6 +1164,7 @@ config("grpc_config") {
"include/grpcpp/security/credentials_impl.h",
"include/grpcpp/security/server_credentials.h",
"include/grpcpp/security/server_credentials_impl.h",
"include/grpcpp/security/tls_credentials_options.h",
"include/grpcpp/server.h",
"include/grpcpp/server_builder.h",
"include/grpcpp/server_builder_impl.h",
@ -1401,6 +1402,9 @@ config("grpc_config") {
"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_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",

@ -3151,6 +3151,8 @@ add_library(grpc++
src/cpp/common/secure_auth_context.cc
src/cpp/common/secure_channel_arguments.cc
src/cpp/common/secure_create_auth_context.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
src/cpp/client/channel_cc.cc
@ -3322,6 +3324,7 @@ foreach(_hdr
include/grpcpp/security/credentials_impl.h
include/grpcpp/security/server_credentials.h
include/grpcpp/security/server_credentials_impl.h
include/grpcpp/security/tls_credentials_options.h
include/grpcpp/server.h
include/grpcpp/server_builder.h
include/grpcpp/server_builder_impl.h
@ -4425,6 +4428,7 @@ foreach(_hdr
include/grpcpp/security/credentials_impl.h
include/grpcpp/security/server_credentials.h
include/grpcpp/security/server_credentials_impl.h
include/grpcpp/security/tls_credentials_options.h
include/grpcpp/server.h
include/grpcpp/server_builder.h
include/grpcpp/server_builder_impl.h

@ -5616,6 +5616,8 @@ LIBGRPC++_SRC = \
src/cpp/common/secure_auth_context.cc \
src/cpp/common/secure_channel_arguments.cc \
src/cpp/common/secure_create_auth_context.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 \
src/cpp/client/channel_cc.cc \
@ -5750,6 +5752,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/security/credentials_impl.h \
include/grpcpp/security/server_credentials.h \
include/grpcpp/security/server_credentials_impl.h \
include/grpcpp/security/tls_credentials_options.h \
include/grpcpp/server.h \
include/grpcpp/server_builder.h \
include/grpcpp/server_builder_impl.h \
@ -6784,6 +6787,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/security/credentials_impl.h \
include/grpcpp/security/server_credentials.h \
include/grpcpp/security/server_credentials_impl.h \
include/grpcpp/security/tls_credentials_options.h \
include/grpcpp/server.h \
include/grpcpp/server_builder.h \
include/grpcpp/server_builder_impl.h \
@ -22688,6 +22692,8 @@ src/cpp/common/auth_property_iterator.cc: $(OPENSSL_DEP)
src/cpp/common/secure_auth_context.cc: $(OPENSSL_DEP)
src/cpp/common/secure_channel_arguments.cc: $(OPENSSL_DEP)
src/cpp/common/secure_create_auth_context.cc: $(OPENSSL_DEP)
src/cpp/common/tls_credentials_options.cc: $(OPENSSL_DEP)
src/cpp/common/tls_credentials_options_util.cc: $(OPENSSL_DEP)
src/cpp/ext/proto_server_reflection.cc: $(OPENSSL_DEP)
src/cpp/ext/proto_server_reflection_plugin.cc: $(OPENSSL_DEP)
src/cpp/server/channelz/channelz_service.cc: $(OPENSSL_DEP)

@ -515,6 +515,7 @@ filegroups:
- include/grpcpp/security/credentials_impl.h
- include/grpcpp/security/server_credentials.h
- include/grpcpp/security/server_credentials_impl.h
- include/grpcpp/security/tls_credentials_options.h
- include/grpcpp/server.h
- include/grpcpp/server_builder.h
- include/grpcpp/server_builder_impl.h
@ -1816,6 +1817,7 @@ libs:
- include/grpcpp/impl/codegen/core_codegen.h
- 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
src:
- src/cpp/client/insecure_credentials.cc
@ -1824,6 +1826,8 @@ libs:
- src/cpp/common/secure_auth_context.cc
- src/cpp/common/secure_channel_arguments.cc
- src/cpp/common/secure_create_auth_context.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
deps:

@ -121,6 +121,7 @@ Pod::Spec.new do |s|
'include/grpcpp/security/credentials_impl.h',
'include/grpcpp/security/server_credentials.h',
'include/grpcpp/security/server_credentials_impl.h',
'include/grpcpp/security/tls_credentials_options.h',
'include/grpcpp/server.h',
'include/grpcpp/server_builder.h',
'include/grpcpp/server_builder_impl.h',
@ -220,6 +221,7 @@ Pod::Spec.new do |s|
ss.source_files = 'include/grpcpp/impl/codegen/core_codegen.h',
'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',
'src/cpp/client/create_channel_internal.h',
'src/cpp/common/channel_filter.h',
@ -234,6 +236,8 @@ Pod::Spec.new do |s|
'src/cpp/common/secure_auth_context.cc',
'src/cpp/common/secure_channel_arguments.cc',
'src/cpp/common/secure_create_auth_context.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',
'src/cpp/client/channel_cc.cc',
@ -277,6 +281,7 @@ Pod::Spec.new do |s|
ss.private_header_files = 'include/grpcpp/impl/codegen/core_codegen.h',
'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',
'src/cpp/client/create_channel_internal.h',
'src/cpp/common/channel_filter.h',

@ -1524,6 +1524,8 @@
'src/cpp/common/secure_auth_context.cc',
'src/cpp/common/secure_channel_arguments.cc',
'src/cpp/common/secure_create_auth_context.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',
'src/cpp/client/channel_cc.cc',

@ -805,20 +805,32 @@ typedef struct grpc_tls_credential_reload_arg grpc_tls_credential_reload_arg;
typedef void (*grpc_tls_on_credential_reload_done_cb)(
grpc_tls_credential_reload_arg* arg);
/** A struct containing all information necessary to schedule/cancel
a credential reload request. cb and cb_user_data represent a gRPC-provided
callback and an argument passed to it. key_materials is an in/output
parameter containing currently used/newly reloaded credentials. If
credential reload does not result in a new credential, key_materials should
not be modified. status and error_details are used to hold information about
errors occurred when a credential reload request is scheduled/cancelled. It
is used for experimental purpose for now and subject to change. */
/** A struct containing all information necessary to schedule/cancel a
credential reload request.
- cb and cb_user_data represent a gRPC-provided
callback and an argument passed to it.
- key_materials_config is an in/output parameter containing currently
used/newly reloaded credentials. If credential reload does not result
in a new credential, key_materials_config should not be modified.
- status and error_details are used to hold information about
errors occurred when a credential reload request is scheduled/cancelled.
- config is a pointer to the unique grpc_tls_credential_reload_config
instance that this argument corresponds to.
- context is a pointer to a wrapped language implementation of this
grpc_tls_credential_reload_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 purposes for now and subject to change.
*/
struct grpc_tls_credential_reload_arg {
grpc_tls_on_credential_reload_done_cb cb;
void* cb_user_data;
grpc_tls_key_materials_config* key_materials_config;
grpc_ssl_certificate_config_reload_status status;
const char* error_details;
grpc_tls_credential_reload_config* config;
void* context;
void (*destroy_context)(void* ctx);
};
/** Create a grpc_tls_credential_reload_config instance.
@ -863,16 +875,27 @@ 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 and certificate represents a complete certificate chain including both
signing and leaf certificates. status and error_details contain information
about errors occurred when a server authorization check request is
scheduled/cancelled. It is used for experimental purpose for now and subject
to change.*/
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.
- 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;
@ -881,6 +904,9 @@ struct grpc_tls_server_authorization_check_arg {
const char* peer_cert;
grpc_status_code status;
const char* 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.

@ -132,6 +132,11 @@ static inline std::shared_ptr<grpc_impl::ChannelCredentials> LocalCredentials(
return ::grpc_impl::experimental::LocalCredentials(type);
}
static inline std::shared_ptr<grpc_impl::ChannelCredentials> TlsCredentials(
const ::grpc_impl::experimental::TlsCredentialsOptions& options) {
return ::grpc_impl::experimental::TlsCredentials(options);
}
} // namespace experimental
} // namespace grpc

@ -28,6 +28,7 @@
#include <grpcpp/impl/codegen/client_interceptor.h>
#include <grpcpp/impl/codegen/grpc_library.h>
#include <grpcpp/security/auth_context.h>
#include <grpcpp/security/tls_credentials_options.h>
#include <grpcpp/support/channel_arguments_impl.h>
#include <grpcpp/support/status.h>
#include <grpcpp/support/string_ref.h>
@ -336,6 +337,10 @@ std::shared_ptr<ChannelCredentials> AltsCredentials(
std::shared_ptr<ChannelCredentials> LocalCredentials(
grpc_local_connect_type type);
/// Builds TLS Credentials given TLS options.
std::shared_ptr<ChannelCredentials> TlsCredentials(
const TlsCredentialsOptions& options);
} // namespace experimental
} // namespace grpc_impl

@ -79,6 +79,12 @@ static inline std::shared_ptr<ServerCredentials> LocalServerCredentials(
return ::grpc_impl::experimental::LocalServerCredentials(type);
}
/// Builds TLS ServerCredentials given TLS options.
static inline std::shared_ptr<ServerCredentials> TlsServerCredentials(
const ::grpc_impl::experimental::TlsCredentialsOptions& options) {
return ::grpc_impl::experimental::TlsServerCredentials(options);
}
} // namespace experimental
} // namespace grpc

@ -24,6 +24,7 @@
#include <grpc/grpc_security_constants.h>
#include <grpcpp/security/auth_metadata_processor.h>
#include <grpcpp/security/tls_credentials_options.h>
#include <grpcpp/support/config.h>
struct grpc_server;
@ -79,6 +80,10 @@ std::shared_ptr<ServerCredentials> AltsServerCredentials(
std::shared_ptr<ServerCredentials> LocalServerCredentials(
grpc_local_connect_type type);
/// Builds TLS ServerCredentials given TLS options.
std::shared_ptr<ServerCredentials> TlsServerCredentials(
const TlsCredentialsOptions& options);
} // namespace experimental
} // namespace grpc_impl

@ -0,0 +1,330 @@
/*
*
* 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 GRPCPP_SECURITY_TLS_CREDENTIALS_OPTIONS_H
#define GRPCPP_SECURITY_TLS_CREDENTIALS_OPTIONS_H
#include <memory>
#include <vector>
#include <grpc/grpc_security_constants.h>
#include <grpc/status.h>
#include <grpc/support/log.h>
#include <grpcpp/support/config.h>
typedef struct grpc_tls_credential_reload_arg grpc_tls_credential_reload_arg;
typedef struct grpc_tls_credential_reload_config
grpc_tls_credential_reload_config;
typedef struct grpc_tls_server_authorization_check_arg
grpc_tls_server_authorization_check_arg;
typedef struct grpc_tls_server_authorization_check_config
grpc_tls_server_authorization_check_config;
typedef struct grpc_tls_credentials_options grpc_tls_credentials_options;
namespace grpc_impl {
namespace experimental {
/** TLS key materials config, wrapper for grpc_tls_key_materials_config. It is
* used for experimental purposes for now and subject to change. **/
class TlsKeyMaterialsConfig {
public:
struct PemKeyCertPair {
grpc::string private_key;
grpc::string cert_chain;
};
/** Getters for member fields. **/
const grpc::string pem_root_certs() const { return pem_root_certs_; }
const std::vector<PemKeyCertPair>& pem_key_cert_pair_list() const {
return pem_key_cert_pair_list_;
}
int version() const { return version_; }
/** Setter for key materials that will be called by the user. The setter
* transfers ownership of the arguments to the config. **/
void set_pem_root_certs(grpc::string pem_root_certs);
void add_pem_key_cert_pair(const PemKeyCertPair& pem_key_cert_pair);
void set_key_materials(grpc::string pem_root_certs,
std::vector<PemKeyCertPair> pem_key_cert_pair_list);
void set_version(int version) { version_ = version; };
private:
int version_ = 0;
std::vector<PemKeyCertPair> pem_key_cert_pair_list_;
grpc::string pem_root_certs_;
};
/** TLS credential reload arguments, wraps grpc_tls_credential_reload_arg. It is
* used for experimental purposes for now and it is subject to change.
*
* The credential reload arg contains all the info necessary to schedule/cancel
* a credential reload request. The callback function must be called after
* finishing the schedule operation. See the description of the
* grpc_tls_credential_reload_arg struct in grpc_security.h for more details.
* **/
class TlsCredentialReloadArg {
public:
/** TlsCredentialReloadArg does not take ownership of the C arg that is passed
* to the constructor. One must remember to free any memory allocated to the C
* arg after using the setter functions below. **/
TlsCredentialReloadArg(grpc_tls_credential_reload_arg* arg);
~TlsCredentialReloadArg();
/** Getters for member fields. The callback function is not exposed.
* They return the corresponding fields of the underlying C arg. In the case
* of the key materials config, it creates a new instance of the C++ key
* materials config from the underlying C grpc_tls_key_materials_config. **/
void* cb_user_data() const;
bool is_pem_key_cert_pair_list_empty() const;
grpc_ssl_certificate_config_reload_status status() const;
grpc::string error_details() const;
/** Setters for member fields. They modify the fields of the underlying C arg.
* The setters for the key_materials_config and the error_details allocate
* memory when modifying c_arg_, so one must remember to free c_arg_'s
* original key_materials_config or error_details after using the appropriate
* setter function.
* **/
void set_cb_user_data(void* cb_user_data);
void set_pem_root_certs(const grpc::string& pem_root_certs);
void add_pem_key_cert_pair(
TlsKeyMaterialsConfig::PemKeyCertPair pem_key_cert_pair);
void set_key_materials_config(
const std::shared_ptr<TlsKeyMaterialsConfig>& key_materials_config);
void set_status(grpc_ssl_certificate_config_reload_status status);
void set_error_details(const grpc::string& error_details);
/** Calls the C arg's callback function. **/
void OnCredentialReloadDoneCallback();
private:
grpc_tls_credential_reload_arg* c_arg_;
};
/** An interface that the application derives and uses to instantiate a
* TlsCredentialReloadConfig instance. Refer to the definition of the
* grpc_tls_credential_reload_config in grpc_tls_credentials_options.h for more
* details on the expectations of the member functions of the interface. **/
struct TlsCredentialReloadInterface {
virtual ~TlsCredentialReloadInterface() = default;
/** A callback that invokes the credential reload. **/
virtual int Schedule(TlsCredentialReloadArg* arg) = 0;
/** A callback that cancels a credential reload request. **/
virtual void Cancel(TlsCredentialReloadArg* arg) {}
};
/** TLS credential reloag config, wraps grpc_tls_credential_reload_config. It is
* used for experimental purposes for now and it is subject to change. **/
class TlsCredentialReloadConfig {
public:
TlsCredentialReloadConfig(std::shared_ptr<TlsCredentialReloadInterface>
credential_reload_interface);
~TlsCredentialReloadConfig();
int Schedule(TlsCredentialReloadArg* arg) const {
if (credential_reload_interface_ == nullptr) {
gpr_log(GPR_ERROR, "credential reload interface is nullptr");
if (arg != nullptr) {
arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL);
arg->set_error_details(
"the interface of the credential reload config is nullptr");
}
return 1;
}
return credential_reload_interface_->Schedule(arg);
}
void Cancel(TlsCredentialReloadArg* arg) const {
if (credential_reload_interface_ == nullptr) {
gpr_log(GPR_ERROR, "credential reload interface is nullptr");
if (arg != nullptr) {
arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL);
arg->set_error_details(
"the interface of the credential reload config is nullptr");
}
return;
}
credential_reload_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_;
std::shared_ptr<TlsCredentialReloadInterface> credential_reload_interface_;
};
/** 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. **/
TlsServerAuthorizationCheckArg(grpc_tls_server_authorization_check_arg* arg);
~TlsServerAuthorizationCheckArg();
/** Getters for member fields. They return the corresponding fields of the
* underlying C arg.**/
void* cb_user_data() const;
int success() const;
grpc::string target_name() const;
grpc::string peer_cert() const;
grpc_status_code status() const;
grpc::string error_details() const;
/** Setters for member fields. They modify the fields of the underlying C arg.
* The setters for target_name, peer_cert, and error_details allocate memory
* when modifying c_arg_, so one must remember to free c_arg_'s original
* target_name, peer_cert, or error_details after using the appropriate setter
* function.
* **/
void set_cb_user_data(void* cb_user_data);
void set_success(int success);
void set_target_name(const grpc::string& target_name);
void set_peer_cert(const grpc::string& peer_cert);
void set_status(grpc_status_code status);
void set_error_details(const grpc::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:
TlsServerAuthorizationCheckConfig(
std::shared_ptr<TlsServerAuthorizationCheckInterface>
server_authorization_check_interface);
~TlsServerAuthorizationCheckConfig();
int Schedule(TlsServerAuthorizationCheckArg* arg) const {
if (server_authorization_check_interface_ == nullptr) {
gpr_log(GPR_ERROR, "server authorization check interface is nullptr");
if (arg != nullptr) {
arg->set_status(GRPC_STATUS_NOT_FOUND);
arg->set_error_details(
"the interface of the server authorization check config is "
"nullptr");
}
return 1;
}
return server_authorization_check_interface_->Schedule(arg);
}
void Cancel(TlsServerAuthorizationCheckArg* arg) const {
if (server_authorization_check_interface_ == nullptr) {
gpr_log(GPR_ERROR, "server authorization check interface is nullptr");
if (arg != nullptr) {
arg->set_status(GRPC_STATUS_NOT_FOUND);
arg->set_error_details(
"the interface of the server authorization check config is "
"nullptr");
}
return;
}
server_authorization_check_interface_->Cancel(arg);
}
/** Returns C struct for the server authorization check config. **/
grpc_tls_server_authorization_check_config* c_config() const {
return c_config_;
}
private:
grpc_tls_server_authorization_check_config* c_config_;
std::shared_ptr<TlsServerAuthorizationCheckInterface>
server_authorization_check_interface_;
};
/** 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
* more details. **/
class TlsCredentialsOptions {
public:
TlsCredentialsOptions(
grpc_ssl_client_certificate_request_type cert_request_type,
std::shared_ptr<TlsKeyMaterialsConfig> key_materials_config,
std::shared_ptr<TlsCredentialReloadConfig> credential_reload_config,
std::shared_ptr<TlsServerAuthorizationCheckConfig>
server_authorization_check_config);
~TlsCredentialsOptions();
/** Getters for member fields. **/
grpc_ssl_client_certificate_request_type cert_request_type() const {
return cert_request_type_;
}
std::shared_ptr<TlsKeyMaterialsConfig> key_materials_config() const {
return key_materials_config_;
}
std::shared_ptr<TlsCredentialReloadConfig> credential_reload_config() const {
return credential_reload_config_;
}
std::shared_ptr<TlsServerAuthorizationCheckConfig>
server_authorization_check_config() const {
return server_authorization_check_config_;
}
grpc_tls_credentials_options* c_credentials_options() const {
return c_credentials_options_;
}
private:
/** The cert_request_type_ flag is only relevant when the
* TlsCredentialsOptions are used to instantiate server credentials; the flag
* goes unused when creating channel credentials, and the user can set it to
* GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE. **/
grpc_ssl_client_certificate_request_type cert_request_type_;
std::shared_ptr<TlsKeyMaterialsConfig> key_materials_config_;
std::shared_ptr<TlsCredentialReloadConfig> credential_reload_config_;
std::shared_ptr<TlsServerAuthorizationCheckConfig>
server_authorization_check_config_;
grpc_tls_credentials_options* c_credentials_options_;
};
} // namespace experimental
} // namespace grpc_impl
#endif // GRPCPP_SECURITY_TLS_CREDENTIALS_OPTIONS_H

@ -42,6 +42,12 @@ struct grpc_tls_key_materials_config
int version() const { return version_; }
/** Setters for member fields. **/
void set_pem_root_certs(grpc_core::UniquePtr<char> pem_root_certs) {
pem_root_certs_ = std::move(pem_root_certs);
}
void add_pem_key_cert_pair(grpc_core::PemKeyCertPair pem_key_cert_pair) {
pem_key_cert_pair_list_.push_back(pem_key_cert_pair);
}
void set_key_materials(grpc_core::UniquePtr<char> pem_root_certs,
PemKeyCertPairList pem_key_cert_pair_list);
void set_version(int version) { version_ = version; }
@ -65,18 +71,46 @@ struct grpc_tls_credential_reload_config
void (*destruct)(void* config_user_data));
~grpc_tls_credential_reload_config();
void* context() const { return context_; }
void set_context(void* context) { context_ = context; }
int Schedule(grpc_tls_credential_reload_arg* arg) const {
if (schedule_ == nullptr) {
gpr_log(GPR_ERROR, "schedule API is nullptr");
if (arg != nullptr) {
arg->status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL;
arg->error_details =
gpr_strdup("schedule API in credential reload config is nullptr");
}
return 1;
}
if (arg != nullptr) {
arg->config = const_cast<grpc_tls_credential_reload_config*>(this);
}
return schedule_(config_user_data_, arg);
}
void Cancel(grpc_tls_credential_reload_arg* arg) const {
if (cancel_ == nullptr) {
gpr_log(GPR_ERROR, "cancel API is nullptr.");
if (arg != nullptr) {
arg->status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL;
arg->error_details =
gpr_strdup("cancel API in credential reload config is nullptr");
}
return;
}
if (arg != nullptr) {
arg->config = const_cast<grpc_tls_credential_reload_config*>(this);
}
cancel_(config_user_data_, arg);
}
private:
/** This is a pointer to the wrapped language implementation of
* grpc_tls_credential_reload_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_;
@ -113,18 +147,48 @@ struct grpc_tls_server_authorization_check_config
void (*destruct)(void* config_user_data));
~grpc_tls_server_authorization_check_config();
void* context() const { return context_; }
void set_context(void* context) { context_ = context; }
int 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 = gpr_strdup(
"schedule API in server authorization check config is nullptr");
}
return 1;
}
if (arg != nullptr && context_ != nullptr) {
arg->config =
const_cast<grpc_tls_server_authorization_check_config*>(this);
}
return schedule_(config_user_data_, arg);
}
void 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 = gpr_strdup(
"schedule API in server authorization check config is nullptr");
}
return;
}
if (arg != nullptr) {
arg->config =
const_cast<grpc_tls_server_authorization_check_config*>(this);
}
cancel_(config_user_data_, arg);
}
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_;

@ -104,6 +104,9 @@ grpc_status_code TlsFetchKeyMaterials(
}
}
gpr_free((void*)arg->error_details);
if (arg->destroy_context != nullptr) {
arg->destroy_context(arg->context);
}
grpc_core::Delete(arg);
}
return status;
@ -393,6 +396,9 @@ void SpiffeChannelSecurityConnector::ServerAuthorizationCheckArgDestroy(
gpr_free((void*)arg->target_name);
gpr_free((void*)arg->peer_cert);
gpr_free((void*)arg->error_details);
if (arg->destroy_context != nullptr) {
arg->destroy_context(arg->context);
}
grpc_core::Delete(arg);
}

@ -280,6 +280,13 @@ std::shared_ptr<ChannelCredentials> LocalCredentials(
return WrapChannelCredentials(grpc_local_credentials_create(type));
}
// Builds TLS Credentials given TLS options.
std::shared_ptr<ChannelCredentials> TlsCredentials(
const TlsCredentialsOptions& options) {
return WrapChannelCredentials(
grpc_tls_spiffe_credentials_create(options.c_credentials_options()));
}
} // namespace experimental
// Builds credentials for use when running in GCE

@ -23,6 +23,7 @@
#include <grpcpp/security/credentials.h>
#include <grpcpp/security/credentials_impl.h>
#include <grpcpp/security/tls_credentials_options.h>
#include <grpcpp/support/config.h>
#include "src/core/lib/security/credentials/credentials.h"

@ -0,0 +1,282 @@
/*
*
* 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 <grpcpp/security/tls_credentials_options.h>
#include "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h"
#include <grpc/support/alloc.h>
#include "src/cpp/common/tls_credentials_options_util.h"
namespace grpc_impl {
namespace experimental {
/** TLS key materials config API implementation **/
void TlsKeyMaterialsConfig::set_pem_root_certs(grpc::string pem_root_certs) {
pem_root_certs_ = std::move(pem_root_certs);
}
void TlsKeyMaterialsConfig::add_pem_key_cert_pair(
const PemKeyCertPair& pem_key_cert_pair) {
pem_key_cert_pair_list_.push_back(pem_key_cert_pair);
}
void TlsKeyMaterialsConfig::set_key_materials(
grpc::string pem_root_certs,
std::vector<PemKeyCertPair> pem_key_cert_pair_list) {
pem_key_cert_pair_list_ = std::move(pem_key_cert_pair_list);
pem_root_certs_ = std::move(pem_root_certs);
}
/** TLS credential reload arg API implementation **/
TlsCredentialReloadArg::TlsCredentialReloadArg(
grpc_tls_credential_reload_arg* arg)
: c_arg_(arg) {
if (c_arg_ != nullptr && c_arg_->context != nullptr) {
gpr_log(GPR_ERROR, "c_arg context has already been set");
}
c_arg_->context = static_cast<void*>(this);
c_arg_->destroy_context = &TlsCredentialReloadArgDestroyContext;
}
TlsCredentialReloadArg::~TlsCredentialReloadArg() {}
void* TlsCredentialReloadArg::cb_user_data() const {
return c_arg_->cb_user_data;
}
bool TlsCredentialReloadArg::is_pem_key_cert_pair_list_empty() const {
return c_arg_->key_materials_config->pem_key_cert_pair_list().empty();
}
grpc_ssl_certificate_config_reload_status TlsCredentialReloadArg::status()
const {
return c_arg_->status;
}
grpc::string TlsCredentialReloadArg::error_details() const {
grpc::string cpp_error_details(c_arg_->error_details);
return cpp_error_details;
}
void TlsCredentialReloadArg::set_cb_user_data(void* cb_user_data) {
c_arg_->cb_user_data = cb_user_data;
}
void TlsCredentialReloadArg::set_pem_root_certs(
const grpc::string& pem_root_certs) {
::grpc_core::UniquePtr<char> c_pem_root_certs(
gpr_strdup(pem_root_certs.c_str()));
c_arg_->key_materials_config->set_pem_root_certs(std::move(c_pem_root_certs));
}
void TlsCredentialReloadArg::add_pem_key_cert_pair(
TlsKeyMaterialsConfig::PemKeyCertPair pem_key_cert_pair) {
grpc_ssl_pem_key_cert_pair* ssl_pair =
(grpc_ssl_pem_key_cert_pair*)gpr_malloc(
sizeof(grpc_ssl_pem_key_cert_pair));
ssl_pair->private_key = gpr_strdup(pem_key_cert_pair.private_key.c_str());
ssl_pair->cert_chain = gpr_strdup(pem_key_cert_pair.cert_chain.c_str());
::grpc_core::PemKeyCertPair c_pem_key_cert_pair =
::grpc_core::PemKeyCertPair(ssl_pair);
c_arg_->key_materials_config->add_pem_key_cert_pair(
std::move(c_pem_key_cert_pair));
}
void TlsCredentialReloadArg::set_key_materials_config(
const std::shared_ptr<TlsKeyMaterialsConfig>& key_materials_config) {
if (key_materials_config == nullptr) {
c_arg_->key_materials_config = nullptr;
return;
}
::grpc_core::InlinedVector<::grpc_core::PemKeyCertPair, 1>
c_pem_key_cert_pair_list;
for (auto key_cert_pair =
key_materials_config->pem_key_cert_pair_list().begin();
key_cert_pair != key_materials_config->pem_key_cert_pair_list().end();
key_cert_pair++) {
grpc_ssl_pem_key_cert_pair* ssl_pair =
(grpc_ssl_pem_key_cert_pair*)gpr_malloc(
sizeof(grpc_ssl_pem_key_cert_pair));
ssl_pair->private_key = gpr_strdup(key_cert_pair->private_key.c_str());
ssl_pair->cert_chain = gpr_strdup(key_cert_pair->cert_chain.c_str());
::grpc_core::PemKeyCertPair c_pem_key_cert_pair =
::grpc_core::PemKeyCertPair(ssl_pair);
c_pem_key_cert_pair_list.emplace_back(std::move(c_pem_key_cert_pair));
}
::grpc_core::UniquePtr<char> c_pem_root_certs(
gpr_strdup(key_materials_config->pem_root_certs().c_str()));
if (c_arg_->key_materials_config == nullptr) {
c_arg_->key_materials_config = grpc_tls_key_materials_config_create();
}
c_arg_->key_materials_config->set_key_materials(
std::move(c_pem_root_certs), std::move(c_pem_key_cert_pair_list));
c_arg_->key_materials_config->set_version(key_materials_config->version());
}
void TlsCredentialReloadArg::set_status(
grpc_ssl_certificate_config_reload_status status) {
c_arg_->status = status;
}
void TlsCredentialReloadArg::set_error_details(
const grpc::string& error_details) {
c_arg_->error_details = gpr_strdup(error_details.c_str());
}
void TlsCredentialReloadArg::OnCredentialReloadDoneCallback() {
if (c_arg_->cb == nullptr) {
gpr_log(GPR_ERROR, "credential reload arg callback API is nullptr");
return;
}
c_arg_->cb(c_arg_);
}
/** gRPC TLS credential reload config API implementation **/
TlsCredentialReloadConfig::TlsCredentialReloadConfig(
std::shared_ptr<TlsCredentialReloadInterface> credential_reload_interface)
: credential_reload_interface_(std::move(credential_reload_interface)) {
c_config_ = grpc_tls_credential_reload_config_create(
nullptr, &TlsCredentialReloadConfigCSchedule,
&TlsCredentialReloadConfigCCancel, nullptr);
c_config_->set_context(static_cast<void*>(this));
}
TlsCredentialReloadConfig::~TlsCredentialReloadConfig() {}
/** gRPC TLS server authorization check arg API implementation **/
TlsServerAuthorizationCheckArg::TlsServerAuthorizationCheckArg(
grpc_tls_server_authorization_check_arg* arg)
: c_arg_(arg) {
if (c_arg_ != nullptr && c_arg_->context != nullptr) {
gpr_log(GPR_ERROR, "c_arg context has already been set");
}
c_arg_->context = static_cast<void*>(this);
c_arg_->destroy_context = &TlsServerAuthorizationCheckArgDestroyContext;
}
TlsServerAuthorizationCheckArg::~TlsServerAuthorizationCheckArg() {}
void* TlsServerAuthorizationCheckArg::cb_user_data() const {
return c_arg_->cb_user_data;
}
int TlsServerAuthorizationCheckArg::success() const { return c_arg_->success; }
grpc::string TlsServerAuthorizationCheckArg::target_name() const {
grpc::string cpp_target_name(c_arg_->target_name);
return cpp_target_name;
}
grpc::string TlsServerAuthorizationCheckArg::peer_cert() const {
grpc::string cpp_peer_cert(c_arg_->peer_cert);
return cpp_peer_cert;
}
grpc_status_code TlsServerAuthorizationCheckArg::status() const {
return c_arg_->status;
}
grpc::string TlsServerAuthorizationCheckArg::error_details() const {
grpc::string cpp_error_details(c_arg_->error_details);
return cpp_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 grpc::string& target_name) {
c_arg_->target_name = gpr_strdup(target_name.c_str());
}
void TlsServerAuthorizationCheckArg::set_peer_cert(
const grpc::string& peer_cert) {
c_arg_->peer_cert = gpr_strdup(peer_cert.c_str());
}
void TlsServerAuthorizationCheckArg::set_status(grpc_status_code status) {
c_arg_->status = status;
}
void TlsServerAuthorizationCheckArg::set_error_details(
const grpc::string& error_details) {
c_arg_->error_details = gpr_strdup(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_);
}
/** gRPC TLS server authorization check config API implementation. **/
TlsServerAuthorizationCheckConfig::TlsServerAuthorizationCheckConfig(
std::shared_ptr<TlsServerAuthorizationCheckInterface>
server_authorization_check_interface)
: server_authorization_check_interface_(
std::move(server_authorization_check_interface)) {
c_config_ = grpc_tls_server_authorization_check_config_create(
nullptr, &TlsServerAuthorizationCheckConfigCSchedule,
&TlsServerAuthorizationCheckConfigCCancel, nullptr);
c_config_->set_context(static_cast<void*>(this));
}
TlsServerAuthorizationCheckConfig::~TlsServerAuthorizationCheckConfig() {}
/** gRPC TLS credential options API implementation **/
TlsCredentialsOptions::TlsCredentialsOptions(
grpc_ssl_client_certificate_request_type cert_request_type,
std::shared_ptr<TlsKeyMaterialsConfig> key_materials_config,
std::shared_ptr<TlsCredentialReloadConfig> credential_reload_config,
std::shared_ptr<TlsServerAuthorizationCheckConfig>
server_authorization_check_config)
: cert_request_type_(cert_request_type),
key_materials_config_(std::move(key_materials_config)),
credential_reload_config_(std::move(credential_reload_config)),
server_authorization_check_config_(
std::move(server_authorization_check_config)) {
c_credentials_options_ = grpc_tls_credentials_options_create();
grpc_tls_credentials_options_set_cert_request_type(c_credentials_options_,
cert_request_type_);
if (key_materials_config_ != nullptr) {
grpc_tls_credentials_options_set_key_materials_config(
c_credentials_options_,
ConvertToCKeyMaterialsConfig(key_materials_config_));
}
if (credential_reload_config_ != nullptr) {
grpc_tls_credentials_options_set_credential_reload_config(
c_credentials_options_, credential_reload_config_->c_config());
}
if (server_authorization_check_config_ != nullptr) {
grpc_tls_credentials_options_set_server_authorization_check_config(
c_credentials_options_, server_authorization_check_config_->c_config());
}
}
TlsCredentialsOptions::~TlsCredentialsOptions() {}
} // namespace experimental
} // namespace grpc_impl

@ -0,0 +1,150 @@
/*
*
* 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 <grpcpp/security/tls_credentials_options.h>
namespace grpc_impl {
namespace experimental {
/** Converts the Cpp key materials to C key materials; this allocates memory for
* the C key materials. Note that the user must free
* the underlying pointer to private key and cert chain duplicates; they are not
* freed when the UniquePtr<char> member variables of PemKeyCertPair are unused.
* Similarly, the user must free the underlying pointer to c_pem_root_certs. **/
grpc_tls_key_materials_config* ConvertToCKeyMaterialsConfig(
const std::shared_ptr<TlsKeyMaterialsConfig>& config) {
if (config == nullptr) {
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 = config->pem_key_cert_pair_list().begin();
key_cert_pair != config->pem_key_cert_pair_list().end();
key_cert_pair++) {
grpc_ssl_pem_key_cert_pair* ssl_pair =
(grpc_ssl_pem_key_cert_pair*)gpr_malloc(
sizeof(grpc_ssl_pem_key_cert_pair));
ssl_pair->private_key = gpr_strdup(key_cert_pair->private_key.c_str());
ssl_pair->cert_chain = gpr_strdup(key_cert_pair->cert_chain.c_str());
::grpc_core::PemKeyCertPair c_pem_key_cert_pair =
::grpc_core::PemKeyCertPair(ssl_pair);
c_pem_key_cert_pair_list.push_back(::std::move(c_pem_key_cert_pair));
}
::grpc_core::UniquePtr<char> c_pem_root_certs(
gpr_strdup(config->pem_root_certs().c_str()));
c_config->set_key_materials(std::move(c_pem_root_certs),
std::move(c_pem_key_cert_pair_list));
c_config->set_version(config->version());
return c_config;
}
/** The C schedule and cancel functions for the credential reload config.
* They populate a C credential reload arg with the result of a C++ credential
* reload schedule/cancel API. **/
int TlsCredentialReloadConfigCSchedule(void* config_user_data,
grpc_tls_credential_reload_arg* arg) {
if (arg == nullptr || arg->config == nullptr ||
arg->config->context() == nullptr) {
gpr_log(GPR_ERROR, "credential reload arg was not properly initialized");
return 1;
}
TlsCredentialReloadConfig* cpp_config =
static_cast<TlsCredentialReloadConfig*>(arg->config->context());
TlsCredentialReloadArg* cpp_arg = new TlsCredentialReloadArg(arg);
int schedule_result = cpp_config->Schedule(cpp_arg);
return schedule_result;
}
void TlsCredentialReloadConfigCCancel(void* config_user_data,
grpc_tls_credential_reload_arg* arg) {
if (arg == nullptr || arg->config == nullptr ||
arg->config->context() == nullptr) {
gpr_log(GPR_ERROR, "credential reload arg was not properly initialized");
return;
}
if (arg->context == nullptr) {
gpr_log(GPR_ERROR, "credential reload arg schedule has already completed");
return;
}
TlsCredentialReloadConfig* cpp_config =
static_cast<TlsCredentialReloadConfig*>(arg->config->context());
TlsCredentialReloadArg* cpp_arg =
static_cast<TlsCredentialReloadArg*>(arg->context);
cpp_config->Cancel(cpp_arg);
}
void TlsCredentialReloadArgDestroyContext(void* context) {
if (context != nullptr) {
TlsCredentialReloadArg* cpp_arg =
static_cast<TlsCredentialReloadArg*>(context);
delete cpp_arg;
}
}
/** The C schedule and cancel functions for the server authorization check
* config. They populate a C server authorization check arg with the result
* of a C++ server authorization check schedule/cancel API. **/
int TlsServerAuthorizationCheckConfigCSchedule(
void* config_user_data, grpc_tls_server_authorization_check_arg* arg) {
if (arg == nullptr || arg->config == nullptr ||
arg->config->context() == nullptr) {
gpr_log(GPR_ERROR,
"server authorization check arg was not properly initialized");
return 1;
}
TlsServerAuthorizationCheckConfig* cpp_config =
static_cast<TlsServerAuthorizationCheckConfig*>(arg->config->context());
TlsServerAuthorizationCheckArg* cpp_arg =
new TlsServerAuthorizationCheckArg(arg);
int schedule_result = cpp_config->Schedule(cpp_arg);
return schedule_result;
}
void TlsServerAuthorizationCheckConfigCCancel(
void* config_user_data, grpc_tls_server_authorization_check_arg* arg) {
if (arg == nullptr || arg->config == nullptr ||
arg->config->context() == nullptr) {
gpr_log(GPR_ERROR,
"server authorization check arg was not properly initialized");
return;
}
if (arg->context == nullptr) {
gpr_log(GPR_ERROR,
"server authorization check arg schedule has already completed");
return;
}
TlsServerAuthorizationCheckConfig* cpp_config =
static_cast<TlsServerAuthorizationCheckConfig*>(arg->config->context());
TlsServerAuthorizationCheckArg* cpp_arg =
static_cast<TlsServerAuthorizationCheckArg*>(arg->context);
cpp_config->Cancel(cpp_arg);
}
void TlsServerAuthorizationCheckArgDestroyContext(void* context) {
if (context != nullptr) {
TlsServerAuthorizationCheckArg* cpp_arg =
static_cast<TlsServerAuthorizationCheckArg*>(context);
delete cpp_arg;
}
}
} // namespace experimental
} // namespace grpc_impl

@ -0,0 +1,58 @@
/*
*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef GRPC_INTERNAL_CPP_COMMON_TLS_CREDENTIALS_OPTIONS_UTIL_H
#define GRPC_INTERNAL_CPP_COMMON_TLS_CREDENTIALS_OPTIONS_UTIL_H
#include <grpc/grpc_security.h>
#include <grpcpp/security/tls_credentials_options.h>
#include "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h"
namespace grpc_impl {
namespace experimental {
/** The following function is exposed for testing purposes. **/
grpc_tls_key_materials_config* ConvertToCKeyMaterialsConfig(
const std::shared_ptr<TlsKeyMaterialsConfig>& config);
/** The following 4 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 TlsCredentialReloadConfigCSchedule(void* config_user_data,
grpc_tls_credential_reload_arg* arg);
void TlsCredentialReloadConfigCCancel(void* config_user_data,
grpc_tls_credential_reload_arg* arg);
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);
/** The following 2 functions cleanup data created in the above C schedule
* functions. **/
void TlsCredentialReloadArgDestroyContext(void* context);
void TlsServerAuthorizationCheckArgDestroyContext(void* context);
} // namespace experimental
} // namespace grpc_impl
#endif // GRPC_INTERNAL_CPP_COMMON_TLS_CREDENTIALS_OPTIONS_UTIL_H

@ -150,5 +150,12 @@ std::shared_ptr<ServerCredentials> LocalServerCredentials(
new SecureServerCredentials(grpc_local_server_credentials_create(type)));
}
std::shared_ptr<ServerCredentials> TlsServerCredentials(
const TlsCredentialsOptions& options) {
return std::shared_ptr<ServerCredentials>(
new SecureServerCredentials(grpc_tls_spiffe_server_credentials_create(
options.c_credentials_options())));
}
} // namespace experimental
} // namespace grpc_impl

@ -22,6 +22,7 @@
#include <memory>
#include <grpcpp/security/server_credentials.h>
#include <grpcpp/security/tls_credentials_options.h>
#include <grpc/grpc_security.h>

@ -17,6 +17,7 @@
*/
#include <grpcpp/security/credentials.h>
#include <grpcpp/security/tls_credentials_options.h>
#include <memory>
@ -26,7 +27,81 @@
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/tmpfile.h"
#include "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h"
#include "src/cpp/client/secure_credentials.h"
#include "src/cpp/common/tls_credentials_options_util.h"
namespace {
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) {
GPR_ASSERT(arg != nullptr);
arg->status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
}
class TestTlsCredentialReload : public TlsCredentialReloadInterface {
int Schedule(TlsCredentialReloadArg* arg) override {
GPR_ASSERT(arg != nullptr);
struct TlsKeyMaterialsConfig::PemKeyCertPair pair3 = {"private_key3",
"cert_chain3"};
arg->set_pem_root_certs("new_pem_root_certs");
arg->add_pem_key_cert_pair(pair3);
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");
}
};
static void tls_server_authorization_check_callback(
grpc_tls_server_authorization_check_arg* arg) {
GPR_ASSERT(arg != nullptr);
grpc::string cb_user_data = "cb_user_data";
arg->cb_user_data = static_cast<void*>(gpr_strdup(cb_user_data.c_str()));
arg->success = 1;
arg->target_name = gpr_strdup("callback_target_name");
arg->peer_cert = gpr_strdup("callback_peer_cert");
arg->status = GRPC_STATUS_OK;
arg->error_details = gpr_strdup("callback_error_details");
}
class TestTlsServerAuthorizationCheck
: 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<void*>(gpr_strdup(cb_user_data.c_str())));
arg->set_success(1);
arg->set_target_name("sync_target_name");
arg->set_peer_cert("sync_peer_cert");
arg->set_status(GRPC_STATUS_OK);
arg->set_error_details("sync_error_details");
return 1;
}
void Cancel(TlsServerAuthorizationCheckArg* arg) override {
GPR_ASSERT(arg != nullptr);
arg->set_status(GRPC_STATUS_PERMISSION_DENIED);
arg->set_error_details("cancelled");
}
};
} // namespace
namespace grpc {
namespace testing {
@ -196,6 +271,474 @@ TEST_F(CredentialsTest, StsCredentialsOptionsFromEnv) {
gpr_unsetenv("STS_CREDENTIALS");
}
typedef class ::grpc_impl::experimental::TlsKeyMaterialsConfig
TlsKeyMaterialsConfig;
TEST_F(CredentialsTest, TlsKeyMaterialsConfigCppToC) {
std::shared_ptr<TlsKeyMaterialsConfig> config(new TlsKeyMaterialsConfig());
struct TlsKeyMaterialsConfig::PemKeyCertPair pair = {"private_key",
"cert_chain"};
std::vector<TlsKeyMaterialsConfig::PemKeyCertPair> pair_list = {pair};
config->set_key_materials("pem_root_certs", pair_list);
grpc_tls_key_materials_config* c_config =
ConvertToCKeyMaterialsConfig(config);
EXPECT_STREQ("pem_root_certs", c_config->pem_root_certs());
EXPECT_EQ(1, static_cast<int>(c_config->pem_key_cert_pair_list().size()));
EXPECT_STREQ(pair.private_key.c_str(),
c_config->pem_key_cert_pair_list()[0].private_key());
EXPECT_STREQ(pair.cert_chain.c_str(),
c_config->pem_key_cert_pair_list()[0].cert_chain());
gpr_free(c_config->pem_key_cert_pair_list()[0].private_key());
gpr_free(c_config->pem_key_cert_pair_list()[0].cert_chain());
gpr_free(const_cast<char*>(c_config->pem_root_certs()));
gpr_free(c_config);
}
TEST_F(CredentialsTest, TlsKeyMaterialsModifiers) {
std::shared_ptr<TlsKeyMaterialsConfig> config(new TlsKeyMaterialsConfig());
struct TlsKeyMaterialsConfig::PemKeyCertPair pair = {"private_key",
"cert_chain"};
config->add_pem_key_cert_pair(pair);
config->set_pem_root_certs("pem_root_certs");
EXPECT_STREQ(config->pem_root_certs().c_str(), "pem_root_certs");
std::vector<TlsKeyMaterialsConfig::PemKeyCertPair> list =
config->pem_key_cert_pair_list();
EXPECT_EQ(static_cast<int>(list.size()), 1);
EXPECT_STREQ(list[0].private_key.c_str(), "private_key");
EXPECT_STREQ(list[0].cert_chain.c_str(), "cert_chain");
}
typedef class ::grpc_impl::experimental::TlsCredentialReloadArg
TlsCredentialReloadArg;
typedef class ::grpc_impl::experimental::TlsCredentialReloadConfig
TlsCredentialReloadConfig;
TEST_F(CredentialsTest, TlsCredentialReloadArgCallback) {
grpc_tls_credential_reload_arg* c_arg = new grpc_tls_credential_reload_arg;
c_arg->cb = tls_credential_reload_callback;
c_arg->context = nullptr;
TlsCredentialReloadArg* arg = new TlsCredentialReloadArg(c_arg);
arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW);
arg->OnCredentialReloadDoneCallback();
EXPECT_EQ(arg->status(), GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED);
// Cleanup.
delete arg;
delete c_arg;
}
TEST_F(CredentialsTest, TlsCredentialReloadConfigSchedule) {
std::shared_ptr<TestTlsCredentialReload> test_credential_reload(
new TestTlsCredentialReload());
std::shared_ptr<TlsCredentialReloadConfig> config(
new TlsCredentialReloadConfig(test_credential_reload));
grpc_tls_credential_reload_arg* c_arg =
grpc_core::New<grpc_tls_credential_reload_arg>();
c_arg->context = nullptr;
TlsCredentialReloadArg* arg = new TlsCredentialReloadArg(c_arg);
std::shared_ptr<TlsKeyMaterialsConfig> key_materials_config(
new TlsKeyMaterialsConfig());
struct TlsKeyMaterialsConfig::PemKeyCertPair pair1 = {"private_key1",
"cert_chain1"};
struct TlsKeyMaterialsConfig::PemKeyCertPair pair2 = {"private_key2",
"cert_chain2"};
std::vector<TlsKeyMaterialsConfig::PemKeyCertPair> pair_list = {pair1, pair2};
key_materials_config->set_key_materials("pem_root_certs", pair_list);
arg->set_key_materials_config(key_materials_config);
arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW);
arg->set_error_details("error_details");
grpc_tls_key_materials_config* key_materials_config_before_schedule =
c_arg->key_materials_config;
const char* error_details_before_schedule = c_arg->error_details;
int schedule_output = config->Schedule(arg);
EXPECT_EQ(schedule_output, 0);
EXPECT_STREQ(c_arg->key_materials_config->pem_root_certs(),
"new_pem_root_certs");
grpc_tls_key_materials_config::PemKeyCertPairList c_pair_list =
c_arg->key_materials_config->pem_key_cert_pair_list();
EXPECT_TRUE(!arg->is_pem_key_cert_pair_list_empty());
EXPECT_EQ(static_cast<int>(c_pair_list.size()), 3);
EXPECT_STREQ(c_pair_list[0].private_key(), "private_key1");
EXPECT_STREQ(c_pair_list[0].cert_chain(), "cert_chain1");
EXPECT_STREQ(c_pair_list[1].private_key(), "private_key2");
EXPECT_STREQ(c_pair_list[1].cert_chain(), "cert_chain2");
EXPECT_STREQ(c_pair_list[2].private_key(), "private_key3");
EXPECT_STREQ(c_pair_list[2].cert_chain(), "cert_chain3");
EXPECT_EQ(arg->status(), GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW);
EXPECT_STREQ(arg->error_details().c_str(), "error_details");
// Cleanup.
gpr_free(const_cast<char*>(error_details_before_schedule));
grpc_core::Delete(c_arg->key_materials_config);
if (c_arg->destroy_context != nullptr) {
c_arg->destroy_context(c_arg->context);
}
gpr_free(c_arg);
gpr_free(config->c_config());
}
TEST_F(CredentialsTest, TlsCredentialReloadConfigCppToC) {
std::shared_ptr<TestTlsCredentialReload> test_credential_reload(
new TestTlsCredentialReload());
TlsCredentialReloadConfig config(test_credential_reload);
grpc_tls_credential_reload_arg c_arg;
c_arg.context = nullptr;
c_arg.cb_user_data = static_cast<void*>(nullptr);
grpc_tls_key_materials_config c_key_materials;
grpc::string test_private_key = "private_key";
grpc::string test_cert_chain = "cert_chain";
grpc_ssl_pem_key_cert_pair* ssl_pair =
(grpc_ssl_pem_key_cert_pair*)gpr_malloc(
sizeof(grpc_ssl_pem_key_cert_pair));
ssl_pair->private_key = gpr_strdup(test_private_key.c_str());
ssl_pair->cert_chain = gpr_strdup(test_cert_chain.c_str());
::grpc_core::PemKeyCertPair pem_key_cert_pair =
::grpc_core::PemKeyCertPair(ssl_pair);
::grpc_core::InlinedVector<::grpc_core::PemKeyCertPair, 1>
pem_key_cert_pair_list;
pem_key_cert_pair_list.push_back(pem_key_cert_pair);
grpc::string test_pem_root_certs = "pem_root_certs";
c_key_materials.set_key_materials(
::grpc_core::UniquePtr<char>(gpr_strdup(test_pem_root_certs.c_str())),
pem_key_cert_pair_list);
c_arg.key_materials_config = &c_key_materials;
c_arg.status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
grpc::string test_error_details = "error_details";
c_arg.error_details = test_error_details.c_str();
grpc_tls_credential_reload_config* c_config = config.c_config();
c_arg.config = c_config;
int c_schedule_output = c_config->Schedule(&c_arg);
EXPECT_EQ(c_schedule_output, 0);
EXPECT_EQ(c_arg.cb_user_data, nullptr);
EXPECT_STREQ(c_arg.key_materials_config->pem_root_certs(),
"new_pem_root_certs");
::grpc_core::InlinedVector<::grpc_core::PemKeyCertPair, 1> pair_list =
c_arg.key_materials_config->pem_key_cert_pair_list();
EXPECT_EQ(static_cast<int>(pair_list.size()), 2);
EXPECT_STREQ(pair_list[0].private_key(), "private_key");
EXPECT_STREQ(pair_list[0].cert_chain(), "cert_chain");
EXPECT_STREQ(pair_list[1].private_key(), "private_key3");
EXPECT_STREQ(pair_list[1].cert_chain(), "cert_chain3");
EXPECT_EQ(c_arg.status, GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW);
EXPECT_STREQ(c_arg.error_details, test_error_details.c_str());
// Cleanup.
c_arg.destroy_context(c_arg.context);
::grpc_core::Delete(config.c_config());
}
typedef class ::grpc_impl::experimental::TlsServerAuthorizationCheckArg
TlsServerAuthorizationCheckArg;
typedef class ::grpc_impl::experimental::TlsServerAuthorizationCheckConfig
TlsServerAuthorizationCheckConfig;
TEST_F(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;
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;
const char* error_details_before_callback = c_arg->error_details;
arg->OnServerAuthorizationCheckDoneCallback();
EXPECT_STREQ(static_cast<char*>(arg->cb_user_data()), "cb_user_data");
gpr_free(arg->cb_user_data());
EXPECT_EQ(arg->success(), 1);
EXPECT_STREQ(arg->target_name().c_str(), "callback_target_name");
EXPECT_STREQ(arg->peer_cert().c_str(), "callback_peer_cert");
EXPECT_EQ(arg->status(), GRPC_STATUS_OK);
EXPECT_STREQ(arg->error_details().c_str(), "callback_error_details");
// Cleanup.
gpr_free(const_cast<char*>(target_name_before_callback));
gpr_free(const_cast<char*>(peer_cert_before_callback));
gpr_free(const_cast<char*>(error_details_before_callback));
gpr_free(const_cast<char*>(c_arg->target_name));
gpr_free(const_cast<char*>(c_arg->peer_cert));
gpr_free(const_cast<char*>(c_arg->error_details));
delete arg;
delete c_arg;
}
TEST_F(CredentialsTest, TlsServerAuthorizationCheckConfigSchedule) {
std::shared_ptr<TestTlsServerAuthorizationCheck>
test_server_authorization_check(new TestTlsServerAuthorizationCheck());
TlsServerAuthorizationCheckConfig config(test_server_authorization_check);
grpc_tls_server_authorization_check_arg* c_arg =
grpc_core::New<grpc_tls_server_authorization_check_arg>();
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;
const char* error_details_before_schedule = c_arg->error_details;
int schedule_output = config.Schedule(arg);
EXPECT_EQ(schedule_output, 1);
EXPECT_STREQ(static_cast<char*>(arg->cb_user_data()), "cb_user_data");
EXPECT_EQ(arg->success(), 1);
EXPECT_STREQ(arg->target_name().c_str(), "sync_target_name");
EXPECT_STREQ(arg->peer_cert().c_str(), "sync_peer_cert");
EXPECT_EQ(arg->status(), GRPC_STATUS_OK);
EXPECT_STREQ(arg->error_details().c_str(), "sync_error_details");
// Cleanup.
gpr_free(arg->cb_user_data());
gpr_free(const_cast<char*>(target_name_before_schedule));
gpr_free(const_cast<char*>(peer_cert_before_schedule));
gpr_free(const_cast<char*>(error_details_before_schedule));
gpr_free(const_cast<char*>(c_arg->target_name));
gpr_free(const_cast<char*>(c_arg->peer_cert));
gpr_free(const_cast<char*>(c_arg->error_details));
if (c_arg->destroy_context != nullptr) {
c_arg->destroy_context(c_arg->context);
}
gpr_free(c_arg);
gpr_free(config.c_config());
}
TEST_F(CredentialsTest, TlsServerAuthorizationCheckConfigCppToC) {
std::shared_ptr<TestTlsServerAuthorizationCheck>
test_server_authorization_check(new TestTlsServerAuthorizationCheck());
TlsServerAuthorizationCheckConfig config(test_server_authorization_check);
grpc_tls_server_authorization_check_arg c_arg;
c_arg.cb = tls_server_authorization_check_callback;
c_arg.cb_user_data = nullptr;
c_arg.success = 0;
c_arg.target_name = "target_name";
c_arg.peer_cert = "peer_cert";
c_arg.status = GRPC_STATUS_UNAUTHENTICATED;
c_arg.error_details = "error_details";
c_arg.config = config.c_config();
c_arg.context = nullptr;
int c_schedule_output = (c_arg.config)->Schedule(&c_arg);
EXPECT_EQ(c_schedule_output, 1);
EXPECT_STREQ(static_cast<char*>(c_arg.cb_user_data), "cb_user_data");
EXPECT_EQ(c_arg.success, 1);
EXPECT_STREQ(c_arg.target_name, "sync_target_name");
EXPECT_STREQ(c_arg.peer_cert, "sync_peer_cert");
EXPECT_EQ(c_arg.status, GRPC_STATUS_OK);
EXPECT_STREQ(c_arg.error_details, "sync_error_details");
// Cleanup.
gpr_free(c_arg.cb_user_data);
c_arg.destroy_context(c_arg.context);
gpr_free(const_cast<char*>(c_arg.error_details));
gpr_free(const_cast<char*>(c_arg.target_name));
gpr_free(const_cast<char*>(c_arg.peer_cert));
gpr_free(config.c_config());
}
typedef class ::grpc_impl::experimental::TlsCredentialsOptions
TlsCredentialsOptions;
TEST_F(CredentialsTest, TlsCredentialsOptionsCppToC) {
std::shared_ptr<TlsKeyMaterialsConfig> key_materials_config(
new TlsKeyMaterialsConfig());
struct TlsKeyMaterialsConfig::PemKeyCertPair pair = {"private_key",
"cert_chain"};
std::vector<TlsKeyMaterialsConfig::PemKeyCertPair> pair_list = {pair};
key_materials_config->set_key_materials("pem_root_certs", pair_list);
std::shared_ptr<TestTlsCredentialReload> test_credential_reload(
new TestTlsCredentialReload());
std::shared_ptr<TlsCredentialReloadConfig> credential_reload_config(
new TlsCredentialReloadConfig(test_credential_reload));
std::shared_ptr<TestTlsServerAuthorizationCheck>
test_server_authorization_check(new TestTlsServerAuthorizationCheck());
std::shared_ptr<TlsServerAuthorizationCheckConfig>
server_authorization_check_config(new TlsServerAuthorizationCheckConfig(
test_server_authorization_check));
TlsCredentialsOptions options = TlsCredentialsOptions(
GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY, key_materials_config,
credential_reload_config, server_authorization_check_config);
grpc_tls_credentials_options* c_options = options.c_credentials_options();
EXPECT_EQ(c_options->cert_request_type(),
GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY);
grpc_tls_key_materials_config* c_key_materials_config =
c_options->key_materials_config();
grpc_tls_credential_reload_config* c_credential_reload_config =
c_options->credential_reload_config();
grpc_tls_credential_reload_arg c_credential_reload_arg;
c_credential_reload_arg.cb_user_data = nullptr;
c_credential_reload_arg.key_materials_config =
c_options->key_materials_config();
c_credential_reload_arg.status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
grpc::string test_error_details = "error_details";
c_credential_reload_arg.error_details = test_error_details.c_str();
c_credential_reload_arg.context = nullptr;
grpc_tls_server_authorization_check_config*
c_server_authorization_check_config =
c_options->server_authorization_check_config();
grpc_tls_server_authorization_check_arg c_server_authorization_check_arg;
c_server_authorization_check_arg.cb = tls_server_authorization_check_callback;
c_server_authorization_check_arg.cb_user_data = nullptr;
c_server_authorization_check_arg.success = 0;
c_server_authorization_check_arg.target_name = "target_name";
c_server_authorization_check_arg.peer_cert = "peer_cert";
c_server_authorization_check_arg.status = GRPC_STATUS_UNAUTHENTICATED;
c_server_authorization_check_arg.error_details = "error_details";
c_server_authorization_check_arg.context = nullptr;
EXPECT_STREQ(c_key_materials_config->pem_root_certs(), "pem_root_certs");
EXPECT_EQ(
static_cast<int>(c_key_materials_config->pem_key_cert_pair_list().size()),
1);
EXPECT_STREQ(
c_key_materials_config->pem_key_cert_pair_list()[0].private_key(),
"private_key");
EXPECT_STREQ(c_key_materials_config->pem_key_cert_pair_list()[0].cert_chain(),
"cert_chain");
GPR_ASSERT(c_credential_reload_config != nullptr);
int c_credential_reload_schedule_output =
c_credential_reload_config->Schedule(&c_credential_reload_arg);
EXPECT_EQ(c_credential_reload_schedule_output, 0);
EXPECT_EQ(c_credential_reload_arg.cb_user_data, nullptr);
EXPECT_STREQ(c_credential_reload_arg.key_materials_config->pem_root_certs(),
"new_pem_root_certs");
::grpc_core::InlinedVector<::grpc_core::PemKeyCertPair, 1> c_pair_list =
c_credential_reload_arg.key_materials_config->pem_key_cert_pair_list();
EXPECT_EQ(static_cast<int>(c_pair_list.size()), 2);
EXPECT_STREQ(c_pair_list[0].private_key(), "private_key");
EXPECT_STREQ(c_pair_list[0].cert_chain(), "cert_chain");
EXPECT_STREQ(c_pair_list[1].private_key(), "private_key3");
EXPECT_STREQ(c_pair_list[1].cert_chain(), "cert_chain3");
EXPECT_EQ(c_credential_reload_arg.status,
GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW);
EXPECT_STREQ(c_credential_reload_arg.error_details,
test_error_details.c_str());
int c_server_authorization_check_schedule_output =
c_server_authorization_check_config->Schedule(
&c_server_authorization_check_arg);
EXPECT_EQ(c_server_authorization_check_schedule_output, 1);
EXPECT_STREQ(
static_cast<char*>(c_server_authorization_check_arg.cb_user_data),
"cb_user_data");
EXPECT_EQ(c_server_authorization_check_arg.success, 1);
EXPECT_STREQ(c_server_authorization_check_arg.target_name,
"sync_target_name");
EXPECT_STREQ(c_server_authorization_check_arg.peer_cert, "sync_peer_cert");
EXPECT_EQ(c_server_authorization_check_arg.status, GRPC_STATUS_OK);
EXPECT_STREQ(c_server_authorization_check_arg.error_details,
"sync_error_details");
// Cleanup.
::grpc_core::Delete(c_credential_reload_arg.key_materials_config);
c_credential_reload_arg.destroy_context(c_credential_reload_arg.context);
c_server_authorization_check_arg.destroy_context(
c_server_authorization_check_arg.context);
gpr_free(c_server_authorization_check_arg.cb_user_data);
gpr_free(const_cast<char*>(c_server_authorization_check_arg.target_name));
gpr_free(const_cast<char*>(c_server_authorization_check_arg.peer_cert));
gpr_free(const_cast<char*>(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<TestTlsCredentialReload> test_credential_reload(
new TestTlsCredentialReload());
std::shared_ptr<TlsCredentialReloadConfig> credential_reload_config(
new TlsCredentialReloadConfig(test_credential_reload));
std::shared_ptr<TestTlsServerAuthorizationCheck>
test_server_authorization_check(new TestTlsServerAuthorizationCheck());
std::shared_ptr<TlsServerAuthorizationCheckConfig>
server_authorization_check_config(new TlsServerAuthorizationCheckConfig(
test_server_authorization_check));
TlsCredentialsOptions options = TlsCredentialsOptions(
GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY, nullptr,
credential_reload_config, server_authorization_check_config);
std::shared_ptr<grpc_impl::ChannelCredentials> channel_credentials =
grpc::experimental::TlsCredentials(options);
GPR_ASSERT(channel_credentials != nullptr);
}
TEST_F(CredentialsTest, TlsCredentialReloadConfigErrorMessages) {
std::shared_ptr<TlsCredentialReloadConfig> config(
new TlsCredentialReloadConfig(nullptr));
grpc_tls_credential_reload_arg* c_arg = new grpc_tls_credential_reload_arg;
c_arg->context = nullptr;
TlsCredentialReloadArg* arg = new TlsCredentialReloadArg(c_arg);
int schedule_output = config->Schedule(arg);
EXPECT_EQ(schedule_output, 1);
EXPECT_EQ(arg->status(), GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL);
EXPECT_STREQ(arg->error_details().c_str(),
"the interface of the credential reload config is nullptr");
gpr_free(const_cast<char*>(c_arg->error_details));
arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED);
config->Cancel(arg);
EXPECT_EQ(arg->status(), GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL);
EXPECT_STREQ(arg->error_details().c_str(),
"the interface of the credential reload config is nullptr");
// Cleanup.
gpr_free(const_cast<char*>(c_arg->error_details));
if (c_arg->destroy_context != nullptr) {
c_arg->destroy_context(c_arg->context);
}
delete c_arg;
gpr_free(config->c_config());
}
TEST_F(CredentialsTest, TlsServerAuthorizationCheckConfigErrorMessages) {
std::shared_ptr<TlsServerAuthorizationCheckConfig> config(
new TlsServerAuthorizationCheckConfig(nullptr));
grpc_tls_server_authorization_check_arg* c_arg =
new grpc_tls_server_authorization_check_arg;
c_arg->context = nullptr;
TlsServerAuthorizationCheckArg* arg =
new TlsServerAuthorizationCheckArg(c_arg);
int schedule_output = config->Schedule(arg);
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");
gpr_free(const_cast<char*>(c_arg->error_details));
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.
gpr_free(const_cast<char*>(c_arg->error_details));
if (c_arg->destroy_context != nullptr) {
c_arg->destroy_context(c_arg->context);
}
delete c_arg;
gpr_free(config->c_config());
}
} // namespace testing
} // namespace grpc

@ -1024,6 +1024,7 @@ include/grpcpp/security/credentials.h \
include/grpcpp/security/credentials_impl.h \
include/grpcpp/security/server_credentials.h \
include/grpcpp/security/server_credentials_impl.h \
include/grpcpp/security/tls_credentials_options.h \
include/grpcpp/server.h \
include/grpcpp/server_builder.h \
include/grpcpp/server_builder_impl.h \

@ -1026,6 +1026,7 @@ include/grpcpp/security/credentials.h \
include/grpcpp/security/credentials_impl.h \
include/grpcpp/security/server_credentials.h \
include/grpcpp/security/server_credentials_impl.h \
include/grpcpp/security/tls_credentials_options.h \
include/grpcpp/server.h \
include/grpcpp/server_builder.h \
include/grpcpp/server_builder_impl.h \
@ -1264,6 +1265,9 @@ 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_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 \

Loading…
Cancel
Save