• 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 <stdio.h>
20 #include <stdlib.h>
21 
22 #include <grpc/grpc.h>
23 #include <grpc/support/sync.h>
24 
25 #include "src/core/lib/gprpp/thd.h"
26 #include "src/core/tsi/alts/handshaker/alts_handshaker_client.h"
27 #include "src/core/tsi/alts/handshaker/alts_tsi_event.h"
28 #include "src/core/tsi/alts/handshaker/alts_tsi_handshaker.h"
29 #include "src/core/tsi/alts/handshaker/alts_tsi_handshaker_private.h"
30 #include "test/core/tsi/alts/handshaker/alts_handshaker_service_api_test_lib.h"
31 
32 #define ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES "Hello World"
33 #define ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME "Hello Google"
34 #define ALTS_TSI_HANDSHAKER_TEST_CONSUMED_BYTES "Hello "
35 #define ALTS_TSI_HANDSHAKER_TEST_REMAIN_BYTES "Google"
36 #define ALTS_TSI_HANDSHAKER_TEST_PEER_IDENTITY "chapi@service.google.com"
37 #define ALTS_TSI_HANDSHAKER_TEST_KEY_DATA \
38   "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKL"
39 #define ALTS_TSI_HANDSHAKER_TEST_BUFFER_SIZE 100
40 #define ALTS_TSI_HANDSHAKER_TEST_SLEEP_TIME_IN_SECONDS 2
41 #define ALTS_TSI_HANDSHAKER_TEST_MAX_RPC_VERSION_MAJOR 3
42 #define ALTS_TSI_HANDSHAKER_TEST_MAX_RPC_VERSION_MINOR 2
43 #define ALTS_TSI_HANDSHAKER_TEST_MIN_RPC_VERSION_MAJOR 2
44 #define ALTS_TSI_HANDSHAKER_TEST_MIN_RPC_VERSION_MINOR 1
45 
46 using grpc_core::internal::
47     alts_tsi_handshaker_get_has_sent_start_message_for_testing;
48 using grpc_core::internal::alts_tsi_handshaker_get_is_client_for_testing;
49 using grpc_core::internal::alts_tsi_handshaker_get_recv_bytes_for_testing;
50 using grpc_core::internal::alts_tsi_handshaker_set_client_for_testing;
51 using grpc_core::internal::alts_tsi_handshaker_set_recv_bytes_for_testing;
52 
53 /* ALTS mock notification. */
54 typedef struct notification {
55   gpr_cv cv;
56   gpr_mu mu;
57   bool notified;
58 } notification;
59 
60 /* ALTS mock handshaker client. */
61 typedef struct alts_mock_handshaker_client {
62   alts_handshaker_client base;
63   bool used_for_success_test;
64 } alts_mock_handshaker_client;
65 
66 /* Type of ALTS handshaker response. */
67 typedef enum {
68   INVALID,
69   FAILED,
70   CLIENT_START,
71   SERVER_START,
72   CLIENT_NEXT,
73   SERVER_NEXT,
74 } alts_handshaker_response_type;
75 
76 static alts_tsi_event* client_start_event;
77 static alts_tsi_event* client_next_event;
78 static alts_tsi_event* server_start_event;
79 static alts_tsi_event* server_next_event;
80 static notification caller_to_tsi_notification;
81 static notification tsi_to_caller_notification;
82 
notification_init(notification * n)83 static void notification_init(notification* n) {
84   gpr_mu_init(&n->mu);
85   gpr_cv_init(&n->cv);
86   n->notified = false;
87 }
88 
notification_destroy(notification * n)89 static void notification_destroy(notification* n) {
90   gpr_mu_destroy(&n->mu);
91   gpr_cv_destroy(&n->cv);
92 }
93 
signal(notification * n)94 static void signal(notification* n) {
95   gpr_mu_lock(&n->mu);
96   n->notified = true;
97   gpr_cv_signal(&n->cv);
98   gpr_mu_unlock(&n->mu);
99 }
100 
wait(notification * n)101 static void wait(notification* n) {
102   gpr_mu_lock(&n->mu);
103   while (!n->notified) {
104     gpr_cv_wait(&n->cv, &n->mu, gpr_inf_future(GPR_CLOCK_REALTIME));
105   }
106   n->notified = false;
107   gpr_mu_unlock(&n->mu);
108 }
109 
110 /**
111  * This method mocks ALTS handshaker service to generate handshaker response
112  * for a specific request.
113  */
generate_handshaker_response(alts_handshaker_response_type type)114 static grpc_byte_buffer* generate_handshaker_response(
115     alts_handshaker_response_type type) {
116   grpc_gcp_handshaker_resp* resp = grpc_gcp_handshaker_resp_create();
117   GPR_ASSERT(grpc_gcp_handshaker_resp_set_code(resp, 0));
118   switch (type) {
119     case INVALID:
120       break;
121     case CLIENT_START:
122     case SERVER_START:
123       GPR_ASSERT(grpc_gcp_handshaker_resp_set_out_frames(
124           resp, ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME,
125           strlen(ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME)));
126       break;
127     case CLIENT_NEXT:
128       GPR_ASSERT(grpc_gcp_handshaker_resp_set_out_frames(
129           resp, ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME,
130           strlen(ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME)));
131       GPR_ASSERT(grpc_gcp_handshaker_resp_set_peer_identity_service_account(
132           resp, ALTS_TSI_HANDSHAKER_TEST_PEER_IDENTITY));
133       GPR_ASSERT(grpc_gcp_handshaker_resp_set_bytes_consumed(
134           resp, strlen(ALTS_TSI_HANDSHAKER_TEST_CONSUMED_BYTES)));
135       GPR_ASSERT(grpc_gcp_handshaker_resp_set_key_data(
136           resp, ALTS_TSI_HANDSHAKER_TEST_KEY_DATA,
137           strlen(ALTS_TSI_HANDSHAKER_TEST_KEY_DATA)));
138       GPR_ASSERT(grpc_gcp_handshaker_resp_set_peer_rpc_versions(
139           resp, ALTS_TSI_HANDSHAKER_TEST_MAX_RPC_VERSION_MAJOR,
140           ALTS_TSI_HANDSHAKER_TEST_MAX_RPC_VERSION_MINOR,
141           ALTS_TSI_HANDSHAKER_TEST_MIN_RPC_VERSION_MAJOR,
142           ALTS_TSI_HANDSHAKER_TEST_MIN_RPC_VERSION_MINOR));
143       break;
144     case SERVER_NEXT:
145       GPR_ASSERT(grpc_gcp_handshaker_resp_set_peer_identity_service_account(
146           resp, ALTS_TSI_HANDSHAKER_TEST_PEER_IDENTITY));
147       GPR_ASSERT(grpc_gcp_handshaker_resp_set_bytes_consumed(
148           resp, strlen(ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME)));
149       GPR_ASSERT(grpc_gcp_handshaker_resp_set_key_data(
150           resp, ALTS_TSI_HANDSHAKER_TEST_KEY_DATA,
151           strlen(ALTS_TSI_HANDSHAKER_TEST_KEY_DATA)));
152       GPR_ASSERT(grpc_gcp_handshaker_resp_set_peer_rpc_versions(
153           resp, ALTS_TSI_HANDSHAKER_TEST_MAX_RPC_VERSION_MAJOR,
154           ALTS_TSI_HANDSHAKER_TEST_MAX_RPC_VERSION_MINOR,
155           ALTS_TSI_HANDSHAKER_TEST_MIN_RPC_VERSION_MAJOR,
156           ALTS_TSI_HANDSHAKER_TEST_MIN_RPC_VERSION_MINOR));
157       break;
158     case FAILED:
159       GPR_ASSERT(
160           grpc_gcp_handshaker_resp_set_code(resp, 3 /* INVALID ARGUMENT */));
161       break;
162   }
163   grpc_slice slice;
164   GPR_ASSERT(grpc_gcp_handshaker_resp_encode(resp, &slice));
165   if (type == INVALID) {
166     grpc_slice bad_slice =
167         grpc_slice_split_head(&slice, GRPC_SLICE_LENGTH(slice) - 1);
168     grpc_slice_unref(slice);
169     slice = grpc_slice_ref(bad_slice);
170     grpc_slice_unref(bad_slice);
171   }
172   grpc_byte_buffer* buffer =
173       grpc_raw_byte_buffer_create(&slice, 1 /* number of slices */);
174   grpc_slice_unref(slice);
175   grpc_gcp_handshaker_resp_destroy(resp);
176   return buffer;
177 }
178 
check_must_not_be_called(tsi_result status,void * user_data,const unsigned char * bytes_to_send,size_t bytes_to_send_size,tsi_handshaker_result * result)179 static void check_must_not_be_called(tsi_result status, void* user_data,
180                                      const unsigned char* bytes_to_send,
181                                      size_t bytes_to_send_size,
182                                      tsi_handshaker_result* result) {
183   GPR_ASSERT(0);
184 }
185 
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)186 static void on_client_start_success_cb(tsi_result status, void* user_data,
187                                        const unsigned char* bytes_to_send,
188                                        size_t bytes_to_send_size,
189                                        tsi_handshaker_result* result) {
190   GPR_ASSERT(status == TSI_OK);
191   GPR_ASSERT(user_data == nullptr);
192   GPR_ASSERT(bytes_to_send_size == strlen(ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME));
193   GPR_ASSERT(memcmp(bytes_to_send, ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME,
194                     bytes_to_send_size) == 0);
195   GPR_ASSERT(result == nullptr);
196   /* Validate peer identity. */
197   tsi_peer peer;
198   GPR_ASSERT(tsi_handshaker_result_extract_peer(result, &peer) ==
199              TSI_INVALID_ARGUMENT);
200   /* Validate frame protector. */
201   tsi_frame_protector* protector = nullptr;
202   GPR_ASSERT(tsi_handshaker_result_create_frame_protector(
203                  result, nullptr, &protector) == TSI_INVALID_ARGUMENT);
204   /* Validate unused bytes. */
205   const unsigned char* unused_bytes = nullptr;
206   size_t unused_bytes_size = 0;
207   GPR_ASSERT(tsi_handshaker_result_get_unused_bytes(result, &unused_bytes,
208                                                     &unused_bytes_size) ==
209              TSI_INVALID_ARGUMENT);
210   signal(&tsi_to_caller_notification);
211 }
212 
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)213 static void on_server_start_success_cb(tsi_result status, void* user_data,
214                                        const unsigned char* bytes_to_send,
215                                        size_t bytes_to_send_size,
216                                        tsi_handshaker_result* result) {
217   GPR_ASSERT(status == TSI_OK);
218   GPR_ASSERT(user_data == nullptr);
219   GPR_ASSERT(bytes_to_send_size == strlen(ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME));
220   GPR_ASSERT(memcmp(bytes_to_send, ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME,
221                     bytes_to_send_size) == 0);
222   GPR_ASSERT(result == nullptr);
223   /* Validate peer identity. */
224   tsi_peer peer;
225   GPR_ASSERT(tsi_handshaker_result_extract_peer(result, &peer) ==
226              TSI_INVALID_ARGUMENT);
227   /* Validate frame protector. */
228   tsi_frame_protector* protector = nullptr;
229   GPR_ASSERT(tsi_handshaker_result_create_frame_protector(
230                  result, nullptr, &protector) == TSI_INVALID_ARGUMENT);
231   /* Validate unused bytes. */
232   const unsigned char* unused_bytes = nullptr;
233   size_t unused_bytes_size = 0;
234   GPR_ASSERT(tsi_handshaker_result_get_unused_bytes(result, &unused_bytes,
235                                                     &unused_bytes_size) ==
236              TSI_INVALID_ARGUMENT);
237   signal(&tsi_to_caller_notification);
238 }
239 
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)240 static void on_client_next_success_cb(tsi_result status, void* user_data,
241                                       const unsigned char* bytes_to_send,
242                                       size_t bytes_to_send_size,
243                                       tsi_handshaker_result* result) {
244   GPR_ASSERT(status == TSI_OK);
245   GPR_ASSERT(user_data == nullptr);
246   GPR_ASSERT(bytes_to_send_size == strlen(ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME));
247   GPR_ASSERT(memcmp(bytes_to_send, ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME,
248                     bytes_to_send_size) == 0);
249   GPR_ASSERT(result != nullptr);
250   /* Validate peer identity. */
251   tsi_peer peer;
252   GPR_ASSERT(tsi_handshaker_result_extract_peer(result, &peer) == TSI_OK);
253   GPR_ASSERT(peer.property_count == kTsiAltsNumOfPeerProperties);
254   GPR_ASSERT(memcmp(TSI_ALTS_CERTIFICATE_TYPE, peer.properties[0].value.data,
255                     peer.properties[0].value.length) == 0);
256   GPR_ASSERT(memcmp(ALTS_TSI_HANDSHAKER_TEST_PEER_IDENTITY,
257                     peer.properties[1].value.data,
258                     peer.properties[1].value.length) == 0);
259   tsi_peer_destruct(&peer);
260   /* Validate unused bytes. */
261   const unsigned char* bytes = nullptr;
262   size_t bytes_size = 0;
263   GPR_ASSERT(tsi_handshaker_result_get_unused_bytes(result, &bytes,
264                                                     &bytes_size) == TSI_OK);
265   GPR_ASSERT(bytes_size == strlen(ALTS_TSI_HANDSHAKER_TEST_REMAIN_BYTES));
266   GPR_ASSERT(memcmp(bytes, ALTS_TSI_HANDSHAKER_TEST_REMAIN_BYTES, bytes_size) ==
267              0);
268   /* Validate frame protector. */
269   tsi_frame_protector* protector = nullptr;
270   GPR_ASSERT(tsi_handshaker_result_create_frame_protector(
271                  result, nullptr, &protector) == TSI_OK);
272   GPR_ASSERT(protector != nullptr);
273   tsi_frame_protector_destroy(protector);
274   tsi_handshaker_result_destroy(result);
275   signal(&tsi_to_caller_notification);
276 }
277 
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)278 static void on_server_next_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   GPR_ASSERT(status == TSI_OK);
283   GPR_ASSERT(user_data == nullptr);
284   GPR_ASSERT(bytes_to_send_size == 0);
285   GPR_ASSERT(bytes_to_send == nullptr);
286   GPR_ASSERT(result != nullptr);
287   /* Validate peer identity. */
288   tsi_peer peer;
289   GPR_ASSERT(tsi_handshaker_result_extract_peer(result, &peer) == TSI_OK);
290   GPR_ASSERT(peer.property_count == kTsiAltsNumOfPeerProperties);
291   GPR_ASSERT(memcmp(TSI_ALTS_CERTIFICATE_TYPE, peer.properties[0].value.data,
292                     peer.properties[0].value.length) == 0);
293   GPR_ASSERT(memcmp(ALTS_TSI_HANDSHAKER_TEST_PEER_IDENTITY,
294                     peer.properties[1].value.data,
295                     peer.properties[1].value.length) == 0);
296   tsi_peer_destruct(&peer);
297   /* Validate unused bytes. */
298   const unsigned char* bytes = nullptr;
299   size_t bytes_size = 0;
300   GPR_ASSERT(tsi_handshaker_result_get_unused_bytes(result, &bytes,
301                                                     &bytes_size) == TSI_OK);
302   GPR_ASSERT(bytes_size == 0);
303   GPR_ASSERT(bytes == nullptr);
304   /* Validate frame protector. */
305   tsi_frame_protector* protector = nullptr;
306   GPR_ASSERT(tsi_handshaker_result_create_frame_protector(
307                  result, nullptr, &protector) == TSI_OK);
308   GPR_ASSERT(protector != nullptr);
309   tsi_frame_protector_destroy(protector);
310   tsi_handshaker_result_destroy(result);
311   signal(&tsi_to_caller_notification);
312 }
313 
mock_client_start(alts_handshaker_client * self,alts_tsi_event * event)314 static tsi_result mock_client_start(alts_handshaker_client* self,
315                                     alts_tsi_event* event) {
316   alts_mock_handshaker_client* client =
317       reinterpret_cast<alts_mock_handshaker_client*>(self);
318   if (!client->used_for_success_test) {
319     alts_tsi_event_destroy(event);
320     return TSI_INTERNAL_ERROR;
321   }
322   GPR_ASSERT(event->cb == on_client_start_success_cb);
323   GPR_ASSERT(event->user_data == nullptr);
324   GPR_ASSERT(!alts_tsi_handshaker_get_has_sent_start_message_for_testing(
325       event->handshaker));
326   /* Populate handshaker response for client_start request. */
327   event->recv_buffer = generate_handshaker_response(CLIENT_START);
328   client_start_event = event;
329   signal(&caller_to_tsi_notification);
330   return TSI_OK;
331 }
332 
mock_shutdown(alts_handshaker_client * self)333 static void mock_shutdown(alts_handshaker_client* self) {}
334 
mock_server_start(alts_handshaker_client * self,alts_tsi_event * event,grpc_slice * bytes_received)335 static tsi_result mock_server_start(alts_handshaker_client* self,
336                                     alts_tsi_event* event,
337                                     grpc_slice* bytes_received) {
338   alts_mock_handshaker_client* client =
339       reinterpret_cast<alts_mock_handshaker_client*>(self);
340   if (!client->used_for_success_test) {
341     alts_tsi_event_destroy(event);
342     return TSI_INTERNAL_ERROR;
343   }
344   GPR_ASSERT(event->cb == on_server_start_success_cb);
345   GPR_ASSERT(event->user_data == nullptr);
346   grpc_slice slice = grpc_empty_slice();
347   GPR_ASSERT(grpc_slice_cmp(*bytes_received, slice) == 0);
348   GPR_ASSERT(!alts_tsi_handshaker_get_has_sent_start_message_for_testing(
349       event->handshaker));
350   /* Populate handshaker response for server_start request. */
351   event->recv_buffer = generate_handshaker_response(SERVER_START);
352   server_start_event = event;
353   grpc_slice_unref(slice);
354   signal(&caller_to_tsi_notification);
355   return TSI_OK;
356 }
357 
mock_next(alts_handshaker_client * self,alts_tsi_event * event,grpc_slice * bytes_received)358 static tsi_result mock_next(alts_handshaker_client* self, alts_tsi_event* event,
359                             grpc_slice* bytes_received) {
360   alts_mock_handshaker_client* client =
361       reinterpret_cast<alts_mock_handshaker_client*>(self);
362   if (!client->used_for_success_test) {
363     alts_tsi_event_destroy(event);
364     return TSI_INTERNAL_ERROR;
365   }
366   bool is_client =
367       alts_tsi_handshaker_get_is_client_for_testing(event->handshaker);
368   if (is_client) {
369     GPR_ASSERT(event->cb == on_client_next_success_cb);
370   } else {
371     GPR_ASSERT(event->cb == on_server_next_success_cb);
372   }
373   GPR_ASSERT(event->user_data == nullptr);
374   GPR_ASSERT(bytes_received != nullptr);
375   GPR_ASSERT(memcmp(GRPC_SLICE_START_PTR(*bytes_received),
376                     ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES,
377                     GRPC_SLICE_LENGTH(*bytes_received)) == 0);
378   GPR_ASSERT(grpc_slice_cmp(alts_tsi_handshaker_get_recv_bytes_for_testing(
379                                 event->handshaker),
380                             *bytes_received) == 0);
381   GPR_ASSERT(alts_tsi_handshaker_get_has_sent_start_message_for_testing(
382       event->handshaker));
383   /* Populate handshaker response for next request. */
384   grpc_slice out_frame =
385       grpc_slice_from_static_string(ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME);
386   if (is_client) {
387     event->recv_buffer = generate_handshaker_response(CLIENT_NEXT);
388   } else {
389     event->recv_buffer = generate_handshaker_response(SERVER_NEXT);
390   }
391   alts_tsi_handshaker_set_recv_bytes_for_testing(event->handshaker, &out_frame);
392   if (is_client) {
393     client_next_event = event;
394   } else {
395     server_next_event = event;
396   }
397   signal(&caller_to_tsi_notification);
398   grpc_slice_unref(out_frame);
399   return TSI_OK;
400 }
401 
mock_destruct(alts_handshaker_client * client)402 static void mock_destruct(alts_handshaker_client* client) {}
403 
404 static const alts_handshaker_client_vtable vtable = {
405     mock_client_start, mock_server_start, mock_next, mock_shutdown,
406     mock_destruct};
407 
alts_mock_handshaker_client_create(bool used_for_success_test)408 static alts_handshaker_client* alts_mock_handshaker_client_create(
409     bool used_for_success_test) {
410   alts_mock_handshaker_client* client =
411       static_cast<alts_mock_handshaker_client*>(gpr_zalloc(sizeof(*client)));
412   client->base.vtable = &vtable;
413   client->used_for_success_test = used_for_success_test;
414   return &client->base;
415 }
416 
create_test_handshaker(bool used_for_success_test,bool is_client)417 static tsi_handshaker* create_test_handshaker(bool used_for_success_test,
418                                               bool is_client) {
419   tsi_handshaker* handshaker = nullptr;
420   alts_handshaker_client* client =
421       alts_mock_handshaker_client_create(used_for_success_test);
422   grpc_alts_credentials_options* options =
423       grpc_alts_credentials_client_options_create();
424   alts_tsi_handshaker_create(options, "target_name", "lame", is_client,
425                              &handshaker);
426   alts_tsi_handshaker* alts_handshaker =
427       reinterpret_cast<alts_tsi_handshaker*>(handshaker);
428   alts_tsi_handshaker_set_client_for_testing(alts_handshaker, client);
429   grpc_alts_credentials_options_destroy(options);
430   return handshaker;
431 }
432 
check_handshaker_next_invalid_input()433 static void check_handshaker_next_invalid_input() {
434   /* Initialization. */
435   tsi_handshaker* handshaker = create_test_handshaker(true, true);
436   /* Check nullptr handshaker. */
437   GPR_ASSERT(tsi_handshaker_next(nullptr, nullptr, 0, nullptr, nullptr, nullptr,
438                                  check_must_not_be_called,
439                                  nullptr) == TSI_INVALID_ARGUMENT);
440   /* Check nullptr callback. */
441   GPR_ASSERT(tsi_handshaker_next(handshaker, nullptr, 0, nullptr, nullptr,
442                                  nullptr, nullptr,
443                                  nullptr) == TSI_INVALID_ARGUMENT);
444   /* Cleanup. */
445   tsi_handshaker_destroy(handshaker);
446 }
447 
check_handshaker_shutdown_invalid_input()448 static void check_handshaker_shutdown_invalid_input() {
449   /* Initialization. */
450   tsi_handshaker* handshaker = create_test_handshaker(
451       false /* used_for_success_test */, true /* is_client */);
452   /* Check nullptr handshaker. */
453   tsi_handshaker_shutdown(nullptr);
454   /* Cleanup. */
455   tsi_handshaker_destroy(handshaker);
456 }
457 
check_handshaker_next_success()458 static void check_handshaker_next_success() {
459   /**
460    * Create handshakers for which internal mock client is going to do
461    * correctness check.
462    */
463   tsi_handshaker* client_handshaker = create_test_handshaker(
464       true /* used_for_success_test */, true /* is_client */);
465   tsi_handshaker* server_handshaker = create_test_handshaker(
466       true /* used_for_success_test */, false /* is_client */);
467   /* Client start. */
468   GPR_ASSERT(tsi_handshaker_next(client_handshaker, nullptr, 0, nullptr,
469                                  nullptr, nullptr, on_client_start_success_cb,
470                                  nullptr) == TSI_ASYNC);
471   wait(&tsi_to_caller_notification);
472   /* Client next. */
473   GPR_ASSERT(tsi_handshaker_next(
474                  client_handshaker,
475                  (const unsigned char*)ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES,
476                  strlen(ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES), nullptr, nullptr,
477                  nullptr, on_client_next_success_cb, nullptr) == TSI_ASYNC);
478   wait(&tsi_to_caller_notification);
479   /* Server start. */
480   GPR_ASSERT(tsi_handshaker_next(server_handshaker, nullptr, 0, nullptr,
481                                  nullptr, nullptr, on_server_start_success_cb,
482                                  nullptr) == TSI_ASYNC);
483   wait(&tsi_to_caller_notification);
484   /* Server next. */
485   GPR_ASSERT(tsi_handshaker_next(
486                  server_handshaker,
487                  (const unsigned char*)ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES,
488                  strlen(ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES), nullptr, nullptr,
489                  nullptr, on_server_next_success_cb, nullptr) == TSI_ASYNC);
490   wait(&tsi_to_caller_notification);
491   /* Cleanup. */
492   tsi_handshaker_destroy(server_handshaker);
493   tsi_handshaker_destroy(client_handshaker);
494 }
495 
check_handshaker_next_with_shutdown()496 static void check_handshaker_next_with_shutdown() {
497   /* Initialization. */
498   tsi_handshaker* handshaker = create_test_handshaker(
499       true /* used_for_success_test */, true /* is_client*/);
500   /* next(success) -- shutdown(success) -- next (fail) */
501   GPR_ASSERT(tsi_handshaker_next(handshaker, nullptr, 0, nullptr, nullptr,
502                                  nullptr, on_client_start_success_cb,
503                                  nullptr) == TSI_ASYNC);
504   wait(&tsi_to_caller_notification);
505   tsi_handshaker_shutdown(handshaker);
506   GPR_ASSERT(tsi_handshaker_next(
507                  handshaker,
508                  (const unsigned char*)ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES,
509                  strlen(ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES), nullptr, nullptr,
510                  nullptr, on_client_next_success_cb,
511                  nullptr) == TSI_HANDSHAKE_SHUTDOWN);
512   /* Cleanup. */
513   tsi_handshaker_destroy(handshaker);
514 }
515 
check_handle_response_with_shutdown(void * unused)516 static void check_handle_response_with_shutdown(void* unused) {
517   /* Client start. */
518   wait(&caller_to_tsi_notification);
519   alts_tsi_event_dispatch_to_handshaker(client_start_event, true /* is_ok */);
520   alts_tsi_event_destroy(client_start_event);
521 }
522 
check_handshaker_next_failure()523 static void check_handshaker_next_failure() {
524   /**
525    * Create handshakers for which internal mock client is always going to fail.
526    */
527   tsi_handshaker* client_handshaker = create_test_handshaker(
528       false /* used_for_success_test */, true /* is_client */);
529   tsi_handshaker* server_handshaker = create_test_handshaker(
530       false /* used_for_success_test */, false /* is_client */);
531   /* Client start. */
532   GPR_ASSERT(tsi_handshaker_next(client_handshaker, nullptr, 0, nullptr,
533                                  nullptr, nullptr, check_must_not_be_called,
534                                  nullptr) == TSI_INTERNAL_ERROR);
535   /* Server start. */
536   GPR_ASSERT(tsi_handshaker_next(server_handshaker, nullptr, 0, nullptr,
537                                  nullptr, nullptr, check_must_not_be_called,
538                                  nullptr) == TSI_INTERNAL_ERROR);
539   /* Server next. */
540   GPR_ASSERT(tsi_handshaker_next(
541                  server_handshaker,
542                  (const unsigned char*)ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES,
543                  strlen(ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES), nullptr, nullptr,
544                  nullptr, check_must_not_be_called,
545                  nullptr) == TSI_INTERNAL_ERROR);
546   /* Client next. */
547   GPR_ASSERT(tsi_handshaker_next(
548                  client_handshaker,
549                  (const unsigned char*)ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES,
550                  strlen(ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES), nullptr, nullptr,
551                  nullptr, check_must_not_be_called,
552                  nullptr) == TSI_INTERNAL_ERROR);
553   /* Cleanup. */
554   tsi_handshaker_destroy(server_handshaker);
555   tsi_handshaker_destroy(client_handshaker);
556 }
557 
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)558 static void on_invalid_input_cb(tsi_result status, void* user_data,
559                                 const unsigned char* bytes_to_send,
560                                 size_t bytes_to_send_size,
561                                 tsi_handshaker_result* result) {
562   GPR_ASSERT(status == TSI_INTERNAL_ERROR);
563   GPR_ASSERT(user_data == nullptr);
564   GPR_ASSERT(bytes_to_send == nullptr);
565   GPR_ASSERT(bytes_to_send_size == 0);
566   GPR_ASSERT(result == nullptr);
567 }
568 
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)569 static void on_failed_grpc_call_cb(tsi_result status, void* user_data,
570                                    const unsigned char* bytes_to_send,
571                                    size_t bytes_to_send_size,
572                                    tsi_handshaker_result* result) {
573   GPR_ASSERT(status == TSI_INTERNAL_ERROR);
574   GPR_ASSERT(user_data == nullptr);
575   GPR_ASSERT(bytes_to_send == nullptr);
576   GPR_ASSERT(bytes_to_send_size == 0);
577   GPR_ASSERT(result == nullptr);
578 }
579 
check_handle_response_invalid_input()580 static void check_handle_response_invalid_input() {
581   /**
582    * Create a handshaker at the client side, for which internal mock client is
583    * always going to fail.
584    */
585   tsi_handshaker* handshaker = create_test_handshaker(
586       false /* used_for_success_test */, true /* is_client */);
587   alts_tsi_handshaker* alts_handshaker =
588       reinterpret_cast<alts_tsi_handshaker*>(handshaker);
589   grpc_byte_buffer recv_buffer;
590   /* Check nullptr handshaker. */
591   alts_tsi_handshaker_handle_response(nullptr, &recv_buffer, GRPC_STATUS_OK,
592                                       nullptr, on_invalid_input_cb, nullptr,
593                                       true);
594   /* Check nullptr recv_bytes. */
595   alts_tsi_handshaker_handle_response(alts_handshaker, nullptr, GRPC_STATUS_OK,
596                                       nullptr, on_invalid_input_cb, nullptr,
597                                       true);
598   /* Check failed grpc call made to handshaker service. */
599   alts_tsi_handshaker_handle_response(alts_handshaker, &recv_buffer,
600                                       GRPC_STATUS_UNKNOWN, nullptr,
601                                       on_failed_grpc_call_cb, nullptr, true);
602 
603   alts_tsi_handshaker_handle_response(alts_handshaker, &recv_buffer,
604                                       GRPC_STATUS_OK, nullptr,
605                                       on_failed_grpc_call_cb, nullptr, false);
606 
607   /* Cleanup. */
608   tsi_handshaker_destroy(handshaker);
609 }
610 
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)611 static void on_invalid_resp_cb(tsi_result status, void* user_data,
612                                const unsigned char* bytes_to_send,
613                                size_t bytes_to_send_size,
614                                tsi_handshaker_result* result) {
615   GPR_ASSERT(status == TSI_DATA_CORRUPTED);
616   GPR_ASSERT(user_data == nullptr);
617   GPR_ASSERT(bytes_to_send == nullptr);
618   GPR_ASSERT(bytes_to_send_size == 0);
619   GPR_ASSERT(result == nullptr);
620 }
621 
check_handle_response_invalid_resp()622 static void check_handle_response_invalid_resp() {
623   /**
624    * Create a handshaker at the client side, for which internal mock client is
625    * always going to fail.
626    */
627   tsi_handshaker* handshaker = create_test_handshaker(
628       false /* used_for_success_test */, true /* is_client */);
629   alts_tsi_handshaker* alts_handshaker =
630       reinterpret_cast<alts_tsi_handshaker*>(handshaker);
631   /* Tests. */
632   grpc_byte_buffer* recv_buffer = generate_handshaker_response(INVALID);
633   alts_tsi_handshaker_handle_response(alts_handshaker, recv_buffer,
634                                       GRPC_STATUS_OK, nullptr,
635                                       on_invalid_resp_cb, nullptr, true);
636   /* Cleanup. */
637   grpc_byte_buffer_destroy(recv_buffer);
638   tsi_handshaker_destroy(handshaker);
639 }
640 
check_handle_response_success(void * unused)641 static void check_handle_response_success(void* unused) {
642   /* Client start. */
643   wait(&caller_to_tsi_notification);
644   alts_tsi_event_dispatch_to_handshaker(client_start_event, true /* is_ok */);
645   alts_tsi_event_destroy(client_start_event);
646   /* Client next. */
647   wait(&caller_to_tsi_notification);
648   alts_tsi_event_dispatch_to_handshaker(client_next_event, true /* is_ok */);
649   alts_tsi_event_destroy(client_next_event);
650   /* Server start. */
651   wait(&caller_to_tsi_notification);
652   alts_tsi_event_dispatch_to_handshaker(server_start_event, true /* is_ok */);
653   alts_tsi_event_destroy(server_start_event);
654   /* Server next. */
655   wait(&caller_to_tsi_notification);
656   alts_tsi_event_dispatch_to_handshaker(server_next_event, true /* is_ok */);
657   alts_tsi_event_destroy(server_next_event);
658 }
659 
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)660 static void on_failed_resp_cb(tsi_result status, void* user_data,
661                               const unsigned char* bytes_to_send,
662                               size_t bytes_to_send_size,
663                               tsi_handshaker_result* result) {
664   GPR_ASSERT(status == TSI_INVALID_ARGUMENT);
665   GPR_ASSERT(user_data == nullptr);
666   GPR_ASSERT(bytes_to_send == nullptr);
667   GPR_ASSERT(bytes_to_send_size == 0);
668   GPR_ASSERT(result == nullptr);
669 }
670 
check_handle_response_failure()671 static void check_handle_response_failure() {
672   /**
673    * Create a handshaker at the client side, for which internal mock client is
674    * always going to fail.
675    */
676   tsi_handshaker* handshaker = create_test_handshaker(
677       false /* used_for_success_test */, true /* is_client */);
678   alts_tsi_handshaker* alts_handshaker =
679       reinterpret_cast<alts_tsi_handshaker*>(handshaker);
680   /* Tests. */
681   grpc_byte_buffer* recv_buffer = generate_handshaker_response(FAILED);
682   alts_tsi_handshaker_handle_response(alts_handshaker, recv_buffer,
683                                       GRPC_STATUS_OK, nullptr,
684                                       on_failed_resp_cb, nullptr, true);
685   grpc_byte_buffer_destroy(recv_buffer);
686   /* Cleanup. */
687   tsi_handshaker_destroy(handshaker);
688 }
689 
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)690 static void on_shutdown_resp_cb(tsi_result status, void* user_data,
691                                 const unsigned char* bytes_to_send,
692                                 size_t bytes_to_send_size,
693                                 tsi_handshaker_result* result) {
694   GPR_ASSERT(status == TSI_HANDSHAKE_SHUTDOWN);
695   GPR_ASSERT(user_data == nullptr);
696   GPR_ASSERT(bytes_to_send == nullptr);
697   GPR_ASSERT(bytes_to_send_size == 0);
698   GPR_ASSERT(result == nullptr);
699 }
700 
check_handle_response_after_shutdown()701 static void check_handle_response_after_shutdown() {
702   tsi_handshaker* handshaker = create_test_handshaker(
703       true /* used_for_success_test */, true /* is_client */);
704   alts_tsi_handshaker* alts_handshaker =
705       reinterpret_cast<alts_tsi_handshaker*>(handshaker);
706   /* Tests. */
707   tsi_handshaker_shutdown(handshaker);
708   grpc_byte_buffer* recv_buffer = generate_handshaker_response(CLIENT_START);
709   alts_tsi_handshaker_handle_response(alts_handshaker, recv_buffer,
710                                       GRPC_STATUS_OK, nullptr,
711                                       on_shutdown_resp_cb, nullptr, true);
712   grpc_byte_buffer_destroy(recv_buffer);
713   /* Cleanup. */
714   tsi_handshaker_destroy(handshaker);
715 }
716 
check_handshaker_next_fails_after_shutdown()717 void check_handshaker_next_fails_after_shutdown() {
718   /* Initialization. */
719   notification_init(&caller_to_tsi_notification);
720   notification_init(&tsi_to_caller_notification);
721   client_start_event = nullptr;
722   /* Tests. */
723   grpc_core::Thread thd("alts_tsi_handshaker_test",
724                         &check_handle_response_with_shutdown, nullptr);
725   thd.Start();
726   check_handshaker_next_with_shutdown();
727   thd.Join();
728   /* Cleanup. */
729   notification_destroy(&caller_to_tsi_notification);
730   notification_destroy(&tsi_to_caller_notification);
731 }
732 
check_handshaker_success()733 void check_handshaker_success() {
734   /* Initialization. */
735   notification_init(&caller_to_tsi_notification);
736   notification_init(&tsi_to_caller_notification);
737   client_start_event = nullptr;
738   client_next_event = nullptr;
739   server_start_event = nullptr;
740   server_next_event = nullptr;
741   /* Tests. */
742   grpc_core::Thread thd("alts_tsi_handshaker_test",
743                         &check_handle_response_success, nullptr);
744   thd.Start();
745   check_handshaker_next_success();
746   thd.Join();
747   /* Cleanup. */
748   notification_destroy(&caller_to_tsi_notification);
749   notification_destroy(&tsi_to_caller_notification);
750 }
751 
main(int argc,char ** argv)752 int main(int argc, char** argv) {
753   /* Initialization. */
754   grpc_init();
755   /* Tests. */
756   check_handshaker_success();
757   check_handshaker_next_invalid_input();
758   check_handshaker_shutdown_invalid_input();
759   check_handshaker_next_fails_after_shutdown();
760   check_handshaker_next_failure();
761   check_handle_response_invalid_input();
762   check_handle_response_invalid_resp();
763   check_handle_response_failure();
764   check_handle_response_after_shutdown();
765   /* Cleanup. */
766   grpc_shutdown();
767   return 0;
768 }
769