mirror of https://github.com/grpc/grpc.git
Merge pull request #15313 from jiangtaoli2016/ssl_tsi_handshaker
Migrate SSL_transport_security TSI to new TSI handshaker APIpull/15328/head
commit
bfa2c8e543
21 changed files with 225 additions and 424 deletions
@ -1,242 +0,0 @@ |
|||||||
/*
|
|
||||||
* |
|
||||||
* Copyright 2017 gRPC authors. |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
* |
|
||||||
*/ |
|
||||||
|
|
||||||
#include <grpc/support/port_platform.h> |
|
||||||
|
|
||||||
#include "src/core/tsi/transport_security_adapter.h" |
|
||||||
|
|
||||||
#include <string.h> |
|
||||||
|
|
||||||
#include <grpc/support/alloc.h> |
|
||||||
#include <grpc/support/log.h> |
|
||||||
#include "src/core/tsi/transport_security.h" |
|
||||||
|
|
||||||
#define TSI_ADAPTER_INITIAL_BUFFER_SIZE 256 |
|
||||||
|
|
||||||
/* --- tsi_adapter_handshaker_result implementation ---*/ |
|
||||||
|
|
||||||
typedef struct { |
|
||||||
tsi_handshaker_result base; |
|
||||||
tsi_handshaker* wrapped; |
|
||||||
unsigned char* unused_bytes; |
|
||||||
size_t unused_bytes_size; |
|
||||||
} tsi_adapter_handshaker_result; |
|
||||||
|
|
||||||
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->wrapped, peer); |
|
||||||
} |
|
||||||
|
|
||||||
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->wrapped, max_output_protected_frame_size, protector); |
|
||||||
} |
|
||||||
|
|
||||||
static tsi_result adapter_result_get_unused_bytes( |
|
||||||
const tsi_handshaker_result* self, const unsigned char** bytes, |
|
||||||
size_t* byte_size) { |
|
||||||
tsi_adapter_handshaker_result* impl = (tsi_adapter_handshaker_result*)self; |
|
||||||
*bytes = impl->unused_bytes; |
|
||||||
*byte_size = impl->unused_bytes_size; |
|
||||||
return TSI_OK; |
|
||||||
} |
|
||||||
|
|
||||||
static void adapter_result_destroy(tsi_handshaker_result* self) { |
|
||||||
tsi_adapter_handshaker_result* impl = |
|
||||||
reinterpret_cast<tsi_adapter_handshaker_result*>(self); |
|
||||||
tsi_handshaker_destroy(impl->wrapped); |
|
||||||
gpr_free(impl->unused_bytes); |
|
||||||
gpr_free(self); |
|
||||||
} |
|
||||||
|
|
||||||
static const tsi_handshaker_result_vtable result_vtable = { |
|
||||||
adapter_result_extract_peer, |
|
||||||
nullptr, /* create_zero_copy_grpc_protector */ |
|
||||||
adapter_result_create_frame_protector, |
|
||||||
adapter_result_get_unused_bytes, |
|
||||||
adapter_result_destroy, |
|
||||||
}; |
|
||||||
|
|
||||||
/* Ownership of wrapped tsi_handshaker is transferred to the result object. */ |
|
||||||
static tsi_result tsi_adapter_create_handshaker_result( |
|
||||||
tsi_handshaker* wrapped, const unsigned char* unused_bytes, |
|
||||||
size_t unused_bytes_size, tsi_handshaker_result** handshaker_result) { |
|
||||||
if (wrapped == nullptr || |
|
||||||
(unused_bytes_size > 0 && unused_bytes == nullptr)) { |
|
||||||
return TSI_INVALID_ARGUMENT; |
|
||||||
} |
|
||||||
tsi_adapter_handshaker_result* impl = |
|
||||||
static_cast<tsi_adapter_handshaker_result*>(gpr_zalloc(sizeof(*impl))); |
|
||||||
impl->base.vtable = &result_vtable; |
|
||||||
impl->wrapped = wrapped; |
|
||||||
impl->unused_bytes_size = unused_bytes_size; |
|
||||||
if (unused_bytes_size > 0) { |
|
||||||
impl->unused_bytes = |
|
||||||
static_cast<unsigned char*>(gpr_malloc(unused_bytes_size)); |
|
||||||
memcpy(impl->unused_bytes, unused_bytes, unused_bytes_size); |
|
||||||
} else { |
|
||||||
impl->unused_bytes = nullptr; |
|
||||||
} |
|
||||||
*handshaker_result = &impl->base; |
|
||||||
return TSI_OK; |
|
||||||
} |
|
||||||
|
|
||||||
/* --- tsi_adapter_handshaker implementation ---*/ |
|
||||||
|
|
||||||
typedef struct { |
|
||||||
tsi_handshaker base; |
|
||||||
tsi_handshaker* wrapped; |
|
||||||
unsigned char* adapter_buffer; |
|
||||||
size_t adapter_buffer_size; |
|
||||||
} tsi_adapter_handshaker; |
|
||||||
|
|
||||||
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 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 adapter_get_result(tsi_handshaker* self) { |
|
||||||
return tsi_handshaker_get_result(tsi_adapter_handshaker_get_wrapped(self)); |
|
||||||
} |
|
||||||
|
|
||||||
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 adapter_create_frame_protector( |
|
||||||
tsi_handshaker* self, size_t* max_protected_frame_size, |
|
||||||
tsi_frame_protector** protector) { |
|
||||||
return tsi_handshaker_create_frame_protector( |
|
||||||
tsi_adapter_handshaker_get_wrapped(self), max_protected_frame_size, |
|
||||||
protector); |
|
||||||
} |
|
||||||
|
|
||||||
static void adapter_destroy(tsi_handshaker* self) { |
|
||||||
tsi_adapter_handshaker* impl = |
|
||||||
reinterpret_cast<tsi_adapter_handshaker*>(self); |
|
||||||
tsi_handshaker_destroy(impl->wrapped); |
|
||||||
gpr_free(impl->adapter_buffer); |
|
||||||
gpr_free(self); |
|
||||||
} |
|
||||||
|
|
||||||
static void adapter_shutdown(tsi_handshaker* self) { |
|
||||||
tsi_adapter_handshaker* impl = |
|
||||||
reinterpret_cast<tsi_adapter_handshaker*>(self); |
|
||||||
tsi_handshaker_shutdown(impl->wrapped); |
|
||||||
} |
|
||||||
|
|
||||||
static tsi_result adapter_next( |
|
||||||
tsi_handshaker* self, const unsigned char* received_bytes, |
|
||||||
size_t received_bytes_size, const unsigned char** bytes_to_send, |
|
||||||
size_t* bytes_to_send_size, tsi_handshaker_result** handshaker_result, |
|
||||||
tsi_handshaker_on_next_done_cb cb, void* user_data) { |
|
||||||
/* Input sanity check. */ |
|
||||||
if ((received_bytes_size > 0 && received_bytes == nullptr) || |
|
||||||
bytes_to_send == nullptr || bytes_to_send_size == nullptr || |
|
||||||
handshaker_result == nullptr) { |
|
||||||
return TSI_INVALID_ARGUMENT; |
|
||||||
} |
|
||||||
|
|
||||||
/* If there are received bytes, process them first. */ |
|
||||||
tsi_adapter_handshaker* impl = |
|
||||||
reinterpret_cast<tsi_adapter_handshaker*>(self); |
|
||||||
tsi_result status = TSI_OK; |
|
||||||
size_t bytes_consumed = received_bytes_size; |
|
||||||
if (received_bytes_size > 0) { |
|
||||||
status = tsi_handshaker_process_bytes_from_peer( |
|
||||||
impl->wrapped, received_bytes, &bytes_consumed); |
|
||||||
if (status != TSI_OK) return status; |
|
||||||
} |
|
||||||
|
|
||||||
/* Get bytes to send to the peer, if available. */ |
|
||||||
size_t offset = 0; |
|
||||||
do { |
|
||||||
size_t to_send_size = impl->adapter_buffer_size - offset; |
|
||||||
status = tsi_handshaker_get_bytes_to_send_to_peer( |
|
||||||
impl->wrapped, impl->adapter_buffer + offset, &to_send_size); |
|
||||||
offset += to_send_size; |
|
||||||
if (status == TSI_INCOMPLETE_DATA) { |
|
||||||
impl->adapter_buffer_size *= 2; |
|
||||||
impl->adapter_buffer = static_cast<unsigned char*>( |
|
||||||
gpr_realloc(impl->adapter_buffer, impl->adapter_buffer_size)); |
|
||||||
} |
|
||||||
} while (status == TSI_INCOMPLETE_DATA); |
|
||||||
if (status != TSI_OK) return status; |
|
||||||
*bytes_to_send = impl->adapter_buffer; |
|
||||||
*bytes_to_send_size = offset; |
|
||||||
|
|
||||||
/* If handshake completes, create tsi_handshaker_result. */ |
|
||||||
if (tsi_handshaker_is_in_progress(impl->wrapped)) { |
|
||||||
*handshaker_result = nullptr; |
|
||||||
} else { |
|
||||||
size_t unused_bytes_size = received_bytes_size - bytes_consumed; |
|
||||||
const unsigned char* unused_bytes = |
|
||||||
unused_bytes_size == 0 ? nullptr : received_bytes + bytes_consumed; |
|
||||||
status = tsi_adapter_create_handshaker_result( |
|
||||||
impl->wrapped, unused_bytes, unused_bytes_size, handshaker_result); |
|
||||||
if (status == TSI_OK) { |
|
||||||
impl->base.handshaker_result_created = true; |
|
||||||
impl->wrapped = nullptr; |
|
||||||
} |
|
||||||
} |
|
||||||
return status; |
|
||||||
} |
|
||||||
|
|
||||||
static const tsi_handshaker_vtable handshaker_vtable = { |
|
||||||
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, |
|
||||||
adapter_shutdown, |
|
||||||
}; |
|
||||||
|
|
||||||
tsi_handshaker* tsi_create_adapter_handshaker(tsi_handshaker* wrapped) { |
|
||||||
GPR_ASSERT(wrapped != nullptr); |
|
||||||
tsi_adapter_handshaker* impl = |
|
||||||
static_cast<tsi_adapter_handshaker*>(gpr_zalloc(sizeof(*impl))); |
|
||||||
impl->base.vtable = &handshaker_vtable; |
|
||||||
impl->wrapped = wrapped; |
|
||||||
impl->adapter_buffer_size = TSI_ADAPTER_INITIAL_BUFFER_SIZE; |
|
||||||
impl->adapter_buffer = |
|
||||||
static_cast<unsigned char*>(gpr_malloc(impl->adapter_buffer_size)); |
|
||||||
return &impl->base; |
|
||||||
} |
|
||||||
|
|
||||||
tsi_handshaker* tsi_adapter_handshaker_get_wrapped(tsi_handshaker* adapter) { |
|
||||||
if (adapter == nullptr) return nullptr; |
|
||||||
tsi_adapter_handshaker* impl = |
|
||||||
reinterpret_cast<tsi_adapter_handshaker*>(adapter); |
|
||||||
return impl->wrapped; |
|
||||||
} |
|
@ -1,41 +0,0 @@ |
|||||||
/*
|
|
||||||
* |
|
||||||
* Copyright 2017 gRPC authors. |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
* |
|
||||||
*/ |
|
||||||
|
|
||||||
#ifndef GRPC_CORE_TSI_TRANSPORT_SECURITY_ADAPTER_H |
|
||||||
#define GRPC_CORE_TSI_TRANSPORT_SECURITY_ADAPTER_H |
|
||||||
|
|
||||||
#include <grpc/support/port_platform.h> |
|
||||||
|
|
||||||
#include "src/core/tsi/transport_security_interface.h" |
|
||||||
|
|
||||||
/* Create a tsi handshaker that takes an implementation of old interface and
|
|
||||||
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. 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); |
|
||||||
|
|
||||||
#endif /* GRPC_CORE_TSI_TRANSPORT_SECURITY_ADAPTER_H */ |
|
Loading…
Reference in new issue