aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar Ian Haken <ihaken@netflix.com>2017-10-26 14:34:15 -0700
committerGravatar Ian Haken <ihaken@netflix.com>2018-06-12 12:59:37 -0700
commit68eff58df61bfde1b438d109c197f1a260230a68 (patch)
treee9ac198d2eadb06927ae527cd0d362b4dd3ffddb /src/core
parentf91adce31c6ac38aec2490e0337cec8430d3a26c (diff)
Create verify_peer_options when creating ssl credentials in order to expose a verification callback option.
These options are not yet exposed to languages outside of core.
Diffstat (limited to 'src/core')
-rw-r--r--src/core/lib/security/credentials/google_default/google_default_credentials.cc3
-rw-r--r--src/core/lib/security/credentials/ssl/ssl_credentials.cc20
-rw-r--r--src/core/lib/security/security_connector/security_connector.cc35
-rw-r--r--src/core/lib/security/security_connector/security_connector.h1
4 files changed, 50 insertions, 9 deletions
diff --git a/src/core/lib/security/credentials/google_default/google_default_credentials.cc b/src/core/lib/security/credentials/google_default/google_default_credentials.cc
index 38c9175717..c456ffaf5d 100644
--- a/src/core/lib/security/credentials/google_default/google_default_credentials.cc
+++ b/src/core/lib/security/credentials/google_default/google_default_credentials.cc
@@ -231,7 +231,8 @@ end:
creds->base.vtable = &google_default_credentials_vtable;
creds->base.type = GRPC_CHANNEL_CREDENTIALS_TYPE_GOOGLE_DEFAULT;
gpr_ref_init(&creds->base.refcount, 1);
- creds->ssl_creds = grpc_ssl_credentials_create(nullptr, nullptr, nullptr);
+ creds->ssl_creds =
+ grpc_ssl_credentials_create(nullptr, nullptr, nullptr, nullptr);
GPR_ASSERT(creds->ssl_creds != nullptr);
grpc_alts_credentials_options* options =
grpc_alts_credentials_client_options_create();
diff --git a/src/core/lib/security/credentials/ssl/ssl_credentials.cc b/src/core/lib/security/credentials/ssl/ssl_credentials.cc
index 2b6377d3ec..3d6f2f200a 100644
--- a/src/core/lib/security/credentials/ssl/ssl_credentials.cc
+++ b/src/core/lib/security/credentials/ssl/ssl_credentials.cc
@@ -48,6 +48,10 @@ static void ssl_destruct(grpc_channel_credentials* creds) {
grpc_ssl_credentials* c = reinterpret_cast<grpc_ssl_credentials*>(creds);
gpr_free(c->config.pem_root_certs);
grpc_tsi_ssl_pem_key_cert_pairs_destroy(c->config.pem_key_cert_pair, 1);
+ if (c->config.verify_options.verify_peer_destruct != nullptr) {
+ c->config.verify_options.verify_peer_destruct(
+ c->config.verify_options.verify_peer_callback_userdata);
+ }
}
static grpc_security_status ssl_create_security_connector(
@@ -87,6 +91,7 @@ static grpc_channel_credentials_vtable ssl_vtable = {
static void ssl_build_config(const char* pem_root_certs,
grpc_ssl_pem_key_cert_pair* pem_key_cert_pair,
+ const verify_peer_options* verify_options,
grpc_ssl_config* config) {
if (pem_root_certs != nullptr) {
config->pem_root_certs = gpr_strdup(pem_root_certs);
@@ -101,23 +106,32 @@ static void ssl_build_config(const char* pem_root_certs,
config->pem_key_cert_pair->private_key =
gpr_strdup(pem_key_cert_pair->private_key);
}
+ if (verify_options != nullptr) {
+ memcpy(&config->verify_options, verify_options,
+ sizeof(verify_peer_options));
+ } else {
+ // Otherwise set all options to default values
+ memset(&config->verify_options, 0, sizeof(verify_peer_options));
+ }
}
grpc_channel_credentials* grpc_ssl_credentials_create(
const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pair,
- void* reserved) {
+ const verify_peer_options* verify_options, void* reserved) {
grpc_ssl_credentials* c = static_cast<grpc_ssl_credentials*>(
gpr_zalloc(sizeof(grpc_ssl_credentials)));
GRPC_API_TRACE(
"grpc_ssl_credentials_create(pem_root_certs=%s, "
"pem_key_cert_pair=%p, "
+ "verify_options=%p, "
"reserved=%p)",
- 3, (pem_root_certs, pem_key_cert_pair, reserved));
+ 4, (pem_root_certs, pem_key_cert_pair, verify_options, reserved));
GPR_ASSERT(reserved == nullptr);
c->base.type = GRPC_CHANNEL_CREDENTIALS_TYPE_SSL;
c->base.vtable = &ssl_vtable;
gpr_ref_init(&c->base.refcount, 1);
- ssl_build_config(pem_root_certs, pem_key_cert_pair, &c->config);
+ ssl_build_config(pem_root_certs, pem_key_cert_pair, verify_options,
+ &c->config);
return &c->base;
}
diff --git a/src/core/lib/security/security_connector/security_connector.cc b/src/core/lib/security/security_connector/security_connector.cc
index b54a7643e4..cc72bb6164 100644
--- a/src/core/lib/security/security_connector/security_connector.cc
+++ b/src/core/lib/security/security_connector/security_connector.cc
@@ -620,6 +620,7 @@ typedef struct {
tsi_ssl_client_handshaker_factory* client_handshaker_factory;
char* target_name;
char* overridden_target_name;
+ const verify_peer_options* verify_options;
} grpc_ssl_channel_security_connector;
typedef struct {
@@ -878,11 +879,34 @@ static void ssl_channel_check_peer(grpc_security_connector* sc, tsi_peer peer,
grpc_closure* on_peer_checked) {
grpc_ssl_channel_security_connector* c =
reinterpret_cast<grpc_ssl_channel_security_connector*>(sc);
- grpc_error* error = ssl_check_peer(sc,
- c->overridden_target_name != nullptr
- ? c->overridden_target_name
- : c->target_name,
- &peer, auth_context);
+ const char* target_name = c->overridden_target_name != nullptr
+ ? c->overridden_target_name
+ : c->target_name;
+ grpc_error* error = ssl_check_peer(sc, target_name, &peer, auth_context);
+ if (error == GRPC_ERROR_NONE &&
+ c->verify_options->verify_peer_callback != nullptr) {
+ const tsi_peer_property* p =
+ tsi_peer_get_property_by_name(&peer, TSI_X509_PEM_CERT_PROPERTY);
+ if (p == nullptr) {
+ error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+ "Cannot check peer: missing pem cert property.");
+ } else {
+ char* peer_pem = static_cast<char*>(gpr_malloc(p->value.length + 1));
+ memcpy(peer_pem, p->value.data, p->value.length);
+ peer_pem[p->value.length] = '\0';
+ int callback_status = c->verify_options->verify_peer_callback(
+ target_name, peer_pem,
+ c->verify_options->verify_peer_callback_userdata);
+ gpr_free(peer_pem);
+ if (callback_status) {
+ char* msg;
+ gpr_asprintf(&msg, "Verify peer callback returned a failure (%d)",
+ callback_status);
+ error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
+ gpr_free(msg);
+ }
+ }
+ }
GRPC_CLOSURE_SCHED(on_peer_checked, error);
tsi_peer_destruct(&peer);
}
@@ -1047,6 +1071,7 @@ grpc_security_status grpc_ssl_channel_security_connector_create(
if (overridden_target_name != nullptr) {
c->overridden_target_name = gpr_strdup(overridden_target_name);
}
+ c->verify_options = &config->verify_options;
has_key_cert_pair = config->pem_key_cert_pair != nullptr &&
config->pem_key_cert_pair->private_key != nullptr &&
diff --git a/src/core/lib/security/security_connector/security_connector.h b/src/core/lib/security/security_connector/security_connector.h
index f9723166d0..67a506b576 100644
--- a/src/core/lib/security/security_connector/security_connector.h
+++ b/src/core/lib/security/security_connector/security_connector.h
@@ -193,6 +193,7 @@ grpc_server_security_connector* grpc_fake_server_security_connector_create(
typedef struct {
tsi_ssl_pem_key_cert_pair* pem_key_cert_pair;
char* pem_root_certs;
+ verify_peer_options verify_options;
} grpc_ssl_config;
/* Creates an SSL channel_security_connector.