|
|
|
@ -39,7 +39,6 @@ |
|
|
|
|
#include "src/core/lib/surface/api_trace.h" |
|
|
|
|
#include "src/core/tsi/ssl/session_cache/ssl_session_cache.h" |
|
|
|
|
#include "src/core/tsi/ssl_transport_security.h" |
|
|
|
|
#include "src/core/tsi/transport_security_interface.h" |
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// SSL Channel Credentials.
|
|
|
|
@ -49,27 +48,6 @@ grpc_ssl_credentials::grpc_ssl_credentials( |
|
|
|
|
const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, |
|
|
|
|
const grpc_ssl_verify_peer_options* verify_options) { |
|
|
|
|
build_config(pem_root_certs, pem_key_cert_pair, verify_options); |
|
|
|
|
// Use default (e.g. OS) root certificates if the user did not pass any root
|
|
|
|
|
// certificates.
|
|
|
|
|
if (config_.pem_root_certs == nullptr) { |
|
|
|
|
const char* pem_root_certs = |
|
|
|
|
grpc_core::DefaultSslRootStore::GetPemRootCerts(); |
|
|
|
|
if (pem_root_certs == nullptr) { |
|
|
|
|
gpr_log(GPR_ERROR, "Could not get default pem root certs."); |
|
|
|
|
} else { |
|
|
|
|
size_t root_len = strlen(pem_root_certs); |
|
|
|
|
char* default_roots = strcpy(new char[root_len + 1], pem_root_certs); |
|
|
|
|
config_.pem_root_certs = default_roots; |
|
|
|
|
root_store_ = grpc_core::DefaultSslRootStore::GetRootStore(); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
config_.pem_root_certs = config_.pem_root_certs; |
|
|
|
|
root_store_ = nullptr; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
client_handshaker_initialization_status_ = InitializeClientHandshakerFactory( |
|
|
|
|
&config_, config_.pem_root_certs, root_store_, nullptr, |
|
|
|
|
&client_handshaker_factory_); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
grpc_ssl_credentials::~grpc_ssl_credentials() { |
|
|
|
@ -79,67 +57,26 @@ grpc_ssl_credentials::~grpc_ssl_credentials() { |
|
|
|
|
config_.verify_options.verify_peer_destruct( |
|
|
|
|
config_.verify_options.verify_peer_callback_userdata); |
|
|
|
|
} |
|
|
|
|
tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory_); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
grpc_core::RefCountedPtr<grpc_channel_security_connector> |
|
|
|
|
grpc_ssl_credentials::create_security_connector( |
|
|
|
|
grpc_core::RefCountedPtr<grpc_call_credentials> call_creds, |
|
|
|
|
const char* target, grpc_core::ChannelArgs* args) { |
|
|
|
|
if (config_.pem_root_certs == nullptr) { |
|
|
|
|
gpr_log(GPR_ERROR, |
|
|
|
|
"No root certs in config. Client-side security connector must have " |
|
|
|
|
"root certs."); |
|
|
|
|
return nullptr; |
|
|
|
|
} |
|
|
|
|
absl::optional<std::string> overridden_target_name = |
|
|
|
|
args->GetOwnedString(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG); |
|
|
|
|
auto* ssl_session_cache = args->GetObject<tsi::SslSessionLRUCache>(); |
|
|
|
|
tsi_ssl_session_cache* session_cache = |
|
|
|
|
ssl_session_cache == nullptr ? nullptr : ssl_session_cache->c_ptr(); |
|
|
|
|
|
|
|
|
|
grpc_core::RefCountedPtr<grpc_channel_security_connector> security_connector = |
|
|
|
|
nullptr; |
|
|
|
|
if (session_cache != nullptr) { |
|
|
|
|
// We need a separate factory and SSL_CTX if there's a cache in the channel
|
|
|
|
|
// args. SSL_CTX should live with the factory and that should live on the
|
|
|
|
|
// credentials. However, there is a way to configure a session cache in the
|
|
|
|
|
// channel args, so that prevents us from also keeping the session cache at
|
|
|
|
|
// the credentials level. In the case of a session cache, we still need to
|
|
|
|
|
// keep a separate factory and SSL_CTX at the subchannel/security_connector
|
|
|
|
|
// level.
|
|
|
|
|
tsi_ssl_client_handshaker_factory* factory_with_cache = nullptr; |
|
|
|
|
grpc_security_status status = InitializeClientHandshakerFactory( |
|
|
|
|
&config_, config_.pem_root_certs, root_store_, session_cache, |
|
|
|
|
&factory_with_cache); |
|
|
|
|
if (status != GRPC_SECURITY_OK) { |
|
|
|
|
gpr_log(GPR_ERROR, |
|
|
|
|
"InitializeClientHandshakerFactory returned bad " |
|
|
|
|
"status."); |
|
|
|
|
return nullptr; |
|
|
|
|
} |
|
|
|
|
security_connector = grpc_ssl_channel_security_connector_create( |
|
|
|
|
this->Ref(), std::move(call_creds), &config_, target, |
|
|
|
|
overridden_target_name.has_value() ? overridden_target_name->c_str() |
|
|
|
|
: nullptr, |
|
|
|
|
factory_with_cache); |
|
|
|
|
tsi_ssl_client_handshaker_factory_unref(factory_with_cache); |
|
|
|
|
} else { |
|
|
|
|
if (client_handshaker_initialization_status_ != GRPC_SECURITY_OK) { |
|
|
|
|
return nullptr; |
|
|
|
|
} |
|
|
|
|
security_connector = grpc_ssl_channel_security_connector_create( |
|
|
|
|
this->Ref(), std::move(call_creds), &config_, target, |
|
|
|
|
overridden_target_name.has_value() ? overridden_target_name->c_str() |
|
|
|
|
: nullptr, |
|
|
|
|
client_handshaker_factory_); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (security_connector == nullptr) { |
|
|
|
|
return security_connector; |
|
|
|
|
grpc_core::RefCountedPtr<grpc_channel_security_connector> sc = |
|
|
|
|
grpc_ssl_channel_security_connector_create( |
|
|
|
|
this->Ref(), std::move(call_creds), &config_, target, |
|
|
|
|
overridden_target_name.has_value() ? overridden_target_name->c_str() |
|
|
|
|
: nullptr, |
|
|
|
|
ssl_session_cache == nullptr ? nullptr : ssl_session_cache->c_ptr()); |
|
|
|
|
if (sc == nullptr) { |
|
|
|
|
return sc; |
|
|
|
|
} |
|
|
|
|
*args = args->Set(GRPC_ARG_HTTP2_SCHEME, "https"); |
|
|
|
|
return security_connector; |
|
|
|
|
return sc; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
grpc_core::UniqueTypeName grpc_ssl_credentials::Type() { |
|
|
|
@ -182,50 +119,6 @@ void grpc_ssl_credentials::set_max_tls_version( |
|
|
|
|
config_.max_tls_version = max_tls_version; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
grpc_security_status grpc_ssl_credentials::InitializeClientHandshakerFactory( |
|
|
|
|
const grpc_ssl_config* config, const char* pem_root_certs, |
|
|
|
|
const tsi_ssl_root_certs_store* root_store, |
|
|
|
|
tsi_ssl_session_cache* ssl_session_cache, |
|
|
|
|
tsi_ssl_client_handshaker_factory** handshaker_factory) { |
|
|
|
|
// This class level factory can't have a session cache by design. If we want
|
|
|
|
|
// to init one with a cache we need to make a new one
|
|
|
|
|
if (client_handshaker_factory_ != nullptr && ssl_session_cache == nullptr) { |
|
|
|
|
return GRPC_SECURITY_OK; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool has_key_cert_pair = config->pem_key_cert_pair != nullptr && |
|
|
|
|
config->pem_key_cert_pair->private_key != nullptr && |
|
|
|
|
config->pem_key_cert_pair->cert_chain != nullptr; |
|
|
|
|
tsi_ssl_client_handshaker_options options; |
|
|
|
|
if (pem_root_certs == nullptr) { |
|
|
|
|
gpr_log( |
|
|
|
|
GPR_ERROR, |
|
|
|
|
"Handshaker factory creation failed. pem_root_certs cannot be nullptr"); |
|
|
|
|
return GRPC_SECURITY_ERROR; |
|
|
|
|
} |
|
|
|
|
options.pem_root_certs = pem_root_certs; |
|
|
|
|
options.root_store = root_store; |
|
|
|
|
options.alpn_protocols = |
|
|
|
|
grpc_fill_alpn_protocol_strings(&options.num_alpn_protocols); |
|
|
|
|
if (has_key_cert_pair) { |
|
|
|
|
options.pem_key_cert_pair = config->pem_key_cert_pair; |
|
|
|
|
} |
|
|
|
|
options.cipher_suites = grpc_get_ssl_cipher_suites(); |
|
|
|
|
options.session_cache = ssl_session_cache; |
|
|
|
|
options.min_tls_version = grpc_get_tsi_tls_version(config->min_tls_version); |
|
|
|
|
options.max_tls_version = grpc_get_tsi_tls_version(config->max_tls_version); |
|
|
|
|
const tsi_result result = |
|
|
|
|
tsi_create_ssl_client_handshaker_factory_with_options(&options, |
|
|
|
|
handshaker_factory); |
|
|
|
|
gpr_free(options.alpn_protocols); |
|
|
|
|
if (result != TSI_OK) { |
|
|
|
|
gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", |
|
|
|
|
tsi_result_to_string(result)); |
|
|
|
|
return GRPC_SECURITY_ERROR; |
|
|
|
|
} |
|
|
|
|
return GRPC_SECURITY_OK; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Deprecated in favor of grpc_ssl_credentials_create_ex. Will be removed
|
|
|
|
|
// once all of its call sites are migrated to grpc_ssl_credentials_create_ex.
|
|
|
|
|
grpc_channel_credentials* grpc_ssl_credentials_create( |
|
|
|
|