Merge pull request #3027 from jboeuf/security_connector_refactoring

Security connector refactoring
diff --git a/BUILD b/BUILD
index 9b39353..c1aa80a 100644
--- a/BUILD
+++ b/BUILD
@@ -134,10 +134,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",
@@ -259,10 +259,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",
@@ -1034,10 +1034,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",
@@ -1182,10 +1182,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",
diff --git a/Makefile b/Makefile
index 0cb6a12..3e154eb 100644
--- a/Makefile
+++ b/Makefile
@@ -4027,10 +4027,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 \
@@ -20552,10 +20552,10 @@
 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)
diff --git a/build.yaml b/build.yaml
index 2985520..527b7d5 100644
--- a/build.yaml
+++ b/build.yaml
@@ -179,15 +179,15 @@
   language: c
   public_headers: [include/grpc/grpc_security.h]
   headers: [src/core/security/auth_filters.h, src/core/security/base64.h, src/core/security/credentials.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,
-    src/core/tsi/ssl_transport_security.h, src/core/tsi/transport_security.h, src/core/tsi/transport_security_interface.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/security_connector.h, src/core/security/security_context.h,
+    src/core/tsi/fake_transport_security.h, src/core/tsi/ssl_transport_security.h,
+    src/core/tsi/transport_security.h, src/core/tsi/transport_security_interface.h]
   src: [src/core/httpcli/httpcli_security_connector.c, src/core/security/base64.c,
     src/core/security/client_auth_filter.c, src/core/security/credentials.c, 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/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/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/security_connector.c, src/core/security/security_context.c,
     src/core/security/server_auth_filter.c, src/core/security/server_secure_chttp2.c,
     src/core/surface/init_secure.c, src/core/surface/secure_channel_create.c, src/core/tsi/fake_transport_security.c,
diff --git a/gRPC.podspec b/gRPC.podspec
index 3b069f2..5a16504 100644
--- a/gRPC.podspec
+++ b/gRPC.podspec
@@ -136,10 +136,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',
@@ -268,10 +268,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',
@@ -416,10 +416,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',
diff --git a/src/core/httpcli/httpcli_security_connector.c b/src/core/httpcli/httpcli_security_connector.c
index 7887f9d..86f34db 100644
--- a/src/core/httpcli/httpcli_security_connector.c
+++ b/src/core/httpcli/httpcli_security_connector.c
@@ -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>
@@ -58,20 +58,27 @@
   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;
+  tsi_handshaker *handshaker;
+  if (c->handshaker_factory == NULL) {
+    cb(user_data, GRPC_SECURITY_ERROR, nonsecure_endpoint, NULL);
+    return;
+  }
   result = tsi_ssl_handshaker_factory_create_handshaker(
-      c->handshaker_factory, c->secure_peer_name, handshaker);
+      c->handshaker_factory, c->secure_peer_name, &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(handshaker, sc, nonsecure_endpoint, cb,
+                               user_data);
   }
-  return GRPC_SECURITY_OK;
 }
 
 static grpc_security_status httpcli_ssl_check_peer(grpc_security_connector *sc,
@@ -94,7 +101,7 @@
 }
 
 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 +176,8 @@
   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");
 }
 
diff --git a/src/core/security/handshake.c b/src/core/security/handshake.c
new file mode 100644
index 0000000..3b49271
--- /dev/null
+++ b/src/core/security/handshake.c
@@ -0,0 +1,308 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/security/handshake.h"
+
+#include <string.h>
+
+#include "src/core/security/secure_endpoint.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/slice_buffer.h>
+
+#define GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE 256
+
+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;
+  gpr_slice_buffer incoming;
+  gpr_slice_buffer outgoing;
+  grpc_security_handshake_done_cb cb;
+  void *user_data;
+  grpc_iomgr_closure on_handshake_data_sent_to_peer;
+  grpc_iomgr_closure on_handshake_data_received_from_peer;
+} grpc_security_handshake;
+
+
+static void on_handshake_data_received_from_peer(void *setup, int success);
+
+static void on_handshake_data_sent_to_peer(void *setup, int success);
+
+static void security_handshake_done(grpc_security_handshake *h,
+                                    int is_success) {
+  if (is_success) {
+    h->cb(h->user_data, GRPC_SECURITY_OK, h->wrapped_endpoint,
+          h->secure_endpoint);
+  } else {
+    if (h->secure_endpoint != NULL) {
+      grpc_endpoint_shutdown(h->secure_endpoint);
+      grpc_endpoint_destroy(h->secure_endpoint);
+    } else {
+      grpc_endpoint_destroy(h->wrapped_endpoint);
+    }
+    h->cb(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(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(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(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(h, 1);
+  return;
+}
+
+static void check_peer(grpc_security_handshake *h) {
+  grpc_security_status peer_status;
+  tsi_peer 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(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(h, 0);
+    return;
+  } else if (peer_status == GRPC_SECURITY_OK) {
+    on_peer_checked(h, peer_status);
+  }
+}
+
+static void send_handshake_bytes_to_peer(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);
+    }
+  } 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(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);
+  /* TODO(klempner,jboeuf): This should probably use the client setup
+         deadline */
+  switch (grpc_endpoint_write(h->wrapped_endpoint, &h->outgoing,
+                              &h->on_handshake_data_sent_to_peer)) {
+    case GRPC_ENDPOINT_ERROR:
+      gpr_log(GPR_ERROR, "Could not send handshake data to peer.");
+      security_handshake_done(h, 0);
+      break;
+    case GRPC_ENDPOINT_DONE:
+      on_handshake_data_sent_to_peer(h, 1);
+      break;
+    case GRPC_ENDPOINT_PENDING:
+      break;
+  }
+}
+
+static void on_handshake_data_received_from_peer(void *handshake, int success) {
+  grpc_security_handshake *h = handshake;
+  size_t consumed_slice_size = 0;
+  tsi_result result = TSI_OK;
+  size_t i;
+  size_t num_left_overs;
+  int has_left_overs_in_current_slice = 0;
+
+  if (!success) {
+    gpr_log(GPR_ERROR, "Read failed.");
+    security_handshake_done(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 (tsi_handshaker_is_in_progress(h->handshaker)) {
+    /* We may need more data. */
+    if (result == TSI_INCOMPLETE_DATA) {
+      switch (grpc_endpoint_read(h->wrapped_endpoint, &h->incoming,
+                                 &h->on_handshake_data_received_from_peer)) {
+        case GRPC_ENDPOINT_DONE:
+          on_handshake_data_received_from_peer(h, 1);
+          break;
+        case GRPC_ENDPOINT_ERROR:
+          on_handshake_data_received_from_peer(h, 0);
+          break;
+        case GRPC_ENDPOINT_PENDING:
+          break;
+      }
+      return;
+    } else {
+      send_handshake_bytes_to_peer(h);
+      return;
+    }
+  }
+
+  if (result != TSI_OK) {
+    gpr_log(GPR_ERROR, "Handshake failed with error %s",
+            tsi_result_to_string(result));
+    security_handshake_done(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(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(h);
+}
+
+/* If handshake is NULL, the handshake is done. */
+static void on_handshake_data_sent_to_peer(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(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 */
+    switch (grpc_endpoint_read(h->wrapped_endpoint, &h->incoming,
+                               &h->on_handshake_data_received_from_peer)) {
+      case GRPC_ENDPOINT_ERROR:
+        on_handshake_data_received_from_peer(h, 0);
+        break;
+      case GRPC_ENDPOINT_PENDING:
+        break;
+      case GRPC_ENDPOINT_DONE:
+        on_handshake_data_received_from_peer(h, 1);
+        break;
+    }
+  } else {
+    check_peer(h);
+  }
+}
+
+void grpc_do_security_handshake(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->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;
+  grpc_iomgr_closure_init(&h->on_handshake_data_sent_to_peer,
+                          on_handshake_data_sent_to_peer, h);
+  grpc_iomgr_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(h);
+}
diff --git a/src/core/security/secure_transport_setup.h b/src/core/security/handshake.h
similarity index 68%
rename from src/core/security/secure_transport_setup.h
rename to src/core/security/handshake.h
index d9b8025..d7e4a30 100644
--- a/src/core/security/secure_transport_setup.h
+++ b/src/core/security/handshake.h
@@ -31,23 +31,18 @@
  *
  */
 
-#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. Takes owership of handshaker. */
+void grpc_do_security_handshake(tsi_handshaker *handshaker,
+                                grpc_security_connector *connector,
+                                grpc_endpoint *nonsecure_endpoint,
+                                grpc_security_handshake_done_cb cb,
+                                void *user_data);
 
-/* 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);
-
-#endif /* GRPC_INTERNAL_CORE_SECURITY_SECURE_TRANSPORT_SETUP_H */
+#endif /* GRPC_INTERNAL_CORE_SECURITY_HANDSHAKE_H */
diff --git a/src/core/security/secure_transport_setup.c b/src/core/security/secure_transport_setup.c
deleted file mode 100644
index bf00795..0000000
--- a/src/core/security/secure_transport_setup.c
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "src/core/security/secure_transport_setup.h"
-
-#include <string.h>
-
-#include "src/core/security/secure_endpoint.h"
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-#include <grpc/support/slice_buffer.h>
-
-#define GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE 256
-
-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;
-  gpr_slice_buffer incoming;
-  gpr_slice_buffer outgoing;
-  grpc_secure_transport_setup_done_cb cb;
-  void *user_data;
-  grpc_iomgr_closure on_handshake_data_sent_to_peer;
-  grpc_iomgr_closure on_handshake_data_received_from_peer;
-} grpc_secure_transport_setup;
-
-static void on_handshake_data_received_from_peer(void *setup, int success);
-
-static void on_handshake_data_sent_to_peer(void *setup, int success);
-
-static void secure_transport_setup_done(grpc_secure_transport_setup *s,
-                                        int is_success) {
-  if (is_success) {
-    s->cb(s->user_data, GRPC_SECURITY_OK, s->wrapped_endpoint,
-          s->secure_endpoint);
-  } else {
-    if (s->secure_endpoint != NULL) {
-      grpc_endpoint_shutdown(s->secure_endpoint);
-      grpc_endpoint_destroy(s->secure_endpoint);
-    } else {
-      grpc_endpoint_destroy(s->wrapped_endpoint);
-    }
-    s->cb(s->user_data, GRPC_SECURITY_ERROR, s->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);
-  gpr_slice_buffer_destroy(&s->outgoing);
-  gpr_slice_buffer_destroy(&s->incoming);
-  GRPC_SECURITY_CONNECTOR_UNREF(s->connector, "secure_transport_setup");
-  gpr_free(s);
-}
-
-static void on_peer_checked(void *user_data, grpc_security_status status) {
-  grpc_secure_transport_setup *s = 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);
-    return;
-  }
-  result =
-      tsi_handshaker_create_frame_protector(s->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);
-    return;
-  }
-  s->secure_endpoint =
-      grpc_secure_endpoint_create(protector, s->wrapped_endpoint,
-                                  s->left_overs.slices, s->left_overs.count);
-  s->left_overs.count = 0;
-  s->left_overs.length = 0;
-  secure_transport_setup_done(s, 1);
-  return;
-}
-
-static void check_peer(grpc_secure_transport_setup *s) {
-  grpc_security_status peer_status;
-  tsi_peer peer;
-  tsi_result result = tsi_handshaker_extract_peer(s->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);
-    return;
-  }
-  peer_status = grpc_security_connector_check_peer(s->connector, peer,
-                                                   on_peer_checked, s);
-  if (peer_status == GRPC_SECURITY_ERROR) {
-    gpr_log(GPR_ERROR, "Peer check failed.");
-    secure_transport_setup_done(s, 0);
-    return;
-  } else if (peer_status == GRPC_SECURITY_OK) {
-    on_peer_checked(s, peer_status);
-  }
-}
-
-static void send_handshake_bytes_to_peer(grpc_secure_transport_setup *s) {
-  size_t offset = 0;
-  tsi_result result = TSI_OK;
-  gpr_slice to_send;
-
-  do {
-    size_t to_send_size = s->handshake_buffer_size - offset;
-    result = tsi_handshaker_get_bytes_to_send_to_peer(
-        s->handshaker, s->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);
-    }
-  } 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);
-    return;
-  }
-
-  to_send =
-      gpr_slice_from_copied_buffer((const char *)s->handshake_buffer, offset);
-  gpr_slice_buffer_reset_and_unref(&s->outgoing);
-  gpr_slice_buffer_add(&s->outgoing, to_send);
-  /* TODO(klempner,jboeuf): This should probably use the client setup
-         deadline */
-  switch (grpc_endpoint_write(s->wrapped_endpoint, &s->outgoing,
-                              &s->on_handshake_data_sent_to_peer)) {
-    case GRPC_ENDPOINT_ERROR:
-      gpr_log(GPR_ERROR, "Could not send handshake data to peer.");
-      secure_transport_setup_done(s, 0);
-      break;
-    case GRPC_ENDPOINT_DONE:
-      on_handshake_data_sent_to_peer(s, 1);
-      break;
-    case GRPC_ENDPOINT_PENDING:
-      break;
-  }
-}
-
-static void on_handshake_data_received_from_peer(void *setup, int success) {
-  grpc_secure_transport_setup *s = setup;
-  size_t consumed_slice_size = 0;
-  tsi_result result = TSI_OK;
-  size_t i;
-  size_t num_left_overs;
-  int has_left_overs_in_current_slice = 0;
-
-  if (!success) {
-    gpr_log(GPR_ERROR, "Read failed.");
-    secure_transport_setup_done(s, 0);
-    return;
-  }
-
-  for (i = 0; i < s->incoming.count; i++) {
-    consumed_slice_size = GPR_SLICE_LENGTH(s->incoming.slices[i]);
-    result = tsi_handshaker_process_bytes_from_peer(
-        s->handshaker, GPR_SLICE_START_PTR(s->incoming.slices[i]),
-        &consumed_slice_size);
-    if (!tsi_handshaker_is_in_progress(s->handshaker)) break;
-  }
-
-  if (tsi_handshaker_is_in_progress(s->handshaker)) {
-    /* We may need more data. */
-    if (result == TSI_INCOMPLETE_DATA) {
-      switch (grpc_endpoint_read(s->wrapped_endpoint, &s->incoming,
-                                 &s->on_handshake_data_received_from_peer)) {
-        case GRPC_ENDPOINT_DONE:
-          on_handshake_data_received_from_peer(s, 1);
-          break;
-        case GRPC_ENDPOINT_ERROR:
-          on_handshake_data_received_from_peer(s, 0);
-          break;
-        case GRPC_ENDPOINT_PENDING:
-          break;
-      }
-      return;
-    } else {
-      send_handshake_bytes_to_peer(s);
-      return;
-    }
-  }
-
-  if (result != TSI_OK) {
-    gpr_log(GPR_ERROR, "Handshake failed with error %s",
-            tsi_result_to_string(result));
-    secure_transport_setup_done(s, 0);
-    return;
-  }
-
-  /* Handshake is done and successful this point. */
-  has_left_overs_in_current_slice =
-      (consumed_slice_size < GPR_SLICE_LENGTH(s->incoming.slices[i]));
-  num_left_overs =
-      (has_left_overs_in_current_slice ? 1 : 0) + s->incoming.count - i - 1;
-  if (num_left_overs == 0) {
-    check_peer(s);
-    return;
-  }
-  /* Put the leftovers in our buffer (ownership transfered). */
-  if (has_left_overs_in_current_slice) {
-    gpr_slice_buffer_add(
-        &s->left_overs,
-        gpr_slice_split_tail(&s->incoming.slices[i], consumed_slice_size));
-    gpr_slice_unref(
-        s->incoming.slices[i]); /* split_tail above increments refcount. */
-  }
-  gpr_slice_buffer_addn(
-      &s->left_overs, &s->incoming.slices[i + 1],
-      num_left_overs - (size_t)has_left_overs_in_current_slice);
-  check_peer(s);
-}
-
-/* If setup is NULL, the setup is done. */
-static void on_handshake_data_sent_to_peer(void *setup, int success) {
-  grpc_secure_transport_setup *s = setup;
-
-  /* Make sure that write is OK. */
-  if (!success) {
-    gpr_log(GPR_ERROR, "Write failed.");
-    if (setup != NULL) secure_transport_setup_done(s, 0);
-    return;
-  }
-
-  /* We may be done. */
-  if (tsi_handshaker_is_in_progress(s->handshaker)) {
-    /* TODO(klempner,jboeuf): This should probably use the client setup
-       deadline */
-    switch (grpc_endpoint_read(s->wrapped_endpoint, &s->incoming,
-                               &s->on_handshake_data_received_from_peer)) {
-      case GRPC_ENDPOINT_ERROR:
-        on_handshake_data_received_from_peer(s, 0);
-        break;
-      case GRPC_ENDPOINT_PENDING:
-        break;
-      case GRPC_ENDPOINT_DONE:
-        on_handshake_data_received_from_peer(s, 1);
-        break;
-    }
-  } else {
-    check_peer(s);
-  }
-}
-
-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;
-  grpc_iomgr_closure_init(&s->on_handshake_data_sent_to_peer,
-                          on_handshake_data_sent_to_peer, s);
-  grpc_iomgr_closure_init(&s->on_handshake_data_received_from_peer,
-                          on_handshake_data_received_from_peer, s);
-  gpr_slice_buffer_init(&s->left_overs);
-  gpr_slice_buffer_init(&s->outgoing);
-  gpr_slice_buffer_init(&s->incoming);
-  send_handshake_bytes_to_peer(s);
-}
diff --git a/src/core/security/security_connector.c b/src/core/security/security_connector.c
index ba9ac68..f6460a3 100644
--- a/src/core/security/security_connector.c
+++ b/src/core/security/security_connector.c
@@ -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 @@
   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(
@@ -225,18 +231,6 @@
   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 +280,27 @@
   }
 }
 
+static void fake_channel_do_handshake(grpc_security_connector *sc,
+                                      grpc_endpoint *nonsecure_endpoint,
+                                      grpc_security_handshake_done_cb cb,
+                                      void *user_data) {
+  grpc_do_security_handshake(tsi_create_fake_handshaker(1), 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) {
+  grpc_do_security_handshake(tsi_create_fake_handshaker(0), 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) {
@@ -372,22 +382,41 @@
   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);
+  tsi_handshaker *handshaker;
+  grpc_security_status status = ssl_create_handshaker(
+      c->handshaker_factory, 1,
+      c->overridden_target_name != NULL ? c->overridden_target_name
+                                        : c->target_name,
+      &handshaker);
+  if (status != GRPC_SECURITY_OK) {
+    cb(user_data, status, nonsecure_endpoint, NULL);
+  } else {
+    grpc_do_security_handshake(handshaker, 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);
+  tsi_handshaker *handshaker;
+  grpc_security_status status =
+      ssl_create_handshaker(c->handshaker_factory, 0, NULL, &handshaker);
+  if (status != GRPC_SECURITY_OK) {
+    cb(user_data, status, nonsecure_endpoint, NULL);
+  } else {
+    grpc_do_security_handshake(handshaker, sc, nonsecure_endpoint, cb,
+                               user_data);
+  }
 }
 
 static int ssl_host_matches_name(const tsi_peer *peer, const char *peer_name) {
@@ -512,10 +541,10 @@
 }
 
 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;
 
diff --git a/src/core/security/security_connector.h b/src/core/security/security_connector.h
index 2c9aa1c..5fc1db3 100644
--- a/src/core/security/security_connector.h
+++ b/src/core/security/security_connector.h
@@ -63,10 +63,17 @@
 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);
@@ -100,9 +107,11 @@
 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
diff --git a/src/core/security/server_secure_chttp2.c b/src/core/security/server_secure_chttp2.c
index 4749f5f..f7318b2 100644
--- a/src/core/security/server_secure_chttp2.c
+++ b/src/core/security/server_secure_chttp2.c
@@ -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>
@@ -123,10 +122,9 @@
   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;
@@ -165,8 +163,8 @@
   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 */
diff --git a/src/core/surface/secure_channel_create.c b/src/core/surface/secure_channel_create.c
index 52c5e93..289bf01 100644
--- a/src/core/surface/secure_channel_create.c
+++ b/src/core/surface/secure_channel_create.c
@@ -47,7 +47,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"
@@ -78,10 +77,9 @@
   }
 }
 
-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;
   gpr_mu_lock(&c->mu);
@@ -90,7 +88,7 @@
     gpr_mu_unlock(&c->mu);
   } else if (status != GRPC_SECURITY_OK) {
     GPR_ASSERT(c->connecting_endpoint == wrapped_endpoint);
-    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));
     c->connecting_endpoint = NULL;
     gpr_mu_unlock(&c->mu);
@@ -119,8 +117,8 @@
     GPR_ASSERT(c->connecting_endpoint == NULL);
     c->connecting_endpoint = tcp;
     gpr_mu_unlock(&c->mu);
-    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;
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 106d235..8b88d54 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -770,10 +770,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 \
@@ -895,10 +895,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 \
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index 7acf0ff..3696e2d 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -12347,10 +12347,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/statistics/census_interface.h", 
@@ -12564,14 +12564,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", 
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj
index 0f8d3f9..a09e813 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj
@@ -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" />
@@ -367,14 +367,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">
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
index 64569c4..1538c33 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
@@ -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>
@@ -467,6 +467,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>
@@ -476,9 +479,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>