Security connector is now responsible for the handshake.

pull/3027/head
Julien Boeuf 9 years ago
parent 10cab1396f
commit 87047d7e93
  1. 8
      BUILD
  2. 4
      Makefile
  3. 4
      build.json
  4. 6
      gRPC.podspec
  5. 28
      src/core/httpcli/httpcli_security_connector.c
  6. 176
      src/core/security/handshake.c
  7. 20
      src/core/security/handshake.h
  8. 93
      src/core/security/security_connector.c
  9. 20
      src/core/security/security_connector.h
  10. 12
      src/core/security/server_secure_chttp2.c
  11. 14
      src/core/surface/secure_channel_create.c
  12. 4
      tools/doxygen/Doxyfile.core.internal
  13. 6
      tools/run_tests/sources_and_headers.json
  14. 1
      tools/run_tests/tests.json
  15. 6
      vsprojects/grpc/grpc.vcxproj
  16. 12
      vsprojects/grpc/grpc.vcxproj.filters

@ -133,10 +133,10 @@ cc_library(
"src/core/security/auth_filters.h",
"src/core/security/base64.h",
"src/core/security/credentials.h",
"src/core/security/handshake.h",
"src/core/security/json_token.h",
"src/core/security/jwt_verifier.h",
"src/core/security/secure_endpoint.h",
"src/core/security/secure_transport_setup.h",
"src/core/security/security_connector.h",
"src/core/security/security_context.h",
"src/core/tsi/fake_transport_security.h",
@ -253,10 +253,10 @@ cc_library(
"src/core/security/credentials_posix.c",
"src/core/security/credentials_win32.c",
"src/core/security/google_default_credentials.c",
"src/core/security/handshake.c",
"src/core/security/json_token.c",
"src/core/security/jwt_verifier.c",
"src/core/security/secure_endpoint.c",
"src/core/security/secure_transport_setup.c",
"src/core/security/security_connector.c",
"src/core/security/security_context.c",
"src/core/security/server_auth_filter.c",
@ -1003,10 +1003,10 @@ objc_library(
"src/core/security/credentials_posix.c",
"src/core/security/credentials_win32.c",
"src/core/security/google_default_credentials.c",
"src/core/security/handshake.c",
"src/core/security/json_token.c",
"src/core/security/jwt_verifier.c",
"src/core/security/secure_endpoint.c",
"src/core/security/secure_transport_setup.c",
"src/core/security/security_connector.c",
"src/core/security/security_context.c",
"src/core/security/server_auth_filter.c",
@ -1146,10 +1146,10 @@ objc_library(
"src/core/security/auth_filters.h",
"src/core/security/base64.h",
"src/core/security/credentials.h",
"src/core/security/handshake.h",
"src/core/security/json_token.h",
"src/core/security/jwt_verifier.h",
"src/core/security/secure_endpoint.h",
"src/core/security/secure_transport_setup.h",
"src/core/security/security_connector.h",
"src/core/security/security_context.h",
"src/core/tsi/fake_transport_security.h",

@ -4067,10 +4067,10 @@ LIBGRPC_SRC = \
src/core/security/credentials_posix.c \
src/core/security/credentials_win32.c \
src/core/security/google_default_credentials.c \
src/core/security/handshake.c \
src/core/security/json_token.c \
src/core/security/jwt_verifier.c \
src/core/security/secure_endpoint.c \
src/core/security/secure_transport_setup.c \
src/core/security/security_connector.c \
src/core/security/security_context.c \
src/core/security/server_auth_filter.c \
@ -20637,10 +20637,10 @@ src/core/security/credentials_metadata.c: $(OPENSSL_DEP)
src/core/security/credentials_posix.c: $(OPENSSL_DEP)
src/core/security/credentials_win32.c: $(OPENSSL_DEP)
src/core/security/google_default_credentials.c: $(OPENSSL_DEP)
src/core/security/handshake.c: $(OPENSSL_DEP)
src/core/security/json_token.c: $(OPENSSL_DEP)
src/core/security/jwt_verifier.c: $(OPENSSL_DEP)
src/core/security/secure_endpoint.c: $(OPENSSL_DEP)
src/core/security/secure_transport_setup.c: $(OPENSSL_DEP)
src/core/security/security_connector.c: $(OPENSSL_DEP)
src/core/security/security_context.c: $(OPENSSL_DEP)
src/core/security/server_auth_filter.c: $(OPENSSL_DEP)

@ -470,10 +470,10 @@
"src/core/security/auth_filters.h",
"src/core/security/base64.h",
"src/core/security/credentials.h",
"src/core/security/handshake.h",
"src/core/security/json_token.h",
"src/core/security/jwt_verifier.h",
"src/core/security/secure_endpoint.h",
"src/core/security/secure_transport_setup.h",
"src/core/security/security_connector.h",
"src/core/security/security_context.h",
"src/core/tsi/fake_transport_security.h",
@ -490,10 +490,10 @@
"src/core/security/credentials_posix.c",
"src/core/security/credentials_win32.c",
"src/core/security/google_default_credentials.c",
"src/core/security/handshake.c",
"src/core/security/json_token.c",
"src/core/security/jwt_verifier.c",
"src/core/security/secure_endpoint.c",
"src/core/security/secure_transport_setup.c",
"src/core/security/security_connector.c",
"src/core/security/security_context.c",
"src/core/security/server_auth_filter.c",

@ -135,10 +135,10 @@ Pod::Spec.new do |s|
'src/core/security/auth_filters.h',
'src/core/security/base64.h',
'src/core/security/credentials.h',
'src/core/security/handshake.h',
'src/core/security/json_token.h',
'src/core/security/jwt_verifier.h',
'src/core/security/secure_endpoint.h',
'src/core/security/secure_transport_setup.h',
'src/core/security/security_connector.h',
'src/core/security/security_context.h',
'src/core/tsi/fake_transport_security.h',
@ -262,10 +262,10 @@ Pod::Spec.new do |s|
'src/core/security/credentials_posix.c',
'src/core/security/credentials_win32.c',
'src/core/security/google_default_credentials.c',
'src/core/security/handshake.c',
'src/core/security/json_token.c',
'src/core/security/jwt_verifier.c',
'src/core/security/secure_endpoint.c',
'src/core/security/secure_transport_setup.c',
'src/core/security/security_connector.c',
'src/core/security/security_context.c',
'src/core/security/server_auth_filter.c',
@ -404,10 +404,10 @@ Pod::Spec.new do |s|
'src/core/security/auth_filters.h',
'src/core/security/base64.h',
'src/core/security/credentials.h',
'src/core/security/handshake.h',
'src/core/security/json_token.h',
'src/core/security/jwt_verifier.h',
'src/core/security/secure_endpoint.h',
'src/core/security/secure_transport_setup.h',
'src/core/security/security_connector.h',
'src/core/security/security_context.h',
'src/core/tsi/fake_transport_security.h',

@ -35,7 +35,7 @@
#include <string.h>
#include "src/core/security/secure_transport_setup.h"
#include "src/core/security/handshake.h"
#include "src/core/support/string.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
@ -55,23 +55,31 @@ static void httpcli_ssl_destroy(grpc_security_connector *sc) {
tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
}
if (c->secure_peer_name != NULL) gpr_free(c->secure_peer_name);
tsi_handshaker_destroy(sc->handshaker);
gpr_free(sc);
}
static grpc_security_status httpcli_ssl_create_handshaker(
grpc_security_connector *sc, tsi_handshaker **handshaker) {
static void httpcli_ssl_do_handshake(
grpc_security_connector *sc, grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb, void *user_data) {
grpc_httpcli_ssl_channel_security_connector *c =
(grpc_httpcli_ssl_channel_security_connector *)sc;
tsi_result result = TSI_OK;
if (c->handshaker_factory == NULL) return GRPC_SECURITY_ERROR;
if (c->handshaker_factory == NULL) {
cb(user_data, GRPC_SECURITY_ERROR, nonsecure_endpoint, NULL);
return;
}
tsi_handshaker_destroy(sc->handshaker);
sc->handshaker = NULL;
result = tsi_ssl_handshaker_factory_create_handshaker(
c->handshaker_factory, c->secure_peer_name, handshaker);
c->handshaker_factory, c->secure_peer_name, &sc->handshaker);
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
tsi_result_to_string(result));
return GRPC_SECURITY_ERROR;
cb(user_data, GRPC_SECURITY_ERROR, nonsecure_endpoint, NULL);
} else {
grpc_do_security_handshake(sc, nonsecure_endpoint, cb, user_data);
}
return GRPC_SECURITY_OK;
}
static grpc_security_status httpcli_ssl_check_peer(grpc_security_connector *sc,
@ -94,7 +102,7 @@ static grpc_security_status httpcli_ssl_check_peer(grpc_security_connector *sc,
}
static grpc_security_connector_vtable httpcli_ssl_vtable = {
httpcli_ssl_destroy, httpcli_ssl_create_handshaker, httpcli_ssl_check_peer};
httpcli_ssl_destroy, httpcli_ssl_do_handshake, httpcli_ssl_check_peer};
static grpc_security_status httpcli_ssl_channel_security_connector_create(
const unsigned char *pem_root_certs, size_t pem_root_certs_size,
@ -169,8 +177,8 @@ static void ssl_handshake(void *arg, grpc_endpoint *tcp, const char *host,
GPR_ASSERT(httpcli_ssl_channel_security_connector_create(
pem_root_certs, pem_root_certs_size, host, &sc) ==
GRPC_SECURITY_OK);
grpc_setup_secure_transport(&sc->base, tcp, on_secure_transport_setup_done,
c);
grpc_security_connector_do_handshake(&sc->base, tcp,
on_secure_transport_setup_done, c);
GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "httpcli");
}

@ -31,7 +31,7 @@
*
*/
#include "src/core/security/secure_transport_setup.h"
#include "src/core/security/handshake.h"
#include <string.h>
@ -44,126 +44,125 @@
typedef struct {
grpc_security_connector *connector;
tsi_handshaker *handshaker;
unsigned char *handshake_buffer;
size_t handshake_buffer_size;
grpc_endpoint *wrapped_endpoint;
grpc_endpoint *secure_endpoint;
gpr_slice_buffer left_overs;
grpc_secure_transport_setup_done_cb cb;
grpc_security_handshake_done_cb cb;
void *user_data;
} grpc_secure_transport_setup;
} grpc_security_handshake;
static void on_handshake_data_received_from_peer(void *setup, gpr_slice *slices,
static void on_handshake_data_received_from_peer(void *handshake,
gpr_slice *slices,
size_t nslices,
grpc_endpoint_cb_status error);
static void on_handshake_data_sent_to_peer(void *setup,
static void on_handshake_data_sent_to_peer(void *handshake,
grpc_endpoint_cb_status error);
static void secure_transport_setup_done(grpc_secure_transport_setup *s,
int is_success) {
static void security_handshake_done(grpc_security_handshake *h,
int is_success) {
if (is_success) {
s->cb(s->user_data, GRPC_SECURITY_OK, s->wrapped_endpoint,
s->secure_endpoint);
h->cb(h->user_data, GRPC_SECURITY_OK, h->wrapped_endpoint,
h->secure_endpoint);
} else {
if (s->secure_endpoint != NULL) {
grpc_endpoint_shutdown(s->secure_endpoint);
grpc_endpoint_destroy(s->secure_endpoint);
if (h->secure_endpoint != NULL) {
grpc_endpoint_shutdown(h->secure_endpoint);
grpc_endpoint_destroy(h->secure_endpoint);
} else {
grpc_endpoint_destroy(s->wrapped_endpoint);
grpc_endpoint_destroy(h->wrapped_endpoint);
}
s->cb(s->user_data, GRPC_SECURITY_ERROR, s->wrapped_endpoint, NULL);
h->cb(h->user_data, GRPC_SECURITY_ERROR, h->wrapped_endpoint, NULL);
}
if (s->handshaker != NULL) tsi_handshaker_destroy(s->handshaker);
if (s->handshake_buffer != NULL) gpr_free(s->handshake_buffer);
gpr_slice_buffer_destroy(&s->left_overs);
GRPC_SECURITY_CONNECTOR_UNREF(s->connector, "secure_transport_setup");
gpr_free(s);
if (h->handshake_buffer != NULL) gpr_free(h->handshake_buffer);
gpr_slice_buffer_destroy(&h->left_overs);
gpr_free(h);
}
static void on_peer_checked(void *user_data, grpc_security_status status) {
grpc_secure_transport_setup *s = user_data;
grpc_security_handshake *h = user_data;
tsi_frame_protector *protector;
tsi_result result;
if (status != GRPC_SECURITY_OK) {
gpr_log(GPR_ERROR, "Error checking peer.");
secure_transport_setup_done(s, 0);
security_handshake_done(h, 0);
return;
}
result =
tsi_handshaker_create_frame_protector(s->handshaker, NULL, &protector);
result = tsi_handshaker_create_frame_protector(h->connector->handshaker, NULL,
&protector);
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Frame protector creation failed with error %s.",
tsi_result_to_string(result));
secure_transport_setup_done(s, 0);
security_handshake_done(h, 0);
return;
}
s->secure_endpoint =
grpc_secure_endpoint_create(protector, s->wrapped_endpoint,
s->left_overs.slices, s->left_overs.count);
secure_transport_setup_done(s, 1);
h->secure_endpoint =
grpc_secure_endpoint_create(protector, h->wrapped_endpoint,
h->left_overs.slices, h->left_overs.count);
security_handshake_done(h, 1);
return;
}
static void check_peer(grpc_secure_transport_setup *s) {
static void check_peer(grpc_security_handshake *h) {
grpc_security_status peer_status;
tsi_peer peer;
tsi_result result = tsi_handshaker_extract_peer(s->handshaker, &peer);
tsi_result result =
tsi_handshaker_extract_peer(h->connector->handshaker, &peer);
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Peer extraction failed with error %s",
tsi_result_to_string(result));
secure_transport_setup_done(s, 0);
security_handshake_done(h, 0);
return;
}
peer_status = grpc_security_connector_check_peer(s->connector, peer,
on_peer_checked, s);
peer_status = grpc_security_connector_check_peer(h->connector, peer,
on_peer_checked, h);
if (peer_status == GRPC_SECURITY_ERROR) {
gpr_log(GPR_ERROR, "Peer check failed.");
secure_transport_setup_done(s, 0);
security_handshake_done(h, 0);
return;
} else if (peer_status == GRPC_SECURITY_OK) {
on_peer_checked(s, peer_status);
on_peer_checked(h, peer_status);
}
}
static void send_handshake_bytes_to_peer(grpc_secure_transport_setup *s) {
static void send_handshake_bytes_to_peer(grpc_security_handshake *h) {
size_t offset = 0;
tsi_result result = TSI_OK;
gpr_slice to_send;
grpc_endpoint_write_status write_status;
do {
size_t to_send_size = s->handshake_buffer_size - offset;
size_t to_send_size = h->handshake_buffer_size - offset;
result = tsi_handshaker_get_bytes_to_send_to_peer(
s->handshaker, s->handshake_buffer + offset, &to_send_size);
h->connector->handshaker, h->handshake_buffer + offset, &to_send_size);
offset += to_send_size;
if (result == TSI_INCOMPLETE_DATA) {
s->handshake_buffer_size *= 2;
s->handshake_buffer =
gpr_realloc(s->handshake_buffer, s->handshake_buffer_size);
h->handshake_buffer_size *= 2;
h->handshake_buffer =
gpr_realloc(h->handshake_buffer, h->handshake_buffer_size);
}
} while (result == TSI_INCOMPLETE_DATA);
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Handshake failed with error %s",
tsi_result_to_string(result));
secure_transport_setup_done(s, 0);
security_handshake_done(h, 0);
return;
}
to_send =
gpr_slice_from_copied_buffer((const char *)s->handshake_buffer, offset);
gpr_slice_from_copied_buffer((const char *)h->handshake_buffer, offset);
/* TODO(klempner,jboeuf): This should probably use the client setup
deadline */
write_status = grpc_endpoint_write(s->wrapped_endpoint, &to_send, 1,
on_handshake_data_sent_to_peer, s);
write_status = grpc_endpoint_write(h->wrapped_endpoint, &to_send, 1,
on_handshake_data_sent_to_peer, h);
if (write_status == GRPC_ENDPOINT_WRITE_ERROR) {
gpr_log(GPR_ERROR, "Could not send handshake data to peer.");
secure_transport_setup_done(s, 0);
security_handshake_done(h, 0);
} else if (write_status == GRPC_ENDPOINT_WRITE_DONE) {
on_handshake_data_sent_to_peer(s, GRPC_ENDPOINT_CB_OK);
on_handshake_data_sent_to_peer(h, GRPC_ENDPOINT_CB_OK);
}
}
@ -175,9 +174,9 @@ static void cleanup_slices(gpr_slice *slices, size_t num_slices) {
}
static void on_handshake_data_received_from_peer(
void *setup, gpr_slice *slices, size_t nslices,
void *handshake, gpr_slice *slices, size_t nslices,
grpc_endpoint_cb_status error) {
grpc_secure_transport_setup *s = setup;
grpc_security_handshake *h = handshake;
size_t consumed_slice_size = 0;
tsi_result result = TSI_OK;
size_t i;
@ -187,28 +186,29 @@ static void on_handshake_data_received_from_peer(
if (error != GRPC_ENDPOINT_CB_OK) {
gpr_log(GPR_ERROR, "Read failed.");
cleanup_slices(slices, nslices);
secure_transport_setup_done(s, 0);
security_handshake_done(h, 0);
return;
}
for (i = 0; i < nslices; i++) {
consumed_slice_size = GPR_SLICE_LENGTH(slices[i]);
result = tsi_handshaker_process_bytes_from_peer(
s->handshaker, GPR_SLICE_START_PTR(slices[i]), &consumed_slice_size);
if (!tsi_handshaker_is_in_progress(s->handshaker)) break;
h->connector->handshaker, GPR_SLICE_START_PTR(slices[i]),
&consumed_slice_size);
if (!tsi_handshaker_is_in_progress(h->connector->handshaker)) break;
}
if (tsi_handshaker_is_in_progress(s->handshaker)) {
if (tsi_handshaker_is_in_progress(h->connector->handshaker)) {
/* We may need more data. */
if (result == TSI_INCOMPLETE_DATA) {
/* TODO(klempner,jboeuf): This should probably use the client setup
deadline */
grpc_endpoint_notify_on_read(s->wrapped_endpoint,
on_handshake_data_received_from_peer, setup);
grpc_endpoint_notify_on_read(
h->wrapped_endpoint, on_handshake_data_received_from_peer, handshake);
cleanup_slices(slices, nslices);
return;
} else {
send_handshake_bytes_to_peer(s);
send_handshake_bytes_to_peer(h);
cleanup_slices(slices, nslices);
return;
}
@ -218,7 +218,7 @@ static void on_handshake_data_received_from_peer(
gpr_log(GPR_ERROR, "Handshake failed with error %s",
tsi_result_to_string(result));
cleanup_slices(slices, nslices);
secure_transport_setup_done(s, 0);
security_handshake_done(h, 0);
return;
}
@ -228,66 +228,58 @@ static void on_handshake_data_received_from_peer(
num_left_overs = (has_left_overs_in_current_slice ? 1 : 0) + nslices - i - 1;
if (num_left_overs == 0) {
cleanup_slices(slices, nslices);
check_peer(s);
check_peer(h);
return;
}
cleanup_slices(slices, nslices - num_left_overs);
/* Put the leftovers in our buffer (ownership transfered). */
if (has_left_overs_in_current_slice) {
gpr_slice_buffer_add(&s->left_overs,
gpr_slice_buffer_add(&h->left_overs,
gpr_slice_split_tail(&slices[i], consumed_slice_size));
gpr_slice_unref(slices[i]); /* split_tail above increments refcount. */
}
gpr_slice_buffer_addn(
&s->left_overs, &slices[i + 1],
&h->left_overs, &slices[i + 1],
num_left_overs - (size_t)has_left_overs_in_current_slice);
check_peer(s);
check_peer(h);
}
/* If setup is NULL, the setup is done. */
static void on_handshake_data_sent_to_peer(void *setup,
/* If handshake is NULL, the handshake is done. */
static void on_handshake_data_sent_to_peer(void *handshake,
grpc_endpoint_cb_status error) {
grpc_secure_transport_setup *s = setup;
grpc_security_handshake *h = handshake;
/* Make sure that write is OK. */
if (error != GRPC_ENDPOINT_CB_OK) {
gpr_log(GPR_ERROR, "Write failed with error %d.", error);
if (setup != NULL) secure_transport_setup_done(s, 0);
if (handshake != NULL) security_handshake_done(h, 0);
return;
}
/* We may be done. */
if (tsi_handshaker_is_in_progress(s->handshaker)) {
if (tsi_handshaker_is_in_progress(h->connector->handshaker)) {
/* TODO(klempner,jboeuf): This should probably use the client setup
deadline */
grpc_endpoint_notify_on_read(s->wrapped_endpoint,
on_handshake_data_received_from_peer, setup);
grpc_endpoint_notify_on_read(
h->wrapped_endpoint, on_handshake_data_received_from_peer, handshake);
} else {
check_peer(s);
check_peer(h);
}
}
void grpc_setup_secure_transport(grpc_security_connector *connector,
grpc_endpoint *nonsecure_endpoint,
grpc_secure_transport_setup_done_cb cb,
void *user_data) {
grpc_security_status result = GRPC_SECURITY_OK;
grpc_secure_transport_setup *s =
gpr_malloc(sizeof(grpc_secure_transport_setup));
memset(s, 0, sizeof(grpc_secure_transport_setup));
result = grpc_security_connector_create_handshaker(connector, &s->handshaker);
if (result != GRPC_SECURITY_OK) {
secure_transport_setup_done(s, 0);
return;
}
s->connector =
GRPC_SECURITY_CONNECTOR_REF(connector, "secure_transport_setup");
s->handshake_buffer_size = GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE;
s->handshake_buffer = gpr_malloc(s->handshake_buffer_size);
s->wrapped_endpoint = nonsecure_endpoint;
s->user_data = user_data;
s->cb = cb;
gpr_slice_buffer_init(&s->left_overs);
send_handshake_bytes_to_peer(s);
void grpc_do_security_handshake(grpc_security_connector *connector,
grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb,
void *user_data) {
grpc_security_handshake *h = gpr_malloc(sizeof(grpc_security_handshake));
memset(h, 0, sizeof(grpc_security_handshake));
h->connector = connector;
h->handshake_buffer_size = GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE;
h->handshake_buffer = gpr_malloc(h->handshake_buffer_size);
h->wrapped_endpoint = nonsecure_endpoint;
h->user_data = user_data;
h->cb = cb;
gpr_slice_buffer_init(&h->left_overs);
send_handshake_bytes_to_peer(h);
}

@ -31,23 +31,17 @@
*
*/
#ifndef GRPC_INTERNAL_CORE_SECURITY_SECURE_TRANSPORT_SETUP_H
#define GRPC_INTERNAL_CORE_SECURITY_SECURE_TRANSPORT_SETUP_H
#ifndef GRPC_INTERNAL_CORE_SECURITY_HANDSHAKE_H
#define GRPC_INTERNAL_CORE_SECURITY_HANDSHAKE_H
#include "src/core/iomgr/endpoint.h"
#include "src/core/security/security_connector.h"
/* --- Secure transport setup --- */
/* Ownership of the secure_endpoint is transfered. */
typedef void (*grpc_secure_transport_setup_done_cb)(
void *user_data, grpc_security_status status,
grpc_endpoint *wrapped_endpoint, grpc_endpoint *secure_endpoint);
/* Calls the callback upon completion. */
void grpc_setup_secure_transport(grpc_security_connector *connector,
grpc_endpoint *nonsecure_endpoint,
grpc_secure_transport_setup_done_cb cb,
void *user_data);
void grpc_do_security_handshake(grpc_security_connector *connector,
grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb,
void *user_data);
#endif /* GRPC_INTERNAL_CORE_SECURITY_SECURE_TRANSPORT_SETUP_H */
#endif /* GRPC_INTERNAL_CORE_SECURITY_HANDSHAKE_H */

@ -36,6 +36,7 @@
#include <string.h>
#include "src/core/security/credentials.h"
#include "src/core/security/handshake.h"
#include "src/core/security/secure_endpoint.h"
#include "src/core/security/security_context.h"
#include "src/core/support/env.h"
@ -101,10 +102,15 @@ const tsi_peer_property *tsi_peer_get_property_by_name(const tsi_peer *peer,
return NULL;
}
grpc_security_status grpc_security_connector_create_handshaker(
grpc_security_connector *sc, tsi_handshaker **handshaker) {
if (sc == NULL || handshaker == NULL) return GRPC_SECURITY_ERROR;
return sc->vtable->create_handshaker(sc, handshaker);
void grpc_security_connector_do_handshake(grpc_security_connector *sc,
grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb,
void *user_data) {
if (sc == NULL || nonsecure_endpoint == NULL) {
cb(user_data, GRPC_SECURITY_ERROR, nonsecure_endpoint, NULL);
} else {
sc->vtable->do_handshake(sc, nonsecure_endpoint, cb, user_data);
}
}
grpc_security_status grpc_security_connector_check_peer(
@ -216,27 +222,17 @@ typedef struct {
static void fake_channel_destroy(grpc_security_connector *sc) {
grpc_channel_security_connector *c = (grpc_channel_security_connector *)sc;
grpc_credentials_unref(c->request_metadata_creds);
tsi_handshaker_destroy(sc->handshaker);
GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
gpr_free(sc);
}
static void fake_server_destroy(grpc_security_connector *sc) {
tsi_handshaker_destroy(sc->handshaker);
GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
gpr_free(sc);
}
static grpc_security_status fake_channel_create_handshaker(
grpc_security_connector *sc, tsi_handshaker **handshaker) {
*handshaker = tsi_create_fake_handshaker(1);
return GRPC_SECURITY_OK;
}
static grpc_security_status fake_server_create_handshaker(
grpc_security_connector *sc, tsi_handshaker **handshaker) {
*handshaker = tsi_create_fake_handshaker(0);
return GRPC_SECURITY_OK;
}
static grpc_security_status fake_check_peer(grpc_security_connector *sc,
tsi_peer peer,
grpc_security_check_cb cb,
@ -286,11 +282,29 @@ static grpc_security_status fake_channel_check_call_host(
}
}
static void fake_channel_do_handshake(grpc_security_connector *sc,
grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb,
void *user_data) {
tsi_handshaker_destroy(sc->handshaker);
sc->handshaker = tsi_create_fake_handshaker(1);
grpc_do_security_handshake(sc, nonsecure_endpoint, cb, user_data);
}
static void fake_server_do_handshake(grpc_security_connector *sc,
grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb,
void *user_data) {
tsi_handshaker_destroy(sc->handshaker);
sc->handshaker = tsi_create_fake_handshaker(0);
grpc_do_security_handshake(sc, nonsecure_endpoint, cb, user_data);
}
static grpc_security_connector_vtable fake_channel_vtable = {
fake_channel_destroy, fake_channel_create_handshaker, fake_check_peer};
fake_channel_destroy, fake_channel_do_handshake, fake_check_peer};
static grpc_security_connector_vtable fake_server_vtable = {
fake_server_destroy, fake_server_create_handshaker, fake_check_peer};
fake_server_destroy, fake_server_do_handshake, fake_check_peer};
grpc_channel_security_connector *grpc_fake_channel_security_connector_create(
grpc_credentials *request_metadata_creds, int call_host_check_is_async) {
@ -344,6 +358,7 @@ static void ssl_channel_destroy(grpc_security_connector *sc) {
if (c->overridden_target_name != NULL) gpr_free(c->overridden_target_name);
tsi_peer_destruct(&c->peer);
GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
tsi_handshaker_destroy(sc->handshaker);
gpr_free(sc);
}
@ -354,6 +369,7 @@ static void ssl_server_destroy(grpc_security_connector *sc) {
tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
}
GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
tsi_handshaker_destroy(sc->handshaker);
gpr_free(sc);
}
@ -362,6 +378,8 @@ static grpc_security_status ssl_create_handshaker(
const char *peer_name, tsi_handshaker **handshaker) {
tsi_result result = TSI_OK;
if (handshaker_factory == NULL) return GRPC_SECURITY_ERROR;
tsi_handshaker_destroy(*handshaker);
*handshaker = NULL;
result = tsi_ssl_handshaker_factory_create_handshaker(
handshaker_factory, is_client ? peer_name : NULL, handshaker);
if (result != TSI_OK) {
@ -372,22 +390,37 @@ static grpc_security_status ssl_create_handshaker(
return GRPC_SECURITY_OK;
}
static grpc_security_status ssl_channel_create_handshaker(
grpc_security_connector *sc, tsi_handshaker **handshaker) {
static void ssl_channel_do_handshake(grpc_security_connector *sc,
grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb,
void *user_data) {
grpc_ssl_channel_security_connector *c =
(grpc_ssl_channel_security_connector *)sc;
return ssl_create_handshaker(c->handshaker_factory, 1,
c->overridden_target_name != NULL
? c->overridden_target_name
: c->target_name,
handshaker);
grpc_security_status status = ssl_create_handshaker(
c->handshaker_factory, 1,
c->overridden_target_name != NULL ? c->overridden_target_name
: c->target_name,
&sc->handshaker);
if (status != GRPC_SECURITY_OK) {
cb(user_data, status, nonsecure_endpoint, NULL);
} else {
grpc_do_security_handshake(sc, nonsecure_endpoint, cb, user_data);
}
}
static grpc_security_status ssl_server_create_handshaker(
grpc_security_connector *sc, tsi_handshaker **handshaker) {
static void ssl_server_do_handshake(grpc_security_connector *sc,
grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb,
void *user_data) {
grpc_ssl_server_security_connector *c =
(grpc_ssl_server_security_connector *)sc;
return ssl_create_handshaker(c->handshaker_factory, 0, NULL, handshaker);
grpc_security_status status =
ssl_create_handshaker(c->handshaker_factory, 0, NULL, &sc->handshaker);
if (status != GRPC_SECURITY_OK) {
cb(user_data, status, nonsecure_endpoint, NULL);
} else {
grpc_do_security_handshake(sc, nonsecure_endpoint, cb, user_data);
}
}
static int ssl_host_matches_name(const tsi_peer *peer, const char *peer_name) {
@ -512,10 +545,10 @@ static grpc_security_status ssl_channel_check_call_host(
}
static grpc_security_connector_vtable ssl_channel_vtable = {
ssl_channel_destroy, ssl_channel_create_handshaker, ssl_channel_check_peer};
ssl_channel_destroy, ssl_channel_do_handshake, ssl_channel_check_peer};
static grpc_security_connector_vtable ssl_server_vtable = {
ssl_server_destroy, ssl_server_create_handshaker, ssl_server_check_peer};
ssl_server_destroy, ssl_server_do_handshake, ssl_server_check_peer};
static gpr_slice default_pem_root_certs;

@ -63,10 +63,17 @@ typedef struct grpc_security_connector grpc_security_connector;
typedef void (*grpc_security_check_cb)(void *user_data,
grpc_security_status status);
/* Ownership of the secure_endpoint is transfered. */
typedef void (*grpc_security_handshake_done_cb)(
void *user_data, grpc_security_status status,
grpc_endpoint *wrapped_endpoint, grpc_endpoint *secure_endpoint);
typedef struct {
void (*destroy)(grpc_security_connector *sc);
grpc_security_status (*create_handshaker)(grpc_security_connector *sc,
tsi_handshaker **handshaker);
void (*do_handshake)(grpc_security_connector *sc,
grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb, void *user_data);
grpc_security_status (*check_peer)(grpc_security_connector *sc, tsi_peer peer,
grpc_security_check_cb cb,
void *user_data);
@ -77,6 +84,7 @@ struct grpc_security_connector {
gpr_refcount refcount;
int is_client_side;
const char *url_scheme;
tsi_handshaker *handshaker;
grpc_auth_context *auth_context; /* Populated after the peer is checked. */
};
@ -100,9 +108,11 @@ grpc_security_connector *grpc_security_connector_ref(
void grpc_security_connector_unref(grpc_security_connector *policy);
#endif
/* Handshake creation. */
grpc_security_status grpc_security_connector_create_handshaker(
grpc_security_connector *sc, tsi_handshaker **handshaker);
/* Handshake. */
void grpc_security_connector_do_handshake(grpc_security_connector *connector,
grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb,
void *user_data);
/* Check the peer.
Implementations can choose to check the peer either synchronously or

@ -44,7 +44,6 @@
#include "src/core/security/credentials.h"
#include "src/core/security/security_connector.h"
#include "src/core/security/security_context.h"
#include "src/core/security/secure_transport_setup.h"
#include "src/core/surface/server.h"
#include "src/core/transport/chttp2_transport.h"
#include <grpc/support/alloc.h>
@ -121,10 +120,9 @@ static int remove_tcp_from_list_locked(grpc_server_secure_state *state,
return -1;
}
static void on_secure_transport_setup_done(void *statep,
grpc_security_status status,
grpc_endpoint *wrapped_endpoint,
grpc_endpoint *secure_endpoint) {
static void on_secure_handshake_done(void *statep, grpc_security_status status,
grpc_endpoint *wrapped_endpoint,
grpc_endpoint *secure_endpoint) {
grpc_server_secure_state *state = statep;
grpc_transport *transport;
grpc_mdctx *mdctx;
@ -163,8 +161,8 @@ static void on_accept(void *statep, grpc_endpoint *tcp) {
node->next = state->handshaking_tcp_endpoints;
state->handshaking_tcp_endpoints = node;
gpr_mu_unlock(&state->mu);
grpc_setup_secure_transport(state->sc, tcp, on_secure_transport_setup_done,
state);
grpc_security_connector_do_handshake(state->sc, tcp, on_secure_handshake_done,
state);
}
/* Server callback: start listening on our ports */

@ -46,7 +46,6 @@
#include "src/core/iomgr/tcp_client.h"
#include "src/core/security/auth_filters.h"
#include "src/core/security/credentials.h"
#include "src/core/security/secure_transport_setup.h"
#include "src/core/surface/channel.h"
#include "src/core/transport/chttp2_transport.h"
#include "src/core/tsi/transport_security_interface.h"
@ -74,14 +73,13 @@ static void connector_unref(grpc_connector *con) {
}
}
static void on_secure_transport_setup_done(void *arg,
grpc_security_status status,
grpc_endpoint *wrapped_endpoint,
grpc_endpoint *secure_endpoint) {
static void on_secure_handshake_done(void *arg, grpc_security_status status,
grpc_endpoint *wrapped_endpoint,
grpc_endpoint *secure_endpoint) {
connector *c = arg;
grpc_iomgr_closure *notify;
if (status != GRPC_SECURITY_OK) {
gpr_log(GPR_ERROR, "Secure transport setup failed with error %d.", status);
gpr_log(GPR_ERROR, "Secure handshake failed with error %d.", status);
memset(c->result, 0, sizeof(*c->result));
} else {
c->result->transport = grpc_create_chttp2_transport(
@ -101,8 +99,8 @@ static void connected(void *arg, grpc_endpoint *tcp) {
connector *c = arg;
grpc_iomgr_closure *notify;
if (tcp != NULL) {
grpc_setup_secure_transport(&c->security_connector->base, tcp,
on_secure_transport_setup_done, c);
grpc_security_connector_do_handshake(&c->security_connector->base, tcp,
on_secure_handshake_done, c);
} else {
memset(c->result, 0, sizeof(*c->result));
notify = c->notify;

@ -770,10 +770,10 @@ include/grpc/census.h \
src/core/security/auth_filters.h \
src/core/security/base64.h \
src/core/security/credentials.h \
src/core/security/handshake.h \
src/core/security/json_token.h \
src/core/security/jwt_verifier.h \
src/core/security/secure_endpoint.h \
src/core/security/secure_transport_setup.h \
src/core/security/security_connector.h \
src/core/security/security_context.h \
src/core/tsi/fake_transport_security.h \
@ -890,10 +890,10 @@ src/core/security/credentials_metadata.c \
src/core/security/credentials_posix.c \
src/core/security/credentials_win32.c \
src/core/security/google_default_credentials.c \
src/core/security/handshake.c \
src/core/security/json_token.c \
src/core/security/jwt_verifier.c \
src/core/security/secure_endpoint.c \
src/core/security/secure_transport_setup.c \
src/core/security/security_connector.c \
src/core/security/security_context.c \
src/core/security/server_auth_filter.c \

@ -12340,10 +12340,10 @@
"src/core/security/auth_filters.h",
"src/core/security/base64.h",
"src/core/security/credentials.h",
"src/core/security/handshake.h",
"src/core/security/json_token.h",
"src/core/security/jwt_verifier.h",
"src/core/security/secure_endpoint.h",
"src/core/security/secure_transport_setup.h",
"src/core/security/security_connector.h",
"src/core/security/security_context.h",
"src/core/surface/byte_buffer_queue.h",
@ -12547,14 +12547,14 @@
"src/core/security/credentials_posix.c",
"src/core/security/credentials_win32.c",
"src/core/security/google_default_credentials.c",
"src/core/security/handshake.c",
"src/core/security/handshake.h",
"src/core/security/json_token.c",
"src/core/security/json_token.h",
"src/core/security/jwt_verifier.c",
"src/core/security/jwt_verifier.h",
"src/core/security/secure_endpoint.c",
"src/core/security/secure_endpoint.h",
"src/core/security/secure_transport_setup.c",
"src/core/security/secure_transport_setup.h",
"src/core/security/security_connector.c",
"src/core/security/security_connector.h",
"src/core/security/security_context.c",

@ -1538,6 +1538,7 @@
"posix",
"windows"
],
"exclude_configs": [],
"flaky": false,
"language": "c++",
"name": "status_test",

@ -232,10 +232,10 @@
<ClInclude Include="..\..\src\core\security\auth_filters.h" />
<ClInclude Include="..\..\src\core\security\base64.h" />
<ClInclude Include="..\..\src\core\security\credentials.h" />
<ClInclude Include="..\..\src\core\security\handshake.h" />
<ClInclude Include="..\..\src\core\security\json_token.h" />
<ClInclude Include="..\..\src\core\security\jwt_verifier.h" />
<ClInclude Include="..\..\src\core\security\secure_endpoint.h" />
<ClInclude Include="..\..\src\core\security\secure_transport_setup.h" />
<ClInclude Include="..\..\src\core\security\security_connector.h" />
<ClInclude Include="..\..\src\core\security\security_context.h" />
<ClInclude Include="..\..\src\core\tsi\fake_transport_security.h" />
@ -362,14 +362,14 @@
</ClCompile>
<ClCompile Include="..\..\src\core\security\google_default_credentials.c">
</ClCompile>
<ClCompile Include="..\..\src\core\security\handshake.c">
</ClCompile>
<ClCompile Include="..\..\src\core\security\json_token.c">
</ClCompile>
<ClCompile Include="..\..\src\core\security\jwt_verifier.c">
</ClCompile>
<ClCompile Include="..\..\src\core\security\secure_endpoint.c">
</ClCompile>
<ClCompile Include="..\..\src\core\security\secure_transport_setup.c">
</ClCompile>
<ClCompile Include="..\..\src\core\security\security_connector.c">
</ClCompile>
<ClCompile Include="..\..\src\core\security\security_context.c">

@ -25,6 +25,9 @@
<ClCompile Include="..\..\src\core\security\google_default_credentials.c">
<Filter>src\core\security</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\security\handshake.c">
<Filter>src\core\security</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\security\json_token.c">
<Filter>src\core\security</Filter>
</ClCompile>
@ -34,9 +37,6 @@
<ClCompile Include="..\..\src\core\security\secure_endpoint.c">
<Filter>src\core\security</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\security\secure_transport_setup.c">
<Filter>src\core\security</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\security\security_connector.c">
<Filter>src\core\security</Filter>
</ClCompile>
@ -452,6 +452,9 @@
<ClInclude Include="..\..\src\core\security\credentials.h">
<Filter>src\core\security</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\security\handshake.h">
<Filter>src\core\security</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\security\json_token.h">
<Filter>src\core\security</Filter>
</ClInclude>
@ -461,9 +464,6 @@
<ClInclude Include="..\..\src\core\security\secure_endpoint.h">
<Filter>src\core\security</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\security\secure_transport_setup.h">
<Filter>src\core\security</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\security\security_connector.h">
<Filter>src\core\security</Filter>
</ClInclude>

Loading…
Cancel
Save