• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  * Copyright 2017 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 #include <string.h>
22 
23 #include <grpc/grpc.h>
24 #include <grpc/support/alloc.h>
25 #include <grpc/support/log.h>
26 
27 #include "src/core/lib/security/transport/tsi_error.h"
28 #include "test/core/tsi/transport_security_test_lib.h"
29 
notification_signal(tsi_test_fixture * fixture)30 static void notification_signal(tsi_test_fixture* fixture) {
31   gpr_mu_lock(&fixture->mu);
32   fixture->notified = true;
33   gpr_cv_signal(&fixture->cv);
34   gpr_mu_unlock(&fixture->mu);
35 }
36 
notification_wait(tsi_test_fixture * fixture)37 static void notification_wait(tsi_test_fixture* fixture) {
38   gpr_mu_lock(&fixture->mu);
39   while (!fixture->notified) {
40     gpr_cv_wait(&fixture->cv, &fixture->mu, gpr_inf_future(GPR_CLOCK_REALTIME));
41   }
42   fixture->notified = false;
43   gpr_mu_unlock(&fixture->mu);
44 }
45 
46 typedef struct handshaker_args {
47   tsi_test_fixture* fixture;
48   unsigned char* handshake_buffer;
49   size_t handshake_buffer_size;
50   bool is_client;
51   bool transferred_data;
52   bool appended_unused_bytes;
53   grpc_error* error;
54 } handshaker_args;
55 
handshaker_args_create(tsi_test_fixture * fixture,bool is_client)56 static handshaker_args* handshaker_args_create(tsi_test_fixture* fixture,
57                                                bool is_client) {
58   GPR_ASSERT(fixture != nullptr);
59   GPR_ASSERT(fixture->config != nullptr);
60   handshaker_args* args =
61       static_cast<handshaker_args*>(gpr_zalloc(sizeof(*args)));
62   args->fixture = fixture;
63   args->handshake_buffer_size = fixture->handshake_buffer_size;
64   args->handshake_buffer =
65       static_cast<unsigned char*>(gpr_zalloc(args->handshake_buffer_size));
66   args->is_client = is_client;
67   args->error = GRPC_ERROR_NONE;
68   return args;
69 }
70 
handshaker_args_destroy(handshaker_args * args)71 static void handshaker_args_destroy(handshaker_args* args) {
72   gpr_free(args->handshake_buffer);
73   GRPC_ERROR_UNREF(args->error);
74   gpr_free(args);
75 }
76 
77 static void do_handshaker_next(handshaker_args* args);
78 
setup_handshakers(tsi_test_fixture * fixture)79 static void setup_handshakers(tsi_test_fixture* fixture) {
80   GPR_ASSERT(fixture != nullptr);
81   GPR_ASSERT(fixture->vtable != nullptr);
82   GPR_ASSERT(fixture->vtable->setup_handshakers != nullptr);
83   fixture->vtable->setup_handshakers(fixture);
84 }
85 
check_unused_bytes(tsi_test_fixture * fixture)86 static void check_unused_bytes(tsi_test_fixture* fixture) {
87   tsi_handshaker_result* result_with_unused_bytes =
88       fixture->has_client_finished_first ? fixture->server_result
89                                          : fixture->client_result;
90   tsi_handshaker_result* result_without_unused_bytes =
91       fixture->has_client_finished_first ? fixture->client_result
92                                          : fixture->server_result;
93   const unsigned char* bytes = nullptr;
94   size_t bytes_size = 0;
95   GPR_ASSERT(tsi_handshaker_result_get_unused_bytes(
96                  result_with_unused_bytes, &bytes, &bytes_size) == TSI_OK);
97   GPR_ASSERT(bytes_size == strlen(TSI_TEST_UNUSED_BYTES));
98   GPR_ASSERT(memcmp(bytes, TSI_TEST_UNUSED_BYTES, bytes_size) == 0);
99   GPR_ASSERT(tsi_handshaker_result_get_unused_bytes(
100                  result_without_unused_bytes, &bytes, &bytes_size) == TSI_OK);
101   GPR_ASSERT(bytes_size == 0);
102   GPR_ASSERT(bytes == nullptr);
103 }
104 
check_handshake_results(tsi_test_fixture * fixture)105 static void check_handshake_results(tsi_test_fixture* fixture) {
106   GPR_ASSERT(fixture != nullptr);
107   GPR_ASSERT(fixture->vtable != nullptr);
108   GPR_ASSERT(fixture->vtable->check_handshaker_peers != nullptr);
109   /* Check handshaker peers. */
110   fixture->vtable->check_handshaker_peers(fixture);
111   /* Check unused bytes. */
112   if (fixture->test_unused_bytes) {
113     tsi_test_channel* channel = fixture->channel;
114     if (fixture->server_result != nullptr &&
115         fixture->client_result != nullptr) {
116       check_unused_bytes(fixture);
117     }
118     channel->bytes_written_to_server_channel = 0;
119     channel->bytes_written_to_client_channel = 0;
120     channel->bytes_read_from_client_channel = 0;
121     channel->bytes_read_from_server_channel = 0;
122   }
123 }
124 
send_bytes_to_peer(tsi_test_channel * test_channel,const unsigned char * buf,size_t buf_size,bool is_client)125 static void send_bytes_to_peer(tsi_test_channel* test_channel,
126                                const unsigned char* buf, size_t buf_size,
127                                bool is_client) {
128   GPR_ASSERT(test_channel != nullptr);
129   GPR_ASSERT(buf != nullptr);
130   uint8_t* channel =
131       is_client ? test_channel->server_channel : test_channel->client_channel;
132   GPR_ASSERT(channel != nullptr);
133   size_t* bytes_written = is_client
134                               ? &test_channel->bytes_written_to_server_channel
135                               : &test_channel->bytes_written_to_client_channel;
136   GPR_ASSERT(bytes_written != nullptr);
137   GPR_ASSERT(*bytes_written + buf_size <= TSI_TEST_DEFAULT_CHANNEL_SIZE);
138   /* Write data to channel. */
139   memcpy(channel + *bytes_written, buf, buf_size);
140   *bytes_written += buf_size;
141 }
142 
maybe_append_unused_bytes(handshaker_args * args)143 static void maybe_append_unused_bytes(handshaker_args* args) {
144   GPR_ASSERT(args != nullptr);
145   GPR_ASSERT(args->fixture != nullptr);
146   tsi_test_fixture* fixture = args->fixture;
147   if (fixture->test_unused_bytes && !args->appended_unused_bytes) {
148     args->appended_unused_bytes = true;
149     send_bytes_to_peer(
150         fixture->channel,
151         reinterpret_cast<const unsigned char*>(TSI_TEST_UNUSED_BYTES),
152         strlen(TSI_TEST_UNUSED_BYTES), args->is_client);
153     if (fixture->client_result != nullptr &&
154         fixture->server_result == nullptr) {
155       fixture->has_client_finished_first = true;
156     }
157   }
158 }
159 
receive_bytes_from_peer(tsi_test_channel * test_channel,unsigned char ** buf,size_t * buf_size,bool is_client)160 static void receive_bytes_from_peer(tsi_test_channel* test_channel,
161                                     unsigned char** buf, size_t* buf_size,
162                                     bool is_client) {
163   GPR_ASSERT(test_channel != nullptr);
164   GPR_ASSERT(*buf != nullptr);
165   GPR_ASSERT(buf_size != nullptr);
166   uint8_t* channel =
167       is_client ? test_channel->client_channel : test_channel->server_channel;
168   GPR_ASSERT(channel != nullptr);
169   size_t* bytes_read = is_client
170                            ? &test_channel->bytes_read_from_client_channel
171                            : &test_channel->bytes_read_from_server_channel;
172   size_t* bytes_written = is_client
173                               ? &test_channel->bytes_written_to_client_channel
174                               : &test_channel->bytes_written_to_server_channel;
175   GPR_ASSERT(bytes_read != nullptr);
176   GPR_ASSERT(bytes_written != nullptr);
177   size_t to_read = *buf_size < *bytes_written - *bytes_read
178                        ? *buf_size
179                        : *bytes_written - *bytes_read;
180   /* Read data from channel. */
181   memcpy(*buf, channel + *bytes_read, to_read);
182   *buf_size = to_read;
183   *bytes_read += to_read;
184 }
185 
tsi_test_frame_protector_send_message_to_peer(tsi_test_frame_protector_config * config,tsi_test_channel * channel,tsi_frame_protector * protector,bool is_client)186 void tsi_test_frame_protector_send_message_to_peer(
187     tsi_test_frame_protector_config* config, tsi_test_channel* channel,
188     tsi_frame_protector* protector, bool is_client) {
189   /* Initialization. */
190   GPR_ASSERT(config != nullptr);
191   GPR_ASSERT(channel != nullptr);
192   GPR_ASSERT(protector != nullptr);
193   unsigned char* protected_buffer =
194       static_cast<unsigned char*>(gpr_zalloc(config->protected_buffer_size));
195   size_t message_size =
196       is_client ? config->client_message_size : config->server_message_size;
197   uint8_t* message =
198       is_client ? config->client_message : config->server_message;
199   GPR_ASSERT(message != nullptr);
200   const unsigned char* message_bytes = (const unsigned char*)message;
201   tsi_result result = TSI_OK;
202   /* Do protect and send protected data to peer. */
203   while (message_size > 0 && result == TSI_OK) {
204     size_t protected_buffer_size_to_send = config->protected_buffer_size;
205     size_t processed_message_size = message_size;
206     /* Do protect. */
207     result = tsi_frame_protector_protect(
208         protector, message_bytes, &processed_message_size, protected_buffer,
209         &protected_buffer_size_to_send);
210     GPR_ASSERT(result == TSI_OK);
211     /* Send protected data to peer. */
212     send_bytes_to_peer(channel, protected_buffer, protected_buffer_size_to_send,
213                        is_client);
214     message_bytes += processed_message_size;
215     message_size -= processed_message_size;
216     /* Flush if we're done. */
217     if (message_size == 0) {
218       size_t still_pending_size;
219       do {
220         protected_buffer_size_to_send = config->protected_buffer_size;
221         result = tsi_frame_protector_protect_flush(
222             protector, protected_buffer, &protected_buffer_size_to_send,
223             &still_pending_size);
224         GPR_ASSERT(result == TSI_OK);
225         send_bytes_to_peer(channel, protected_buffer,
226                            protected_buffer_size_to_send, is_client);
227       } while (still_pending_size > 0 && result == TSI_OK);
228       GPR_ASSERT(result == TSI_OK);
229     }
230   }
231   GPR_ASSERT(result == TSI_OK);
232   gpr_free(protected_buffer);
233 }
234 
tsi_test_frame_protector_receive_message_from_peer(tsi_test_frame_protector_config * config,tsi_test_channel * channel,tsi_frame_protector * protector,unsigned char * message,size_t * bytes_received,bool is_client)235 void tsi_test_frame_protector_receive_message_from_peer(
236     tsi_test_frame_protector_config* config, tsi_test_channel* channel,
237     tsi_frame_protector* protector, unsigned char* message,
238     size_t* bytes_received, bool is_client) {
239   /* Initialization. */
240   GPR_ASSERT(config != nullptr);
241   GPR_ASSERT(channel != nullptr);
242   GPR_ASSERT(protector != nullptr);
243   GPR_ASSERT(message != nullptr);
244   GPR_ASSERT(bytes_received != nullptr);
245   size_t read_offset = 0;
246   size_t message_offset = 0;
247   size_t read_from_peer_size = 0;
248   tsi_result result = TSI_OK;
249   bool done = false;
250   unsigned char* read_buffer = static_cast<unsigned char*>(
251       gpr_zalloc(config->read_buffer_allocated_size));
252   unsigned char* message_buffer = static_cast<unsigned char*>(
253       gpr_zalloc(config->message_buffer_allocated_size));
254   /* Do unprotect on data received from peer. */
255   while (!done && result == TSI_OK) {
256     /* Receive data from peer. */
257     if (read_from_peer_size == 0) {
258       read_from_peer_size = config->read_buffer_allocated_size;
259       receive_bytes_from_peer(channel, &read_buffer, &read_from_peer_size,
260                               is_client);
261       read_offset = 0;
262     }
263     if (read_from_peer_size == 0) {
264       done = true;
265     }
266     /* Do unprotect. */
267     size_t message_buffer_size;
268     do {
269       message_buffer_size = config->message_buffer_allocated_size;
270       size_t processed_size = read_from_peer_size;
271       result = tsi_frame_protector_unprotect(
272           protector, read_buffer + read_offset, &processed_size, message_buffer,
273           &message_buffer_size);
274       GPR_ASSERT(result == TSI_OK);
275       if (message_buffer_size > 0) {
276         memcpy(message + message_offset, message_buffer, message_buffer_size);
277         message_offset += message_buffer_size;
278       }
279       read_offset += processed_size;
280       read_from_peer_size -= processed_size;
281     } while ((read_from_peer_size > 0 || message_buffer_size > 0) &&
282              result == TSI_OK);
283     GPR_ASSERT(result == TSI_OK);
284   }
285   GPR_ASSERT(result == TSI_OK);
286   *bytes_received = message_offset;
287   gpr_free(read_buffer);
288   gpr_free(message_buffer);
289 }
290 
on_handshake_next_done(tsi_result result,void * user_data,const unsigned char * bytes_to_send,size_t bytes_to_send_size,tsi_handshaker_result * handshaker_result)291 grpc_error* on_handshake_next_done(tsi_result result, void* user_data,
292                                    const unsigned char* bytes_to_send,
293                                    size_t bytes_to_send_size,
294                                    tsi_handshaker_result* handshaker_result) {
295   handshaker_args* args = static_cast<handshaker_args*>(user_data);
296   GPR_ASSERT(args != nullptr);
297   GPR_ASSERT(args->fixture != nullptr);
298   tsi_test_fixture* fixture = args->fixture;
299   grpc_error* error = GRPC_ERROR_NONE;
300   /* Read more data if we need to. */
301   if (result == TSI_INCOMPLETE_DATA) {
302     GPR_ASSERT(bytes_to_send_size == 0);
303     notification_signal(fixture);
304     return error;
305   }
306   if (result != TSI_OK) {
307     notification_signal(fixture);
308     return grpc_set_tsi_error_result(
309         GRPC_ERROR_CREATE_FROM_STATIC_STRING("Handshake failed"), result);
310   }
311   /* Update handshaker result. */
312   if (handshaker_result != nullptr) {
313     tsi_handshaker_result** result_to_write =
314         args->is_client ? &fixture->client_result : &fixture->server_result;
315     GPR_ASSERT(*result_to_write == nullptr);
316     *result_to_write = handshaker_result;
317   }
318   /* Send data to peer, if needed. */
319   if (bytes_to_send_size > 0) {
320     send_bytes_to_peer(fixture->channel, bytes_to_send, bytes_to_send_size,
321                        args->is_client);
322     args->transferred_data = true;
323   }
324   if (handshaker_result != nullptr) {
325     maybe_append_unused_bytes(args);
326   }
327   notification_signal(fixture);
328   return error;
329 }
330 
on_handshake_next_done_wrapper(tsi_result result,void * user_data,const unsigned char * bytes_to_send,size_t bytes_to_send_size,tsi_handshaker_result * handshaker_result)331 static void on_handshake_next_done_wrapper(
332     tsi_result result, void* user_data, const unsigned char* bytes_to_send,
333     size_t bytes_to_send_size, tsi_handshaker_result* handshaker_result) {
334   handshaker_args* args = static_cast<handshaker_args*>(user_data);
335   args->error = on_handshake_next_done(result, user_data, bytes_to_send,
336                                        bytes_to_send_size, handshaker_result);
337 }
338 
is_handshake_finished_properly(handshaker_args * args)339 static bool is_handshake_finished_properly(handshaker_args* args) {
340   GPR_ASSERT(args != nullptr);
341   GPR_ASSERT(args->fixture != nullptr);
342   tsi_test_fixture* fixture = args->fixture;
343   if ((args->is_client && fixture->client_result != nullptr) ||
344       (!args->is_client && fixture->server_result != nullptr)) {
345     return true;
346   }
347   return false;
348 }
349 
do_handshaker_next(handshaker_args * args)350 static void do_handshaker_next(handshaker_args* args) {
351   /* Initialization. */
352   GPR_ASSERT(args != nullptr);
353   GPR_ASSERT(args->fixture != nullptr);
354   tsi_test_fixture* fixture = args->fixture;
355   tsi_handshaker* handshaker =
356       args->is_client ? fixture->client_handshaker : fixture->server_handshaker;
357   if (is_handshake_finished_properly(args)) {
358     return;
359   }
360   tsi_handshaker_result* handshaker_result = nullptr;
361   unsigned char* bytes_to_send = nullptr;
362   size_t bytes_to_send_size = 0;
363   tsi_result result = TSI_OK;
364   /* Receive data from peer, if available. */
365   do {
366     size_t buf_size = args->handshake_buffer_size;
367     receive_bytes_from_peer(fixture->channel, &args->handshake_buffer,
368                             &buf_size, args->is_client);
369     if (buf_size > 0) {
370       args->transferred_data = true;
371     }
372     /* Peform handshaker next. */
373     result = tsi_handshaker_next(handshaker, args->handshake_buffer, buf_size,
374                                  (const unsigned char**)&bytes_to_send,
375                                  &bytes_to_send_size, &handshaker_result,
376                                  &on_handshake_next_done_wrapper, args);
377     if (result != TSI_ASYNC) {
378       args->error = on_handshake_next_done(
379           result, args, bytes_to_send, bytes_to_send_size, handshaker_result);
380       if (args->error != GRPC_ERROR_NONE) {
381         return;
382       }
383     }
384   } while (result == TSI_INCOMPLETE_DATA);
385   notification_wait(fixture);
386 }
387 
tsi_test_do_handshake(tsi_test_fixture * fixture)388 void tsi_test_do_handshake(tsi_test_fixture* fixture) {
389   /* Initializaiton. */
390   setup_handshakers(fixture);
391   handshaker_args* client_args =
392       handshaker_args_create(fixture, true /* is_client */);
393   handshaker_args* server_args =
394       handshaker_args_create(fixture, false /* is_client */);
395   /* Do handshake. */
396   do {
397     client_args->transferred_data = false;
398     server_args->transferred_data = false;
399     do_handshaker_next(client_args);
400     if (client_args->error != GRPC_ERROR_NONE) {
401       break;
402     }
403     do_handshaker_next(server_args);
404     if (server_args->error != GRPC_ERROR_NONE) {
405       break;
406     }
407     GPR_ASSERT(client_args->transferred_data || server_args->transferred_data);
408   } while (fixture->client_result == nullptr ||
409            fixture->server_result == nullptr);
410   /* Verify handshake results. */
411   check_handshake_results(fixture);
412   /* Cleanup. */
413   handshaker_args_destroy(client_args);
414   handshaker_args_destroy(server_args);
415 }
416 
tsi_test_do_ping_pong(tsi_test_frame_protector_config * config,tsi_test_channel * channel,tsi_frame_protector * client_frame_protector,tsi_frame_protector * server_frame_protector)417 static void tsi_test_do_ping_pong(tsi_test_frame_protector_config* config,
418                                   tsi_test_channel* channel,
419                                   tsi_frame_protector* client_frame_protector,
420                                   tsi_frame_protector* server_frame_protector) {
421   GPR_ASSERT(config != nullptr);
422   GPR_ASSERT(channel != nullptr);
423   GPR_ASSERT(client_frame_protector != nullptr);
424   GPR_ASSERT(server_frame_protector != nullptr);
425   /* Client sends a message to server. */
426   tsi_test_frame_protector_send_message_to_peer(
427       config, channel, client_frame_protector, true /* is_client */);
428   unsigned char* server_received_message =
429       static_cast<unsigned char*>(gpr_zalloc(TSI_TEST_DEFAULT_CHANNEL_SIZE));
430   size_t server_received_message_size = 0;
431   tsi_test_frame_protector_receive_message_from_peer(
432       config, channel, server_frame_protector, server_received_message,
433       &server_received_message_size, false /* is_client */);
434   GPR_ASSERT(config->client_message_size == server_received_message_size);
435   GPR_ASSERT(memcmp(config->client_message, server_received_message,
436                     server_received_message_size) == 0);
437   /* Server sends a message to client. */
438   tsi_test_frame_protector_send_message_to_peer(
439       config, channel, server_frame_protector, false /* is_client */);
440   unsigned char* client_received_message =
441       static_cast<unsigned char*>(gpr_zalloc(TSI_TEST_DEFAULT_CHANNEL_SIZE));
442   size_t client_received_message_size = 0;
443   tsi_test_frame_protector_receive_message_from_peer(
444       config, channel, client_frame_protector, client_received_message,
445       &client_received_message_size, true /* is_client */);
446   GPR_ASSERT(config->server_message_size == client_received_message_size);
447   GPR_ASSERT(memcmp(config->server_message, client_received_message,
448                     client_received_message_size) == 0);
449   gpr_free(server_received_message);
450   gpr_free(client_received_message);
451 }
452 
tsi_test_frame_protector_do_round_trip_no_handshake(tsi_test_frame_protector_fixture * fixture)453 void tsi_test_frame_protector_do_round_trip_no_handshake(
454     tsi_test_frame_protector_fixture* fixture) {
455   GPR_ASSERT(fixture != nullptr);
456   tsi_test_do_ping_pong(fixture->config, fixture->channel,
457                         fixture->client_frame_protector,
458                         fixture->server_frame_protector);
459 }
460 
tsi_test_do_round_trip(tsi_test_fixture * fixture)461 void tsi_test_do_round_trip(tsi_test_fixture* fixture) {
462   /* Initialization. */
463   GPR_ASSERT(fixture != nullptr);
464   GPR_ASSERT(fixture->config != nullptr);
465   tsi_test_frame_protector_config* config = fixture->config;
466   tsi_frame_protector* client_frame_protector = nullptr;
467   tsi_frame_protector* server_frame_protector = nullptr;
468   /* Perform handshake. */
469   tsi_test_do_handshake(fixture);
470   /* Create frame protectors.*/
471   size_t client_max_output_protected_frame_size =
472       config->client_max_output_protected_frame_size;
473   GPR_ASSERT(tsi_handshaker_result_create_frame_protector(
474                  fixture->client_result,
475                  client_max_output_protected_frame_size == 0
476                      ? nullptr
477                      : &client_max_output_protected_frame_size,
478                  &client_frame_protector) == TSI_OK);
479   size_t server_max_output_protected_frame_size =
480       config->server_max_output_protected_frame_size;
481   GPR_ASSERT(tsi_handshaker_result_create_frame_protector(
482                  fixture->server_result,
483                  server_max_output_protected_frame_size == 0
484                      ? nullptr
485                      : &server_max_output_protected_frame_size,
486                  &server_frame_protector) == TSI_OK);
487   tsi_test_do_ping_pong(config, fixture->channel, client_frame_protector,
488                         server_frame_protector);
489   /* Destroy server and client frame protectors. */
490   tsi_frame_protector_destroy(client_frame_protector);
491   tsi_frame_protector_destroy(server_frame_protector);
492 }
493 
generate_random_message(size_t size)494 static unsigned char* generate_random_message(size_t size) {
495   size_t i;
496   unsigned char chars[] = "abcdefghijklmnopqrstuvwxyz1234567890";
497   unsigned char* output =
498       static_cast<unsigned char*>(gpr_zalloc(sizeof(unsigned char) * size));
499   for (i = 0; i < size - 1; ++i) {
500     output[i] = chars[rand() % static_cast<int>(sizeof(chars) - 1)];
501   }
502   return output;
503 }
504 
tsi_test_frame_protector_config_create(bool use_default_read_buffer_allocated_size,bool use_default_message_buffer_allocated_size,bool use_default_protected_buffer_size,bool use_default_client_message,bool use_default_server_message,bool use_default_client_max_output_protected_frame_size,bool use_default_server_max_output_protected_frame_size)505 tsi_test_frame_protector_config* tsi_test_frame_protector_config_create(
506     bool use_default_read_buffer_allocated_size,
507     bool use_default_message_buffer_allocated_size,
508     bool use_default_protected_buffer_size, bool use_default_client_message,
509     bool use_default_server_message,
510     bool use_default_client_max_output_protected_frame_size,
511     bool use_default_server_max_output_protected_frame_size) {
512   tsi_test_frame_protector_config* config =
513       static_cast<tsi_test_frame_protector_config*>(
514           gpr_zalloc(sizeof(*config)));
515   /* Set the value for read_buffer_allocated_size. */
516   config->read_buffer_allocated_size =
517       use_default_read_buffer_allocated_size
518           ? TSI_TEST_DEFAULT_BUFFER_SIZE
519           : TSI_TEST_SMALL_READ_BUFFER_ALLOCATED_SIZE;
520   /* Set the value for message_buffer_allocated_size. */
521   config->message_buffer_allocated_size =
522       use_default_message_buffer_allocated_size
523           ? TSI_TEST_DEFAULT_BUFFER_SIZE
524           : TSI_TEST_SMALL_MESSAGE_BUFFER_ALLOCATED_SIZE;
525   /* Set the value for protected_buffer_size. */
526   config->protected_buffer_size = use_default_protected_buffer_size
527                                       ? TSI_TEST_DEFAULT_PROTECTED_BUFFER_SIZE
528                                       : TSI_TEST_SMALL_PROTECTED_BUFFER_SIZE;
529   /* Set the value for client message. */
530   config->client_message_size = use_default_client_message
531                                     ? TSI_TEST_BIG_MESSAGE_SIZE
532                                     : TSI_TEST_SMALL_MESSAGE_SIZE;
533   config->client_message =
534       use_default_client_message
535           ? generate_random_message(TSI_TEST_BIG_MESSAGE_SIZE)
536           : generate_random_message(TSI_TEST_SMALL_MESSAGE_SIZE);
537   /* Set the value for server message. */
538   config->server_message_size = use_default_server_message
539                                     ? TSI_TEST_BIG_MESSAGE_SIZE
540                                     : TSI_TEST_SMALL_MESSAGE_SIZE;
541   config->server_message =
542       use_default_server_message
543           ? generate_random_message(TSI_TEST_BIG_MESSAGE_SIZE)
544           : generate_random_message(TSI_TEST_SMALL_MESSAGE_SIZE);
545   /* Set the value for client max_output_protected_frame_size.
546      If it is 0, we pass NULL to tsi_handshaker_result_create_frame_protector(),
547      which then uses default protected frame size for it. */
548   config->client_max_output_protected_frame_size =
549       use_default_client_max_output_protected_frame_size
550           ? 0
551           : TSI_TEST_SMALL_CLIENT_MAX_OUTPUT_PROTECTED_FRAME_SIZE;
552   /* Set the value for server max_output_protected_frame_size.
553      If it is 0, we pass NULL to tsi_handshaker_result_create_frame_protector(),
554      which then uses default protected frame size for it. */
555   config->server_max_output_protected_frame_size =
556       use_default_server_max_output_protected_frame_size
557           ? 0
558           : TSI_TEST_SMALL_SERVER_MAX_OUTPUT_PROTECTED_FRAME_SIZE;
559   return config;
560 }
561 
tsi_test_frame_protector_config_set_buffer_size(tsi_test_frame_protector_config * config,size_t read_buffer_allocated_size,size_t message_buffer_allocated_size,size_t protected_buffer_size,size_t client_max_output_protected_frame_size,size_t server_max_output_protected_frame_size)562 void tsi_test_frame_protector_config_set_buffer_size(
563     tsi_test_frame_protector_config* config, size_t read_buffer_allocated_size,
564     size_t message_buffer_allocated_size, size_t protected_buffer_size,
565     size_t client_max_output_protected_frame_size,
566     size_t server_max_output_protected_frame_size) {
567   GPR_ASSERT(config != nullptr);
568   config->read_buffer_allocated_size = read_buffer_allocated_size;
569   config->message_buffer_allocated_size = message_buffer_allocated_size;
570   config->protected_buffer_size = protected_buffer_size;
571   config->client_max_output_protected_frame_size =
572       client_max_output_protected_frame_size;
573   config->server_max_output_protected_frame_size =
574       server_max_output_protected_frame_size;
575 }
576 
tsi_test_frame_protector_config_destroy(tsi_test_frame_protector_config * config)577 void tsi_test_frame_protector_config_destroy(
578     tsi_test_frame_protector_config* config) {
579   if (config == nullptr) {
580     return;
581   }
582   gpr_free(config->client_message);
583   gpr_free(config->server_message);
584   gpr_free(config);
585 }
586 
tsi_test_channel_create()587 static tsi_test_channel* tsi_test_channel_create() {
588   tsi_test_channel* channel =
589       static_cast<tsi_test_channel*>(gpr_zalloc(sizeof(*channel)));
590   channel->client_channel =
591       static_cast<uint8_t*>(gpr_zalloc(TSI_TEST_DEFAULT_CHANNEL_SIZE));
592   channel->server_channel =
593       static_cast<uint8_t*>(gpr_zalloc(TSI_TEST_DEFAULT_CHANNEL_SIZE));
594   channel->bytes_written_to_client_channel = 0;
595   channel->bytes_written_to_server_channel = 0;
596   channel->bytes_read_from_client_channel = 0;
597   channel->bytes_read_from_server_channel = 0;
598   return channel;
599 }
600 
tsi_test_channel_destroy(tsi_test_channel * channel)601 static void tsi_test_channel_destroy(tsi_test_channel* channel) {
602   if (channel == nullptr) {
603     return;
604   }
605   gpr_free(channel->client_channel);
606   gpr_free(channel->server_channel);
607   gpr_free(channel);
608 }
609 
tsi_test_fixture_init(tsi_test_fixture * fixture)610 void tsi_test_fixture_init(tsi_test_fixture* fixture) {
611   fixture->config = tsi_test_frame_protector_config_create(
612       true, true, true, true, true, true, true);
613   fixture->handshake_buffer_size = TSI_TEST_DEFAULT_BUFFER_SIZE;
614   fixture->channel = tsi_test_channel_create();
615   fixture->test_unused_bytes = true;
616   fixture->has_client_finished_first = false;
617   gpr_mu_init(&fixture->mu);
618   gpr_cv_init(&fixture->cv);
619   fixture->notified = false;
620 }
621 
tsi_test_fixture_destroy(tsi_test_fixture * fixture)622 void tsi_test_fixture_destroy(tsi_test_fixture* fixture) {
623   if (fixture == nullptr) {
624     return;
625   }
626   tsi_test_frame_protector_config_destroy(fixture->config);
627   tsi_handshaker_destroy(fixture->client_handshaker);
628   tsi_handshaker_destroy(fixture->server_handshaker);
629   tsi_handshaker_result_destroy(fixture->client_result);
630   tsi_handshaker_result_destroy(fixture->server_result);
631   tsi_test_channel_destroy(fixture->channel);
632   GPR_ASSERT(fixture->vtable != nullptr);
633   GPR_ASSERT(fixture->vtable->destruct != nullptr);
634   fixture->vtable->destruct(fixture);
635   gpr_mu_destroy(&fixture->mu);
636   gpr_cv_destroy(&fixture->cv);
637   gpr_free(fixture);
638 }
639 
tsi_test_frame_protector_fixture_create()640 tsi_test_frame_protector_fixture* tsi_test_frame_protector_fixture_create() {
641   tsi_test_frame_protector_fixture* fixture =
642       static_cast<tsi_test_frame_protector_fixture*>(
643           gpr_zalloc(sizeof(*fixture)));
644   fixture->config = tsi_test_frame_protector_config_create(
645       true, true, true, true, true, true, true);
646   fixture->channel = tsi_test_channel_create();
647   return fixture;
648 }
649 
tsi_test_frame_protector_fixture_init(tsi_test_frame_protector_fixture * fixture,tsi_frame_protector * client_frame_protector,tsi_frame_protector * server_frame_protector)650 void tsi_test_frame_protector_fixture_init(
651     tsi_test_frame_protector_fixture* fixture,
652     tsi_frame_protector* client_frame_protector,
653     tsi_frame_protector* server_frame_protector) {
654   GPR_ASSERT(fixture != nullptr);
655   fixture->client_frame_protector = client_frame_protector;
656   fixture->server_frame_protector = server_frame_protector;
657 }
658 
tsi_test_frame_protector_fixture_destroy(tsi_test_frame_protector_fixture * fixture)659 void tsi_test_frame_protector_fixture_destroy(
660     tsi_test_frame_protector_fixture* fixture) {
661   if (fixture == nullptr) {
662     return;
663   }
664   tsi_test_frame_protector_config_destroy(fixture->config);
665   tsi_test_channel_destroy(fixture->channel);
666   tsi_frame_protector_destroy(fixture->client_frame_protector);
667   tsi_frame_protector_destroy(fixture->server_frame_protector);
668   gpr_free(fixture);
669 }
670