aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/core/tsi/transport_security.c36
-rw-r--r--src/core/tsi/transport_security_adapter.c62
-rw-r--r--src/core/tsi/transport_security_adapter.h11
-rw-r--r--src/core/tsi/transport_security_interface.h89
4 files changed, 93 insertions, 105 deletions
diff --git a/src/core/tsi/transport_security.c b/src/core/tsi/transport_security.c
index aa8808ab74..b11c00c43c 100644
--- a/src/core/tsi/transport_security.c
+++ b/src/core/tsi/transport_security.c
@@ -94,6 +94,9 @@ tsi_result tsi_frame_protector_protect(tsi_frame_protector *self,
protected_output_frames_size == NULL) {
return TSI_INVALID_ARGUMENT;
}
+ if (self->vtable == NULL || self->vtable->protect == NULL) {
+ return TSI_UNIMPLEMENTED;
+ }
return self->vtable->protect(self, unprotected_bytes, unprotected_bytes_size,
protected_output_frames,
protected_output_frames_size);
@@ -106,6 +109,9 @@ tsi_result tsi_frame_protector_protect_flush(
protected_output_frames_size == NULL || still_pending_size == NULL) {
return TSI_INVALID_ARGUMENT;
}
+ if (self->vtable == NULL || self->vtable->protect_flush == NULL) {
+ return TSI_UNIMPLEMENTED;
+ }
return self->vtable->protect_flush(self, protected_output_frames,
protected_output_frames_size,
still_pending_size);
@@ -120,6 +126,9 @@ tsi_result tsi_frame_protector_unprotect(
unprotected_bytes_size == NULL) {
return TSI_INVALID_ARGUMENT;
}
+ if (self->vtable == NULL || self->vtable->unprotect == NULL) {
+ return TSI_UNIMPLEMENTED;
+ }
return self->vtable->unprotect(self, protected_frames_bytes,
protected_frames_bytes_size, unprotected_bytes,
unprotected_bytes_size);
@@ -141,6 +150,9 @@ tsi_result tsi_handshaker_get_bytes_to_send_to_peer(tsi_handshaker *self,
return TSI_INVALID_ARGUMENT;
}
if (self->frame_protector_created) return TSI_FAILED_PRECONDITION;
+ if (self->vtable == NULL || self->vtable->get_bytes_to_send_to_peer == NULL) {
+ return TSI_UNIMPLEMENTED;
+ }
return self->vtable->get_bytes_to_send_to_peer(self, bytes, bytes_size);
}
@@ -151,12 +163,18 @@ tsi_result tsi_handshaker_process_bytes_from_peer(tsi_handshaker *self,
return TSI_INVALID_ARGUMENT;
}
if (self->frame_protector_created) return TSI_FAILED_PRECONDITION;
+ if (self->vtable == NULL || self->vtable->process_bytes_from_peer == NULL) {
+ return TSI_UNIMPLEMENTED;
+ }
return self->vtable->process_bytes_from_peer(self, bytes, bytes_size);
}
tsi_result tsi_handshaker_get_result(tsi_handshaker *self) {
if (self == NULL) return TSI_INVALID_ARGUMENT;
if (self->frame_protector_created) return TSI_FAILED_PRECONDITION;
+ if (self->vtable == NULL || self->vtable->get_result == NULL) {
+ return TSI_UNIMPLEMENTED;
+ }
return self->vtable->get_result(self);
}
@@ -167,6 +185,9 @@ tsi_result tsi_handshaker_extract_peer(tsi_handshaker *self, tsi_peer *peer) {
if (tsi_handshaker_get_result(self) != TSI_OK) {
return TSI_FAILED_PRECONDITION;
}
+ if (self->vtable == NULL || self->vtable->extract_peer == NULL) {
+ return TSI_UNIMPLEMENTED;
+ }
return self->vtable->extract_peer(self, peer);
}
@@ -179,6 +200,9 @@ tsi_result tsi_handshaker_create_frame_protector(
if (tsi_handshaker_get_result(self) != TSI_OK) {
return TSI_FAILED_PRECONDITION;
}
+ if (self->vtable == NULL || self->vtable->create_frame_protector == NULL) {
+ return TSI_UNIMPLEMENTED;
+ }
result = self->vtable->create_frame_protector(self, max_protected_frame_size,
protector);
if (result == TSI_OK) {
@@ -194,6 +218,9 @@ tsi_result tsi_handshaker_next(
tsi_handshaker_on_next_done_cb cb, void *user_data) {
if (self == NULL) return TSI_INVALID_ARGUMENT;
if (self->handshaker_result_created) return TSI_FAILED_PRECONDITION;
+ if (self->vtable == NULL || self->vtable->next == NULL) {
+ return TSI_UNIMPLEMENTED;
+ }
return self->vtable->next(self, received_bytes, received_bytes_size,
bytes_to_send, bytes_to_send_size,
handshaker_result, cb, user_data);
@@ -210,6 +237,9 @@ tsi_result tsi_handshaker_result_extract_peer(const tsi_handshaker_result *self,
tsi_peer *peer) {
if (self == NULL || peer == NULL) return TSI_INVALID_ARGUMENT;
memset(peer, 0, sizeof(tsi_peer));
+ if (self->vtable == NULL || self->vtable->extract_peer == NULL) {
+ return TSI_UNIMPLEMENTED;
+ }
return self->vtable->extract_peer(self, peer);
}
@@ -217,6 +247,9 @@ tsi_result tsi_handshaker_result_create_frame_protector(
const tsi_handshaker_result *self, size_t *max_protected_frame_size,
tsi_frame_protector **protector) {
if (self == NULL || protector == NULL) return TSI_INVALID_ARGUMENT;
+ if (self->vtable == NULL || self->vtable->create_frame_protector == NULL) {
+ return TSI_UNIMPLEMENTED;
+ }
return self->vtable->create_frame_protector(self, max_protected_frame_size,
protector);
}
@@ -227,6 +260,9 @@ tsi_result tsi_handshaker_result_get_unused_bytes(
if (self == NULL || bytes == NULL || bytes_size == NULL) {
return TSI_INVALID_ARGUMENT;
}
+ if (self->vtable == NULL || self->vtable->get_unused_bytes == NULL) {
+ return TSI_UNIMPLEMENTED;
+ }
return self->vtable->get_unused_bytes(self, bytes, bytes_size);
}
diff --git a/src/core/tsi/transport_security_adapter.c b/src/core/tsi/transport_security_adapter.c
index ebf0279139..d83339b3eb 100644
--- a/src/core/tsi/transport_security_adapter.c
+++ b/src/core/tsi/transport_security_adapter.c
@@ -45,26 +45,26 @@
typedef struct {
tsi_handshaker_result base;
- tsi_handshaker *handshaker;
+ tsi_handshaker *wrapped;
unsigned char *unused_bytes;
size_t unused_bytes_size;
} tsi_adapter_handshaker_result;
-static tsi_result tsi_adapter_result_extract_peer(
- const tsi_handshaker_result *self, tsi_peer *peer) {
+static tsi_result adapter_result_extract_peer(const tsi_handshaker_result *self,
+ tsi_peer *peer) {
tsi_adapter_handshaker_result *impl = (tsi_adapter_handshaker_result *)self;
- return tsi_handshaker_extract_peer(impl->handshaker, peer);
+ return tsi_handshaker_extract_peer(impl->wrapped, peer);
}
-static tsi_result tsi_adapter_result_create_frame_protector(
+static tsi_result adapter_result_create_frame_protector(
const tsi_handshaker_result *self, size_t *max_output_protected_frame_size,
tsi_frame_protector **protector) {
tsi_adapter_handshaker_result *impl = (tsi_adapter_handshaker_result *)self;
return tsi_handshaker_create_frame_protector(
- impl->handshaker, max_output_protected_frame_size, protector);
+ impl->wrapped, max_output_protected_frame_size, protector);
}
-static tsi_result tsi_adapter_result_get_unused_bytes(
+static tsi_result adapter_result_get_unused_bytes(
const tsi_handshaker_result *self, unsigned char **bytes,
size_t *byte_size) {
tsi_adapter_handshaker_result *impl = (tsi_adapter_handshaker_result *)self;
@@ -73,26 +73,26 @@ static tsi_result tsi_adapter_result_get_unused_bytes(
return TSI_OK;
}
-static void tsi_adapter_result_destroy(tsi_handshaker_result *self) {
+static void adapter_result_destroy(tsi_handshaker_result *self) {
tsi_adapter_handshaker_result *impl = (tsi_adapter_handshaker_result *)self;
gpr_free(impl->unused_bytes);
gpr_free(self);
}
static const tsi_handshaker_result_vtable result_vtable = {
- tsi_adapter_result_extract_peer, tsi_adapter_result_create_frame_protector,
- tsi_adapter_result_get_unused_bytes, tsi_adapter_result_destroy,
+ adapter_result_extract_peer, adapter_result_create_frame_protector,
+ adapter_result_get_unused_bytes, adapter_result_destroy,
};
tsi_result tsi_adapter_create_handshaker_result(
- tsi_handshaker *handshaker, const unsigned char *unused_bytes,
+ tsi_handshaker *wrapped, const unsigned char *unused_bytes,
size_t unused_bytes_size, tsi_handshaker_result **handshaker_result) {
- if (handshaker == NULL || (unused_bytes_size > 0 && unused_bytes == NULL)) {
+ if (wrapped == NULL || (unused_bytes_size > 0 && unused_bytes == NULL)) {
return TSI_INVALID_ARGUMENT;
}
tsi_adapter_handshaker_result *impl = gpr_zalloc(sizeof(*impl));
impl->base.vtable = &result_vtable;
- impl->handshaker = handshaker;
+ impl->wrapped = wrapped;
impl->unused_bytes_size = unused_bytes_size;
if (unused_bytes_size > 0) {
impl->unused_bytes = gpr_malloc(unused_bytes_size);
@@ -113,30 +113,30 @@ typedef struct {
size_t adapter_buffer_size;
} tsi_adapter_handshaker;
-static tsi_result tsi_adapter_get_bytes_to_send_to_peer(tsi_handshaker *self,
- unsigned char *bytes,
- size_t *bytes_size) {
+static tsi_result adapter_get_bytes_to_send_to_peer(tsi_handshaker *self,
+ unsigned char *bytes,
+ size_t *bytes_size) {
return tsi_handshaker_get_bytes_to_send_to_peer(
tsi_adapter_handshaker_get_wrapped(self), bytes, bytes_size);
}
-static tsi_result tsi_adapter_process_bytes_from_peer(
- tsi_handshaker *self, const unsigned char *bytes, size_t *bytes_size) {
+static tsi_result adapter_process_bytes_from_peer(tsi_handshaker *self,
+ const unsigned char *bytes,
+ size_t *bytes_size) {
return tsi_handshaker_process_bytes_from_peer(
tsi_adapter_handshaker_get_wrapped(self), bytes, bytes_size);
}
-static tsi_result tsi_adapter_get_result(tsi_handshaker *self) {
+static tsi_result adapter_get_result(tsi_handshaker *self) {
return tsi_handshaker_get_result(tsi_adapter_handshaker_get_wrapped(self));
}
-static tsi_result tsi_adapter_extract_peer(tsi_handshaker *self,
- tsi_peer *peer) {
+static tsi_result adapter_extract_peer(tsi_handshaker *self, tsi_peer *peer) {
return tsi_handshaker_extract_peer(tsi_adapter_handshaker_get_wrapped(self),
peer);
}
-static tsi_result tsi_adapter_create_frame_protector(
+static tsi_result adapter_create_frame_protector(
tsi_handshaker *self, size_t *max_protected_frame_size,
tsi_frame_protector **protector) {
return tsi_handshaker_create_frame_protector(
@@ -144,14 +144,14 @@ static tsi_result tsi_adapter_create_frame_protector(
protector);
}
-static void tsi_adapter_destroy(tsi_handshaker *self) {
+static void adapter_destroy(tsi_handshaker *self) {
tsi_adapter_handshaker *impl = (tsi_adapter_handshaker *)self;
tsi_handshaker_destroy(impl->wrapped);
gpr_free(impl->adapter_buffer);
gpr_free(self);
}
-static tsi_result tsi_adapter_next(
+static tsi_result adapter_next(
tsi_handshaker *self, const unsigned char *received_bytes,
size_t received_bytes_size, unsigned char **bytes_to_send,
size_t *bytes_to_send_size, tsi_handshaker_result **handshaker_result,
@@ -207,13 +207,13 @@ static tsi_result tsi_adapter_next(
}
static const tsi_handshaker_vtable handshaker_vtable = {
- tsi_adapter_get_bytes_to_send_to_peer,
- tsi_adapter_process_bytes_from_peer,
- tsi_adapter_get_result,
- tsi_adapter_extract_peer,
- tsi_adapter_create_frame_protector,
- tsi_adapter_destroy,
- tsi_adapter_next,
+ adapter_get_bytes_to_send_to_peer,
+ adapter_process_bytes_from_peer,
+ adapter_get_result,
+ adapter_extract_peer,
+ adapter_create_frame_protector,
+ adapter_destroy,
+ adapter_next,
};
tsi_handshaker *tsi_create_adapter_handshaker(tsi_handshaker *wrapped) {
diff --git a/src/core/tsi/transport_security_adapter.h b/src/core/tsi/transport_security_adapter.h
index de5aaefd5f..686618b53b 100644
--- a/src/core/tsi/transport_security_adapter.h
+++ b/src/core/tsi/transport_security_adapter.h
@@ -41,11 +41,18 @@ extern "C" {
#endif
/* Create a tsi handshaker that takes an implementation of old interface and
- converts into an implementation of new interface.
+ converts into an implementation of new interface. In the old interface,
+ there are get_bytes_to_send_to_peer, process_bytes_from_peer, get_result,
+ extract_peer, and create_frame_protector. In the new interface, only next
+ method is needed. See transport_security_interface.h for details. Note that
+ this tsi adapter handshaker is temporary. It will be removed once TSI has
+ been fully migrated to the new interface.
Ownership of input tsi_handshaker is transferred to this new adapter. */
tsi_handshaker *tsi_create_adapter_handshaker(tsi_handshaker *wrapped);
-/* Given a tsi adapter handshaker, return the original wrapped handshaker. */
+/* Given a tsi adapter handshaker, return the original wrapped handshaker. The
+ adapter still owns the wrapped handshaker which should not be destroyed by
+ the caller. */
tsi_handshaker *tsi_adapter_handshaker_get_wrapped(tsi_handshaker *adapter);
#ifdef __cplusplus
diff --git a/src/core/tsi/transport_security_interface.h b/src/core/tsi/transport_security_interface.h
index c9495f80b6..f2112b62b6 100644
--- a/src/core/tsi/transport_security_interface.h
+++ b/src/core/tsi/transport_security_interface.h
@@ -232,7 +232,8 @@ tsi_result tsi_handshaker_result_create_frame_protector(
/* This method returns the unused bytes from the handshake. It returns TSI_OK
assuming there is no fatal error.
- The caller should not free the bytes. */
+ Ownership of the bytes is retained by the handshaker result. As a
+ consequence, the caller must not free the bytes. */
tsi_result tsi_handshaker_result_get_unused_bytes(
const tsi_handshaker_result *self, unsigned char **bytes,
size_t *byte_size);
@@ -247,64 +248,6 @@ void tsi_handshaker_result_destroy(tsi_handshaker_result *self);
------------------------------------------------------------------------
- A typical usage of the synchronous TSI handshaker would be:
-
- ------------------------------------------------------------------------
- tsi_result status = TSI_OK;
- unsigned char buf[4096];
- const size_t buf_size = 4906;
- size_t bytes_received_size = 0;
- unsigned char *bytes_to_send = NULL;
- size_t bytes_to_send_size = 0;
- tsi_handshaker_result *result = NULL;
-
- while (1) {
- status = tsi_handshaker_next(
- handshaker, buf, bytes_received_size,
- &bytes_to_send, &bytes_to_send_size, &result, NULL, NULL);
- if (status == TSI_INCOMPLETE_DATA) {
- // Need more data from the peer.
- bytes_received_size = buf_size;
- read_bytes_from_peer(buf, &bytes_received_size);
- continue;
- }
- if (status != TSI_OK) return status;
- if (bytes_to_send_size > 0) {
- send_bytes_to_peer(bytes_to_send, bytes_to_send_size);
- }
- if (result != NULL) break;
- bytes_received_size = buf_size;
- read_bytes_from_peer(buf, &bytes_received_size);
- }
-
- // Check the Peer.
- tsi_peer peer;
- status = tsi_handshaker_result_extract_peer(result, &peer);
- if (status != TSI_OK) return status;
- status = check_peer(&peer);
- tsi_peer_destruct(&peer);
- if (status != TSI_OK) return status;
-
- // Create the protector.
- tsi_frame_protector* protector = NULL;
- status = tsi_handshaker_result_create_frame_protector(result, NULL,
- &protector);
- if (status != TSI_OK) return status;
-
- // Do not forget to unprotect outstanding data if any.
- unsigned char *unused_bytes = NULL;
- size_t unused_bytes_size = 0;
- status = tsi_handshaker_result_get_unused_bytes(result, &unused_bytes,
- &unused_bytes_size);
- if (status != TSI_OK) return status;
- if (unused_bytes_size > 0) {
- status = tsi_frame_protector_unprotect(protector, unused_bytes,
- unused_bytes_size, ..., ...);
- ....
- }
- ...
- ------------------------------------------------------------------------
-
A typical usage supporting both synchronous and asynchronous TSI handshaker
implementations would be:
@@ -324,8 +267,8 @@ void tsi_handshaker_result_destroy(tsi_handshaker_result *self);
...
}
- // This method is the callback function when there are data received from
- // the peer. This method will read bytes into the handshake buffer and call
+ // This method is the callback function when data is received from the
+ // peer. This method will read bytes into the handshake buffer and call
// do_handshake_next.
void on_handshake_data_received_from_peer(void *user_data) {
security_handshaker *h = (security_handshaker *)user_data;
@@ -396,7 +339,7 @@ void tsi_handshaker_result_destroy(tsi_handshaker_result *self);
------------------------------------------------------------------------ */
typedef struct tsi_handshaker tsi_handshaker;
-/* TO BE DEPRECATED SOON.
+/* TO BE DEPRECATED SOON. Use tsi_handshaker_next instead.
Gets bytes that need to be sent to the peer.
- bytes is the buffer that will be written with the data to be sent to the
peer.
@@ -412,7 +355,7 @@ tsi_result tsi_handshaker_get_bytes_to_send_to_peer(tsi_handshaker *self,
unsigned char *bytes,
size_t *bytes_size);
-/* TO BE DEPRECATED SOON.
+/* TO BE DEPRECATED SOON. Use tsi_handshaker_next instead.
Processes bytes received from the peer.
- bytes is the buffer containing the data.
- bytes_size is an input/output parameter specifying the size of the data as
@@ -439,14 +382,15 @@ tsi_result tsi_handshaker_get_result(tsi_handshaker *self);
#define tsi_handshaker_is_in_progress(h) \
(tsi_handshaker_get_result((h)) == TSI_HANDSHAKE_IN_PROGRESS)
-/* TO BE DEPRECATED SOON.
+/* TO BE DEPRECATED SOON. Use tsi_handshaker_result_extract_peer instead.
This method may return TSI_FAILED_PRECONDITION if
tsi_handshaker_is_in_progress returns 1, it returns TSI_OK otherwise
assuming the handshaker is not in a fatal error state.
The caller is responsible for destructing the peer. */
tsi_result tsi_handshaker_extract_peer(tsi_handshaker *self, tsi_peer *peer);
-/* TO BE DEPRECATED SOON.
+/* TO BE DEPRECATED SOON. Use tsi_handshaker_result_create_frame_protector
+ instead.
This method creates a tsi_frame_protector object after the handshake phase
is done. After this method has been called successfully, the only method
that can be called on this object is Destroy.
@@ -488,13 +432,14 @@ typedef void (*tsi_handshaker_on_next_done_cb)(
TSI handshaker implementation.
- user_data is the argument to callback function passed from the caller.
This method returns TSI_ASYNC if the TSI handshaker implementation is
- asynchronous. It returns TSI_OK if the handshake completes or if there are
- data to send to the peer, otherwise returns TSI_INCOMPLETE_DATA which
- indicates that this method needs to be called again with more data from the
- peer. In case of a fatal error in the handshake, another specific error code
- is returned.
- The caller is responsible for destroying the handshaker_result. However, the
- caller should not free bytes_to_send, as the buffer is owned by the
+ asynchronous, and in this case, the callback is guaranteed to run in another
+ thread owned by TSI. It returns TSI_OK if the handshake completes or if
+ there are data to send to the peer, otherwise returns TSI_INCOMPLETE_DATA
+ which indicates that this method needs to be called again with more data
+ from the peer. In case of a fatal error in the handshake, another specific
+ error code is returned.
+ The caller is responsible for destroying the handshaker_result. However,
+ the caller should not free bytes_to_send, as the buffer is owned by the
tsi_handshaker object. */
tsi_result tsi_handshaker_next(
tsi_handshaker *self, const unsigned char *received_bytes,