Revise based on Julien's comments.

reviewable/pr10522/r7
jiangtaoli2016 8 years ago
parent a2a2024944
commit c19550272e
  1. 36
      src/core/tsi/transport_security.c
  2. 62
      src/core/tsi/transport_security_adapter.c
  3. 11
      src/core/tsi/transport_security_adapter.h
  4. 89
      src/core/tsi/transport_security_interface.h

@ -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);
}

@ -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) {

@ -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

@ -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,

Loading…
Cancel
Save