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