Imported Upstream version 1.33.1
[platform/upstream/grpc.git] / test / core / tsi / alts / handshaker / alts_tsi_handshaker_test.cc
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 <stdio.h>
20 #include <stdlib.h>
21
22 #include "upb/upb.hpp"
23
24 #include <grpc/grpc.h>
25 #include <grpc/support/sync.h>
26
27 #include "src/core/lib/gprpp/thd.h"
28 #include "src/core/tsi/alts/handshaker/alts_handshaker_client.h"
29 #include "src/core/tsi/alts/handshaker/alts_shared_resource.h"
30 #include "src/core/tsi/alts/handshaker/alts_tsi_handshaker.h"
31 #include "src/core/tsi/alts/handshaker/alts_tsi_handshaker_private.h"
32 #include "src/core/tsi/transport_security_grpc.h"
33 #include "src/proto/grpc/gcp/altscontext.upb.h"
34 #include "test/core/tsi/alts/handshaker/alts_handshaker_service_api_test_lib.h"
35 #include "test/core/util/test_config.h"
36
37 #define ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES "Hello World"
38 #define ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME "Hello Google"
39 #define ALTS_TSI_HANDSHAKER_TEST_CONSUMED_BYTES "Hello "
40 #define ALTS_TSI_HANDSHAKER_TEST_REMAIN_BYTES "Google"
41 #define ALTS_TSI_HANDSHAKER_TEST_PEER_IDENTITY "chapi@service.google.com"
42 #define ALTS_TSI_HANDSHAKER_TEST_SECURITY_LEVEL "TSI_PRIVACY_AND_INTEGRITY"
43 #define ALTS_TSI_HANDSHAKER_TEST_KEY_DATA \
44   "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKL"
45 #define ALTS_TSI_HANDSHAKER_TEST_BUFFER_SIZE 100
46 #define ALTS_TSI_HANDSHAKER_TEST_SLEEP_TIME_IN_SECONDS 2
47 #define ALTS_TSI_HANDSHAKER_TEST_MAX_RPC_VERSION_MAJOR 3
48 #define ALTS_TSI_HANDSHAKER_TEST_MAX_RPC_VERSION_MINOR 2
49 #define ALTS_TSI_HANDSHAKER_TEST_MIN_RPC_VERSION_MAJOR 2
50 #define ALTS_TSI_HANDSHAKER_TEST_MIN_RPC_VERSION_MINOR 1
51 #define ALTS_TSI_HANDSHAKER_TEST_LOCAL_IDENTITY "chapilocal@service.google.com"
52 #define ALTS_TSI_HANDSHAKER_TEST_APPLICATION_PROTOCOL \
53   "test application protocol"
54 #define ALTS_TSI_HANDSHAKER_TEST_RECORD_PROTOCOL "test record protocol"
55 #define ALTS_TSI_HANDSHAKER_TEST_MAX_FRAME_SIZE 256 * 1024
56 #define ALTS_TSI_HANDSHAKER_TEST_PEER_ATTRIBUTES_KEY "peer"
57 #define ALTS_TSI_HANDSHAKER_TEST_PEER_ATTRIBUTES_VALUE "attributes"
58
59 using grpc_core::internal::alts_handshaker_client_check_fields_for_testing;
60 using grpc_core::internal::alts_handshaker_client_get_handshaker_for_testing;
61 using grpc_core::internal::
62     alts_handshaker_client_get_recv_buffer_addr_for_testing;
63 using grpc_core::internal::
64     alts_handshaker_client_on_status_received_for_testing;
65 using grpc_core::internal::alts_handshaker_client_ref_for_testing;
66 using grpc_core::internal::alts_handshaker_client_set_cb_for_testing;
67 using grpc_core::internal::alts_handshaker_client_set_fields_for_testing;
68 using grpc_core::internal::alts_handshaker_client_set_recv_bytes_for_testing;
69 using grpc_core::internal::alts_handshaker_client_set_vtable_for_testing;
70 using grpc_core::internal::alts_tsi_handshaker_get_client_for_testing;
71 using grpc_core::internal::alts_tsi_handshaker_get_is_client_for_testing;
72 using grpc_core::internal::alts_tsi_handshaker_set_client_vtable_for_testing;
73 static bool should_handshaker_client_api_succeed = true;
74
75 /* ALTS mock notification. */
76 typedef struct notification {
77   gpr_cv cv;
78   gpr_mu mu;
79   bool notified;
80 } notification;
81
82 /* Type of ALTS handshaker response. */
83 typedef enum {
84   INVALID,
85   FAILED,
86   CLIENT_START,
87   SERVER_START,
88   CLIENT_NEXT,
89   SERVER_NEXT,
90 } alts_handshaker_response_type;
91
92 static alts_handshaker_client* cb_event = nullptr;
93 static notification caller_to_tsi_notification;
94 static notification tsi_to_caller_notification;
95
96 static void notification_init(notification* n) {
97   gpr_mu_init(&n->mu);
98   gpr_cv_init(&n->cv);
99   n->notified = false;
100 }
101
102 static void notification_destroy(notification* n) {
103   gpr_mu_destroy(&n->mu);
104   gpr_cv_destroy(&n->cv);
105 }
106
107 static void signal(notification* n) {
108   gpr_mu_lock(&n->mu);
109   n->notified = true;
110   gpr_cv_signal(&n->cv);
111   gpr_mu_unlock(&n->mu);
112 }
113
114 static void wait(notification* n) {
115   gpr_mu_lock(&n->mu);
116   while (!n->notified) {
117     gpr_cv_wait(&n->cv, &n->mu, gpr_inf_future(GPR_CLOCK_REALTIME));
118   }
119   n->notified = false;
120   gpr_mu_unlock(&n->mu);
121 }
122
123 /**
124  * This method mocks ALTS handshaker service to generate handshaker response
125  * for a specific request.
126  */
127 static grpc_byte_buffer* generate_handshaker_response(
128     alts_handshaker_response_type type) {
129   upb::Arena arena;
130   grpc_gcp_HandshakerResult* result;
131   grpc_gcp_Identity* peer_identity;
132   grpc_gcp_HandshakerResp* resp = grpc_gcp_HandshakerResp_new(arena.ptr());
133   grpc_gcp_HandshakerStatus* status =
134       grpc_gcp_HandshakerResp_mutable_status(resp, arena.ptr());
135   grpc_gcp_HandshakerStatus_set_code(status, 0);
136   grpc_gcp_Identity* local_identity;
137   switch (type) {
138     case INVALID:
139       break;
140     case CLIENT_START:
141     case SERVER_START:
142       grpc_gcp_HandshakerResp_set_out_frames(
143           resp, upb_strview_makez(ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME));
144       break;
145     case CLIENT_NEXT:
146       grpc_gcp_HandshakerResp_set_out_frames(
147           resp, upb_strview_makez(ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME));
148       grpc_gcp_HandshakerResp_set_bytes_consumed(
149           resp, strlen(ALTS_TSI_HANDSHAKER_TEST_CONSUMED_BYTES));
150       result = grpc_gcp_HandshakerResp_mutable_result(resp, arena.ptr());
151       peer_identity =
152           grpc_gcp_HandshakerResult_mutable_peer_identity(result, arena.ptr());
153       grpc_gcp_Identity_attributes_set(
154           peer_identity,
155           upb_strview_makez(ALTS_TSI_HANDSHAKER_TEST_PEER_ATTRIBUTES_KEY),
156           upb_strview_makez(ALTS_TSI_HANDSHAKER_TEST_PEER_ATTRIBUTES_VALUE),
157           arena.ptr());
158       grpc_gcp_Identity_set_service_account(
159           peer_identity,
160           upb_strview_makez(ALTS_TSI_HANDSHAKER_TEST_PEER_IDENTITY));
161       grpc_gcp_HandshakerResult_set_key_data(
162           result, upb_strview_makez(ALTS_TSI_HANDSHAKER_TEST_KEY_DATA));
163       GPR_ASSERT(grpc_gcp_handshaker_resp_set_peer_rpc_versions(
164           resp, arena.ptr(), ALTS_TSI_HANDSHAKER_TEST_MAX_RPC_VERSION_MAJOR,
165           ALTS_TSI_HANDSHAKER_TEST_MAX_RPC_VERSION_MINOR,
166           ALTS_TSI_HANDSHAKER_TEST_MIN_RPC_VERSION_MAJOR,
167           ALTS_TSI_HANDSHAKER_TEST_MIN_RPC_VERSION_MINOR));
168       local_identity =
169           grpc_gcp_HandshakerResult_mutable_local_identity(result, arena.ptr());
170       grpc_gcp_Identity_set_service_account(
171           local_identity,
172           upb_strview_makez(ALTS_TSI_HANDSHAKER_TEST_LOCAL_IDENTITY));
173       grpc_gcp_HandshakerResult_set_application_protocol(
174           result,
175           upb_strview_makez(ALTS_TSI_HANDSHAKER_TEST_APPLICATION_PROTOCOL));
176       grpc_gcp_HandshakerResult_set_record_protocol(
177           result, upb_strview_makez(ALTS_TSI_HANDSHAKER_TEST_RECORD_PROTOCOL));
178       grpc_gcp_HandshakerResult_set_max_frame_size(
179           result, ALTS_TSI_HANDSHAKER_TEST_MAX_FRAME_SIZE);
180       break;
181     case SERVER_NEXT:
182       grpc_gcp_HandshakerResp_set_bytes_consumed(
183           resp, strlen(ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME));
184       result = grpc_gcp_HandshakerResp_mutable_result(resp, arena.ptr());
185       peer_identity =
186           grpc_gcp_HandshakerResult_mutable_peer_identity(result, arena.ptr());
187       grpc_gcp_Identity_attributes_set(
188           peer_identity,
189           upb_strview_makez(ALTS_TSI_HANDSHAKER_TEST_PEER_ATTRIBUTES_KEY),
190           upb_strview_makez(ALTS_TSI_HANDSHAKER_TEST_PEER_ATTRIBUTES_VALUE),
191           arena.ptr());
192       grpc_gcp_Identity_set_service_account(
193           peer_identity,
194           upb_strview_makez(ALTS_TSI_HANDSHAKER_TEST_PEER_IDENTITY));
195       grpc_gcp_HandshakerResult_set_key_data(
196           result, upb_strview_makez(ALTS_TSI_HANDSHAKER_TEST_KEY_DATA));
197       GPR_ASSERT(grpc_gcp_handshaker_resp_set_peer_rpc_versions(
198           resp, arena.ptr(), ALTS_TSI_HANDSHAKER_TEST_MAX_RPC_VERSION_MAJOR,
199           ALTS_TSI_HANDSHAKER_TEST_MAX_RPC_VERSION_MINOR,
200           ALTS_TSI_HANDSHAKER_TEST_MIN_RPC_VERSION_MAJOR,
201           ALTS_TSI_HANDSHAKER_TEST_MIN_RPC_VERSION_MINOR));
202       local_identity =
203           grpc_gcp_HandshakerResult_mutable_local_identity(result, arena.ptr());
204       grpc_gcp_Identity_set_service_account(
205           local_identity,
206           upb_strview_makez(ALTS_TSI_HANDSHAKER_TEST_LOCAL_IDENTITY));
207       grpc_gcp_HandshakerResult_set_application_protocol(
208           result,
209           upb_strview_makez(ALTS_TSI_HANDSHAKER_TEST_APPLICATION_PROTOCOL));
210       grpc_gcp_HandshakerResult_set_record_protocol(
211           result, upb_strview_makez(ALTS_TSI_HANDSHAKER_TEST_RECORD_PROTOCOL));
212       break;
213     case FAILED:
214       grpc_gcp_HandshakerStatus_set_code(status, 3 /* INVALID ARGUMENT */);
215       break;
216   }
217   size_t buf_len;
218   char* buf = grpc_gcp_HandshakerResp_serialize(resp, arena.ptr(), &buf_len);
219   grpc_slice slice = gpr_slice_from_copied_buffer(buf, buf_len);
220   if (type == INVALID) {
221     grpc_slice bad_slice =
222         grpc_slice_split_head(&slice, GRPC_SLICE_LENGTH(slice) - 1);
223     grpc_slice_unref(slice);
224     slice = grpc_slice_ref(bad_slice);
225     grpc_slice_unref(bad_slice);
226   }
227   grpc_byte_buffer* buffer =
228       grpc_raw_byte_buffer_create(&slice, 1 /* number of slices */);
229   grpc_slice_unref(slice);
230   return buffer;
231 }
232
233 static void check_must_not_be_called(tsi_result /*status*/, void* /*user_data*/,
234                                      const unsigned char* /*bytes_to_send*/,
235                                      size_t /*bytes_to_send_size*/,
236                                      tsi_handshaker_result* /*result*/) {
237   GPR_ASSERT(0);
238 }
239
240 static void on_client_start_success_cb(tsi_result status, void* user_data,
241                                        const unsigned char* bytes_to_send,
242                                        size_t bytes_to_send_size,
243                                        tsi_handshaker_result* result) {
244   GPR_ASSERT(status == TSI_OK);
245   GPR_ASSERT(user_data == nullptr);
246   GPR_ASSERT(bytes_to_send_size == strlen(ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME));
247   GPR_ASSERT(memcmp(bytes_to_send, ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME,
248                     bytes_to_send_size) == 0);
249   GPR_ASSERT(result == nullptr);
250   /* Validate peer identity. */
251   tsi_peer peer;
252   GPR_ASSERT(tsi_handshaker_result_extract_peer(result, &peer) ==
253              TSI_INVALID_ARGUMENT);
254   /* Validate frame protector. */
255   tsi_frame_protector* protector = nullptr;
256   GPR_ASSERT(tsi_handshaker_result_create_frame_protector(
257                  result, nullptr, &protector) == TSI_INVALID_ARGUMENT);
258   /* Validate unused bytes. */
259   const unsigned char* unused_bytes = nullptr;
260   size_t unused_bytes_size = 0;
261   GPR_ASSERT(tsi_handshaker_result_get_unused_bytes(result, &unused_bytes,
262                                                     &unused_bytes_size) ==
263              TSI_INVALID_ARGUMENT);
264   signal(&tsi_to_caller_notification);
265 }
266
267 static void on_server_start_success_cb(tsi_result status, void* user_data,
268                                        const unsigned char* bytes_to_send,
269                                        size_t bytes_to_send_size,
270                                        tsi_handshaker_result* result) {
271   GPR_ASSERT(status == TSI_OK);
272   GPR_ASSERT(user_data == nullptr);
273   GPR_ASSERT(bytes_to_send_size == strlen(ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME));
274   GPR_ASSERT(memcmp(bytes_to_send, ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME,
275                     bytes_to_send_size) == 0);
276   GPR_ASSERT(result == nullptr);
277   /* Validate peer identity. */
278   tsi_peer peer;
279   GPR_ASSERT(tsi_handshaker_result_extract_peer(result, &peer) ==
280              TSI_INVALID_ARGUMENT);
281   /* Validate frame protector. */
282   tsi_frame_protector* protector = nullptr;
283   GPR_ASSERT(tsi_handshaker_result_create_frame_protector(
284                  result, nullptr, &protector) == TSI_INVALID_ARGUMENT);
285   /* Validate unused bytes. */
286   const unsigned char* unused_bytes = nullptr;
287   size_t unused_bytes_size = 0;
288   GPR_ASSERT(tsi_handshaker_result_get_unused_bytes(result, &unused_bytes,
289                                                     &unused_bytes_size) ==
290              TSI_INVALID_ARGUMENT);
291   signal(&tsi_to_caller_notification);
292 }
293
294 static void on_client_next_success_cb(tsi_result status, void* user_data,
295                                       const unsigned char* bytes_to_send,
296                                       size_t bytes_to_send_size,
297                                       tsi_handshaker_result* result) {
298   GPR_ASSERT(status == TSI_OK);
299   GPR_ASSERT(user_data == nullptr);
300   GPR_ASSERT(bytes_to_send_size == strlen(ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME));
301   GPR_ASSERT(memcmp(bytes_to_send, ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME,
302                     bytes_to_send_size) == 0);
303   GPR_ASSERT(result != nullptr);
304   // Validate max frame size value after Frame Size Negotiation. Here peer max
305   // frame size is greater than default value, and user specified max frame size
306   // is absent.
307   tsi_zero_copy_grpc_protector* zero_copy_protector = nullptr;
308   GPR_ASSERT(tsi_handshaker_result_create_zero_copy_grpc_protector(
309                  result, nullptr, &zero_copy_protector) == TSI_OK);
310   size_t actual_max_frame_size;
311   tsi_zero_copy_grpc_protector_max_frame_size(zero_copy_protector,
312                                               &actual_max_frame_size);
313   GPR_ASSERT(actual_max_frame_size == kTsiAltsMaxFrameSize);
314   tsi_zero_copy_grpc_protector_destroy(zero_copy_protector);
315   /* Validate peer identity. */
316   tsi_peer peer;
317   GPR_ASSERT(tsi_handshaker_result_extract_peer(result, &peer) == TSI_OK);
318   GPR_ASSERT(peer.property_count == kTsiAltsNumOfPeerProperties);
319   GPR_ASSERT(memcmp(TSI_ALTS_CERTIFICATE_TYPE, peer.properties[0].value.data,
320                     peer.properties[0].value.length) == 0);
321   GPR_ASSERT(memcmp(ALTS_TSI_HANDSHAKER_TEST_PEER_IDENTITY,
322                     peer.properties[1].value.data,
323                     peer.properties[1].value.length) == 0);
324   /* Validate alts context. */
325   upb::Arena context_arena;
326   grpc_gcp_AltsContext* ctx = grpc_gcp_AltsContext_parse(
327       peer.properties[3].value.data, peer.properties[3].value.length,
328       context_arena.ptr());
329   GPR_ASSERT(ctx != nullptr);
330   upb_strview application_protocol =
331       grpc_gcp_AltsContext_application_protocol(ctx);
332   upb_strview record_protocol = grpc_gcp_AltsContext_record_protocol(ctx);
333   upb_strview peer_account = grpc_gcp_AltsContext_peer_service_account(ctx);
334   upb_strview local_account = grpc_gcp_AltsContext_local_service_account(ctx);
335   GPR_ASSERT(memcmp(ALTS_TSI_HANDSHAKER_TEST_APPLICATION_PROTOCOL,
336                     application_protocol.data, application_protocol.size) == 0);
337   GPR_ASSERT(memcmp(ALTS_TSI_HANDSHAKER_TEST_RECORD_PROTOCOL,
338                     record_protocol.data, record_protocol.size) == 0);
339   GPR_ASSERT(memcmp(ALTS_TSI_HANDSHAKER_TEST_PEER_IDENTITY, peer_account.data,
340                     peer_account.size) == 0);
341   GPR_ASSERT(memcmp(ALTS_TSI_HANDSHAKER_TEST_LOCAL_IDENTITY, local_account.data,
342                     local_account.size) == 0);
343   size_t iter = UPB_MAP_BEGIN;
344   grpc_gcp_AltsContext_PeerAttributesEntry* peer_attributes_entry =
345       grpc_gcp_AltsContext_peer_attributes_nextmutable(ctx, &iter);
346   GPR_ASSERT(peer_attributes_entry != nullptr);
347   while (peer_attributes_entry != nullptr) {
348     upb_strview key = grpc_gcp_AltsContext_PeerAttributesEntry_key(
349         const_cast<grpc_gcp_AltsContext_PeerAttributesEntry*>(
350             peer_attributes_entry));
351     upb_strview val = grpc_gcp_AltsContext_PeerAttributesEntry_value(
352         const_cast<grpc_gcp_AltsContext_PeerAttributesEntry*>(
353             peer_attributes_entry));
354     GPR_ASSERT(upb_strview_eql(
355         key, upb_strview_makez(ALTS_TSI_HANDSHAKER_TEST_PEER_ATTRIBUTES_KEY)));
356     GPR_ASSERT(upb_strview_eql(
357         val,
358         upb_strview_makez(ALTS_TSI_HANDSHAKER_TEST_PEER_ATTRIBUTES_VALUE)));
359     peer_attributes_entry =
360         grpc_gcp_AltsContext_peer_attributes_nextmutable(ctx, &iter);
361   }
362   /* Validate security level. */
363   GPR_ASSERT(memcmp(ALTS_TSI_HANDSHAKER_TEST_SECURITY_LEVEL,
364                     peer.properties[4].value.data,
365                     peer.properties[4].value.length) == 0);
366   tsi_peer_destruct(&peer);
367   /* Validate unused bytes. */
368   const unsigned char* bytes = nullptr;
369   size_t bytes_size = 0;
370   GPR_ASSERT(tsi_handshaker_result_get_unused_bytes(result, &bytes,
371                                                     &bytes_size) == TSI_OK);
372   GPR_ASSERT(bytes_size == strlen(ALTS_TSI_HANDSHAKER_TEST_REMAIN_BYTES));
373   GPR_ASSERT(memcmp(bytes, ALTS_TSI_HANDSHAKER_TEST_REMAIN_BYTES, bytes_size) ==
374              0);
375   /* Validate frame protector. */
376   tsi_frame_protector* protector = nullptr;
377   GPR_ASSERT(tsi_handshaker_result_create_frame_protector(
378                  result, nullptr, &protector) == TSI_OK);
379   GPR_ASSERT(protector != nullptr);
380   tsi_frame_protector_destroy(protector);
381   tsi_handshaker_result_destroy(result);
382   signal(&tsi_to_caller_notification);
383 }
384
385 static void on_server_next_success_cb(tsi_result status, void* user_data,
386                                       const unsigned char* bytes_to_send,
387                                       size_t bytes_to_send_size,
388                                       tsi_handshaker_result* result) {
389   GPR_ASSERT(status == TSI_OK);
390   GPR_ASSERT(user_data == nullptr);
391   GPR_ASSERT(bytes_to_send_size == 0);
392   GPR_ASSERT(bytes_to_send == nullptr);
393   GPR_ASSERT(result != nullptr);
394   // Validate max frame size value after Frame Size Negotiation. The negotiated
395   // frame size value equals minimum send frame size, due to the absence of peer
396   // max frame size.
397   tsi_zero_copy_grpc_protector* zero_copy_protector = nullptr;
398   size_t user_specified_max_frame_size =
399       ALTS_TSI_HANDSHAKER_TEST_MAX_FRAME_SIZE;
400   GPR_ASSERT(tsi_handshaker_result_create_zero_copy_grpc_protector(
401                  result, &user_specified_max_frame_size,
402                  &zero_copy_protector) == TSI_OK);
403   size_t actual_max_frame_size;
404   tsi_zero_copy_grpc_protector_max_frame_size(zero_copy_protector,
405                                               &actual_max_frame_size);
406   GPR_ASSERT(actual_max_frame_size == kTsiAltsMinFrameSize);
407   tsi_zero_copy_grpc_protector_destroy(zero_copy_protector);
408   /* Validate peer identity. */
409   tsi_peer peer;
410   GPR_ASSERT(tsi_handshaker_result_extract_peer(result, &peer) == TSI_OK);
411   GPR_ASSERT(peer.property_count == kTsiAltsNumOfPeerProperties);
412   GPR_ASSERT(memcmp(TSI_ALTS_CERTIFICATE_TYPE, peer.properties[0].value.data,
413                     peer.properties[0].value.length) == 0);
414   GPR_ASSERT(memcmp(ALTS_TSI_HANDSHAKER_TEST_PEER_IDENTITY,
415                     peer.properties[1].value.data,
416                     peer.properties[1].value.length) == 0);
417   /* Validate alts context. */
418   upb::Arena context_arena;
419   grpc_gcp_AltsContext* ctx = grpc_gcp_AltsContext_parse(
420       peer.properties[3].value.data, peer.properties[3].value.length,
421       context_arena.ptr());
422   GPR_ASSERT(ctx != nullptr);
423   upb_strview application_protocol =
424       grpc_gcp_AltsContext_application_protocol(ctx);
425   upb_strview record_protocol = grpc_gcp_AltsContext_record_protocol(ctx);
426   upb_strview peer_account = grpc_gcp_AltsContext_peer_service_account(ctx);
427   upb_strview local_account = grpc_gcp_AltsContext_local_service_account(ctx);
428   GPR_ASSERT(memcmp(ALTS_TSI_HANDSHAKER_TEST_APPLICATION_PROTOCOL,
429                     application_protocol.data, application_protocol.size) == 0);
430   GPR_ASSERT(memcmp(ALTS_TSI_HANDSHAKER_TEST_RECORD_PROTOCOL,
431                     record_protocol.data, record_protocol.size) == 0);
432   GPR_ASSERT(memcmp(ALTS_TSI_HANDSHAKER_TEST_PEER_IDENTITY, peer_account.data,
433                     peer_account.size) == 0);
434   GPR_ASSERT(memcmp(ALTS_TSI_HANDSHAKER_TEST_LOCAL_IDENTITY, local_account.data,
435                     local_account.size) == 0);
436   size_t iter = UPB_MAP_BEGIN;
437   grpc_gcp_AltsContext_PeerAttributesEntry* peer_attributes_entry =
438       grpc_gcp_AltsContext_peer_attributes_nextmutable(ctx, &iter);
439   GPR_ASSERT(peer_attributes_entry != nullptr);
440   while (peer_attributes_entry != nullptr) {
441     upb_strview key = grpc_gcp_AltsContext_PeerAttributesEntry_key(
442         const_cast<grpc_gcp_AltsContext_PeerAttributesEntry*>(
443             peer_attributes_entry));
444     upb_strview val = grpc_gcp_AltsContext_PeerAttributesEntry_value(
445         const_cast<grpc_gcp_AltsContext_PeerAttributesEntry*>(
446             peer_attributes_entry));
447     GPR_ASSERT(upb_strview_eql(
448         key, upb_strview_makez(ALTS_TSI_HANDSHAKER_TEST_PEER_ATTRIBUTES_KEY)));
449     GPR_ASSERT(upb_strview_eql(
450         val,
451         upb_strview_makez(ALTS_TSI_HANDSHAKER_TEST_PEER_ATTRIBUTES_VALUE)));
452     peer_attributes_entry =
453         grpc_gcp_AltsContext_peer_attributes_nextmutable(ctx, &iter);
454   }
455   /* Check security level. */
456   GPR_ASSERT(memcmp(ALTS_TSI_HANDSHAKER_TEST_SECURITY_LEVEL,
457                     peer.properties[4].value.data,
458                     peer.properties[4].value.length) == 0);
459
460   tsi_peer_destruct(&peer);
461   /* Validate unused bytes. */
462   const unsigned char* bytes = nullptr;
463   size_t bytes_size = 0;
464   GPR_ASSERT(tsi_handshaker_result_get_unused_bytes(result, &bytes,
465                                                     &bytes_size) == TSI_OK);
466   GPR_ASSERT(bytes_size == 0);
467   GPR_ASSERT(bytes == nullptr);
468   /* Validate frame protector. */
469   tsi_frame_protector* protector = nullptr;
470   GPR_ASSERT(tsi_handshaker_result_create_frame_protector(
471                  result, nullptr, &protector) == TSI_OK);
472   GPR_ASSERT(protector != nullptr);
473   tsi_frame_protector_destroy(protector);
474   tsi_handshaker_result_destroy(result);
475   signal(&tsi_to_caller_notification);
476 }
477
478 static tsi_result mock_client_start(alts_handshaker_client* client) {
479   if (!should_handshaker_client_api_succeed) {
480     return TSI_INTERNAL_ERROR;
481   }
482   /* Note that the alts_tsi_handshaker needs to set its
483    * has_sent_start_message field field to true
484    * before the call to alts_handshaker_client_start is made because
485    * because it's unsafe to access it afterwards. */
486   alts_handshaker_client_check_fields_for_testing(
487       client, on_client_start_success_cb, nullptr, true, nullptr);
488   /* Populate handshaker response for client_start request. */
489   grpc_byte_buffer** recv_buffer_ptr =
490       alts_handshaker_client_get_recv_buffer_addr_for_testing(client);
491   *recv_buffer_ptr = generate_handshaker_response(CLIENT_START);
492   cb_event = client;
493   signal(&caller_to_tsi_notification);
494   return TSI_OK;
495 }
496
497 static void mock_shutdown(alts_handshaker_client* /*self*/) {}
498
499 static tsi_result mock_server_start(alts_handshaker_client* client,
500                                     grpc_slice* bytes_received) {
501   if (!should_handshaker_client_api_succeed) {
502     return TSI_INTERNAL_ERROR;
503   }
504   alts_handshaker_client_check_fields_for_testing(
505       client, on_server_start_success_cb, nullptr, true, nullptr);
506   grpc_slice slice = grpc_empty_slice();
507   GPR_ASSERT(grpc_slice_cmp(*bytes_received, slice) == 0);
508   /* Populate handshaker response for server_start request. */
509   grpc_byte_buffer** recv_buffer_ptr =
510       alts_handshaker_client_get_recv_buffer_addr_for_testing(client);
511   *recv_buffer_ptr = generate_handshaker_response(SERVER_START);
512   cb_event = client;
513   grpc_slice_unref(slice);
514   signal(&caller_to_tsi_notification);
515   return TSI_OK;
516 }
517
518 static tsi_result mock_next(alts_handshaker_client* client,
519                             grpc_slice* bytes_received) {
520   if (!should_handshaker_client_api_succeed) {
521     return TSI_INTERNAL_ERROR;
522   }
523   alts_tsi_handshaker* handshaker =
524       alts_handshaker_client_get_handshaker_for_testing(client);
525   bool is_client = alts_tsi_handshaker_get_is_client_for_testing(handshaker);
526   tsi_handshaker_on_next_done_cb cb =
527       is_client ? on_client_next_success_cb : on_server_next_success_cb;
528   alts_handshaker_client_set_cb_for_testing(client, cb);
529   alts_handshaker_client_set_recv_bytes_for_testing(client, bytes_received);
530   alts_handshaker_client_check_fields_for_testing(client, cb, nullptr, true,
531                                                   bytes_received);
532   GPR_ASSERT(bytes_received != nullptr);
533   GPR_ASSERT(memcmp(GRPC_SLICE_START_PTR(*bytes_received),
534                     ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES,
535                     GRPC_SLICE_LENGTH(*bytes_received)) == 0);
536   /* Populate handshaker response for next request. */
537   grpc_slice out_frame =
538       grpc_slice_from_static_string(ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME);
539   grpc_byte_buffer** recv_buffer_ptr =
540       alts_handshaker_client_get_recv_buffer_addr_for_testing(client);
541   *recv_buffer_ptr = is_client ? generate_handshaker_response(CLIENT_NEXT)
542                                : generate_handshaker_response(SERVER_NEXT);
543   alts_handshaker_client_set_recv_bytes_for_testing(client, &out_frame);
544   cb_event = client;
545   signal(&caller_to_tsi_notification);
546   grpc_slice_unref(out_frame);
547   return TSI_OK;
548 }
549
550 static void mock_destruct(alts_handshaker_client* /*client*/) {}
551
552 static alts_handshaker_client_vtable vtable = {mock_client_start,
553                                                mock_server_start, mock_next,
554                                                mock_shutdown, mock_destruct};
555
556 static tsi_handshaker* create_test_handshaker(bool is_client) {
557   tsi_handshaker* handshaker = nullptr;
558   grpc_alts_credentials_options* options =
559       grpc_alts_credentials_client_options_create();
560   alts_tsi_handshaker_create(options, "target_name",
561                              ALTS_HANDSHAKER_SERVICE_URL_FOR_TESTING, is_client,
562                              nullptr, &handshaker, 0);
563   alts_tsi_handshaker* alts_handshaker =
564       reinterpret_cast<alts_tsi_handshaker*>(handshaker);
565   alts_tsi_handshaker_set_client_vtable_for_testing(alts_handshaker, &vtable);
566   grpc_alts_credentials_options_destroy(options);
567   return handshaker;
568 }
569
570 static void run_tsi_handshaker_destroy_with_exec_ctx(
571     tsi_handshaker* handshaker) {
572   grpc_core::ExecCtx exec_ctx;
573   tsi_handshaker_destroy(handshaker);
574 }
575
576 static void check_handshaker_next_invalid_input() {
577   /* Initialization. */
578   tsi_handshaker* handshaker = create_test_handshaker(true);
579   /* Check nullptr handshaker. */
580   GPR_ASSERT(tsi_handshaker_next(nullptr, nullptr, 0, nullptr, nullptr, nullptr,
581                                  check_must_not_be_called,
582                                  nullptr) == TSI_INVALID_ARGUMENT);
583   /* Check nullptr callback. */
584   GPR_ASSERT(tsi_handshaker_next(handshaker, nullptr, 0, nullptr, nullptr,
585                                  nullptr, nullptr,
586                                  nullptr) == TSI_INVALID_ARGUMENT);
587   /* Cleanup. */
588   run_tsi_handshaker_destroy_with_exec_ctx(handshaker);
589 }
590
591 static void check_handshaker_shutdown_invalid_input() {
592   /* Initialization. */
593   tsi_handshaker* handshaker = create_test_handshaker(true /* is_client */);
594   /* Check nullptr handshaker. */
595   tsi_handshaker_shutdown(nullptr);
596   /* Cleanup. */
597   run_tsi_handshaker_destroy_with_exec_ctx(handshaker);
598 }
599
600 static void check_handshaker_next_success() {
601   /**
602    * Create handshakers for which internal mock client is going to do
603    * correctness check.
604    */
605   tsi_handshaker* client_handshaker =
606       create_test_handshaker(true /* is_client */);
607   tsi_handshaker* server_handshaker =
608       create_test_handshaker(false /* is_client */);
609   /* Client start. */
610   GPR_ASSERT(tsi_handshaker_next(client_handshaker, nullptr, 0, nullptr,
611                                  nullptr, nullptr, on_client_start_success_cb,
612                                  nullptr) == TSI_ASYNC);
613   wait(&tsi_to_caller_notification);
614   /* Client next. */
615   GPR_ASSERT(tsi_handshaker_next(
616                  client_handshaker,
617                  (const unsigned char*)ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES,
618                  strlen(ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES), nullptr, nullptr,
619                  nullptr, on_client_next_success_cb, nullptr) == TSI_ASYNC);
620   wait(&tsi_to_caller_notification);
621   /* Server start. */
622   GPR_ASSERT(tsi_handshaker_next(server_handshaker, nullptr, 0, nullptr,
623                                  nullptr, nullptr, on_server_start_success_cb,
624                                  nullptr) == TSI_ASYNC);
625   wait(&tsi_to_caller_notification);
626   /* Server next. */
627   GPR_ASSERT(tsi_handshaker_next(
628                  server_handshaker,
629                  (const unsigned char*)ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES,
630                  strlen(ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES), nullptr, nullptr,
631                  nullptr, on_server_next_success_cb, nullptr) == TSI_ASYNC);
632   wait(&tsi_to_caller_notification);
633   /* Cleanup. */
634   run_tsi_handshaker_destroy_with_exec_ctx(server_handshaker);
635   run_tsi_handshaker_destroy_with_exec_ctx(client_handshaker);
636 }
637
638 static void check_handshaker_next_with_shutdown() {
639   tsi_handshaker* handshaker = create_test_handshaker(true /* is_client*/);
640   /* next(success) -- shutdown(success) -- next (fail) */
641   GPR_ASSERT(tsi_handshaker_next(handshaker, nullptr, 0, nullptr, nullptr,
642                                  nullptr, on_client_start_success_cb,
643                                  nullptr) == TSI_ASYNC);
644   wait(&tsi_to_caller_notification);
645   tsi_handshaker_shutdown(handshaker);
646   GPR_ASSERT(tsi_handshaker_next(
647                  handshaker,
648                  (const unsigned char*)ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES,
649                  strlen(ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES), nullptr, nullptr,
650                  nullptr, on_client_next_success_cb,
651                  nullptr) == TSI_HANDSHAKE_SHUTDOWN);
652   /* Cleanup. */
653   run_tsi_handshaker_destroy_with_exec_ctx(handshaker);
654 }
655
656 static void check_handle_response_with_shutdown(void* /*unused*/) {
657   wait(&caller_to_tsi_notification);
658   alts_handshaker_client_handle_response(cb_event, true /* is_ok */);
659 }
660
661 static void check_handshaker_next_failure() {
662   /**
663    * Create handshakers for which internal mock client is always going to fail.
664    */
665   tsi_handshaker* client_handshaker =
666       create_test_handshaker(true /* is_client */);
667   tsi_handshaker* server_handshaker =
668       create_test_handshaker(false /* is_client */);
669   /* Client start. */
670   GPR_ASSERT(tsi_handshaker_next(client_handshaker, nullptr, 0, nullptr,
671                                  nullptr, nullptr, check_must_not_be_called,
672                                  nullptr) == TSI_INTERNAL_ERROR);
673   /* Server start. */
674   GPR_ASSERT(tsi_handshaker_next(server_handshaker, nullptr, 0, nullptr,
675                                  nullptr, nullptr, check_must_not_be_called,
676                                  nullptr) == TSI_INTERNAL_ERROR);
677   /* Server next. */
678   GPR_ASSERT(tsi_handshaker_next(
679                  server_handshaker,
680                  (const unsigned char*)ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES,
681                  strlen(ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES), nullptr, nullptr,
682                  nullptr, check_must_not_be_called,
683                  nullptr) == TSI_INTERNAL_ERROR);
684   /* Client next. */
685   GPR_ASSERT(tsi_handshaker_next(
686                  client_handshaker,
687                  (const unsigned char*)ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES,
688                  strlen(ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES), nullptr, nullptr,
689                  nullptr, check_must_not_be_called,
690                  nullptr) == TSI_INTERNAL_ERROR);
691   /* Cleanup. */
692   run_tsi_handshaker_destroy_with_exec_ctx(server_handshaker);
693   run_tsi_handshaker_destroy_with_exec_ctx(client_handshaker);
694 }
695
696 static void on_invalid_input_cb(tsi_result status, void* user_data,
697                                 const unsigned char* bytes_to_send,
698                                 size_t bytes_to_send_size,
699                                 tsi_handshaker_result* result) {
700   GPR_ASSERT(status == TSI_INTERNAL_ERROR);
701   GPR_ASSERT(user_data == nullptr);
702   GPR_ASSERT(bytes_to_send == nullptr);
703   GPR_ASSERT(bytes_to_send_size == 0);
704   GPR_ASSERT(result == nullptr);
705 }
706
707 static void on_failed_grpc_call_cb(tsi_result status, void* user_data,
708                                    const unsigned char* bytes_to_send,
709                                    size_t bytes_to_send_size,
710                                    tsi_handshaker_result* result) {
711   GPR_ASSERT(status == TSI_INTERNAL_ERROR);
712   GPR_ASSERT(user_data == nullptr);
713   GPR_ASSERT(bytes_to_send == nullptr);
714   GPR_ASSERT(bytes_to_send_size == 0);
715   GPR_ASSERT(result == nullptr);
716 }
717
718 static void check_handle_response_nullptr_handshaker() {
719   /* Initialization. */
720   notification_init(&caller_to_tsi_notification);
721   notification_init(&tsi_to_caller_notification);
722   /**
723    * Create a handshaker at the client side, for which internal mock client is
724    * always going to fail.
725    */
726   tsi_handshaker* handshaker = create_test_handshaker(true /* is_client */);
727   tsi_handshaker_next(handshaker, nullptr, 0, nullptr, nullptr, nullptr,
728                       on_client_start_success_cb, nullptr);
729   alts_tsi_handshaker* alts_handshaker =
730       reinterpret_cast<alts_tsi_handshaker*>(handshaker);
731   grpc_slice slice = grpc_empty_slice();
732   grpc_byte_buffer* recv_buffer = grpc_raw_byte_buffer_create(&slice, 1);
733   alts_handshaker_client* client =
734       alts_tsi_handshaker_get_client_for_testing(alts_handshaker);
735   /* Check nullptr handshaker. */
736   alts_handshaker_client_set_fields_for_testing(client, nullptr,
737                                                 on_invalid_input_cb, nullptr,
738                                                 recv_buffer, GRPC_STATUS_OK);
739   alts_handshaker_client_handle_response(client, true);
740   /* Note: here and elsewhere in this test, we first ref the handshaker in order
741    * to match the unref that on_status_received will do. This necessary
742    * because this test mocks out the grpc call in such a way that the code
743    * path that would usually take this ref is skipped. */
744   alts_handshaker_client_ref_for_testing(client);
745   {
746     grpc_core::ExecCtx exec_ctx;
747     alts_handshaker_client_on_status_received_for_testing(
748         client, GRPC_STATUS_OK, GRPC_ERROR_NONE);
749   }
750   /* Cleanup. */
751   grpc_slice_unref(slice);
752   run_tsi_handshaker_destroy_with_exec_ctx(handshaker);
753   notification_destroy(&caller_to_tsi_notification);
754   notification_destroy(&tsi_to_caller_notification);
755 }
756
757 static void check_handle_response_nullptr_recv_bytes() {
758   /* Initialization. */
759   notification_init(&caller_to_tsi_notification);
760   notification_init(&tsi_to_caller_notification);
761   /**
762    * Create a handshaker at the client side, for which internal mock client is
763    * always going to fail.
764    */
765   tsi_handshaker* handshaker = create_test_handshaker(true /* is_client */);
766   tsi_handshaker_next(handshaker, nullptr, 0, nullptr, nullptr, nullptr,
767                       on_client_start_success_cb, nullptr);
768   alts_tsi_handshaker* alts_handshaker =
769       reinterpret_cast<alts_tsi_handshaker*>(handshaker);
770   alts_handshaker_client* client =
771       alts_tsi_handshaker_get_client_for_testing(alts_handshaker);
772   /* Check nullptr recv_bytes. */
773   alts_handshaker_client_set_fields_for_testing(client, alts_handshaker,
774                                                 on_invalid_input_cb, nullptr,
775                                                 nullptr, GRPC_STATUS_OK);
776   alts_handshaker_client_handle_response(client, true);
777   alts_handshaker_client_ref_for_testing(client);
778   {
779     grpc_core::ExecCtx exec_ctx;
780     alts_handshaker_client_on_status_received_for_testing(
781         client, GRPC_STATUS_OK, GRPC_ERROR_NONE);
782   }
783   /* Cleanup. */
784   run_tsi_handshaker_destroy_with_exec_ctx(handshaker);
785   notification_destroy(&caller_to_tsi_notification);
786   notification_destroy(&tsi_to_caller_notification);
787 }
788
789 static void check_handle_response_failed_grpc_call_to_handshaker_service() {
790   /* Initialization. */
791   notification_init(&caller_to_tsi_notification);
792   notification_init(&tsi_to_caller_notification);
793   /**
794    * Create a handshaker at the client side, for which internal mock client is
795    * always going to fail.
796    */
797   tsi_handshaker* handshaker = create_test_handshaker(true /* is_client */);
798   tsi_handshaker_next(handshaker, nullptr, 0, nullptr, nullptr, nullptr,
799                       on_client_start_success_cb, nullptr);
800   alts_tsi_handshaker* alts_handshaker =
801       reinterpret_cast<alts_tsi_handshaker*>(handshaker);
802   grpc_slice slice = grpc_empty_slice();
803   grpc_byte_buffer* recv_buffer = grpc_raw_byte_buffer_create(&slice, 1);
804   alts_handshaker_client* client =
805       alts_tsi_handshaker_get_client_for_testing(alts_handshaker);
806   /* Check failed grpc call made to handshaker service. */
807   alts_handshaker_client_set_fields_for_testing(
808       client, alts_handshaker, on_failed_grpc_call_cb, nullptr, recv_buffer,
809       GRPC_STATUS_UNKNOWN);
810   alts_handshaker_client_handle_response(client, true);
811   alts_handshaker_client_ref_for_testing(client);
812   {
813     grpc_core::ExecCtx exec_ctx;
814     alts_handshaker_client_on_status_received_for_testing(
815         client, GRPC_STATUS_UNKNOWN, GRPC_ERROR_NONE);
816   }
817   /* Cleanup. */
818   grpc_slice_unref(slice);
819   run_tsi_handshaker_destroy_with_exec_ctx(handshaker);
820   notification_destroy(&caller_to_tsi_notification);
821   notification_destroy(&tsi_to_caller_notification);
822 }
823
824 static void
825 check_handle_response_failed_recv_message_from_handshaker_service() {
826   /* Initialization. */
827   notification_init(&caller_to_tsi_notification);
828   notification_init(&tsi_to_caller_notification);
829   /**
830    * Create a handshaker at the client side, for which internal mock client is
831    * always going to fail.
832    */
833   tsi_handshaker* handshaker = create_test_handshaker(true /* is_client */);
834   tsi_handshaker_next(handshaker, nullptr, 0, nullptr, nullptr, nullptr,
835                       on_client_start_success_cb, nullptr);
836   alts_tsi_handshaker* alts_handshaker =
837       reinterpret_cast<alts_tsi_handshaker*>(handshaker);
838   grpc_slice slice = grpc_empty_slice();
839   grpc_byte_buffer* recv_buffer = grpc_raw_byte_buffer_create(&slice, 1);
840   alts_handshaker_client* client =
841       alts_tsi_handshaker_get_client_for_testing(alts_handshaker);
842   /* Check failed recv message op from handshaker service. */
843   alts_handshaker_client_set_fields_for_testing(client, alts_handshaker,
844                                                 on_failed_grpc_call_cb, nullptr,
845                                                 recv_buffer, GRPC_STATUS_OK);
846   alts_handshaker_client_handle_response(client, false);
847   alts_handshaker_client_ref_for_testing(client);
848   {
849     grpc_core::ExecCtx exec_ctx;
850     alts_handshaker_client_on_status_received_for_testing(
851         client, GRPC_STATUS_OK, GRPC_ERROR_NONE);
852   }
853   /* Cleanup. */
854   grpc_slice_unref(slice);
855   run_tsi_handshaker_destroy_with_exec_ctx(handshaker);
856   notification_destroy(&caller_to_tsi_notification);
857   notification_destroy(&tsi_to_caller_notification);
858 }
859
860 static void on_invalid_resp_cb(tsi_result status, void* user_data,
861                                const unsigned char* bytes_to_send,
862                                size_t bytes_to_send_size,
863                                tsi_handshaker_result* result) {
864   GPR_ASSERT(status == TSI_DATA_CORRUPTED);
865   GPR_ASSERT(user_data == nullptr);
866   GPR_ASSERT(bytes_to_send == nullptr);
867   GPR_ASSERT(bytes_to_send_size == 0);
868   GPR_ASSERT(result == nullptr);
869 }
870
871 static void check_handle_response_invalid_resp() {
872   /* Initialization. */
873   notification_init(&caller_to_tsi_notification);
874   notification_init(&tsi_to_caller_notification);
875   /**
876    * Create a handshaker at the client side, for which internal mock client is
877    * always going to fail.
878    */
879   tsi_handshaker* handshaker = create_test_handshaker(true /* is_client */);
880   tsi_handshaker_next(handshaker, nullptr, 0, nullptr, nullptr, nullptr,
881                       on_client_start_success_cb, nullptr);
882   alts_tsi_handshaker* alts_handshaker =
883       reinterpret_cast<alts_tsi_handshaker*>(handshaker);
884   alts_handshaker_client* client =
885       alts_tsi_handshaker_get_client_for_testing(alts_handshaker);
886   /* Tests. */
887   grpc_byte_buffer* recv_buffer = generate_handshaker_response(INVALID);
888   alts_handshaker_client_set_fields_for_testing(client, alts_handshaker,
889                                                 on_invalid_resp_cb, nullptr,
890                                                 recv_buffer, GRPC_STATUS_OK);
891   alts_handshaker_client_handle_response(client, true);
892   alts_handshaker_client_ref_for_testing(client);
893   {
894     grpc_core::ExecCtx exec_ctx;
895     alts_handshaker_client_on_status_received_for_testing(
896         client, GRPC_STATUS_OK, GRPC_ERROR_NONE);
897   }
898   /* Cleanup. */
899   run_tsi_handshaker_destroy_with_exec_ctx(handshaker);
900   notification_destroy(&caller_to_tsi_notification);
901   notification_destroy(&tsi_to_caller_notification);
902 }
903
904 static void check_handle_response_success(void* /*unused*/) {
905   /* Client start. */
906   wait(&caller_to_tsi_notification);
907   alts_handshaker_client_handle_response(cb_event, true /* is_ok */);
908   /* Client next. */
909   wait(&caller_to_tsi_notification);
910   alts_handshaker_client_handle_response(cb_event, true /* is_ok */);
911   alts_handshaker_client_ref_for_testing(cb_event);
912   {
913     grpc_core::ExecCtx exec_ctx;
914     alts_handshaker_client_on_status_received_for_testing(
915         cb_event, GRPC_STATUS_OK, GRPC_ERROR_NONE);
916   }
917   /* Server start. */
918   wait(&caller_to_tsi_notification);
919   alts_handshaker_client_handle_response(cb_event, true /* is_ok */);
920   /* Server next. */
921   wait(&caller_to_tsi_notification);
922   alts_handshaker_client_handle_response(cb_event, true /* is_ok */);
923   alts_handshaker_client_ref_for_testing(cb_event);
924   {
925     grpc_core::ExecCtx exec_ctx;
926     alts_handshaker_client_on_status_received_for_testing(
927         cb_event, GRPC_STATUS_OK, GRPC_ERROR_NONE);
928   }
929 }
930
931 static void on_failed_resp_cb(tsi_result status, void* user_data,
932                               const unsigned char* bytes_to_send,
933                               size_t bytes_to_send_size,
934                               tsi_handshaker_result* result) {
935   GPR_ASSERT(status == TSI_INVALID_ARGUMENT);
936   GPR_ASSERT(user_data == nullptr);
937   GPR_ASSERT(bytes_to_send == nullptr);
938   GPR_ASSERT(bytes_to_send_size == 0);
939   GPR_ASSERT(result == nullptr);
940 }
941
942 static void check_handle_response_failure() {
943   /* Initialization. */
944   notification_init(&caller_to_tsi_notification);
945   notification_init(&tsi_to_caller_notification);
946   /**
947    * Create a handshaker at the client side, for which internal mock client is
948    * always going to fail.
949    */
950   tsi_handshaker* handshaker = create_test_handshaker(true /* is_client */);
951   tsi_handshaker_next(handshaker, nullptr, 0, nullptr, nullptr, nullptr,
952                       on_client_start_success_cb, nullptr);
953   alts_tsi_handshaker* alts_handshaker =
954       reinterpret_cast<alts_tsi_handshaker*>(handshaker);
955   alts_handshaker_client* client =
956       alts_tsi_handshaker_get_client_for_testing(alts_handshaker);
957   /* Tests. */
958   grpc_byte_buffer* recv_buffer = generate_handshaker_response(FAILED);
959   alts_handshaker_client_set_fields_for_testing(client, alts_handshaker,
960                                                 on_failed_resp_cb, nullptr,
961                                                 recv_buffer, GRPC_STATUS_OK);
962   alts_handshaker_client_handle_response(client, true /* is_ok*/);
963   alts_handshaker_client_ref_for_testing(client);
964   {
965     grpc_core::ExecCtx exec_ctx;
966     alts_handshaker_client_on_status_received_for_testing(
967         client, GRPC_STATUS_OK, GRPC_ERROR_NONE);
968   }
969   /* Cleanup. */
970   run_tsi_handshaker_destroy_with_exec_ctx(handshaker);
971   notification_destroy(&caller_to_tsi_notification);
972   notification_destroy(&tsi_to_caller_notification);
973 }
974
975 static void on_shutdown_resp_cb(tsi_result status, void* user_data,
976                                 const unsigned char* bytes_to_send,
977                                 size_t bytes_to_send_size,
978                                 tsi_handshaker_result* result) {
979   GPR_ASSERT(status == TSI_HANDSHAKE_SHUTDOWN);
980   GPR_ASSERT(user_data == nullptr);
981   GPR_ASSERT(bytes_to_send == nullptr);
982   GPR_ASSERT(bytes_to_send_size == 0);
983   GPR_ASSERT(result == nullptr);
984 }
985
986 static void check_handle_response_after_shutdown() {
987   /* Initialization. */
988   notification_init(&caller_to_tsi_notification);
989   notification_init(&tsi_to_caller_notification);
990   tsi_handshaker* handshaker = create_test_handshaker(true /* is_client */);
991   tsi_handshaker_next(handshaker, nullptr, 0, nullptr, nullptr, nullptr,
992                       on_client_start_success_cb, nullptr);
993   alts_tsi_handshaker* alts_handshaker =
994       reinterpret_cast<alts_tsi_handshaker*>(handshaker);
995   alts_handshaker_client* client =
996       alts_tsi_handshaker_get_client_for_testing(alts_handshaker);
997   grpc_byte_buffer** recv_buffer_ptr =
998       alts_handshaker_client_get_recv_buffer_addr_for_testing(client);
999   grpc_byte_buffer_destroy(*recv_buffer_ptr);
1000
1001   /* Tests. */
1002   tsi_handshaker_shutdown(handshaker);
1003   grpc_byte_buffer* recv_buffer = generate_handshaker_response(CLIENT_START);
1004   alts_handshaker_client_set_fields_for_testing(client, alts_handshaker,
1005                                                 on_shutdown_resp_cb, nullptr,
1006                                                 recv_buffer, GRPC_STATUS_OK);
1007   alts_handshaker_client_handle_response(client, true);
1008   alts_handshaker_client_ref_for_testing(client);
1009   {
1010     grpc_core::ExecCtx exec_ctx;
1011     alts_handshaker_client_on_status_received_for_testing(
1012         client, GRPC_STATUS_OK, GRPC_ERROR_NONE);
1013   }
1014   /* Cleanup. */
1015   run_tsi_handshaker_destroy_with_exec_ctx(handshaker);
1016   notification_destroy(&caller_to_tsi_notification);
1017   notification_destroy(&tsi_to_caller_notification);
1018 }
1019
1020 void check_handshaker_next_fails_after_shutdown() {
1021   /* Initialization. */
1022   notification_init(&caller_to_tsi_notification);
1023   notification_init(&tsi_to_caller_notification);
1024   cb_event = nullptr;
1025   /* Tests. */
1026   grpc_core::Thread thd("alts_tsi_handshaker_test",
1027                         &check_handle_response_with_shutdown, nullptr);
1028   thd.Start();
1029   check_handshaker_next_with_shutdown();
1030   thd.Join();
1031   /* Cleanup. */
1032   notification_destroy(&caller_to_tsi_notification);
1033   notification_destroy(&tsi_to_caller_notification);
1034 }
1035
1036 void check_handshaker_success() {
1037   /* Initialization. */
1038   notification_init(&caller_to_tsi_notification);
1039   notification_init(&tsi_to_caller_notification);
1040   /* Tests. */
1041   grpc_core::Thread thd("alts_tsi_handshaker_test",
1042                         &check_handle_response_success, nullptr);
1043   thd.Start();
1044   check_handshaker_next_success();
1045   thd.Join();
1046   /* Cleanup. */
1047   notification_destroy(&caller_to_tsi_notification);
1048   notification_destroy(&tsi_to_caller_notification);
1049 }
1050
1051 int main(int argc, char** argv) {
1052   grpc::testing::TestEnvironment env(argc, argv);
1053   /* Initialization. */
1054   grpc_init();
1055   grpc_alts_shared_resource_dedicated_init();
1056   /* Tests. */
1057   should_handshaker_client_api_succeed = true;
1058   check_handshaker_success();
1059   check_handshaker_next_invalid_input();
1060   check_handshaker_next_fails_after_shutdown();
1061   check_handle_response_after_shutdown();
1062   should_handshaker_client_api_succeed = false;
1063   check_handshaker_shutdown_invalid_input();
1064   check_handshaker_next_failure();
1065   check_handle_response_nullptr_handshaker();
1066   check_handle_response_nullptr_recv_bytes();
1067   check_handle_response_failed_grpc_call_to_handshaker_service();
1068   check_handle_response_failed_recv_message_from_handshaker_service();
1069   check_handle_response_invalid_resp();
1070   check_handle_response_failure();
1071   /* Cleanup. */
1072   grpc_alts_shared_resource_dedicated_shutdown();
1073   grpc_shutdown();
1074   return 0;
1075 }