diff options
Diffstat (limited to 'src/core/lib/security/security_connector')
-rw-r--r-- | src/core/lib/security/security_connector/security_connector.cc | 35 | ||||
-rw-r--r-- | src/core/lib/security/security_connector/security_connector.h | 1 |
2 files changed, 31 insertions, 5 deletions
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. |