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/alts/handshaker/alts_handshaker_client.h"
22
23 #include <grpc/byte_buffer.h>
24 #include <grpc/support/alloc.h>
25 #include <grpc/support/log.h>
26
27 #include "src/core/lib/slice/slice_internal.h"
28 #include "src/core/lib/surface/call.h"
29 #include "src/core/lib/surface/channel.h"
30 #include "src/core/tsi/alts/handshaker/alts_handshaker_service_api.h"
31 #include "src/core/tsi/alts/handshaker/alts_shared_resource.h"
32 #include "src/core/tsi/alts/handshaker/alts_tsi_handshaker_private.h"
33 #include "src/core/tsi/alts/handshaker/alts_tsi_utils.h"
34
35 #define TSI_ALTS_INITIAL_BUFFER_SIZE 256
36
37 const int kHandshakerClientOpNum = 4;
38
39 struct alts_handshaker_client {
40 const alts_handshaker_client_vtable* vtable;
41 };
42
43 typedef struct alts_grpc_handshaker_client {
44 alts_handshaker_client base;
45 alts_tsi_handshaker* handshaker;
46 grpc_call* call;
47 /* A pointer to a function handling the interaction with handshaker service.
48 * That is, it points to grpc_call_start_batch_and_execute when the handshaker
49 * client is used in a non-testing use case and points to a custom function
50 * that validates the data to be sent to handshaker service in a testing use
51 * case. */
52 alts_grpc_caller grpc_caller;
53 /* A callback function provided by gRPC to handle the response returned from
54 * handshaker service. It also serves to bring the control safely back to
55 * application when dedicated CQ and thread are used. */
56 grpc_iomgr_cb_func grpc_cb;
57 /* A gRPC closure to be scheduled when the response from handshaker service
58 * is received. It will be initialized with grpc_cb. */
59 grpc_closure on_handshaker_service_resp_recv;
60 /* Buffers containing information to be sent (or received) to (or from) the
61 * handshaker service. */
62 grpc_byte_buffer* send_buffer;
63 grpc_byte_buffer* recv_buffer;
64 grpc_status_code status;
65 /* Initial metadata to be received from handshaker service. */
66 grpc_metadata_array recv_initial_metadata;
67 /* A callback function provided by an application to be invoked when response
68 * is received from handshaker service. */
69 tsi_handshaker_on_next_done_cb cb;
70 void* user_data;
71 /* ALTS credential options passed in from the caller. */
72 grpc_alts_credentials_options* options;
73 /* target name information to be passed to handshaker service for server
74 * authorization check. */
75 grpc_slice target_name;
76 /* boolean flag indicating if the handshaker client is used at client
77 * (is_client = true) or server (is_client = false) side. */
78 bool is_client;
79 /* a temporary store for data received from handshaker service used to extract
80 * unused data. */
81 grpc_slice recv_bytes;
82 /* a buffer containing data to be sent to the grpc client or server's peer. */
83 unsigned char* buffer;
84 size_t buffer_size;
85 } alts_grpc_handshaker_client;
86
handshaker_client_send_buffer_destroy(alts_grpc_handshaker_client * client)87 static void handshaker_client_send_buffer_destroy(
88 alts_grpc_handshaker_client* client) {
89 GPR_ASSERT(client != nullptr);
90 grpc_byte_buffer_destroy(client->send_buffer);
91 client->send_buffer = nullptr;
92 }
93
is_handshake_finished_properly(grpc_gcp_handshaker_resp * resp)94 static bool is_handshake_finished_properly(grpc_gcp_handshaker_resp* resp) {
95 GPR_ASSERT(resp != nullptr);
96 if (resp->has_result) {
97 return true;
98 }
99 return false;
100 }
101
alts_handshaker_client_handle_response(alts_handshaker_client * c,bool is_ok)102 void alts_handshaker_client_handle_response(alts_handshaker_client* c,
103 bool is_ok) {
104 GPR_ASSERT(c != nullptr);
105 alts_grpc_handshaker_client* client =
106 reinterpret_cast<alts_grpc_handshaker_client*>(c);
107 grpc_byte_buffer* recv_buffer = client->recv_buffer;
108 grpc_status_code status = client->status;
109 tsi_handshaker_on_next_done_cb cb = client->cb;
110 void* user_data = client->user_data;
111 alts_tsi_handshaker* handshaker = client->handshaker;
112
113 /* Invalid input check. */
114 if (cb == nullptr) {
115 gpr_log(GPR_ERROR,
116 "cb is nullptr in alts_tsi_handshaker_handle_response()");
117 return;
118 }
119 if (handshaker == nullptr) {
120 gpr_log(GPR_ERROR,
121 "handshaker is nullptr in alts_tsi_handshaker_handle_response()");
122 cb(TSI_INTERNAL_ERROR, user_data, nullptr, 0, nullptr);
123 return;
124 }
125 /* TSI handshake has been shutdown. */
126 if (alts_tsi_handshaker_has_shutdown(handshaker)) {
127 gpr_log(GPR_ERROR, "TSI handshake shutdown");
128 cb(TSI_HANDSHAKE_SHUTDOWN, user_data, nullptr, 0, nullptr);
129 return;
130 }
131 /* Failed grpc call check. */
132 if (!is_ok || status != GRPC_STATUS_OK) {
133 gpr_log(GPR_ERROR, "grpc call made to handshaker service failed");
134 cb(TSI_INTERNAL_ERROR, user_data, nullptr, 0, nullptr);
135 return;
136 }
137 if (recv_buffer == nullptr) {
138 gpr_log(GPR_ERROR,
139 "recv_buffer is nullptr in alts_tsi_handshaker_handle_response()");
140 cb(TSI_INTERNAL_ERROR, user_data, nullptr, 0, nullptr);
141 return;
142 }
143 grpc_gcp_handshaker_resp* resp =
144 alts_tsi_utils_deserialize_response(recv_buffer);
145 grpc_byte_buffer_destroy(client->recv_buffer);
146 client->recv_buffer = nullptr;
147 /* Invalid handshaker response check. */
148 if (resp == nullptr) {
149 gpr_log(GPR_ERROR, "alts_tsi_utils_deserialize_response() failed");
150 cb(TSI_DATA_CORRUPTED, user_data, nullptr, 0, nullptr);
151 return;
152 }
153 grpc_slice* slice = static_cast<grpc_slice*>(resp->out_frames.arg);
154 unsigned char* bytes_to_send = nullptr;
155 size_t bytes_to_send_size = 0;
156 if (slice != nullptr) {
157 bytes_to_send_size = GRPC_SLICE_LENGTH(*slice);
158 while (bytes_to_send_size > client->buffer_size) {
159 client->buffer_size *= 2;
160 client->buffer = static_cast<unsigned char*>(
161 gpr_realloc(client->buffer, client->buffer_size));
162 }
163 memcpy(client->buffer, GRPC_SLICE_START_PTR(*slice), bytes_to_send_size);
164 bytes_to_send = client->buffer;
165 }
166 tsi_handshaker_result* result = nullptr;
167 if (is_handshake_finished_properly(resp)) {
168 alts_tsi_handshaker_result_create(resp, client->is_client, &result);
169 alts_tsi_handshaker_result_set_unused_bytes(result, &client->recv_bytes,
170 resp->bytes_consumed);
171 }
172 grpc_status_code code = static_cast<grpc_status_code>(resp->status.code);
173 if (code != GRPC_STATUS_OK) {
174 grpc_slice* details = static_cast<grpc_slice*>(resp->status.details.arg);
175 if (details != nullptr) {
176 char* error_details = grpc_slice_to_c_string(*details);
177 gpr_log(GPR_ERROR, "Error from handshaker service:%s", error_details);
178 gpr_free(error_details);
179 }
180 }
181 grpc_gcp_handshaker_resp_destroy(resp);
182 cb(alts_tsi_utils_convert_to_tsi_result(code), user_data, bytes_to_send,
183 bytes_to_send_size, result);
184 }
185
186 /**
187 * Populate grpc operation data with the fields of ALTS handshaker client and
188 * make a grpc call.
189 */
make_grpc_call(alts_handshaker_client * c,bool is_start)190 static tsi_result make_grpc_call(alts_handshaker_client* c, bool is_start) {
191 GPR_ASSERT(c != nullptr);
192 alts_grpc_handshaker_client* client =
193 reinterpret_cast<alts_grpc_handshaker_client*>(c);
194 grpc_op ops[kHandshakerClientOpNum];
195 memset(ops, 0, sizeof(ops));
196 grpc_op* op = ops;
197 if (is_start) {
198 op->op = GRPC_OP_SEND_INITIAL_METADATA;
199 op->data.send_initial_metadata.count = 0;
200 op++;
201 GPR_ASSERT(op - ops <= kHandshakerClientOpNum);
202 op->op = GRPC_OP_RECV_INITIAL_METADATA;
203 op->data.recv_initial_metadata.recv_initial_metadata =
204 &client->recv_initial_metadata;
205 op++;
206 GPR_ASSERT(op - ops <= kHandshakerClientOpNum);
207 }
208 op->op = GRPC_OP_SEND_MESSAGE;
209 op->data.send_message.send_message = client->send_buffer;
210 op++;
211 GPR_ASSERT(op - ops <= kHandshakerClientOpNum);
212 op->op = GRPC_OP_RECV_MESSAGE;
213 op->data.recv_message.recv_message = &client->recv_buffer;
214 op++;
215 GPR_ASSERT(op - ops <= kHandshakerClientOpNum);
216 GPR_ASSERT(client->grpc_caller != nullptr);
217 if (client->grpc_caller(client->call, ops, static_cast<size_t>(op - ops),
218 &client->on_handshaker_service_resp_recv) !=
219 GRPC_CALL_OK) {
220 gpr_log(GPR_ERROR, "Start batch operation failed");
221 return TSI_INTERNAL_ERROR;
222 }
223 return TSI_OK;
224 }
225
226 /* Create and populate a client_start handshaker request, then serialize it. */
get_serialized_start_client(alts_handshaker_client * c)227 static grpc_byte_buffer* get_serialized_start_client(
228 alts_handshaker_client* c) {
229 GPR_ASSERT(c != nullptr);
230 alts_grpc_handshaker_client* client =
231 reinterpret_cast<alts_grpc_handshaker_client*>(c);
232 bool ok = true;
233 grpc_gcp_handshaker_req* req =
234 grpc_gcp_handshaker_req_create(CLIENT_START_REQ);
235 ok &= grpc_gcp_handshaker_req_set_handshake_protocol(
236 req, grpc_gcp_HandshakeProtocol_ALTS);
237 ok &= grpc_gcp_handshaker_req_add_application_protocol(
238 req, ALTS_APPLICATION_PROTOCOL);
239 ok &= grpc_gcp_handshaker_req_add_record_protocol(req, ALTS_RECORD_PROTOCOL);
240 grpc_gcp_rpc_protocol_versions* versions = &client->options->rpc_versions;
241 ok &= grpc_gcp_handshaker_req_set_rpc_versions(
242 req, versions->max_rpc_version.major, versions->max_rpc_version.minor,
243 versions->min_rpc_version.major, versions->min_rpc_version.minor);
244 char* target_name = grpc_slice_to_c_string(client->target_name);
245 ok &= grpc_gcp_handshaker_req_set_target_name(req, target_name);
246 target_service_account* ptr =
247 (reinterpret_cast<grpc_alts_credentials_client_options*>(client->options))
248 ->target_account_list_head;
249 while (ptr != nullptr) {
250 grpc_gcp_handshaker_req_add_target_identity_service_account(req, ptr->data);
251 ptr = ptr->next;
252 }
253 grpc_slice slice;
254 ok &= grpc_gcp_handshaker_req_encode(req, &slice);
255 grpc_byte_buffer* buffer = nullptr;
256 if (ok) {
257 buffer = grpc_raw_byte_buffer_create(&slice, 1 /* number of slices */);
258 }
259 grpc_slice_unref_internal(slice);
260 gpr_free(target_name);
261 grpc_gcp_handshaker_req_destroy(req);
262 return buffer;
263 }
264
handshaker_client_start_client(alts_handshaker_client * c)265 static tsi_result handshaker_client_start_client(alts_handshaker_client* c) {
266 if (c == nullptr) {
267 gpr_log(GPR_ERROR, "client is nullptr in handshaker_client_start_client()");
268 return TSI_INVALID_ARGUMENT;
269 }
270 grpc_byte_buffer* buffer = get_serialized_start_client(c);
271 alts_grpc_handshaker_client* client =
272 reinterpret_cast<alts_grpc_handshaker_client*>(c);
273 if (buffer == nullptr) {
274 gpr_log(GPR_ERROR, "get_serialized_start_client() failed");
275 return TSI_INTERNAL_ERROR;
276 }
277 handshaker_client_send_buffer_destroy(client);
278 client->send_buffer = buffer;
279 tsi_result result = make_grpc_call(&client->base, true /* is_start */);
280 if (result != TSI_OK) {
281 gpr_log(GPR_ERROR, "make_grpc_call() failed");
282 }
283 return result;
284 }
285
286 /* Create and populate a start_server handshaker request, then serialize it. */
get_serialized_start_server(alts_handshaker_client * c,grpc_slice * bytes_received)287 static grpc_byte_buffer* get_serialized_start_server(
288 alts_handshaker_client* c, grpc_slice* bytes_received) {
289 GPR_ASSERT(c != nullptr);
290 GPR_ASSERT(bytes_received != nullptr);
291 alts_grpc_handshaker_client* client =
292 reinterpret_cast<alts_grpc_handshaker_client*>(c);
293 grpc_gcp_handshaker_req* req =
294 grpc_gcp_handshaker_req_create(SERVER_START_REQ);
295 bool ok = grpc_gcp_handshaker_req_add_application_protocol(
296 req, ALTS_APPLICATION_PROTOCOL);
297 ok &= grpc_gcp_handshaker_req_param_add_record_protocol(
298 req, grpc_gcp_HandshakeProtocol_ALTS, ALTS_RECORD_PROTOCOL);
299 ok &= grpc_gcp_handshaker_req_set_in_bytes(
300 req, reinterpret_cast<const char*> GRPC_SLICE_START_PTR(*bytes_received),
301 GRPC_SLICE_LENGTH(*bytes_received));
302 grpc_gcp_rpc_protocol_versions* versions = &client->options->rpc_versions;
303 ok &= grpc_gcp_handshaker_req_set_rpc_versions(
304 req, versions->max_rpc_version.major, versions->max_rpc_version.minor,
305 versions->min_rpc_version.major, versions->min_rpc_version.minor);
306 grpc_slice req_slice;
307 ok &= grpc_gcp_handshaker_req_encode(req, &req_slice);
308 grpc_byte_buffer* buffer = nullptr;
309 if (ok) {
310 buffer = grpc_raw_byte_buffer_create(&req_slice, 1 /* number of slices */);
311 }
312 grpc_slice_unref_internal(req_slice);
313 grpc_gcp_handshaker_req_destroy(req);
314 return buffer;
315 }
316
handshaker_client_start_server(alts_handshaker_client * c,grpc_slice * bytes_received)317 static tsi_result handshaker_client_start_server(alts_handshaker_client* c,
318 grpc_slice* bytes_received) {
319 if (c == nullptr || bytes_received == nullptr) {
320 gpr_log(GPR_ERROR, "Invalid arguments to handshaker_client_start_server()");
321 return TSI_INVALID_ARGUMENT;
322 }
323 alts_grpc_handshaker_client* client =
324 reinterpret_cast<alts_grpc_handshaker_client*>(c);
325 grpc_byte_buffer* buffer = get_serialized_start_server(c, bytes_received);
326 if (buffer == nullptr) {
327 gpr_log(GPR_ERROR, "get_serialized_start_server() failed");
328 return TSI_INTERNAL_ERROR;
329 }
330 handshaker_client_send_buffer_destroy(client);
331 client->send_buffer = buffer;
332 tsi_result result = make_grpc_call(&client->base, true /* is_start */);
333 if (result != TSI_OK) {
334 gpr_log(GPR_ERROR, "make_grpc_call() failed");
335 }
336 return result;
337 }
338
339 /* Create and populate a next handshaker request, then serialize it. */
get_serialized_next(grpc_slice * bytes_received)340 static grpc_byte_buffer* get_serialized_next(grpc_slice* bytes_received) {
341 GPR_ASSERT(bytes_received != nullptr);
342 grpc_gcp_handshaker_req* req = grpc_gcp_handshaker_req_create(NEXT_REQ);
343 bool ok = grpc_gcp_handshaker_req_set_in_bytes(
344 req, reinterpret_cast<const char*> GRPC_SLICE_START_PTR(*bytes_received),
345 GRPC_SLICE_LENGTH(*bytes_received));
346 grpc_slice req_slice;
347 ok &= grpc_gcp_handshaker_req_encode(req, &req_slice);
348 grpc_byte_buffer* buffer = nullptr;
349 if (ok) {
350 buffer = grpc_raw_byte_buffer_create(&req_slice, 1 /* number of slices */);
351 }
352 grpc_slice_unref_internal(req_slice);
353 grpc_gcp_handshaker_req_destroy(req);
354 return buffer;
355 }
356
handshaker_client_next(alts_handshaker_client * c,grpc_slice * bytes_received)357 static tsi_result handshaker_client_next(alts_handshaker_client* c,
358 grpc_slice* bytes_received) {
359 if (c == nullptr || bytes_received == nullptr) {
360 gpr_log(GPR_ERROR, "Invalid arguments to handshaker_client_next()");
361 return TSI_INVALID_ARGUMENT;
362 }
363 alts_grpc_handshaker_client* client =
364 reinterpret_cast<alts_grpc_handshaker_client*>(c);
365 grpc_slice_unref_internal(client->recv_bytes);
366 client->recv_bytes = grpc_slice_ref_internal(*bytes_received);
367 grpc_byte_buffer* buffer = get_serialized_next(bytes_received);
368 if (buffer == nullptr) {
369 gpr_log(GPR_ERROR, "get_serialized_next() failed");
370 return TSI_INTERNAL_ERROR;
371 }
372 handshaker_client_send_buffer_destroy(client);
373 client->send_buffer = buffer;
374 tsi_result result = make_grpc_call(&client->base, false /* is_start */);
375 if (result != TSI_OK) {
376 gpr_log(GPR_ERROR, "make_grpc_call() failed");
377 }
378 return result;
379 }
380
handshaker_client_shutdown(alts_handshaker_client * c)381 static void handshaker_client_shutdown(alts_handshaker_client* c) {
382 GPR_ASSERT(c != nullptr);
383 alts_grpc_handshaker_client* client =
384 reinterpret_cast<alts_grpc_handshaker_client*>(c);
385 if (client->call != nullptr) {
386 grpc_call_cancel_internal(client->call);
387 }
388 }
389
handshaker_client_destruct(alts_handshaker_client * c)390 static void handshaker_client_destruct(alts_handshaker_client* c) {
391 if (c == nullptr) {
392 return;
393 }
394 alts_grpc_handshaker_client* client =
395 reinterpret_cast<alts_grpc_handshaker_client*>(c);
396 if (client->call != nullptr) {
397 grpc_call_unref(client->call);
398 }
399 }
400
401 static const alts_handshaker_client_vtable vtable = {
402 handshaker_client_start_client, handshaker_client_start_server,
403 handshaker_client_next, handshaker_client_shutdown,
404 handshaker_client_destruct};
405
alts_grpc_handshaker_client_create(alts_tsi_handshaker * handshaker,grpc_channel * channel,const char * handshaker_service_url,grpc_pollset_set * interested_parties,grpc_alts_credentials_options * options,const grpc_slice & target_name,grpc_iomgr_cb_func grpc_cb,tsi_handshaker_on_next_done_cb cb,void * user_data,alts_handshaker_client_vtable * vtable_for_testing,bool is_client)406 alts_handshaker_client* alts_grpc_handshaker_client_create(
407 alts_tsi_handshaker* handshaker, grpc_channel* channel,
408 const char* handshaker_service_url, grpc_pollset_set* interested_parties,
409 grpc_alts_credentials_options* options, const grpc_slice& target_name,
410 grpc_iomgr_cb_func grpc_cb, tsi_handshaker_on_next_done_cb cb,
411 void* user_data, alts_handshaker_client_vtable* vtable_for_testing,
412 bool is_client) {
413 if (channel == nullptr || handshaker_service_url == nullptr) {
414 gpr_log(GPR_ERROR, "Invalid arguments to alts_handshaker_client_create()");
415 return nullptr;
416 }
417 alts_grpc_handshaker_client* client =
418 static_cast<alts_grpc_handshaker_client*>(gpr_zalloc(sizeof(*client)));
419 client->grpc_caller = grpc_call_start_batch_and_execute;
420 client->handshaker = handshaker;
421 client->cb = cb;
422 client->user_data = user_data;
423 client->send_buffer = nullptr;
424 client->recv_buffer = nullptr;
425 client->options = grpc_alts_credentials_options_copy(options);
426 client->target_name = grpc_slice_copy(target_name);
427 client->recv_bytes = grpc_empty_slice();
428 grpc_metadata_array_init(&client->recv_initial_metadata);
429 client->grpc_cb = grpc_cb;
430 client->is_client = is_client;
431 client->buffer_size = TSI_ALTS_INITIAL_BUFFER_SIZE;
432 client->buffer = static_cast<unsigned char*>(gpr_zalloc(client->buffer_size));
433 grpc_slice slice = grpc_slice_from_copied_string(handshaker_service_url);
434 client->call =
435 strcmp(handshaker_service_url, ALTS_HANDSHAKER_SERVICE_URL_FOR_TESTING) ==
436 0
437 ? nullptr
438 : grpc_channel_create_pollset_set_call(
439 channel, nullptr, GRPC_PROPAGATE_DEFAULTS, interested_parties,
440 grpc_slice_from_static_string(ALTS_SERVICE_METHOD), &slice,
441 GRPC_MILLIS_INF_FUTURE, nullptr);
442 client->base.vtable =
443 vtable_for_testing == nullptr ? &vtable : vtable_for_testing;
444 GRPC_CLOSURE_INIT(&client->on_handshaker_service_resp_recv, client->grpc_cb,
445 client, grpc_schedule_on_exec_ctx);
446 grpc_slice_unref_internal(slice);
447 return &client->base;
448 }
449
450 namespace grpc_core {
451 namespace internal {
452
alts_handshaker_client_set_grpc_caller_for_testing(alts_handshaker_client * c,alts_grpc_caller caller)453 void alts_handshaker_client_set_grpc_caller_for_testing(
454 alts_handshaker_client* c, alts_grpc_caller caller) {
455 GPR_ASSERT(c != nullptr && caller != nullptr);
456 alts_grpc_handshaker_client* client =
457 reinterpret_cast<alts_grpc_handshaker_client*>(c);
458 client->grpc_caller = caller;
459 }
460
alts_handshaker_client_get_send_buffer_for_testing(alts_handshaker_client * c)461 grpc_byte_buffer* alts_handshaker_client_get_send_buffer_for_testing(
462 alts_handshaker_client* c) {
463 GPR_ASSERT(c != nullptr);
464 alts_grpc_handshaker_client* client =
465 reinterpret_cast<alts_grpc_handshaker_client*>(c);
466 return client->send_buffer;
467 }
468
alts_handshaker_client_get_recv_buffer_addr_for_testing(alts_handshaker_client * c)469 grpc_byte_buffer** alts_handshaker_client_get_recv_buffer_addr_for_testing(
470 alts_handshaker_client* c) {
471 GPR_ASSERT(c != nullptr);
472 alts_grpc_handshaker_client* client =
473 reinterpret_cast<alts_grpc_handshaker_client*>(c);
474 return &client->recv_buffer;
475 }
476
alts_handshaker_client_get_initial_metadata_for_testing(alts_handshaker_client * c)477 grpc_metadata_array* alts_handshaker_client_get_initial_metadata_for_testing(
478 alts_handshaker_client* c) {
479 GPR_ASSERT(c != nullptr);
480 alts_grpc_handshaker_client* client =
481 reinterpret_cast<alts_grpc_handshaker_client*>(c);
482 return &client->recv_initial_metadata;
483 }
484
alts_handshaker_client_set_recv_bytes_for_testing(alts_handshaker_client * c,grpc_slice * recv_bytes)485 void alts_handshaker_client_set_recv_bytes_for_testing(
486 alts_handshaker_client* c, grpc_slice* recv_bytes) {
487 GPR_ASSERT(c != nullptr);
488 alts_grpc_handshaker_client* client =
489 reinterpret_cast<alts_grpc_handshaker_client*>(c);
490 client->recv_bytes = grpc_slice_ref_internal(*recv_bytes);
491 }
492
alts_handshaker_client_set_fields_for_testing(alts_handshaker_client * c,alts_tsi_handshaker * handshaker,tsi_handshaker_on_next_done_cb cb,void * user_data,grpc_byte_buffer * recv_buffer,grpc_status_code status)493 void alts_handshaker_client_set_fields_for_testing(
494 alts_handshaker_client* c, alts_tsi_handshaker* handshaker,
495 tsi_handshaker_on_next_done_cb cb, void* user_data,
496 grpc_byte_buffer* recv_buffer, grpc_status_code status) {
497 GPR_ASSERT(c != nullptr);
498 alts_grpc_handshaker_client* client =
499 reinterpret_cast<alts_grpc_handshaker_client*>(c);
500 client->handshaker = handshaker;
501 client->cb = cb;
502 client->user_data = user_data;
503 client->recv_buffer = recv_buffer;
504 client->status = status;
505 }
506
alts_handshaker_client_check_fields_for_testing(alts_handshaker_client * c,tsi_handshaker_on_next_done_cb cb,void * user_data,bool has_sent_start_message,grpc_slice * recv_bytes)507 void alts_handshaker_client_check_fields_for_testing(
508 alts_handshaker_client* c, tsi_handshaker_on_next_done_cb cb,
509 void* user_data, bool has_sent_start_message, grpc_slice* recv_bytes) {
510 GPR_ASSERT(c != nullptr);
511 alts_grpc_handshaker_client* client =
512 reinterpret_cast<alts_grpc_handshaker_client*>(c);
513 GPR_ASSERT(client->cb == cb);
514 GPR_ASSERT(client->user_data == user_data);
515 if (recv_bytes != nullptr) {
516 GPR_ASSERT(grpc_slice_cmp(client->recv_bytes, *recv_bytes) == 0);
517 }
518 GPR_ASSERT(alts_tsi_handshaker_get_has_sent_start_message_for_testing(
519 client->handshaker) == has_sent_start_message);
520 }
521
alts_handshaker_client_set_vtable_for_testing(alts_handshaker_client * c,alts_handshaker_client_vtable * vtable)522 void alts_handshaker_client_set_vtable_for_testing(
523 alts_handshaker_client* c, alts_handshaker_client_vtable* vtable) {
524 GPR_ASSERT(c != nullptr);
525 GPR_ASSERT(vtable != nullptr);
526 alts_grpc_handshaker_client* client =
527 reinterpret_cast<alts_grpc_handshaker_client*>(c);
528 client->base.vtable = vtable;
529 }
530
alts_handshaker_client_get_handshaker_for_testing(alts_handshaker_client * c)531 alts_tsi_handshaker* alts_handshaker_client_get_handshaker_for_testing(
532 alts_handshaker_client* c) {
533 GPR_ASSERT(c != nullptr);
534 alts_grpc_handshaker_client* client =
535 reinterpret_cast<alts_grpc_handshaker_client*>(c);
536 return client->handshaker;
537 }
538
alts_handshaker_client_set_cb_for_testing(alts_handshaker_client * c,tsi_handshaker_on_next_done_cb cb)539 void alts_handshaker_client_set_cb_for_testing(
540 alts_handshaker_client* c, tsi_handshaker_on_next_done_cb cb) {
541 GPR_ASSERT(c != nullptr);
542 alts_grpc_handshaker_client* client =
543 reinterpret_cast<alts_grpc_handshaker_client*>(c);
544 client->cb = cb;
545 }
546
alts_handshaker_client_get_closure_for_testing(alts_handshaker_client * c)547 grpc_closure* alts_handshaker_client_get_closure_for_testing(
548 alts_handshaker_client* c) {
549 GPR_ASSERT(c != nullptr);
550 alts_grpc_handshaker_client* client =
551 reinterpret_cast<alts_grpc_handshaker_client*>(c);
552 return &client->on_handshaker_service_resp_recv;
553 }
554
555 } // namespace internal
556 } // namespace grpc_core
557
alts_handshaker_client_start_client(alts_handshaker_client * client)558 tsi_result alts_handshaker_client_start_client(alts_handshaker_client* client) {
559 if (client != nullptr && client->vtable != nullptr &&
560 client->vtable->client_start != nullptr) {
561 return client->vtable->client_start(client);
562 }
563 gpr_log(GPR_ERROR,
564 "client or client->vtable has not been initialized properly");
565 return TSI_INVALID_ARGUMENT;
566 }
567
alts_handshaker_client_start_server(alts_handshaker_client * client,grpc_slice * bytes_received)568 tsi_result alts_handshaker_client_start_server(alts_handshaker_client* client,
569 grpc_slice* bytes_received) {
570 if (client != nullptr && client->vtable != nullptr &&
571 client->vtable->server_start != nullptr) {
572 return client->vtable->server_start(client, bytes_received);
573 }
574 gpr_log(GPR_ERROR,
575 "client or client->vtable has not been initialized properly");
576 return TSI_INVALID_ARGUMENT;
577 }
578
alts_handshaker_client_next(alts_handshaker_client * client,grpc_slice * bytes_received)579 tsi_result alts_handshaker_client_next(alts_handshaker_client* client,
580 grpc_slice* bytes_received) {
581 if (client != nullptr && client->vtable != nullptr &&
582 client->vtable->next != nullptr) {
583 return client->vtable->next(client, bytes_received);
584 }
585 gpr_log(GPR_ERROR,
586 "client or client->vtable has not been initialized properly");
587 return TSI_INVALID_ARGUMENT;
588 }
589
alts_handshaker_client_shutdown(alts_handshaker_client * client)590 void alts_handshaker_client_shutdown(alts_handshaker_client* client) {
591 if (client != nullptr && client->vtable != nullptr &&
592 client->vtable->shutdown != nullptr) {
593 client->vtable->shutdown(client);
594 }
595 }
596
alts_handshaker_client_destroy(alts_handshaker_client * c)597 void alts_handshaker_client_destroy(alts_handshaker_client* c) {
598 if (c != nullptr) {
599 if (c->vtable != nullptr && c->vtable->destruct != nullptr) {
600 c->vtable->destruct(c);
601 }
602 alts_grpc_handshaker_client* client =
603 reinterpret_cast<alts_grpc_handshaker_client*>(c);
604 grpc_byte_buffer_destroy(client->send_buffer);
605 grpc_byte_buffer_destroy(client->recv_buffer);
606 client->send_buffer = nullptr;
607 client->recv_buffer = nullptr;
608 grpc_metadata_array_destroy(&client->recv_initial_metadata);
609 grpc_slice_unref_internal(client->recv_bytes);
610 grpc_slice_unref_internal(client->target_name);
611 grpc_alts_credentials_options_destroy(client->options);
612 gpr_free(client->buffer);
613 gpr_free(client);
614 }
615 }
616