• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  * Copyright 2018 gRPC authors.
4  *
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
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  *
17  */
18 
19 #include <grpc/support/port_platform.h>
20 
21 #include "src/core/tsi/local_transport_security.h"
22 
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 
27 #include <grpc/support/alloc.h>
28 #include <grpc/support/log.h>
29 #include <grpc/support/string_util.h>
30 
31 #include "src/core/lib/iomgr/exec_ctx.h"
32 #include "src/core/tsi/transport_security_grpc.h"
33 
34 namespace {
35 
36 /* Main struct for local TSI zero-copy frame protector. */
37 typedef struct local_zero_copy_grpc_protector {
38   tsi_zero_copy_grpc_protector base;
39 } local_zero_copy_grpc_protector;
40 
41 /* Main struct for local TSI handshaker result. */
42 typedef struct local_tsi_handshaker_result {
43   tsi_handshaker_result base;
44   bool is_client;
45 } local_tsi_handshaker_result;
46 
47 /* Main struct for local TSI handshaker. */
48 typedef struct local_tsi_handshaker {
49   tsi_handshaker base;
50   bool is_client;
51 } local_tsi_handshaker;
52 
53 /* --- tsi_zero_copy_grpc_protector methods implementation. --- */
54 
local_zero_copy_grpc_protector_protect(tsi_zero_copy_grpc_protector * self,grpc_slice_buffer * unprotected_slices,grpc_slice_buffer * protected_slices)55 static tsi_result local_zero_copy_grpc_protector_protect(
56     tsi_zero_copy_grpc_protector* self, grpc_slice_buffer* unprotected_slices,
57     grpc_slice_buffer* protected_slices) {
58   if (self == nullptr || unprotected_slices == nullptr ||
59       protected_slices == nullptr) {
60     gpr_log(GPR_ERROR, "Invalid nullptr arguments to zero-copy grpc protect.");
61     return TSI_INVALID_ARGUMENT;
62   }
63   grpc_slice_buffer_move_into(unprotected_slices, protected_slices);
64   return TSI_OK;
65 }
66 
local_zero_copy_grpc_protector_unprotect(tsi_zero_copy_grpc_protector * self,grpc_slice_buffer * protected_slices,grpc_slice_buffer * unprotected_slices)67 static tsi_result local_zero_copy_grpc_protector_unprotect(
68     tsi_zero_copy_grpc_protector* self, grpc_slice_buffer* protected_slices,
69     grpc_slice_buffer* unprotected_slices) {
70   if (self == nullptr || unprotected_slices == nullptr ||
71       protected_slices == nullptr) {
72     gpr_log(GPR_ERROR,
73             "Invalid nullptr arguments to zero-copy grpc unprotect.");
74     return TSI_INVALID_ARGUMENT;
75   }
76   grpc_slice_buffer_move_into(protected_slices, unprotected_slices);
77   return TSI_OK;
78 }
79 
local_zero_copy_grpc_protector_destroy(tsi_zero_copy_grpc_protector * self)80 static void local_zero_copy_grpc_protector_destroy(
81     tsi_zero_copy_grpc_protector* self) {
82   gpr_free(self);
83 }
84 
85 static const tsi_zero_copy_grpc_protector_vtable
86     local_zero_copy_grpc_protector_vtable = {
87         local_zero_copy_grpc_protector_protect,
88         local_zero_copy_grpc_protector_unprotect,
89         local_zero_copy_grpc_protector_destroy,
90         nullptr /* local_zero_copy_grpc_protector_max_frame_size */};
91 
local_zero_copy_grpc_protector_create(tsi_zero_copy_grpc_protector ** protector)92 tsi_result local_zero_copy_grpc_protector_create(
93     tsi_zero_copy_grpc_protector** protector) {
94   if (grpc_core::ExecCtx::Get() == nullptr || protector == nullptr) {
95     gpr_log(
96         GPR_ERROR,
97         "Invalid nullptr arguments to local_zero_copy_grpc_protector create.");
98     return TSI_INVALID_ARGUMENT;
99   }
100   local_zero_copy_grpc_protector* impl =
101       static_cast<local_zero_copy_grpc_protector*>(gpr_zalloc(sizeof(*impl)));
102   impl->base.vtable = &local_zero_copy_grpc_protector_vtable;
103   *protector = &impl->base;
104   return TSI_OK;
105 }
106 
107 /* --- tsi_handshaker_result methods implementation. --- */
108 
handshaker_result_extract_peer(const tsi_handshaker_result *,tsi_peer *)109 static tsi_result handshaker_result_extract_peer(
110     const tsi_handshaker_result* /*self*/, tsi_peer* /*peer*/) {
111   return TSI_OK;
112 }
113 
handshaker_result_create_zero_copy_grpc_protector(const tsi_handshaker_result * self,size_t *,tsi_zero_copy_grpc_protector ** protector)114 static tsi_result handshaker_result_create_zero_copy_grpc_protector(
115     const tsi_handshaker_result* self,
116     size_t* /*max_output_protected_frame_size*/,
117     tsi_zero_copy_grpc_protector** protector) {
118   if (self == nullptr || protector == nullptr) {
119     gpr_log(GPR_ERROR,
120             "Invalid arguments to create_zero_copy_grpc_protector()");
121     return TSI_INVALID_ARGUMENT;
122   }
123   tsi_result ok = local_zero_copy_grpc_protector_create(protector);
124   if (ok != TSI_OK) {
125     gpr_log(GPR_ERROR, "Failed to create zero-copy grpc protector");
126   }
127   return ok;
128 }
129 
handshaker_result_destroy(tsi_handshaker_result * self)130 static void handshaker_result_destroy(tsi_handshaker_result* self) {
131   if (self == nullptr) {
132     return;
133   }
134   local_tsi_handshaker_result* result =
135       reinterpret_cast<local_tsi_handshaker_result*>(
136           const_cast<tsi_handshaker_result*>(self));
137   gpr_free(result);
138 }
139 
140 static const tsi_handshaker_result_vtable result_vtable = {
141     handshaker_result_extract_peer,
142     handshaker_result_create_zero_copy_grpc_protector,
143     nullptr, /* handshaker_result_create_frame_protector */
144     nullptr, /* handshaker_result_get_unused_bytes */
145     handshaker_result_destroy};
146 
create_handshaker_result(bool is_client,tsi_handshaker_result ** self)147 static tsi_result create_handshaker_result(bool is_client,
148                                            tsi_handshaker_result** self) {
149   if (self == nullptr) {
150     gpr_log(GPR_ERROR, "Invalid arguments to create_handshaker_result()");
151     return TSI_INVALID_ARGUMENT;
152   }
153   local_tsi_handshaker_result* result =
154       static_cast<local_tsi_handshaker_result*>(gpr_zalloc(sizeof(*result)));
155   result->is_client = is_client;
156   result->base.vtable = &result_vtable;
157   *self = &result->base;
158   return TSI_OK;
159 }
160 
161 /* --- tsi_handshaker methods implementation. --- */
162 
handshaker_next(tsi_handshaker * self,const unsigned char *,size_t,const unsigned char **,size_t * bytes_to_send_size,tsi_handshaker_result ** result,tsi_handshaker_on_next_done_cb,void *)163 static tsi_result handshaker_next(
164     tsi_handshaker* self, const unsigned char* /*received_bytes*/,
165     size_t /*received_bytes_size*/, const unsigned char** /*bytes_to_send*/,
166     size_t* bytes_to_send_size, tsi_handshaker_result** result,
167     tsi_handshaker_on_next_done_cb /*cb*/, void* /*user_data*/) {
168   if (self == nullptr) {
169     gpr_log(GPR_ERROR, "Invalid arguments to handshaker_next()");
170     return TSI_INVALID_ARGUMENT;
171   }
172   /* Note that there is no interaction between TSI peers, and all operations are
173    * local.
174    */
175   local_tsi_handshaker* handshaker =
176       reinterpret_cast<local_tsi_handshaker*>(self);
177   *bytes_to_send_size = 0;
178   create_handshaker_result(handshaker->is_client, result);
179   return TSI_OK;
180 }
181 
handshaker_destroy(tsi_handshaker * self)182 static void handshaker_destroy(tsi_handshaker* self) {
183   if (self == nullptr) {
184     return;
185   }
186   local_tsi_handshaker* handshaker =
187       reinterpret_cast<local_tsi_handshaker*>(self);
188   gpr_free(handshaker);
189 }
190 
191 static const tsi_handshaker_vtable handshaker_vtable = {
192     nullptr, /* get_bytes_to_send_to_peer -- deprecated */
193     nullptr, /* process_bytes_from_peer   -- deprecated */
194     nullptr, /* get_result                -- deprecated */
195     nullptr, /* extract_peer              -- deprecated */
196     nullptr, /* create_frame_protector    -- deprecated */
197     handshaker_destroy,
198     handshaker_next,
199     nullptr, /* shutdown */
200 };
201 
202 }  // namespace
203 
tsi_local_handshaker_create(bool is_client,tsi_handshaker ** self)204 tsi_result tsi_local_handshaker_create(bool is_client, tsi_handshaker** self) {
205   if (self == nullptr) {
206     gpr_log(GPR_ERROR, "Invalid arguments to local_tsi_handshaker_create()");
207     return TSI_INVALID_ARGUMENT;
208   }
209   local_tsi_handshaker* handshaker =
210       static_cast<local_tsi_handshaker*>(gpr_zalloc(sizeof(*handshaker)));
211   handshaker->is_client = is_client;
212   handshaker->base.vtable = &handshaker_vtable;
213   *self = &handshaker->base;
214   return TSI_OK;
215 }
216