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/alts/handshaker/alts_handshaker_client.h"
23 #include <grpc/byte_buffer.h>
24 #include <grpc/support/alloc.h>
25 #include <grpc/support/log.h>
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_shared_resource.h"
31 #include "src/core/tsi/alts/handshaker/alts_tsi_handshaker_private.h"
32 #include "src/core/tsi/alts/handshaker/alts_tsi_utils.h"
34 #define TSI_ALTS_INITIAL_BUFFER_SIZE 256
36 const int kHandshakerClientOpNum = 4;
38 struct alts_handshaker_client {
39 const alts_handshaker_client_vtable* vtable;
42 typedef struct alts_grpc_handshaker_client {
43 alts_handshaker_client base;
44 alts_tsi_handshaker* handshaker;
46 /* A pointer to a function handling the interaction with handshaker service.
47 * That is, it points to grpc_call_start_batch_and_execute when the handshaker
48 * client is used in a non-testing use case and points to a custom function
49 * that validates the data to be sent to handshaker service in a testing use
51 alts_grpc_caller grpc_caller;
52 /* A callback function provided by gRPC to handle the response returned from
53 * handshaker service. It also serves to bring the control safely back to
54 * application when dedicated CQ and thread are used. */
55 grpc_iomgr_cb_func grpc_cb;
56 /* A gRPC closure to be scheduled when the response from handshaker service
57 * is received. It will be initialized with grpc_cb. */
58 grpc_closure on_handshaker_service_resp_recv;
59 /* Buffers containing information to be sent (or received) to (or from) the
60 * handshaker service. */
61 grpc_byte_buffer* send_buffer;
62 grpc_byte_buffer* recv_buffer;
63 grpc_status_code status;
64 /* Initial metadata to be received from handshaker service. */
65 grpc_metadata_array recv_initial_metadata;
66 /* A callback function provided by an application to be invoked when response
67 * is received from handshaker service. */
68 tsi_handshaker_on_next_done_cb cb;
70 /* ALTS credential options passed in from the caller. */
71 grpc_alts_credentials_options* options;
72 /* target name information to be passed to handshaker service for server
73 * authorization check. */
74 grpc_slice target_name;
75 /* boolean flag indicating if the handshaker client is used at client
76 * (is_client = true) or server (is_client = false) side. */
78 /* a temporary store for data received from handshaker service used to extract
80 grpc_slice recv_bytes;
81 /* a buffer containing data to be sent to the grpc client or server's peer. */
82 unsigned char* buffer;
84 } alts_grpc_handshaker_client;
86 static void handshaker_client_send_buffer_destroy(
87 alts_grpc_handshaker_client* client) {
88 GPR_ASSERT(client != nullptr);
89 grpc_byte_buffer_destroy(client->send_buffer);
90 client->send_buffer = nullptr;
93 static bool is_handshake_finished_properly(grpc_gcp_HandshakerResp* resp) {
94 GPR_ASSERT(resp != nullptr);
95 if (grpc_gcp_HandshakerResp_result(resp)) {
101 void alts_handshaker_client_handle_response(alts_handshaker_client* c,
103 GPR_ASSERT(c != nullptr);
104 alts_grpc_handshaker_client* client =
105 reinterpret_cast<alts_grpc_handshaker_client*>(c);
106 grpc_byte_buffer* recv_buffer = client->recv_buffer;
107 grpc_status_code status = client->status;
108 tsi_handshaker_on_next_done_cb cb = client->cb;
109 void* user_data = client->user_data;
110 alts_tsi_handshaker* handshaker = client->handshaker;
112 /* Invalid input check. */
115 "cb is nullptr in alts_tsi_handshaker_handle_response()");
118 if (handshaker == nullptr) {
120 "handshaker is nullptr in alts_tsi_handshaker_handle_response()");
121 cb(TSI_INTERNAL_ERROR, user_data, nullptr, 0, nullptr);
124 /* TSI handshake has been shutdown. */
125 if (alts_tsi_handshaker_has_shutdown(handshaker)) {
126 gpr_log(GPR_ERROR, "TSI handshake shutdown");
127 cb(TSI_HANDSHAKE_SHUTDOWN, user_data, nullptr, 0, nullptr);
130 /* Failed grpc call check. */
131 if (!is_ok || status != GRPC_STATUS_OK) {
132 gpr_log(GPR_ERROR, "grpc call made to handshaker service failed");
133 cb(TSI_INTERNAL_ERROR, user_data, nullptr, 0, nullptr);
136 if (recv_buffer == nullptr) {
138 "recv_buffer is nullptr in alts_tsi_handshaker_handle_response()");
139 cb(TSI_INTERNAL_ERROR, user_data, nullptr, 0, nullptr);
143 grpc_gcp_HandshakerResp* resp =
144 alts_tsi_utils_deserialize_response(recv_buffer, arena.ptr());
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);
153 const grpc_gcp_HandshakerStatus* resp_status =
154 grpc_gcp_HandshakerResp_status(resp);
155 if (resp_status == nullptr) {
156 gpr_log(GPR_ERROR, "No status in HandshakerResp");
157 cb(TSI_DATA_CORRUPTED, user_data, nullptr, 0, nullptr);
160 upb_strview out_frames = grpc_gcp_HandshakerResp_out_frames(resp);
161 unsigned char* bytes_to_send = nullptr;
162 size_t bytes_to_send_size = 0;
163 if (out_frames.size > 0) {
164 bytes_to_send_size = out_frames.size;
165 while (bytes_to_send_size > client->buffer_size) {
166 client->buffer_size *= 2;
167 client->buffer = static_cast<unsigned char*>(
168 gpr_realloc(client->buffer, client->buffer_size));
170 memcpy(client->buffer, out_frames.data, bytes_to_send_size);
171 bytes_to_send = client->buffer;
173 tsi_handshaker_result* result = nullptr;
174 if (is_handshake_finished_properly(resp)) {
175 alts_tsi_handshaker_result_create(resp, client->is_client, &result);
176 alts_tsi_handshaker_result_set_unused_bytes(
177 result, &client->recv_bytes,
178 grpc_gcp_HandshakerResp_bytes_consumed(resp));
180 grpc_status_code code = static_cast<grpc_status_code>(
181 grpc_gcp_HandshakerStatus_code(resp_status));
182 if (code != GRPC_STATUS_OK) {
183 upb_strview details = grpc_gcp_HandshakerStatus_details(resp_status);
184 if (details.size > 0) {
185 char* error_details = (char*)gpr_zalloc(details.size + 1);
186 memcpy(error_details, details.data, details.size);
187 gpr_log(GPR_ERROR, "Error from handshaker service:%s", error_details);
188 gpr_free(error_details);
191 cb(alts_tsi_utils_convert_to_tsi_result(code), user_data, bytes_to_send,
192 bytes_to_send_size, result);
196 * Populate grpc operation data with the fields of ALTS handshaker client and
199 static tsi_result make_grpc_call(alts_handshaker_client* c, bool is_start) {
200 GPR_ASSERT(c != nullptr);
201 alts_grpc_handshaker_client* client =
202 reinterpret_cast<alts_grpc_handshaker_client*>(c);
203 grpc_op ops[kHandshakerClientOpNum];
204 memset(ops, 0, sizeof(ops));
207 op->op = GRPC_OP_SEND_INITIAL_METADATA;
208 op->data.send_initial_metadata.count = 0;
210 GPR_ASSERT(op - ops <= kHandshakerClientOpNum);
211 op->op = GRPC_OP_RECV_INITIAL_METADATA;
212 op->data.recv_initial_metadata.recv_initial_metadata =
213 &client->recv_initial_metadata;
215 GPR_ASSERT(op - ops <= kHandshakerClientOpNum);
217 op->op = GRPC_OP_SEND_MESSAGE;
218 op->data.send_message.send_message = client->send_buffer;
220 GPR_ASSERT(op - ops <= kHandshakerClientOpNum);
221 op->op = GRPC_OP_RECV_MESSAGE;
222 op->data.recv_message.recv_message = &client->recv_buffer;
224 GPR_ASSERT(op - ops <= kHandshakerClientOpNum);
225 GPR_ASSERT(client->grpc_caller != nullptr);
226 if (client->grpc_caller(client->call, ops, static_cast<size_t>(op - ops),
227 &client->on_handshaker_service_resp_recv) !=
229 gpr_log(GPR_ERROR, "Start batch operation failed");
230 return TSI_INTERNAL_ERROR;
235 /* Serializes a grpc_gcp_HandshakerReq message into a buffer and returns newly
236 * grpc_byte_buffer holding it. */
237 static grpc_byte_buffer* get_serialized_handshaker_req(
238 grpc_gcp_HandshakerReq* req, upb_arena* arena) {
240 char* buf = grpc_gcp_HandshakerReq_serialize(req, arena, &buf_length);
241 if (buf == nullptr) {
244 grpc_slice slice = grpc_slice_from_copied_buffer(buf, buf_length);
245 grpc_byte_buffer* byte_buffer = grpc_raw_byte_buffer_create(&slice, 1);
246 grpc_slice_unref_internal(slice);
250 /* Create and populate a client_start handshaker request, then serialize it. */
251 static grpc_byte_buffer* get_serialized_start_client(
252 alts_handshaker_client* c) {
253 GPR_ASSERT(c != nullptr);
254 alts_grpc_handshaker_client* client =
255 reinterpret_cast<alts_grpc_handshaker_client*>(c);
257 grpc_gcp_HandshakerReq* req = grpc_gcp_HandshakerReq_new(arena.ptr());
258 grpc_gcp_StartClientHandshakeReq* start_client =
259 grpc_gcp_HandshakerReq_mutable_client_start(req, arena.ptr());
260 grpc_gcp_StartClientHandshakeReq_set_handshake_security_protocol(
261 start_client, grpc_gcp_ALTS);
262 grpc_gcp_StartClientHandshakeReq_add_application_protocols(
263 start_client, upb_strview_makez(ALTS_APPLICATION_PROTOCOL), arena.ptr());
264 grpc_gcp_StartClientHandshakeReq_add_record_protocols(
265 start_client, upb_strview_makez(ALTS_RECORD_PROTOCOL), arena.ptr());
266 grpc_gcp_RpcProtocolVersions* client_version =
267 grpc_gcp_StartClientHandshakeReq_mutable_rpc_versions(start_client,
269 grpc_gcp_RpcProtocolVersions_assign_from_struct(
270 client_version, arena.ptr(), &client->options->rpc_versions);
271 grpc_gcp_StartClientHandshakeReq_set_target_name(
273 upb_strview_make(reinterpret_cast<const char*>(
274 GRPC_SLICE_START_PTR(client->target_name)),
275 GRPC_SLICE_LENGTH(client->target_name)));
276 target_service_account* ptr =
277 (reinterpret_cast<grpc_alts_credentials_client_options*>(client->options))
278 ->target_account_list_head;
279 while (ptr != nullptr) {
280 grpc_gcp_Identity* target_identity =
281 grpc_gcp_StartClientHandshakeReq_add_target_identities(start_client,
283 grpc_gcp_Identity_set_service_account(target_identity,
284 upb_strview_makez(ptr->data));
287 return get_serialized_handshaker_req(req, arena.ptr());
290 static tsi_result handshaker_client_start_client(alts_handshaker_client* c) {
292 gpr_log(GPR_ERROR, "client is nullptr in handshaker_client_start_client()");
293 return TSI_INVALID_ARGUMENT;
295 grpc_byte_buffer* buffer = get_serialized_start_client(c);
296 alts_grpc_handshaker_client* client =
297 reinterpret_cast<alts_grpc_handshaker_client*>(c);
298 if (buffer == nullptr) {
299 gpr_log(GPR_ERROR, "get_serialized_start_client() failed");
300 return TSI_INTERNAL_ERROR;
302 handshaker_client_send_buffer_destroy(client);
303 client->send_buffer = buffer;
304 tsi_result result = make_grpc_call(&client->base, true /* is_start */);
305 if (result != TSI_OK) {
306 gpr_log(GPR_ERROR, "make_grpc_call() failed");
311 /* Create and populate a start_server handshaker request, then serialize it. */
312 static grpc_byte_buffer* get_serialized_start_server(
313 alts_handshaker_client* c, grpc_slice* bytes_received) {
314 GPR_ASSERT(c != nullptr);
315 GPR_ASSERT(bytes_received != nullptr);
316 alts_grpc_handshaker_client* client =
317 reinterpret_cast<alts_grpc_handshaker_client*>(c);
320 grpc_gcp_HandshakerReq* req = grpc_gcp_HandshakerReq_new(arena.ptr());
322 grpc_gcp_StartServerHandshakeReq* start_server =
323 grpc_gcp_HandshakerReq_mutable_server_start(req, arena.ptr());
324 grpc_gcp_StartServerHandshakeReq_add_application_protocols(
325 start_server, upb_strview_makez(ALTS_APPLICATION_PROTOCOL), arena.ptr());
326 grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry* param =
327 grpc_gcp_StartServerHandshakeReq_add_handshake_parameters(start_server,
329 grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry_set_key(
330 param, grpc_gcp_ALTS);
331 grpc_gcp_ServerHandshakeParameters* value =
332 grpc_gcp_ServerHandshakeParameters_new(arena.ptr());
333 grpc_gcp_ServerHandshakeParameters_add_record_protocols(
334 value, upb_strview_makez(ALTS_RECORD_PROTOCOL), arena.ptr());
335 grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry_set_value(param,
337 grpc_gcp_StartServerHandshakeReq_set_in_bytes(
338 start_server, upb_strview_make(reinterpret_cast<const char*>(
339 GRPC_SLICE_START_PTR(*bytes_received)),
340 GRPC_SLICE_LENGTH(*bytes_received)));
341 grpc_gcp_RpcProtocolVersions* server_version =
342 grpc_gcp_StartServerHandshakeReq_mutable_rpc_versions(start_server,
344 grpc_gcp_RpcProtocolVersions_assign_from_struct(
345 server_version, arena.ptr(), &client->options->rpc_versions);
346 return get_serialized_handshaker_req(req, arena.ptr());
349 static tsi_result handshaker_client_start_server(alts_handshaker_client* c,
350 grpc_slice* bytes_received) {
351 if (c == nullptr || bytes_received == nullptr) {
352 gpr_log(GPR_ERROR, "Invalid arguments to handshaker_client_start_server()");
353 return TSI_INVALID_ARGUMENT;
355 alts_grpc_handshaker_client* client =
356 reinterpret_cast<alts_grpc_handshaker_client*>(c);
357 grpc_byte_buffer* buffer = get_serialized_start_server(c, bytes_received);
358 if (buffer == nullptr) {
359 gpr_log(GPR_ERROR, "get_serialized_start_server() failed");
360 return TSI_INTERNAL_ERROR;
362 handshaker_client_send_buffer_destroy(client);
363 client->send_buffer = buffer;
364 tsi_result result = make_grpc_call(&client->base, true /* is_start */);
365 if (result != TSI_OK) {
366 gpr_log(GPR_ERROR, "make_grpc_call() failed");
371 /* Create and populate a next handshaker request, then serialize it. */
372 static grpc_byte_buffer* get_serialized_next(grpc_slice* bytes_received) {
373 GPR_ASSERT(bytes_received != nullptr);
375 grpc_gcp_HandshakerReq* req = grpc_gcp_HandshakerReq_new(arena.ptr());
376 grpc_gcp_NextHandshakeMessageReq* next =
377 grpc_gcp_HandshakerReq_mutable_next(req, arena.ptr());
378 grpc_gcp_NextHandshakeMessageReq_set_in_bytes(
379 next, upb_strview_make(reinterpret_cast<const char*> GRPC_SLICE_START_PTR(
381 GRPC_SLICE_LENGTH(*bytes_received)));
382 return get_serialized_handshaker_req(req, arena.ptr());
385 static tsi_result handshaker_client_next(alts_handshaker_client* c,
386 grpc_slice* bytes_received) {
387 if (c == nullptr || bytes_received == nullptr) {
388 gpr_log(GPR_ERROR, "Invalid arguments to handshaker_client_next()");
389 return TSI_INVALID_ARGUMENT;
391 alts_grpc_handshaker_client* client =
392 reinterpret_cast<alts_grpc_handshaker_client*>(c);
393 grpc_slice_unref_internal(client->recv_bytes);
394 client->recv_bytes = grpc_slice_ref_internal(*bytes_received);
395 grpc_byte_buffer* buffer = get_serialized_next(bytes_received);
396 if (buffer == nullptr) {
397 gpr_log(GPR_ERROR, "get_serialized_next() failed");
398 return TSI_INTERNAL_ERROR;
400 handshaker_client_send_buffer_destroy(client);
401 client->send_buffer = buffer;
402 tsi_result result = make_grpc_call(&client->base, false /* is_start */);
403 if (result != TSI_OK) {
404 gpr_log(GPR_ERROR, "make_grpc_call() failed");
409 static void handshaker_client_shutdown(alts_handshaker_client* c) {
410 GPR_ASSERT(c != nullptr);
411 alts_grpc_handshaker_client* client =
412 reinterpret_cast<alts_grpc_handshaker_client*>(c);
413 if (client->call != nullptr) {
414 grpc_call_cancel_internal(client->call);
418 static void handshaker_client_destruct(alts_handshaker_client* c) {
422 alts_grpc_handshaker_client* client =
423 reinterpret_cast<alts_grpc_handshaker_client*>(c);
424 if (client->call != nullptr) {
425 grpc_call_unref(client->call);
429 static const alts_handshaker_client_vtable vtable = {
430 handshaker_client_start_client, handshaker_client_start_server,
431 handshaker_client_next, handshaker_client_shutdown,
432 handshaker_client_destruct};
434 alts_handshaker_client* alts_grpc_handshaker_client_create(
435 alts_tsi_handshaker* handshaker, grpc_channel* channel,
436 const char* handshaker_service_url, grpc_pollset_set* interested_parties,
437 grpc_alts_credentials_options* options, const grpc_slice& target_name,
438 grpc_iomgr_cb_func grpc_cb, tsi_handshaker_on_next_done_cb cb,
439 void* user_data, alts_handshaker_client_vtable* vtable_for_testing,
441 if (channel == nullptr || handshaker_service_url == nullptr) {
442 gpr_log(GPR_ERROR, "Invalid arguments to alts_handshaker_client_create()");
445 alts_grpc_handshaker_client* client =
446 static_cast<alts_grpc_handshaker_client*>(gpr_zalloc(sizeof(*client)));
447 client->grpc_caller = grpc_call_start_batch_and_execute;
448 client->handshaker = handshaker;
450 client->user_data = user_data;
451 client->send_buffer = nullptr;
452 client->recv_buffer = nullptr;
453 client->options = grpc_alts_credentials_options_copy(options);
454 client->target_name = grpc_slice_copy(target_name);
455 client->recv_bytes = grpc_empty_slice();
456 grpc_metadata_array_init(&client->recv_initial_metadata);
457 client->grpc_cb = grpc_cb;
458 client->is_client = is_client;
459 client->buffer_size = TSI_ALTS_INITIAL_BUFFER_SIZE;
460 client->buffer = static_cast<unsigned char*>(gpr_zalloc(client->buffer_size));
461 grpc_slice slice = grpc_slice_from_copied_string(handshaker_service_url);
463 strcmp(handshaker_service_url, ALTS_HANDSHAKER_SERVICE_URL_FOR_TESTING) ==
466 : grpc_channel_create_pollset_set_call(
467 channel, nullptr, GRPC_PROPAGATE_DEFAULTS, interested_parties,
468 grpc_slice_from_static_string(ALTS_SERVICE_METHOD), &slice,
469 GRPC_MILLIS_INF_FUTURE, nullptr);
470 client->base.vtable =
471 vtable_for_testing == nullptr ? &vtable : vtable_for_testing;
472 GRPC_CLOSURE_INIT(&client->on_handshaker_service_resp_recv, client->grpc_cb,
473 client, grpc_schedule_on_exec_ctx);
474 grpc_slice_unref_internal(slice);
475 return &client->base;
478 namespace grpc_core {
481 void alts_handshaker_client_set_grpc_caller_for_testing(
482 alts_handshaker_client* c, alts_grpc_caller caller) {
483 GPR_ASSERT(c != nullptr && caller != nullptr);
484 alts_grpc_handshaker_client* client =
485 reinterpret_cast<alts_grpc_handshaker_client*>(c);
486 client->grpc_caller = caller;
489 grpc_byte_buffer* alts_handshaker_client_get_send_buffer_for_testing(
490 alts_handshaker_client* c) {
491 GPR_ASSERT(c != nullptr);
492 alts_grpc_handshaker_client* client =
493 reinterpret_cast<alts_grpc_handshaker_client*>(c);
494 return client->send_buffer;
497 grpc_byte_buffer** alts_handshaker_client_get_recv_buffer_addr_for_testing(
498 alts_handshaker_client* c) {
499 GPR_ASSERT(c != nullptr);
500 alts_grpc_handshaker_client* client =
501 reinterpret_cast<alts_grpc_handshaker_client*>(c);
502 return &client->recv_buffer;
505 grpc_metadata_array* alts_handshaker_client_get_initial_metadata_for_testing(
506 alts_handshaker_client* c) {
507 GPR_ASSERT(c != nullptr);
508 alts_grpc_handshaker_client* client =
509 reinterpret_cast<alts_grpc_handshaker_client*>(c);
510 return &client->recv_initial_metadata;
513 void alts_handshaker_client_set_recv_bytes_for_testing(
514 alts_handshaker_client* c, grpc_slice* recv_bytes) {
515 GPR_ASSERT(c != nullptr);
516 alts_grpc_handshaker_client* client =
517 reinterpret_cast<alts_grpc_handshaker_client*>(c);
518 client->recv_bytes = grpc_slice_ref_internal(*recv_bytes);
521 void alts_handshaker_client_set_fields_for_testing(
522 alts_handshaker_client* c, alts_tsi_handshaker* handshaker,
523 tsi_handshaker_on_next_done_cb cb, void* user_data,
524 grpc_byte_buffer* recv_buffer, grpc_status_code status) {
525 GPR_ASSERT(c != nullptr);
526 alts_grpc_handshaker_client* client =
527 reinterpret_cast<alts_grpc_handshaker_client*>(c);
528 client->handshaker = handshaker;
530 client->user_data = user_data;
531 client->recv_buffer = recv_buffer;
532 client->status = status;
535 void alts_handshaker_client_check_fields_for_testing(
536 alts_handshaker_client* c, tsi_handshaker_on_next_done_cb cb,
537 void* user_data, bool has_sent_start_message, grpc_slice* recv_bytes) {
538 GPR_ASSERT(c != nullptr);
539 alts_grpc_handshaker_client* client =
540 reinterpret_cast<alts_grpc_handshaker_client*>(c);
541 GPR_ASSERT(client->cb == cb);
542 GPR_ASSERT(client->user_data == user_data);
543 if (recv_bytes != nullptr) {
544 GPR_ASSERT(grpc_slice_cmp(client->recv_bytes, *recv_bytes) == 0);
546 GPR_ASSERT(alts_tsi_handshaker_get_has_sent_start_message_for_testing(
547 client->handshaker) == has_sent_start_message);
550 void alts_handshaker_client_set_vtable_for_testing(
551 alts_handshaker_client* c, alts_handshaker_client_vtable* vtable) {
552 GPR_ASSERT(c != nullptr);
553 GPR_ASSERT(vtable != nullptr);
554 alts_grpc_handshaker_client* client =
555 reinterpret_cast<alts_grpc_handshaker_client*>(c);
556 client->base.vtable = vtable;
559 alts_tsi_handshaker* alts_handshaker_client_get_handshaker_for_testing(
560 alts_handshaker_client* c) {
561 GPR_ASSERT(c != nullptr);
562 alts_grpc_handshaker_client* client =
563 reinterpret_cast<alts_grpc_handshaker_client*>(c);
564 return client->handshaker;
567 void alts_handshaker_client_set_cb_for_testing(
568 alts_handshaker_client* c, tsi_handshaker_on_next_done_cb cb) {
569 GPR_ASSERT(c != nullptr);
570 alts_grpc_handshaker_client* client =
571 reinterpret_cast<alts_grpc_handshaker_client*>(c);
575 grpc_closure* alts_handshaker_client_get_closure_for_testing(
576 alts_handshaker_client* c) {
577 GPR_ASSERT(c != nullptr);
578 alts_grpc_handshaker_client* client =
579 reinterpret_cast<alts_grpc_handshaker_client*>(c);
580 return &client->on_handshaker_service_resp_recv;
583 } // namespace internal
584 } // namespace grpc_core
586 tsi_result alts_handshaker_client_start_client(alts_handshaker_client* client) {
587 if (client != nullptr && client->vtable != nullptr &&
588 client->vtable->client_start != nullptr) {
589 return client->vtable->client_start(client);
592 "client or client->vtable has not been initialized properly");
593 return TSI_INVALID_ARGUMENT;
596 tsi_result alts_handshaker_client_start_server(alts_handshaker_client* client,
597 grpc_slice* bytes_received) {
598 if (client != nullptr && client->vtable != nullptr &&
599 client->vtable->server_start != nullptr) {
600 return client->vtable->server_start(client, bytes_received);
603 "client or client->vtable has not been initialized properly");
604 return TSI_INVALID_ARGUMENT;
607 tsi_result alts_handshaker_client_next(alts_handshaker_client* client,
608 grpc_slice* bytes_received) {
609 if (client != nullptr && client->vtable != nullptr &&
610 client->vtable->next != nullptr) {
611 return client->vtable->next(client, bytes_received);
614 "client or client->vtable has not been initialized properly");
615 return TSI_INVALID_ARGUMENT;
618 void alts_handshaker_client_shutdown(alts_handshaker_client* client) {
619 if (client != nullptr && client->vtable != nullptr &&
620 client->vtable->shutdown != nullptr) {
621 client->vtable->shutdown(client);
625 void alts_handshaker_client_destroy(alts_handshaker_client* c) {
627 if (c->vtable != nullptr && c->vtable->destruct != nullptr) {
628 c->vtable->destruct(c);
630 alts_grpc_handshaker_client* client =
631 reinterpret_cast<alts_grpc_handshaker_client*>(c);
632 grpc_byte_buffer_destroy(client->send_buffer);
633 grpc_byte_buffer_destroy(client->recv_buffer);
634 client->send_buffer = nullptr;
635 client->recv_buffer = nullptr;
636 grpc_metadata_array_destroy(&client->recv_initial_metadata);
637 grpc_slice_unref_internal(client->recv_bytes);
638 grpc_slice_unref_internal(client->target_name);
639 grpc_alts_credentials_options_destroy(client->options);
640 gpr_free(client->buffer);