aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/tsi
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/tsi')
-rw-r--r--src/core/tsi/fake_transport_security.c135
-rw-r--r--src/core/tsi/fake_transport_security.h5
-rw-r--r--src/core/tsi/ssl_transport_security.c113
-rw-r--r--src/core/tsi/ssl_transport_security.h37
-rw-r--r--src/core/tsi/test_creds/BUILD14
-rw-r--r--src/core/tsi/transport_security.h10
-rw-r--r--src/core/tsi/transport_security_grpc.c33
-rw-r--r--src/core/tsi/transport_security_grpc.h22
8 files changed, 325 insertions, 44 deletions
diff --git a/src/core/tsi/fake_transport_security.c b/src/core/tsi/fake_transport_security.c
index 967126ecee..64043fea08 100644
--- a/src/core/tsi/fake_transport_security.c
+++ b/src/core/tsi/fake_transport_security.c
@@ -25,7 +25,8 @@
#include <grpc/support/log.h>
#include <grpc/support/port_platform.h>
#include <grpc/support/useful.h>
-#include "src/core/tsi/transport_security.h"
+#include "src/core/lib/slice/slice_internal.h"
+#include "src/core/tsi/transport_security_grpc.h"
/* --- Constants. ---*/
#define TSI_FAKE_FRAME_HEADER_SIZE 4
@@ -74,6 +75,14 @@ typedef struct {
size_t max_frame_size;
} tsi_fake_frame_protector;
+typedef struct {
+ tsi_zero_copy_grpc_protector base;
+ grpc_slice_buffer header_sb;
+ grpc_slice_buffer protected_sb;
+ size_t max_frame_size;
+ size_t parsed_frame_size;
+} tsi_fake_zero_copy_grpc_protector;
+
/* --- Utils. ---*/
static const char *tsi_fake_handshake_message_strings[] = {
@@ -113,6 +122,28 @@ static void store32_little_endian(uint32_t value, unsigned char *buf) {
buf[0] = (unsigned char)((value)&0xFF);
}
+static uint32_t read_frame_size(const grpc_slice_buffer *sb) {
+ GPR_ASSERT(sb != NULL && sb->length >= TSI_FAKE_FRAME_HEADER_SIZE);
+ uint8_t frame_size_buffer[TSI_FAKE_FRAME_HEADER_SIZE];
+ uint8_t *buf = frame_size_buffer;
+ /* Copies the first 4 bytes to a temporary buffer. */
+ size_t remaining = TSI_FAKE_FRAME_HEADER_SIZE;
+ for (size_t i = 0; i < sb->count; i++) {
+ size_t slice_length = GRPC_SLICE_LENGTH(sb->slices[i]);
+ if (remaining <= slice_length) {
+ memcpy(buf, GRPC_SLICE_START_PTR(sb->slices[i]), remaining);
+ remaining = 0;
+ break;
+ } else {
+ memcpy(buf, GRPC_SLICE_START_PTR(sb->slices[i]), slice_length);
+ buf += slice_length;
+ remaining -= slice_length;
+ }
+ }
+ GPR_ASSERT(remaining == 0);
+ return load32_little_endian(frame_size_buffer);
+}
+
static void tsi_fake_frame_reset(tsi_fake_frame *frame, int needs_draining) {
frame->offset = 0;
frame->needs_draining = needs_draining;
@@ -363,6 +394,84 @@ static const tsi_frame_protector_vtable frame_protector_vtable = {
fake_protector_unprotect, fake_protector_destroy,
};
+/* --- tsi_zero_copy_grpc_protector methods implementation. ---*/
+
+static tsi_result fake_zero_copy_grpc_protector_protect(
+ grpc_exec_ctx *exec_ctx, tsi_zero_copy_grpc_protector *self,
+ grpc_slice_buffer *unprotected_slices,
+ grpc_slice_buffer *protected_slices) {
+ if (self == NULL || unprotected_slices == NULL || protected_slices == NULL) {
+ return TSI_INVALID_ARGUMENT;
+ }
+ tsi_fake_zero_copy_grpc_protector *impl =
+ (tsi_fake_zero_copy_grpc_protector *)self;
+ /* Protects each frame. */
+ while (unprotected_slices->length > 0) {
+ size_t frame_length =
+ GPR_MIN(impl->max_frame_size,
+ unprotected_slices->length + TSI_FAKE_FRAME_HEADER_SIZE);
+ grpc_slice slice = GRPC_SLICE_MALLOC(TSI_FAKE_FRAME_HEADER_SIZE);
+ store32_little_endian((uint32_t)frame_length, GRPC_SLICE_START_PTR(slice));
+ grpc_slice_buffer_add(protected_slices, slice);
+ size_t data_length = frame_length - TSI_FAKE_FRAME_HEADER_SIZE;
+ grpc_slice_buffer_move_first(unprotected_slices, data_length,
+ protected_slices);
+ }
+ return TSI_OK;
+}
+
+static tsi_result fake_zero_copy_grpc_protector_unprotect(
+ grpc_exec_ctx *exec_ctx, tsi_zero_copy_grpc_protector *self,
+ grpc_slice_buffer *protected_slices,
+ grpc_slice_buffer *unprotected_slices) {
+ if (self == NULL || unprotected_slices == NULL || protected_slices == NULL) {
+ return TSI_INVALID_ARGUMENT;
+ }
+ tsi_fake_zero_copy_grpc_protector *impl =
+ (tsi_fake_zero_copy_grpc_protector *)self;
+ grpc_slice_buffer_move_into(protected_slices, &impl->protected_sb);
+ /* Unprotect each frame, if we get a full frame. */
+ while (impl->protected_sb.length >= TSI_FAKE_FRAME_HEADER_SIZE) {
+ if (impl->parsed_frame_size == 0) {
+ impl->parsed_frame_size = read_frame_size(&impl->protected_sb);
+ if (impl->parsed_frame_size <= 4) {
+ gpr_log(GPR_ERROR, "Invalid frame size.");
+ return TSI_DATA_CORRUPTED;
+ }
+ }
+ /* If we do not have a full frame, return with OK status. */
+ if (impl->protected_sb.length < impl->parsed_frame_size) break;
+ /* Strips header bytes. */
+ grpc_slice_buffer_move_first(&impl->protected_sb,
+ TSI_FAKE_FRAME_HEADER_SIZE, &impl->header_sb);
+ /* Moves data to unprotected slices. */
+ grpc_slice_buffer_move_first(
+ &impl->protected_sb,
+ impl->parsed_frame_size - TSI_FAKE_FRAME_HEADER_SIZE,
+ unprotected_slices);
+ impl->parsed_frame_size = 0;
+ grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &impl->header_sb);
+ }
+ return TSI_OK;
+}
+
+static void fake_zero_copy_grpc_protector_destroy(
+ grpc_exec_ctx *exec_ctx, tsi_zero_copy_grpc_protector *self) {
+ if (self == NULL) return;
+ tsi_fake_zero_copy_grpc_protector *impl =
+ (tsi_fake_zero_copy_grpc_protector *)self;
+ grpc_slice_buffer_destroy_internal(exec_ctx, &impl->header_sb);
+ grpc_slice_buffer_destroy_internal(exec_ctx, &impl->protected_sb);
+ gpr_free(impl);
+}
+
+static const tsi_zero_copy_grpc_protector_vtable
+ zero_copy_grpc_protector_vtable = {
+ fake_zero_copy_grpc_protector_protect,
+ fake_zero_copy_grpc_protector_unprotect,
+ fake_zero_copy_grpc_protector_destroy,
+};
+
/* --- tsi_handshaker_result methods implementation. ---*/
typedef struct {
@@ -383,6 +492,15 @@ static tsi_result fake_handshaker_result_extract_peer(
return result;
}
+static tsi_result fake_handshaker_result_create_zero_copy_grpc_protector(
+ void *exec_ctx, const tsi_handshaker_result *self,
+ size_t *max_output_protected_frame_size,
+ tsi_zero_copy_grpc_protector **protector) {
+ *protector =
+ tsi_create_fake_zero_copy_grpc_protector(max_output_protected_frame_size);
+ return TSI_OK;
+}
+
static tsi_result fake_handshaker_result_create_frame_protector(
const tsi_handshaker_result *self, size_t *max_output_protected_frame_size,
tsi_frame_protector **protector) {
@@ -407,7 +525,7 @@ static void fake_handshaker_result_destroy(tsi_handshaker_result *self) {
static const tsi_handshaker_result_vtable handshaker_result_vtable = {
fake_handshaker_result_extract_peer,
- NULL, /* create_zero_copy_grpc_protector */
+ fake_handshaker_result_create_zero_copy_grpc_protector,
fake_handshaker_result_create_frame_protector,
fake_handshaker_result_get_unused_bytes,
fake_handshaker_result_destroy,
@@ -631,3 +749,16 @@ tsi_frame_protector *tsi_create_fake_frame_protector(
impl->base.vtable = &frame_protector_vtable;
return &impl->base;
}
+
+tsi_zero_copy_grpc_protector *tsi_create_fake_zero_copy_grpc_protector(
+ size_t *max_protected_frame_size) {
+ tsi_fake_zero_copy_grpc_protector *impl = gpr_zalloc(sizeof(*impl));
+ grpc_slice_buffer_init(&impl->header_sb);
+ grpc_slice_buffer_init(&impl->protected_sb);
+ impl->max_frame_size = (max_protected_frame_size == NULL)
+ ? TSI_FAKE_DEFAULT_FRAME_SIZE
+ : *max_protected_frame_size;
+ impl->parsed_frame_size = 0;
+ impl->base.vtable = &zero_copy_grpc_protector_vtable;
+ return &impl->base;
+}
diff --git a/src/core/tsi/fake_transport_security.h b/src/core/tsi/fake_transport_security.h
index 934b3cbeb2..6159708a84 100644
--- a/src/core/tsi/fake_transport_security.h
+++ b/src/core/tsi/fake_transport_security.h
@@ -39,6 +39,11 @@ tsi_handshaker *tsi_create_fake_handshaker(int is_client);
tsi_frame_protector *tsi_create_fake_frame_protector(
size_t *max_protected_frame_size);
+/* Creates a zero-copy protector directly without going through the handshake
+ * phase. */
+tsi_zero_copy_grpc_protector *tsi_create_fake_zero_copy_grpc_protector(
+ size_t *max_protected_frame_size);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/core/tsi/ssl_transport_security.c b/src/core/tsi/ssl_transport_security.c
index 1fd65928f9..7ebf9dd96f 100644
--- a/src/core/tsi/ssl_transport_security.c
+++ b/src/core/tsi/ssl_transport_security.c
@@ -67,7 +67,13 @@
/* --- Structure definitions. ---*/
+struct tsi_ssl_handshaker_factory {
+ const tsi_ssl_handshaker_factory_vtable *vtable;
+ gpr_refcount refcount;
+};
+
struct tsi_ssl_client_handshaker_factory {
+ tsi_ssl_handshaker_factory base;
SSL_CTX *ssl_context;
unsigned char *alpn_protocol_list;
size_t alpn_protocol_list_length;
@@ -77,6 +83,7 @@ struct tsi_ssl_server_handshaker_factory {
/* Several contexts to support SNI.
The tsi_peer array contains the subject names of the server certificates
associated with the contexts at the same index. */
+ tsi_ssl_handshaker_factory base;
SSL_CTX **ssl_contexts;
tsi_peer *ssl_context_x509_subject_names;
size_t ssl_context_count;
@@ -90,6 +97,7 @@ typedef struct {
BIO *into_ssl;
BIO *from_ssl;
tsi_result result;
+ tsi_ssl_handshaker_factory *factory_ref;
} tsi_ssl_handshaker;
typedef struct {
@@ -846,6 +854,47 @@ static const tsi_frame_protector_vtable frame_protector_vtable = {
ssl_protector_destroy,
};
+/* --- tsi_server_handshaker_factory methods implementation. --- */
+
+static void tsi_ssl_handshaker_factory_destroy(
+ tsi_ssl_handshaker_factory *self) {
+ if (self == NULL) return;
+
+ if (self->vtable != NULL && self->vtable->destroy != NULL) {
+ self->vtable->destroy(self);
+ }
+ /* Note, we don't free(self) here because this object is always directly
+ * embedded in another object. If tsi_ssl_handshaker_factory_init allocates
+ * any memory, it should be free'd here. */
+}
+
+static tsi_ssl_handshaker_factory *tsi_ssl_handshaker_factory_ref(
+ tsi_ssl_handshaker_factory *self) {
+ if (self == NULL) return NULL;
+ gpr_refn(&self->refcount, 1);
+ return self;
+}
+
+static void tsi_ssl_handshaker_factory_unref(tsi_ssl_handshaker_factory *self) {
+ if (self == NULL) return;
+
+ if (gpr_unref(&self->refcount)) {
+ tsi_ssl_handshaker_factory_destroy(self);
+ }
+}
+
+static tsi_ssl_handshaker_factory_vtable handshaker_factory_vtable = {NULL};
+
+/* Initializes a tsi_ssl_handshaker_factory object. Caller is responsible for
+ * allocating memory for the factory. */
+static void tsi_ssl_handshaker_factory_init(
+ tsi_ssl_handshaker_factory *factory) {
+ GPR_ASSERT(factory != NULL);
+
+ factory->vtable = &handshaker_factory_vtable;
+ gpr_ref_init(&factory->refcount, 1);
+}
+
/* --- tsi_handshaker methods implementation. ---*/
static tsi_result ssl_handshaker_get_bytes_to_send_to_peer(tsi_handshaker *self,
@@ -1013,6 +1062,7 @@ static tsi_result ssl_handshaker_create_frame_protector(
static void ssl_handshaker_destroy(tsi_handshaker *self) {
tsi_ssl_handshaker *impl = (tsi_ssl_handshaker *)self;
SSL_free(impl->ssl); /* The BIO objects are owned by ssl */
+ tsi_ssl_handshaker_factory_unref(impl->factory_ref);
gpr_free(impl);
}
@@ -1030,6 +1080,7 @@ static const tsi_handshaker_vtable handshaker_vtable = {
static tsi_result create_tsi_ssl_handshaker(SSL_CTX *ctx, int is_client,
const char *server_name_indication,
+ tsi_ssl_handshaker_factory *factory,
tsi_handshaker **handshaker) {
SSL *ssl = SSL_new(ctx);
BIO *into_ssl = NULL;
@@ -1085,6 +1136,8 @@ static tsi_result create_tsi_ssl_handshaker(SSL_CTX *ctx, int is_client,
impl->from_ssl = from_ssl;
impl->result = TSI_HANDSHAKE_IN_PROGRESS;
impl->base.vtable = &handshaker_vtable;
+ impl->factory_ref = tsi_ssl_handshaker_factory_ref(factory);
+
*handshaker = &impl->base;
return TSI_OK;
}
@@ -1121,11 +1174,20 @@ tsi_result tsi_ssl_client_handshaker_factory_create_handshaker(
tsi_ssl_client_handshaker_factory *self, const char *server_name_indication,
tsi_handshaker **handshaker) {
return create_tsi_ssl_handshaker(self->ssl_context, 1, server_name_indication,
- handshaker);
+ &self->base, handshaker);
}
-void tsi_ssl_client_handshaker_factory_destroy(
+void tsi_ssl_client_handshaker_factory_unref(
tsi_ssl_client_handshaker_factory *self) {
+ if (self == NULL) return;
+ tsi_ssl_handshaker_factory_unref(&self->base);
+}
+
+static void tsi_ssl_client_handshaker_factory_destroy(
+ tsi_ssl_handshaker_factory *factory) {
+ if (factory == NULL) return;
+ tsi_ssl_client_handshaker_factory *self =
+ (tsi_ssl_client_handshaker_factory *)factory;
if (self->ssl_context != NULL) SSL_CTX_free(self->ssl_context);
if (self->alpn_protocol_list != NULL) gpr_free(self->alpn_protocol_list);
gpr_free(self);
@@ -1150,11 +1212,21 @@ tsi_result tsi_ssl_server_handshaker_factory_create_handshaker(
if (self->ssl_context_count == 0) return TSI_INVALID_ARGUMENT;
/* Create the handshaker with the first context. We will switch if needed
because of SNI in ssl_server_handshaker_factory_servername_callback. */
- return create_tsi_ssl_handshaker(self->ssl_contexts[0], 0, NULL, handshaker);
+ return create_tsi_ssl_handshaker(self->ssl_contexts[0], 0, NULL, &self->base,
+ handshaker);
}
-void tsi_ssl_server_handshaker_factory_destroy(
+void tsi_ssl_server_handshaker_factory_unref(
tsi_ssl_server_handshaker_factory *self) {
+ if (self == NULL) return;
+ tsi_ssl_handshaker_factory_unref(&self->base);
+}
+
+static void tsi_ssl_server_handshaker_factory_destroy(
+ tsi_ssl_handshaker_factory *factory) {
+ if (factory == NULL) return;
+ tsi_ssl_server_handshaker_factory *self =
+ (tsi_ssl_server_handshaker_factory *)factory;
size_t i;
for (i = 0; i < self->ssl_context_count; i++) {
if (self->ssl_contexts[i] != NULL) {
@@ -1263,6 +1335,9 @@ static int server_handshaker_factory_npn_advertised_callback(
/* --- tsi_ssl_handshaker_factory constructors. --- */
+static tsi_ssl_handshaker_factory_vtable client_handshaker_factory_vtable = {
+ tsi_ssl_client_handshaker_factory_destroy};
+
tsi_result tsi_create_ssl_client_handshaker_factory(
const tsi_ssl_pem_key_cert_pair *pem_key_cert_pair,
const char *pem_root_certs, const char *cipher_suites,
@@ -1285,6 +1360,9 @@ tsi_result tsi_create_ssl_client_handshaker_factory(
}
impl = gpr_zalloc(sizeof(*impl));
+ tsi_ssl_handshaker_factory_init(&impl->base);
+ impl->base.vtable = &client_handshaker_factory_vtable;
+
impl->ssl_context = ssl_context;
do {
@@ -1322,7 +1400,7 @@ tsi_result tsi_create_ssl_client_handshaker_factory(
}
} while (0);
if (result != TSI_OK) {
- tsi_ssl_client_handshaker_factory_destroy(impl);
+ tsi_ssl_handshaker_factory_unref(&impl->base);
return result;
}
SSL_CTX_set_verify(ssl_context, SSL_VERIFY_PEER, NULL);
@@ -1332,6 +1410,9 @@ tsi_result tsi_create_ssl_client_handshaker_factory(
return TSI_OK;
}
+static tsi_ssl_handshaker_factory_vtable server_handshaker_factory_vtable = {
+ tsi_ssl_server_handshaker_factory_destroy};
+
tsi_result tsi_create_ssl_server_handshaker_factory(
const tsi_ssl_pem_key_cert_pair *pem_key_cert_pairs,
size_t num_key_cert_pairs, const char *pem_client_root_certs,
@@ -1364,12 +1445,15 @@ tsi_result tsi_create_ssl_server_handshaker_factory_ex(
}
impl = gpr_zalloc(sizeof(*impl));
+ tsi_ssl_handshaker_factory_init(&impl->base);
+ impl->base.vtable = &server_handshaker_factory_vtable;
+
impl->ssl_contexts = gpr_zalloc(num_key_cert_pairs * sizeof(SSL_CTX *));
impl->ssl_context_x509_subject_names =
gpr_zalloc(num_key_cert_pairs * sizeof(tsi_peer));
if (impl->ssl_contexts == NULL ||
impl->ssl_context_x509_subject_names == NULL) {
- tsi_ssl_server_handshaker_factory_destroy(impl);
+ tsi_ssl_handshaker_factory_unref(&impl->base);
return TSI_OUT_OF_RESOURCES;
}
impl->ssl_context_count = num_key_cert_pairs;
@@ -1379,7 +1463,7 @@ tsi_result tsi_create_ssl_server_handshaker_factory_ex(
&impl->alpn_protocol_list,
&impl->alpn_protocol_list_length);
if (result != TSI_OK) {
- tsi_ssl_server_handshaker_factory_destroy(impl);
+ tsi_ssl_handshaker_factory_unref(&impl->base);
return result;
}
}
@@ -1451,10 +1535,11 @@ tsi_result tsi_create_ssl_server_handshaker_factory_ex(
} while (0);
if (result != TSI_OK) {
- tsi_ssl_server_handshaker_factory_destroy(impl);
+ tsi_ssl_handshaker_factory_unref(&impl->base);
return result;
}
}
+
*factory = impl;
return TSI_OK;
}
@@ -1501,3 +1586,15 @@ int tsi_ssl_peer_matches_name(const tsi_peer *peer, const char *name) {
return 0; /* Not found. */
}
+
+/* --- Testing support. --- */
+const tsi_ssl_handshaker_factory_vtable *tsi_ssl_handshaker_factory_swap_vtable(
+ tsi_ssl_handshaker_factory *factory,
+ tsi_ssl_handshaker_factory_vtable *new_vtable) {
+ GPR_ASSERT(factory != NULL);
+ GPR_ASSERT(factory->vtable != NULL);
+
+ const tsi_ssl_handshaker_factory_vtable *orig_vtable = factory->vtable;
+ factory->vtable = new_vtable;
+ return orig_vtable;
+}
diff --git a/src/core/tsi/ssl_transport_security.h b/src/core/tsi/ssl_transport_security.h
index 177599930b..3abfdf5ed8 100644
--- a/src/core/tsi/ssl_transport_security.h
+++ b/src/core/tsi/ssl_transport_security.h
@@ -96,10 +96,10 @@ tsi_result tsi_ssl_client_handshaker_factory_create_handshaker(
tsi_ssl_client_handshaker_factory *self, const char *server_name_indication,
tsi_handshaker **handshaker);
-/* Destroys the handshaker factory. WARNING: it is unsafe to destroy a factory
- while handshakers created with this factory are still in use. */
-void tsi_ssl_client_handshaker_factory_destroy(
- tsi_ssl_client_handshaker_factory *self);
+/* Decrements reference count of the handshaker factory. Handshaker factory will
+ * be destroyed once no references exist. */
+void tsi_ssl_client_handshaker_factory_unref(
+ tsi_ssl_client_handshaker_factory *factory);
/* --- tsi_ssl_server_handshaker_factory object ---
@@ -158,9 +158,9 @@ tsi_result tsi_create_ssl_server_handshaker_factory_ex(
tsi_result tsi_ssl_server_handshaker_factory_create_handshaker(
tsi_ssl_server_handshaker_factory *self, tsi_handshaker **handshaker);
-/* Destroys the handshaker factory. WARNING: it is unsafe to destroy a factory
- while handshakers created with this factory are still in use. */
-void tsi_ssl_server_handshaker_factory_destroy(
+/* Decrements reference count of the handshaker factory. Handshaker factory will
+ * be destroyed once no references exist. */
+void tsi_ssl_server_handshaker_factory_unref(
tsi_ssl_server_handshaker_factory *self);
/* Util that checks that an ssl peer matches a specific name.
@@ -170,6 +170,29 @@ void tsi_ssl_server_handshaker_factory_destroy(
- handle public suffix wildchar more strictly (e.g. *.co.uk) */
int tsi_ssl_peer_matches_name(const tsi_peer *peer, const char *name);
+/* --- Testing support. ---
+
+ These functions and typedefs are not intended to be used outside of testing.
+ */
+
+/* Base type of client and server handshaker factories. */
+typedef struct tsi_ssl_handshaker_factory tsi_ssl_handshaker_factory;
+
+/* Function pointer to handshaker_factory destructor. */
+typedef void (*tsi_ssl_handshaker_factory_destructor)(
+ tsi_ssl_handshaker_factory *factory);
+
+/* Virtual table for tsi_ssl_handshaker_factory. */
+typedef struct {
+ tsi_ssl_handshaker_factory_destructor destroy;
+} tsi_ssl_handshaker_factory_vtable;
+
+/* Set destructor of handshaker_factory to new_destructor, returns previous
+ destructor. */
+const tsi_ssl_handshaker_factory_vtable *tsi_ssl_handshaker_factory_swap_vtable(
+ tsi_ssl_handshaker_factory *factory,
+ tsi_ssl_handshaker_factory_vtable *new_vtable);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/core/tsi/test_creds/BUILD b/src/core/tsi/test_creds/BUILD
index 4b0786d7b8..732f6d91b2 100644
--- a/src/core/tsi/test_creds/BUILD
+++ b/src/core/tsi/test_creds/BUILD
@@ -15,7 +15,15 @@
licenses(["notice"]) # Apache v2
exports_files([
- "ca.pem",
- "server1.key",
- "server1.pem",
+ "ca.pem",
+ "server1.key",
+ "server1.pem",
+ "server0.key",
+ "server0.pem",
+ "client.key",
+ "client.pem",
+ "badserver.key",
+ "badserver.pem",
+ "badclient.key",
+ "badclient.pem",
])
diff --git a/src/core/tsi/transport_security.h b/src/core/tsi/transport_security.h
index b0d7039850..3bba38149c 100644
--- a/src/core/tsi/transport_security.h
+++ b/src/core/tsi/transport_security.h
@@ -84,11 +84,17 @@ struct tsi_handshaker {
};
/* Base for tsi_handshaker_result implementations.
- See transport_security_interface.h for documentation. */
+ See transport_security_interface.h for documentation.
+ The exec_ctx parameter in create_zero_copy_grpc_protector is supposed to be
+ of type grpc_exec_ctx*, but we're using void* instead to avoid making the TSI
+ API depend on grpc. The create_zero_copy_grpc_protector() method is only used
+ in grpc, where we do need the exec_ctx passed through, but the API still
+ needs to compile in other applications, where grpc_exec_ctx is not defined.
+*/
typedef struct {
tsi_result (*extract_peer)(const tsi_handshaker_result *self, tsi_peer *peer);
tsi_result (*create_zero_copy_grpc_protector)(
- const tsi_handshaker_result *self,
+ void *exec_ctx, const tsi_handshaker_result *self,
size_t *max_output_protected_frame_size,
tsi_zero_copy_grpc_protector **protector);
tsi_result (*create_frame_protector)(const tsi_handshaker_result *self,
diff --git a/src/core/tsi/transport_security_grpc.c b/src/core/tsi/transport_security_grpc.c
index 5bcfdfa61f..affd995230 100644
--- a/src/core/tsi/transport_security_grpc.c
+++ b/src/core/tsi/transport_security_grpc.c
@@ -20,16 +20,18 @@
/* This method creates a tsi_zero_copy_grpc_protector object. */
tsi_result tsi_handshaker_result_create_zero_copy_grpc_protector(
- const tsi_handshaker_result *self, size_t *max_output_protected_frame_size,
+ grpc_exec_ctx *exec_ctx, const tsi_handshaker_result *self,
+ size_t *max_output_protected_frame_size,
tsi_zero_copy_grpc_protector **protector) {
- if (self == NULL || self->vtable == NULL || protector == NULL) {
+ if (exec_ctx == NULL || self == NULL || self->vtable == NULL ||
+ protector == NULL) {
return TSI_INVALID_ARGUMENT;
}
if (self->vtable->create_zero_copy_grpc_protector == NULL) {
return TSI_UNIMPLEMENTED;
}
return self->vtable->create_zero_copy_grpc_protector(
- self, max_output_protected_frame_size, protector);
+ exec_ctx, self, max_output_protected_frame_size, protector);
}
/* --- tsi_zero_copy_grpc_protector common implementation. ---
@@ -37,28 +39,33 @@ tsi_result tsi_handshaker_result_create_zero_copy_grpc_protector(
Calls specific implementation after state/input validation. */
tsi_result tsi_zero_copy_grpc_protector_protect(
- tsi_zero_copy_grpc_protector *self, grpc_slice_buffer *unprotected_slices,
+ grpc_exec_ctx *exec_ctx, tsi_zero_copy_grpc_protector *self,
+ grpc_slice_buffer *unprotected_slices,
grpc_slice_buffer *protected_slices) {
- if (self == NULL || self->vtable == NULL || unprotected_slices == NULL ||
- protected_slices == NULL) {
+ if (exec_ctx == NULL || self == NULL || self->vtable == NULL ||
+ unprotected_slices == NULL || protected_slices == NULL) {
return TSI_INVALID_ARGUMENT;
}
if (self->vtable->protect == NULL) return TSI_UNIMPLEMENTED;
- return self->vtable->protect(self, unprotected_slices, protected_slices);
+ return self->vtable->protect(exec_ctx, self, unprotected_slices,
+ protected_slices);
}
tsi_result tsi_zero_copy_grpc_protector_unprotect(
- tsi_zero_copy_grpc_protector *self, grpc_slice_buffer *protected_slices,
+ grpc_exec_ctx *exec_ctx, tsi_zero_copy_grpc_protector *self,
+ grpc_slice_buffer *protected_slices,
grpc_slice_buffer *unprotected_slices) {
- if (self == NULL || self->vtable == NULL || protected_slices == NULL ||
- unprotected_slices == NULL) {
+ if (exec_ctx == NULL || self == NULL || self->vtable == NULL ||
+ protected_slices == NULL || unprotected_slices == NULL) {
return TSI_INVALID_ARGUMENT;
}
if (self->vtable->unprotect == NULL) return TSI_UNIMPLEMENTED;
- return self->vtable->unprotect(self, protected_slices, unprotected_slices);
+ return self->vtable->unprotect(exec_ctx, self, protected_slices,
+ unprotected_slices);
}
-void tsi_zero_copy_grpc_protector_destroy(tsi_zero_copy_grpc_protector *self) {
+void tsi_zero_copy_grpc_protector_destroy(grpc_exec_ctx *exec_ctx,
+ tsi_zero_copy_grpc_protector *self) {
if (self == NULL) return;
- self->vtable->destroy(self);
+ self->vtable->destroy(exec_ctx, self);
}
diff --git a/src/core/tsi/transport_security_grpc.h b/src/core/tsi/transport_security_grpc.h
index 5ab5297cc4..ca6755c12f 100644
--- a/src/core/tsi/transport_security_grpc.h
+++ b/src/core/tsi/transport_security_grpc.h
@@ -30,7 +30,8 @@ extern "C" {
assuming there is no fatal error.
The caller is responsible for destroying the protector. */
tsi_result tsi_handshaker_result_create_zero_copy_grpc_protector(
- const tsi_handshaker_result *self, size_t *max_output_protected_frame_size,
+ grpc_exec_ctx *exec_ctx, const tsi_handshaker_result *self,
+ size_t *max_output_protected_frame_size,
tsi_zero_copy_grpc_protector **protector);
/* -- tsi_zero_copy_grpc_protector object -- */
@@ -42,8 +43,8 @@ tsi_result tsi_handshaker_result_create_zero_copy_grpc_protector(
- This method returns TSI_OK in case of success or a specific error code in
case of failure. */
tsi_result tsi_zero_copy_grpc_protector_protect(
- tsi_zero_copy_grpc_protector *self, grpc_slice_buffer *unprotected_slices,
- grpc_slice_buffer *protected_slices);
+ grpc_exec_ctx *exec_ctx, tsi_zero_copy_grpc_protector *self,
+ grpc_slice_buffer *unprotected_slices, grpc_slice_buffer *protected_slices);
/* Outputs unprotected bytes.
- protected_slices is the bytes of protected frames.
@@ -52,21 +53,24 @@ tsi_result tsi_zero_copy_grpc_protector_protect(
there is not enough data to output in which case unprotected_slices has 0
bytes. */
tsi_result tsi_zero_copy_grpc_protector_unprotect(
- tsi_zero_copy_grpc_protector *self, grpc_slice_buffer *protected_slices,
- grpc_slice_buffer *unprotected_slices);
+ grpc_exec_ctx *exec_ctx, tsi_zero_copy_grpc_protector *self,
+ grpc_slice_buffer *protected_slices, grpc_slice_buffer *unprotected_slices);
/* Destroys the tsi_zero_copy_grpc_protector object. */
-void tsi_zero_copy_grpc_protector_destroy(tsi_zero_copy_grpc_protector *self);
+void tsi_zero_copy_grpc_protector_destroy(grpc_exec_ctx *exec_ctx,
+ tsi_zero_copy_grpc_protector *self);
/* Base for tsi_zero_copy_grpc_protector implementations. */
typedef struct {
- tsi_result (*protect)(tsi_zero_copy_grpc_protector *self,
+ tsi_result (*protect)(grpc_exec_ctx *exec_ctx,
+ tsi_zero_copy_grpc_protector *self,
grpc_slice_buffer *unprotected_slices,
grpc_slice_buffer *protected_slices);
- tsi_result (*unprotect)(tsi_zero_copy_grpc_protector *self,
+ tsi_result (*unprotect)(grpc_exec_ctx *exec_ctx,
+ tsi_zero_copy_grpc_protector *self,
grpc_slice_buffer *protected_slices,
grpc_slice_buffer *unprotected_slices);
- void (*destroy)(tsi_zero_copy_grpc_protector *self);
+ void (*destroy)(grpc_exec_ctx *exec_ctx, tsi_zero_copy_grpc_protector *self);
} tsi_zero_copy_grpc_protector_vtable;
struct tsi_zero_copy_grpc_protector {