3 * Copyright 2018 gRPC authors.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
19 #include <grpc/support/port_platform.h>
21 #include "src/core/tsi/local_transport_security.h"
27 #include <grpc/support/alloc.h>
28 #include <grpc/support/log.h>
29 #include <grpc/support/string_util.h>
31 #include "src/core/lib/iomgr/exec_ctx.h"
32 #include "src/core/tsi/transport_security_grpc.h"
34 /* Main struct for local TSI zero-copy frame protector. */
35 typedef struct local_zero_copy_grpc_protector {
36 tsi_zero_copy_grpc_protector base;
37 } local_zero_copy_grpc_protector;
39 /* Main struct for local TSI handshaker result. */
40 typedef struct local_tsi_handshaker_result {
41 tsi_handshaker_result base;
43 } local_tsi_handshaker_result;
45 /* Main struct for local TSI handshaker. */
46 typedef struct local_tsi_handshaker {
49 } local_tsi_handshaker;
51 /* --- tsi_zero_copy_grpc_protector methods implementation. --- */
53 static tsi_result local_zero_copy_grpc_protector_protect(
54 tsi_zero_copy_grpc_protector* self, grpc_slice_buffer* unprotected_slices,
55 grpc_slice_buffer* protected_slices) {
56 if (self == nullptr || unprotected_slices == nullptr ||
57 protected_slices == nullptr) {
58 gpr_log(GPR_ERROR, "Invalid nullptr arguments to zero-copy grpc protect.");
59 return TSI_INVALID_ARGUMENT;
61 grpc_slice_buffer_move_into(unprotected_slices, protected_slices);
65 static tsi_result local_zero_copy_grpc_protector_unprotect(
66 tsi_zero_copy_grpc_protector* self, grpc_slice_buffer* protected_slices,
67 grpc_slice_buffer* unprotected_slices) {
68 if (self == nullptr || unprotected_slices == nullptr ||
69 protected_slices == nullptr) {
71 "Invalid nullptr arguments to zero-copy grpc unprotect.");
72 return TSI_INVALID_ARGUMENT;
74 grpc_slice_buffer_move_into(protected_slices, unprotected_slices);
78 static void local_zero_copy_grpc_protector_destroy(
79 tsi_zero_copy_grpc_protector* self) {
83 static const tsi_zero_copy_grpc_protector_vtable
84 local_zero_copy_grpc_protector_vtable = {
85 local_zero_copy_grpc_protector_protect,
86 local_zero_copy_grpc_protector_unprotect,
87 local_zero_copy_grpc_protector_destroy,
88 nullptr /* local_zero_copy_grpc_protector_max_frame_size */};
90 tsi_result local_zero_copy_grpc_protector_create(
91 tsi_zero_copy_grpc_protector** protector) {
92 if (grpc_core::ExecCtx::Get() == nullptr || protector == nullptr) {
95 "Invalid nullptr arguments to local_zero_copy_grpc_protector create.");
96 return TSI_INVALID_ARGUMENT;
98 local_zero_copy_grpc_protector* impl =
99 static_cast<local_zero_copy_grpc_protector*>(gpr_zalloc(sizeof(*impl)));
100 impl->base.vtable = &local_zero_copy_grpc_protector_vtable;
101 *protector = &impl->base;
105 /* --- tsi_handshaker_result methods implementation. --- */
107 static tsi_result handshaker_result_extract_peer(
108 const tsi_handshaker_result* /*self*/, tsi_peer* /*peer*/) {
112 static tsi_result handshaker_result_create_zero_copy_grpc_protector(
113 const tsi_handshaker_result* self,
114 size_t* /*max_output_protected_frame_size*/,
115 tsi_zero_copy_grpc_protector** protector) {
116 if (self == nullptr || protector == nullptr) {
118 "Invalid arguments to create_zero_copy_grpc_protector()");
119 return TSI_INVALID_ARGUMENT;
121 tsi_result ok = local_zero_copy_grpc_protector_create(protector);
123 gpr_log(GPR_ERROR, "Failed to create zero-copy grpc protector");
128 static void handshaker_result_destroy(tsi_handshaker_result* self) {
129 if (self == nullptr) {
132 local_tsi_handshaker_result* result =
133 reinterpret_cast<local_tsi_handshaker_result*>(
134 const_cast<tsi_handshaker_result*>(self));
138 static const tsi_handshaker_result_vtable result_vtable = {
139 handshaker_result_extract_peer,
140 handshaker_result_create_zero_copy_grpc_protector,
141 nullptr, /* handshaker_result_create_frame_protector */
142 nullptr, /* handshaker_result_get_unused_bytes */
143 handshaker_result_destroy};
145 static tsi_result create_handshaker_result(bool is_client,
146 tsi_handshaker_result** self) {
147 if (self == nullptr) {
148 gpr_log(GPR_ERROR, "Invalid arguments to create_handshaker_result()");
149 return TSI_INVALID_ARGUMENT;
151 local_tsi_handshaker_result* result =
152 static_cast<local_tsi_handshaker_result*>(gpr_zalloc(sizeof(*result)));
153 result->is_client = is_client;
154 result->base.vtable = &result_vtable;
155 *self = &result->base;
159 /* --- tsi_handshaker methods implementation. --- */
161 static tsi_result handshaker_next(
162 tsi_handshaker* self, const unsigned char* /*received_bytes*/,
163 size_t /*received_bytes_size*/, const unsigned char** /*bytes_to_send*/,
164 size_t* bytes_to_send_size, tsi_handshaker_result** result,
165 tsi_handshaker_on_next_done_cb /*cb*/, void* /*user_data*/) {
166 if (self == nullptr) {
167 gpr_log(GPR_ERROR, "Invalid arguments to handshaker_next()");
168 return TSI_INVALID_ARGUMENT;
170 /* Note that there is no interaction between TSI peers, and all operations are
173 local_tsi_handshaker* handshaker =
174 reinterpret_cast<local_tsi_handshaker*>(self);
175 *bytes_to_send_size = 0;
176 create_handshaker_result(handshaker->is_client, result);
180 static void handshaker_destroy(tsi_handshaker* self) {
181 if (self == nullptr) {
184 local_tsi_handshaker* handshaker =
185 reinterpret_cast<local_tsi_handshaker*>(self);
186 gpr_free(handshaker);
189 static const tsi_handshaker_vtable handshaker_vtable = {
190 nullptr, /* get_bytes_to_send_to_peer -- deprecated */
191 nullptr, /* process_bytes_from_peer -- deprecated */
192 nullptr, /* get_result -- deprecated */
193 nullptr, /* extract_peer -- deprecated */
194 nullptr, /* create_frame_protector -- deprecated */
197 nullptr, /* shutdown */
200 tsi_result local_tsi_handshaker_create(bool is_client, tsi_handshaker** self) {
201 if (self == nullptr) {
202 gpr_log(GPR_ERROR, "Invalid arguments to local_tsi_handshaker_create()");
203 return TSI_INVALID_ARGUMENT;
205 local_tsi_handshaker* handshaker =
206 static_cast<local_tsi_handshaker*>(gpr_zalloc(sizeof(*handshaker)));
207 handshaker->is_client = is_client;
208 handshaker->base.vtable = &handshaker_vtable;
209 *self = &handshaker->base;