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