diff --git a/Makefile b/Makefile
index de8a26283bf164a8cbb1946454fa2cea488de4a9..cb7658d8ccf33631d2ccb098d98ee926cd05c700 100644
--- a/Makefile
+++ b/Makefile
@@ -1019,6 +1019,7 @@ set_initial_connect_string_test: $(BINDIR)/$(CONFIG)/set_initial_connect_string_
 sockaddr_resolver_test: $(BINDIR)/$(CONFIG)/sockaddr_resolver_test
 sockaddr_utils_test: $(BINDIR)/$(CONFIG)/sockaddr_utils_test
 socket_utils_test: $(BINDIR)/$(CONFIG)/socket_utils_test
+ssl_server_fuzzer: $(BINDIR)/$(CONFIG)/ssl_server_fuzzer
 tcp_client_posix_test: $(BINDIR)/$(CONFIG)/tcp_client_posix_test
 tcp_posix_test: $(BINDIR)/$(CONFIG)/tcp_posix_test
 tcp_server_posix_test: $(BINDIR)/$(CONFIG)/tcp_server_posix_test
@@ -1183,6 +1184,7 @@ nanopb_fuzzer_serverlist_test_one_entry: $(BINDIR)/$(CONFIG)/nanopb_fuzzer_serve
 percent_decode_fuzzer_one_entry: $(BINDIR)/$(CONFIG)/percent_decode_fuzzer_one_entry
 percent_encode_fuzzer_one_entry: $(BINDIR)/$(CONFIG)/percent_encode_fuzzer_one_entry
 server_fuzzer_one_entry: $(BINDIR)/$(CONFIG)/server_fuzzer_one_entry
+ssl_server_fuzzer_one_entry: $(BINDIR)/$(CONFIG)/ssl_server_fuzzer_one_entry
 uri_fuzzer_test_one_entry: $(BINDIR)/$(CONFIG)/uri_fuzzer_test_one_entry
 
 run_dep_checks:
@@ -1411,6 +1413,7 @@ buildtests_c: privatelibs_c \
   $(BINDIR)/$(CONFIG)/percent_decode_fuzzer_one_entry \
   $(BINDIR)/$(CONFIG)/percent_encode_fuzzer_one_entry \
   $(BINDIR)/$(CONFIG)/server_fuzzer_one_entry \
+  $(BINDIR)/$(CONFIG)/ssl_server_fuzzer_one_entry \
   $(BINDIR)/$(CONFIG)/uri_fuzzer_test_one_entry \
 
 
@@ -10779,6 +10782,38 @@ endif
 endif
 
 
+SSL_SERVER_FUZZER_SRC = \
+    test/core/security/ssl_server_fuzzer.c \
+
+SSL_SERVER_FUZZER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SSL_SERVER_FUZZER_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/ssl_server_fuzzer: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/ssl_server_fuzzer: $(SSL_SERVER_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LDXX) $(LDFLAGS) $(SSL_SERVER_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/ssl_server_fuzzer
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/security/ssl_server_fuzzer.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_ssl_server_fuzzer: $(SSL_SERVER_FUZZER_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(SSL_SERVER_FUZZER_OBJS:.o=.dep)
+endif
+endif
+
+
 TCP_CLIENT_POSIX_TEST_SRC = \
     test/core/iomgr/tcp_client_posix_test.c \
 
@@ -16225,6 +16260,41 @@ endif
 endif
 
 
+SSL_SERVER_FUZZER_ONE_ENTRY_SRC = \
+    test/core/security/ssl_server_fuzzer.c \
+    test/core/util/one_corpus_entry_fuzzer.c \
+
+SSL_SERVER_FUZZER_ONE_ENTRY_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SSL_SERVER_FUZZER_ONE_ENTRY_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/ssl_server_fuzzer_one_entry: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/ssl_server_fuzzer_one_entry: $(SSL_SERVER_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS) $(SSL_SERVER_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/ssl_server_fuzzer_one_entry
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/security/ssl_server_fuzzer.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_ssl_server_fuzzer_one_entry: $(SSL_SERVER_FUZZER_ONE_ENTRY_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(SSL_SERVER_FUZZER_ONE_ENTRY_OBJS:.o=.dep)
+endif
+endif
+
+
 URI_FUZZER_TEST_ONE_ENTRY_SRC = \
     test/core/client_channel/uri_fuzzer_test.c \
     test/core/util/one_corpus_entry_fuzzer.c \
diff --git a/build.yaml b/build.yaml
index a5b811e80033c57457b822104f98c2772720d722..059a2b315da4d5046d01686eb5d07bb79028acc8 100644
--- a/build.yaml
+++ b/build.yaml
@@ -2554,6 +2554,19 @@ targets:
   - mac
   - linux
   - posix
+- name: ssl_server_fuzzer
+  build: fuzzer
+  language: c
+  src:
+  - test/core/security/ssl_server_fuzzer.c
+  deps:
+  - grpc_test_util
+  - grpc
+  - gpr_test_util
+  - gpr
+  corpus_dirs:
+  - test/core/security/corpus/ssl_server_corpus
+  maxlen: 2048
 - name: tcp_client_posix_test
   cpu_cost: 0.5
   build: test
diff --git a/test/core/security/ssl_server_fuzzer.c b/test/core/security/ssl_server_fuzzer.c
new file mode 100644
index 0000000000000000000000000000000000000000..7723a67ff5a0ee7821ef76a203f6d60d861721b8
--- /dev/null
+++ b/test/core/security/ssl_server_fuzzer.c
@@ -0,0 +1,154 @@
+/*
+ *
+ * Copyright 2016, 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 <grpc/grpc.h>
+#include <grpc/grpc_security.h>
+#include <grpc/support/log.h>
+
+#include "src/core/lib/iomgr/load_file.h"
+#include "src/core/lib/security/credentials/credentials.h"
+#include "src/core/lib/security/transport/security_connector.h"
+#include "test/core/util/memory_counters.h"
+#include "test/core/util/mock_endpoint.h"
+
+bool squelch = true;
+// ssl has an array of global gpr_mu's that are never released.
+// Turning this on will fail the leak check.
+bool leak_check = false;
+
+#define SSL_CERT_PATH "src/core/lib/tsi/test_creds/server1.pem"
+#define SSL_KEY_PATH "src/core/lib/tsi/test_creds/server1.key"
+#define SSL_CA_PATH "src/core/lib/tsi/test_creds/ca.pem"
+
+static void discard_write(gpr_slice slice) {}
+
+static void dont_log(gpr_log_func_args *args) {}
+
+struct handshake_state {
+  bool done_callback_called;
+};
+
+static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep,
+                                     grpc_security_status status,
+                                     grpc_endpoint *secure_endpoint,
+                                     grpc_auth_context *auth_context) {
+  struct handshake_state *state = (struct handshake_state *)statep;
+  GPR_ASSERT(state->done_callback_called == false);
+  state->done_callback_called = true;
+  // The fuzzer should not pass the handshake.
+  GPR_ASSERT(status != GRPC_SECURITY_OK);
+  GPR_ASSERT(secure_endpoint == NULL);
+  GPR_ASSERT(auth_context == NULL);
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+  struct grpc_memory_counters counters;
+  if (squelch) gpr_set_log_function(dont_log);
+  if (leak_check) grpc_memory_counters_init();
+  grpc_init();
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+
+  grpc_resource_quota *resource_quota =
+      grpc_resource_quota_create("ssl_server_fuzzer");
+  grpc_endpoint *mock_endpoint =
+      grpc_mock_endpoint_create(discard_write, resource_quota);
+  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+
+  grpc_mock_endpoint_put_read(
+      &exec_ctx, mock_endpoint,
+      gpr_slice_from_copied_buffer((const char *)data, size));
+
+  // Load key pair and establish server SSL credentials.
+  grpc_ssl_pem_key_cert_pair pem_key_cert_pair;
+  gpr_slice ca_slice, cert_slice, key_slice;
+  GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file",
+                               grpc_load_file(SSL_CA_PATH, 1, &ca_slice)));
+  GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file",
+                               grpc_load_file(SSL_CERT_PATH, 1, &cert_slice)));
+  GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file",
+                               grpc_load_file(SSL_KEY_PATH, 1, &key_slice)));
+  const char *ca_cert = (const char *)GPR_SLICE_START_PTR(ca_slice);
+  pem_key_cert_pair.private_key = (const char *)GPR_SLICE_START_PTR(key_slice);
+  pem_key_cert_pair.cert_chain = (const char *)GPR_SLICE_START_PTR(cert_slice);
+  grpc_server_credentials *creds = grpc_ssl_server_credentials_create(
+      ca_cert, &pem_key_cert_pair, 1, 0, NULL);
+
+  // Create security connector
+  grpc_server_security_connector *sc = NULL;
+  grpc_security_status status =
+      grpc_server_credentials_create_security_connector(creds, &sc);
+  GPR_ASSERT(status == GRPC_SECURITY_OK);
+  sc->channel_args = NULL;
+  gpr_timespec deadline = gpr_time_add(
+              gpr_now(GPR_CLOCK_MONOTONIC),
+              gpr_time_from_seconds(1, GPR_TIMESPAN));
+
+  struct handshake_state state;
+  state.done_callback_called = false;
+  grpc_server_security_connector_do_handshake(
+      &exec_ctx, sc, NULL, mock_endpoint, NULL, deadline,
+      on_secure_handshake_done, &state);
+  grpc_exec_ctx_flush(&exec_ctx);
+
+  bool mock_endpoint_shutdown = false;
+  // If the given string happens to be part of the correct client hello, the
+  // server will wait for more data. Explicitly fail the server by shutting down
+  // the endpoint.
+  if (!state.done_callback_called) {
+    mock_endpoint_shutdown = true;
+    grpc_endpoint_shutdown(&exec_ctx, mock_endpoint);
+    grpc_exec_ctx_flush(&exec_ctx);
+  }
+
+  GPR_ASSERT(state.done_callback_called);
+
+  GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "test");
+  grpc_server_credentials_release(creds);
+  gpr_slice_unref(cert_slice);
+  gpr_slice_unref(key_slice);
+  gpr_slice_unref(ca_slice);
+  // grpc_endpoint_destroy has been called in handshake failure handling code.
+  if (!mock_endpoint_shutdown) {
+    grpc_endpoint_shutdown(&exec_ctx, mock_endpoint);
+    grpc_exec_ctx_flush(&exec_ctx);
+  }
+  grpc_exec_ctx_flush(&exec_ctx);
+
+  grpc_shutdown();
+  if (leak_check) {
+    counters = grpc_memory_counters_snapshot();
+    grpc_memory_counters_destroy();
+    GPR_ASSERT(counters.total_size_relative == 0);
+  }
+  return 0;
+}
diff --git a/tools/fuzzer/runners/ssl_server_fuzzer.sh b/tools/fuzzer/runners/ssl_server_fuzzer.sh
new file mode 100644
index 0000000000000000000000000000000000000000..23aef992e083b7f55306b93a72680d1d0fca0551
--- /dev/null
+++ b/tools/fuzzer/runners/ssl_server_fuzzer.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+# Copyright 2016, 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.
+#
+
+flags="-max_total_time=$runtime -artifact_prefix=fuzzer_output/ -max_len=2048 -timeout=120"
+
+if [ "$jobs" != "1" ]
+then
+  flags="-jobs=$jobs -workers=$jobs $flags"
+fi
+
+if [ "$config" == "asan-trace-cmp" ]
+then
+  flags="-use_traces=1 $flags"
+fi
+
+bins/$config/ssl_server_fuzzer $flags fuzzer_output test/core/security/corpus/ssl_server_corpus
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index 8efa2f40d699d48915fe9886ebe2e5421b58f024..231c302b0902ab9766b61b2aa8800a44f8770785 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -1909,6 +1909,23 @@
     "third_party": false, 
     "type": "target"
   }, 
+  {
+    "deps": [
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "is_filegroup": false, 
+    "language": "c", 
+    "name": "ssl_server_fuzzer", 
+    "src": [
+      "test/core/security/ssl_server_fuzzer.c"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
   {
     "deps": [
       "gpr", 
@@ -4782,6 +4799,24 @@
     "third_party": false, 
     "type": "target"
   }, 
+  {
+    "deps": [
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "is_filegroup": false, 
+    "language": "c", 
+    "name": "ssl_server_fuzzer_one_entry", 
+    "src": [
+      "test/core/security/ssl_server_fuzzer.c", 
+      "test/core/util/one_corpus_entry_fuzzer.c"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
   {
     "deps": [
       "gpr",