aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/security/handshake.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/security/handshake.c')
-rw-r--r--src/core/security/handshake.c346
1 files changed, 169 insertions, 177 deletions
diff --git a/src/core/security/handshake.c b/src/core/security/handshake.c
index 687cc575a7..adbdd0b40e 100644
--- a/src/core/security/handshake.c
+++ b/src/core/security/handshake.c
@@ -42,8 +42,7 @@
#define GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE 256
-typedef struct
-{
+typedef struct {
grpc_security_connector *connector;
tsi_handshaker *handshaker;
unsigned char *handshake_buffer;
@@ -59,131 +58,123 @@ typedef struct
grpc_closure on_handshake_data_received_from_peer;
} grpc_security_handshake;
-static void on_handshake_data_received_from_peer (grpc_exec_ctx * exec_ctx, void *setup, int success);
+static void on_handshake_data_received_from_peer(grpc_exec_ctx *exec_ctx,
+ void *setup, int success);
-static void on_handshake_data_sent_to_peer (grpc_exec_ctx * exec_ctx, void *setup, int success);
+static void on_handshake_data_sent_to_peer(grpc_exec_ctx *exec_ctx, void *setup,
+ int success);
-static void
-security_handshake_done (grpc_exec_ctx * exec_ctx, grpc_security_handshake * h, int is_success)
-{
- if (is_success)
- {
- h->cb (exec_ctx, h->user_data, GRPC_SECURITY_OK, h->wrapped_endpoint, h->secure_endpoint);
+static void security_handshake_done(grpc_exec_ctx *exec_ctx,
+ grpc_security_handshake *h,
+ int is_success) {
+ if (is_success) {
+ h->cb(exec_ctx, h->user_data, GRPC_SECURITY_OK, h->wrapped_endpoint,
+ h->secure_endpoint);
+ } else {
+ if (h->secure_endpoint != NULL) {
+ grpc_endpoint_shutdown(exec_ctx, h->secure_endpoint);
+ grpc_endpoint_destroy(exec_ctx, h->secure_endpoint);
+ } else {
+ grpc_endpoint_destroy(exec_ctx, h->wrapped_endpoint);
}
- else
- {
- if (h->secure_endpoint != NULL)
- {
- grpc_endpoint_shutdown (exec_ctx, h->secure_endpoint);
- grpc_endpoint_destroy (exec_ctx, h->secure_endpoint);
- }
- else
- {
- grpc_endpoint_destroy (exec_ctx, h->wrapped_endpoint);
- }
- h->cb (exec_ctx, h->user_data, GRPC_SECURITY_ERROR, h->wrapped_endpoint, NULL);
- }
- if (h->handshaker != NULL)
- tsi_handshaker_destroy (h->handshaker);
- if (h->handshake_buffer != NULL)
- gpr_free (h->handshake_buffer);
- gpr_slice_buffer_destroy (&h->left_overs);
- gpr_slice_buffer_destroy (&h->outgoing);
- gpr_slice_buffer_destroy (&h->incoming);
- GRPC_SECURITY_CONNECTOR_UNREF (h->connector, "handshake");
- gpr_free (h);
+ h->cb(exec_ctx, h->user_data, GRPC_SECURITY_ERROR, h->wrapped_endpoint,
+ NULL);
+ }
+ if (h->handshaker != NULL) tsi_handshaker_destroy(h->handshaker);
+ if (h->handshake_buffer != NULL) gpr_free(h->handshake_buffer);
+ gpr_slice_buffer_destroy(&h->left_overs);
+ gpr_slice_buffer_destroy(&h->outgoing);
+ gpr_slice_buffer_destroy(&h->incoming);
+ GRPC_SECURITY_CONNECTOR_UNREF(h->connector, "handshake");
+ gpr_free(h);
}
-static void
-on_peer_checked (grpc_exec_ctx * exec_ctx, void *user_data, grpc_security_status status)
-{
+static void on_peer_checked(grpc_exec_ctx *exec_ctx, void *user_data,
+ grpc_security_status status) {
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.");
- security_handshake_done (exec_ctx, h, 0);
- return;
- }
- result = tsi_handshaker_create_frame_protector (h->handshaker, NULL, &protector);
- if (result != TSI_OK)
- {
- gpr_log (GPR_ERROR, "Frame protector creation failed with error %s.", tsi_result_to_string (result));
- security_handshake_done (exec_ctx, h, 0);
- return;
- }
- h->secure_endpoint = grpc_secure_endpoint_create (protector, h->wrapped_endpoint, h->left_overs.slices, h->left_overs.count);
+ if (status != GRPC_SECURITY_OK) {
+ gpr_log(GPR_ERROR, "Error checking peer.");
+ security_handshake_done(exec_ctx, h, 0);
+ return;
+ }
+ result =
+ tsi_handshaker_create_frame_protector(h->handshaker, NULL, &protector);
+ if (result != TSI_OK) {
+ gpr_log(GPR_ERROR, "Frame protector creation failed with error %s.",
+ tsi_result_to_string(result));
+ security_handshake_done(exec_ctx, h, 0);
+ return;
+ }
+ h->secure_endpoint =
+ grpc_secure_endpoint_create(protector, h->wrapped_endpoint,
+ h->left_overs.slices, h->left_overs.count);
h->left_overs.count = 0;
h->left_overs.length = 0;
- security_handshake_done (exec_ctx, h, 1);
+ security_handshake_done(exec_ctx, h, 1);
return;
}
-static void
-check_peer (grpc_exec_ctx * exec_ctx, grpc_security_handshake * h)
-{
+static void check_peer(grpc_exec_ctx *exec_ctx, grpc_security_handshake *h) {
grpc_security_status peer_status;
tsi_peer peer;
- tsi_result result = tsi_handshaker_extract_peer (h->handshaker, &peer);
+ tsi_result result = tsi_handshaker_extract_peer(h->handshaker, &peer);
- if (result != TSI_OK)
- {
- gpr_log (GPR_ERROR, "Peer extraction failed with error %s", tsi_result_to_string (result));
- security_handshake_done (exec_ctx, h, 0);
- return;
- }
- 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.");
- security_handshake_done (exec_ctx, h, 0);
- return;
- }
- else if (peer_status == GRPC_SECURITY_OK)
- {
- on_peer_checked (exec_ctx, h, peer_status);
- }
+ if (result != TSI_OK) {
+ gpr_log(GPR_ERROR, "Peer extraction failed with error %s",
+ tsi_result_to_string(result));
+ security_handshake_done(exec_ctx, h, 0);
+ return;
+ }
+ 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.");
+ security_handshake_done(exec_ctx, h, 0);
+ return;
+ } else if (peer_status == GRPC_SECURITY_OK) {
+ on_peer_checked(exec_ctx, h, peer_status);
+ }
}
-static void
-send_handshake_bytes_to_peer (grpc_exec_ctx * exec_ctx, grpc_security_handshake * h)
-{
+static void send_handshake_bytes_to_peer(grpc_exec_ctx *exec_ctx,
+ grpc_security_handshake *h) {
size_t offset = 0;
tsi_result result = TSI_OK;
gpr_slice to_send;
- do
- {
- size_t to_send_size = h->handshake_buffer_size - offset;
- result = tsi_handshaker_get_bytes_to_send_to_peer (h->handshaker, h->handshake_buffer + offset, &to_send_size);
- offset += to_send_size;
- if (result == TSI_INCOMPLETE_DATA)
- {
- h->handshake_buffer_size *= 2;
- h->handshake_buffer = gpr_realloc (h->handshake_buffer, h->handshake_buffer_size);
- }
+ do {
+ size_t to_send_size = h->handshake_buffer_size - offset;
+ result = tsi_handshaker_get_bytes_to_send_to_peer(
+ h->handshaker, h->handshake_buffer + offset, &to_send_size);
+ offset += to_send_size;
+ if (result == TSI_INCOMPLETE_DATA) {
+ h->handshake_buffer_size *= 2;
+ h->handshake_buffer =
+ gpr_realloc(h->handshake_buffer, h->handshake_buffer_size);
}
- while (result == TSI_INCOMPLETE_DATA);
+ } while (result == TSI_INCOMPLETE_DATA);
- if (result != TSI_OK)
- {
- gpr_log (GPR_ERROR, "Handshake failed with error %s", tsi_result_to_string (result));
- security_handshake_done (exec_ctx, h, 0);
- return;
- }
+ if (result != TSI_OK) {
+ gpr_log(GPR_ERROR, "Handshake failed with error %s",
+ tsi_result_to_string(result));
+ security_handshake_done(exec_ctx, h, 0);
+ return;
+ }
- to_send = gpr_slice_from_copied_buffer ((const char *) h->handshake_buffer, offset);
- gpr_slice_buffer_reset_and_unref (&h->outgoing);
- gpr_slice_buffer_add (&h->outgoing, to_send);
+ to_send =
+ gpr_slice_from_copied_buffer((const char *)h->handshake_buffer, offset);
+ gpr_slice_buffer_reset_and_unref(&h->outgoing);
+ gpr_slice_buffer_add(&h->outgoing, to_send);
/* TODO(klempner,jboeuf): This should probably use the client setup
deadline */
- grpc_endpoint_write (exec_ctx, h->wrapped_endpoint, &h->outgoing, &h->on_handshake_data_sent_to_peer);
+ grpc_endpoint_write(exec_ctx, h->wrapped_endpoint, &h->outgoing,
+ &h->on_handshake_data_sent_to_peer);
}
-static void
-on_handshake_data_received_from_peer (grpc_exec_ctx * exec_ctx, void *handshake, int success)
-{
+static void on_handshake_data_received_from_peer(grpc_exec_ctx *exec_ctx,
+ void *handshake, int success) {
grpc_security_handshake *h = handshake;
size_t consumed_slice_size = 0;
tsi_result result = TSI_OK;
@@ -191,106 +182,107 @@ on_handshake_data_received_from_peer (grpc_exec_ctx * exec_ctx, void *handshake,
size_t num_left_overs;
int has_left_overs_in_current_slice = 0;
- if (!success)
- {
- gpr_log (GPR_ERROR, "Read failed.");
- security_handshake_done (exec_ctx, h, 0);
- return;
- }
-
- for (i = 0; i < h->incoming.count; i++)
- {
- consumed_slice_size = GPR_SLICE_LENGTH (h->incoming.slices[i]);
- result = tsi_handshaker_process_bytes_from_peer (h->handshaker, GPR_SLICE_START_PTR (h->incoming.slices[i]), &consumed_slice_size);
- if (!tsi_handshaker_is_in_progress (h->handshaker))
- break;
- }
+ if (!success) {
+ gpr_log(GPR_ERROR, "Read failed.");
+ security_handshake_done(exec_ctx, h, 0);
+ return;
+ }
- if (tsi_handshaker_is_in_progress (h->handshaker))
- {
- /* We may need more data. */
- if (result == TSI_INCOMPLETE_DATA)
- {
- grpc_endpoint_read (exec_ctx, h->wrapped_endpoint, &h->incoming, &h->on_handshake_data_received_from_peer);
- return;
- }
- else
- {
- send_handshake_bytes_to_peer (exec_ctx, h);
- return;
- }
- }
+ for (i = 0; i < h->incoming.count; i++) {
+ consumed_slice_size = GPR_SLICE_LENGTH(h->incoming.slices[i]);
+ result = tsi_handshaker_process_bytes_from_peer(
+ h->handshaker, GPR_SLICE_START_PTR(h->incoming.slices[i]),
+ &consumed_slice_size);
+ if (!tsi_handshaker_is_in_progress(h->handshaker)) break;
+ }
- if (result != TSI_OK)
- {
- gpr_log (GPR_ERROR, "Handshake failed with error %s", tsi_result_to_string (result));
- security_handshake_done (exec_ctx, h, 0);
+ if (tsi_handshaker_is_in_progress(h->handshaker)) {
+ /* We may need more data. */
+ if (result == TSI_INCOMPLETE_DATA) {
+ grpc_endpoint_read(exec_ctx, h->wrapped_endpoint, &h->incoming,
+ &h->on_handshake_data_received_from_peer);
+ return;
+ } else {
+ send_handshake_bytes_to_peer(exec_ctx, h);
return;
}
+ }
+
+ if (result != TSI_OK) {
+ gpr_log(GPR_ERROR, "Handshake failed with error %s",
+ tsi_result_to_string(result));
+ security_handshake_done(exec_ctx, h, 0);
+ return;
+ }
/* Handshake is done and successful this point. */
- has_left_overs_in_current_slice = (consumed_slice_size < GPR_SLICE_LENGTH (h->incoming.slices[i]));
- num_left_overs = (has_left_overs_in_current_slice ? 1 : 0) + h->incoming.count - i - 1;
- if (num_left_overs == 0)
- {
- check_peer (exec_ctx, h);
- return;
- }
+ has_left_overs_in_current_slice =
+ (consumed_slice_size < GPR_SLICE_LENGTH(h->incoming.slices[i]));
+ num_left_overs =
+ (has_left_overs_in_current_slice ? 1 : 0) + h->incoming.count - i - 1;
+ if (num_left_overs == 0) {
+ check_peer(exec_ctx, h);
+ return;
+ }
/* Put the leftovers in our buffer (ownership transfered). */
- if (has_left_overs_in_current_slice)
- {
- gpr_slice_buffer_add (&h->left_overs, gpr_slice_split_tail (&h->incoming.slices[i], consumed_slice_size));
- gpr_slice_unref (h->incoming.slices[i]); /* split_tail above increments refcount. */
- }
- gpr_slice_buffer_addn (&h->left_overs, &h->incoming.slices[i + 1], num_left_overs - (size_t) has_left_overs_in_current_slice);
- check_peer (exec_ctx, h);
+ if (has_left_overs_in_current_slice) {
+ gpr_slice_buffer_add(
+ &h->left_overs,
+ gpr_slice_split_tail(&h->incoming.slices[i], consumed_slice_size));
+ gpr_slice_unref(
+ h->incoming.slices[i]); /* split_tail above increments refcount. */
+ }
+ gpr_slice_buffer_addn(
+ &h->left_overs, &h->incoming.slices[i + 1],
+ num_left_overs - (size_t)has_left_overs_in_current_slice);
+ check_peer(exec_ctx, h);
}
/* If handshake is NULL, the handshake is done. */
-static void
-on_handshake_data_sent_to_peer (grpc_exec_ctx * exec_ctx, void *handshake, int success)
-{
+static void on_handshake_data_sent_to_peer(grpc_exec_ctx *exec_ctx,
+ void *handshake, int success) {
grpc_security_handshake *h = handshake;
/* Make sure that write is OK. */
- if (!success)
- {
- gpr_log (GPR_ERROR, "Write failed.");
- if (handshake != NULL)
- security_handshake_done (exec_ctx, h, 0);
- return;
- }
+ if (!success) {
+ gpr_log(GPR_ERROR, "Write failed.");
+ if (handshake != NULL) security_handshake_done(exec_ctx, h, 0);
+ return;
+ }
/* We may be done. */
- if (tsi_handshaker_is_in_progress (h->handshaker))
- {
- /* TODO(klempner,jboeuf): This should probably use the client setup
- deadline */
- grpc_endpoint_read (exec_ctx, h->wrapped_endpoint, &h->incoming, &h->on_handshake_data_received_from_peer);
- }
- else
- {
- check_peer (exec_ctx, h);
- }
+ if (tsi_handshaker_is_in_progress(h->handshaker)) {
+ /* TODO(klempner,jboeuf): This should probably use the client setup
+ deadline */
+ grpc_endpoint_read(exec_ctx, h->wrapped_endpoint, &h->incoming,
+ &h->on_handshake_data_received_from_peer);
+ } else {
+ check_peer(exec_ctx, h);
+ }
}
-void
-grpc_do_security_handshake (grpc_exec_ctx * exec_ctx, tsi_handshaker * handshaker, 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));
+void grpc_do_security_handshake(grpc_exec_ctx *exec_ctx,
+ tsi_handshaker *handshaker,
+ 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->handshaker = handshaker;
- h->connector = GRPC_SECURITY_CONNECTOR_REF (connector, "handshake");
+ h->connector = GRPC_SECURITY_CONNECTOR_REF(connector, "handshake");
h->handshake_buffer_size = GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE;
- h->handshake_buffer = gpr_malloc (h->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;
- grpc_closure_init (&h->on_handshake_data_sent_to_peer, on_handshake_data_sent_to_peer, h);
- grpc_closure_init (&h->on_handshake_data_received_from_peer, on_handshake_data_received_from_peer, h);
- gpr_slice_buffer_init (&h->left_overs);
- gpr_slice_buffer_init (&h->outgoing);
- gpr_slice_buffer_init (&h->incoming);
- send_handshake_bytes_to_peer (exec_ctx, h);
+ grpc_closure_init(&h->on_handshake_data_sent_to_peer,
+ on_handshake_data_sent_to_peer, h);
+ grpc_closure_init(&h->on_handshake_data_received_from_peer,
+ on_handshake_data_received_from_peer, h);
+ gpr_slice_buffer_init(&h->left_overs);
+ gpr_slice_buffer_init(&h->outgoing);
+ gpr_slice_buffer_init(&h->incoming);
+ send_handshake_bytes_to_peer(exec_ctx, h);
}