• 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 "test/core/tsi/transport_security_test_lib.h"
20 
21 #include <grpc/grpc.h>
22 #include <grpc/support/alloc.h>
23 #include <openssl/asn1.h>
24 #include <openssl/bio.h>
25 #include <openssl/bn.h>
26 #include <openssl/evp.h>
27 #include <openssl/pem.h>
28 #include <openssl/rsa.h>
29 #include <openssl/x509.h>
30 #include <openssl/x509v3.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 
35 #include "absl/log/check.h"
36 #include "absl/strings/str_cat.h"
37 #include "src/core/lib/iomgr/error.h"
38 #include "src/core/util/crash.h"
39 #include "src/core/util/memory.h"
40 
notification_signal(tsi_test_fixture * fixture)41 static void notification_signal(tsi_test_fixture* fixture) {
42   gpr_mu_lock(&fixture->mu);
43   fixture->notified = true;
44   gpr_cv_signal(&fixture->cv);
45   gpr_mu_unlock(&fixture->mu);
46 }
47 
notification_wait(tsi_test_fixture * fixture)48 static void notification_wait(tsi_test_fixture* fixture) {
49   gpr_mu_lock(&fixture->mu);
50   while (!fixture->notified) {
51     gpr_cv_wait(&fixture->cv, &fixture->mu, gpr_inf_future(GPR_CLOCK_REALTIME));
52   }
53   fixture->notified = false;
54   gpr_mu_unlock(&fixture->mu);
55 }
56 
57 typedef struct handshaker_args {
58   tsi_test_fixture* fixture;
59   unsigned char* handshake_buffer;
60   size_t handshake_buffer_size;
61   bool is_client;
62   bool transferred_data;
63   bool appended_unused_bytes;
64   grpc_error_handle error;
65 } handshaker_args;
66 
handshaker_args_create(tsi_test_fixture * fixture,bool is_client)67 static handshaker_args* handshaker_args_create(tsi_test_fixture* fixture,
68                                                bool is_client) {
69   CHECK_NE(fixture, nullptr);
70   CHECK_NE(fixture->config, nullptr);
71   handshaker_args* args = new handshaker_args();
72   args->fixture = fixture;
73   args->handshake_buffer_size = fixture->handshake_buffer_size;
74   args->handshake_buffer =
75       static_cast<unsigned char*>(gpr_zalloc(args->handshake_buffer_size));
76   args->is_client = is_client;
77   args->error = absl::OkStatus();
78   return args;
79 }
80 
handshaker_args_destroy(handshaker_args * args)81 static void handshaker_args_destroy(handshaker_args* args) {
82   gpr_free(args->handshake_buffer);
83   delete args;
84 }
85 
86 static void do_handshaker_next(handshaker_args* args);
87 
setup_handshakers(tsi_test_fixture * fixture)88 static void setup_handshakers(tsi_test_fixture* fixture) {
89   CHECK_NE(fixture, nullptr);
90   CHECK_NE(fixture->vtable, nullptr);
91   CHECK_NE(fixture->vtable->setup_handshakers, nullptr);
92   fixture->vtable->setup_handshakers(fixture);
93 }
94 
check_unused_bytes(tsi_test_fixture * fixture)95 static void check_unused_bytes(tsi_test_fixture* fixture) {
96   tsi_handshaker_result* result_with_unused_bytes =
97       fixture->has_client_finished_first ? fixture->server_result
98                                          : fixture->client_result;
99   tsi_handshaker_result* result_without_unused_bytes =
100       fixture->has_client_finished_first ? fixture->client_result
101                                          : fixture->server_result;
102   const unsigned char* bytes = nullptr;
103   size_t bytes_size = 0;
104   CHECK(tsi_handshaker_result_get_unused_bytes(result_with_unused_bytes, &bytes,
105                                                &bytes_size) == TSI_OK);
106   CHECK_EQ(bytes_size, strlen(TSI_TEST_UNUSED_BYTES));
107   CHECK_EQ(memcmp(bytes, TSI_TEST_UNUSED_BYTES, bytes_size), 0);
108   CHECK(tsi_handshaker_result_get_unused_bytes(result_without_unused_bytes,
109                                                &bytes, &bytes_size) == TSI_OK);
110   CHECK_EQ(bytes_size, 0u);
111   CHECK_EQ(bytes, nullptr);
112 }
113 
check_handshake_results(tsi_test_fixture * fixture)114 static void check_handshake_results(tsi_test_fixture* fixture) {
115   CHECK_NE(fixture, nullptr);
116   CHECK_NE(fixture->vtable, nullptr);
117   CHECK_NE(fixture->vtable->check_handshaker_peers, nullptr);
118   // Check handshaker peers.
119   fixture->vtable->check_handshaker_peers(fixture);
120   // Check unused bytes.
121   if (fixture->test_unused_bytes) {
122     tsi_test_channel* channel = fixture->channel;
123     if (fixture->server_result != nullptr &&
124         fixture->client_result != nullptr) {
125       check_unused_bytes(fixture);
126     }
127     channel->bytes_written_to_server_channel = 0;
128     channel->bytes_written_to_client_channel = 0;
129     channel->bytes_read_from_client_channel = 0;
130     channel->bytes_read_from_server_channel = 0;
131   }
132 }
133 
send_bytes_to_peer(tsi_test_channel * test_channel,const unsigned char * buf,size_t buf_size,bool is_client)134 static void send_bytes_to_peer(tsi_test_channel* test_channel,
135                                const unsigned char* buf, size_t buf_size,
136                                bool is_client) {
137   CHECK_NE(test_channel, nullptr);
138   CHECK_NE(buf, nullptr);
139   uint8_t* channel =
140       is_client ? test_channel->server_channel : test_channel->client_channel;
141   CHECK_NE(channel, nullptr);
142   size_t* bytes_written = is_client
143                               ? &test_channel->bytes_written_to_server_channel
144                               : &test_channel->bytes_written_to_client_channel;
145   CHECK_NE(bytes_written, nullptr);
146   CHECK_LE(*bytes_written + buf_size,
147            static_cast<size_t>(TSI_TEST_DEFAULT_CHANNEL_SIZE));
148   // Write data to channel.
149   memcpy(channel + *bytes_written, buf, buf_size);
150   *bytes_written += buf_size;
151 }
152 
maybe_append_unused_bytes(handshaker_args * args)153 static void maybe_append_unused_bytes(handshaker_args* args) {
154   CHECK_NE(args, nullptr);
155   CHECK_NE(args->fixture, nullptr);
156   tsi_test_fixture* fixture = args->fixture;
157   if (fixture->test_unused_bytes && !args->appended_unused_bytes) {
158     args->appended_unused_bytes = true;
159     send_bytes_to_peer(
160         fixture->channel,
161         reinterpret_cast<const unsigned char*>(TSI_TEST_UNUSED_BYTES),
162         strlen(TSI_TEST_UNUSED_BYTES), args->is_client);
163     if (fixture->client_result != nullptr &&
164         fixture->server_result == nullptr) {
165       fixture->has_client_finished_first = true;
166     }
167   }
168 }
169 
receive_bytes_from_peer(tsi_test_channel * test_channel,unsigned char ** buf,size_t * buf_size,bool is_client)170 static void receive_bytes_from_peer(tsi_test_channel* test_channel,
171                                     unsigned char** buf, size_t* buf_size,
172                                     bool is_client) {
173   CHECK_NE(test_channel, nullptr);
174   CHECK_NE(*buf, nullptr);
175   CHECK_NE(buf_size, nullptr);
176   uint8_t* channel =
177       is_client ? test_channel->client_channel : test_channel->server_channel;
178   CHECK_NE(channel, nullptr);
179   size_t* bytes_read = is_client
180                            ? &test_channel->bytes_read_from_client_channel
181                            : &test_channel->bytes_read_from_server_channel;
182   size_t* bytes_written = is_client
183                               ? &test_channel->bytes_written_to_client_channel
184                               : &test_channel->bytes_written_to_server_channel;
185   CHECK_NE(bytes_read, nullptr);
186   CHECK_NE(bytes_written, nullptr);
187   size_t to_read = *buf_size < *bytes_written - *bytes_read
188                        ? *buf_size
189                        : *bytes_written - *bytes_read;
190   // Read data from channel.
191   memcpy(*buf, channel + *bytes_read, to_read);
192   *buf_size = to_read;
193   *bytes_read += to_read;
194 }
195 
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)196 void tsi_test_frame_protector_send_message_to_peer(
197     tsi_test_frame_protector_config* config, tsi_test_channel* channel,
198     tsi_frame_protector* protector, bool is_client) {
199   // Initialization.
200   CHECK_NE(config, nullptr);
201   CHECK_NE(channel, nullptr);
202   CHECK_NE(protector, nullptr);
203   unsigned char* protected_buffer =
204       static_cast<unsigned char*>(gpr_zalloc(config->protected_buffer_size));
205   size_t message_size =
206       is_client ? config->client_message_size : config->server_message_size;
207   uint8_t* message =
208       is_client ? config->client_message : config->server_message;
209   CHECK_NE(message, nullptr);
210   const unsigned char* message_bytes =
211       reinterpret_cast<unsigned char*>(message);
212   tsi_result result = TSI_OK;
213   // Do protect and send protected data to peer.
214   while (message_size > 0 && result == TSI_OK) {
215     size_t protected_buffer_size_to_send = config->protected_buffer_size;
216     size_t processed_message_size = message_size;
217     // Do protect.
218     result = tsi_frame_protector_protect(
219         protector, message_bytes, &processed_message_size, protected_buffer,
220         &protected_buffer_size_to_send);
221     CHECK(result == TSI_OK);
222     // Send protected data to peer.
223     send_bytes_to_peer(channel, protected_buffer, protected_buffer_size_to_send,
224                        is_client);
225     message_bytes += processed_message_size;
226     message_size -= processed_message_size;
227     // Flush if we're done.
228     if (message_size == 0) {
229       size_t still_pending_size;
230       do {
231         protected_buffer_size_to_send = config->protected_buffer_size;
232         result = tsi_frame_protector_protect_flush(
233             protector, protected_buffer, &protected_buffer_size_to_send,
234             &still_pending_size);
235         CHECK(result == TSI_OK);
236         send_bytes_to_peer(channel, protected_buffer,
237                            protected_buffer_size_to_send, is_client);
238       } while (still_pending_size > 0 && result == TSI_OK);
239       CHECK(result == TSI_OK);
240     }
241   }
242   CHECK(result == TSI_OK);
243   gpr_free(protected_buffer);
244 }
245 
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)246 void tsi_test_frame_protector_receive_message_from_peer(
247     tsi_test_frame_protector_config* config, tsi_test_channel* channel,
248     tsi_frame_protector* protector, unsigned char* message,
249     size_t* bytes_received, bool is_client) {
250   // Initialization.
251   CHECK_NE(config, nullptr);
252   CHECK_NE(channel, nullptr);
253   CHECK_NE(protector, nullptr);
254   CHECK_NE(message, nullptr);
255   CHECK_NE(bytes_received, nullptr);
256   size_t read_offset = 0;
257   size_t message_offset = 0;
258   size_t read_from_peer_size = 0;
259   tsi_result result = TSI_OK;
260   bool done = false;
261   unsigned char* read_buffer = static_cast<unsigned char*>(
262       gpr_zalloc(config->read_buffer_allocated_size));
263   unsigned char* message_buffer = static_cast<unsigned char*>(
264       gpr_zalloc(config->message_buffer_allocated_size));
265   // Do unprotect on data received from peer.
266   while (!done && result == TSI_OK) {
267     // Receive data from peer.
268     if (read_from_peer_size == 0) {
269       read_from_peer_size = config->read_buffer_allocated_size;
270       receive_bytes_from_peer(channel, &read_buffer, &read_from_peer_size,
271                               is_client);
272       read_offset = 0;
273     }
274     if (read_from_peer_size == 0) {
275       done = true;
276     }
277     // Do unprotect.
278     size_t message_buffer_size;
279     do {
280       message_buffer_size = config->message_buffer_allocated_size;
281       size_t processed_size = read_from_peer_size;
282       result = tsi_frame_protector_unprotect(
283           protector, read_buffer + read_offset, &processed_size, message_buffer,
284           &message_buffer_size);
285       CHECK(result == TSI_OK);
286       if (message_buffer_size > 0) {
287         memcpy(message + message_offset, message_buffer, message_buffer_size);
288         message_offset += message_buffer_size;
289       }
290       read_offset += processed_size;
291       read_from_peer_size -= processed_size;
292     } while ((read_from_peer_size > 0 || message_buffer_size > 0) &&
293              result == TSI_OK);
294     CHECK(result == TSI_OK);
295   }
296   CHECK(result == TSI_OK);
297   *bytes_received = message_offset;
298   gpr_free(read_buffer);
299   gpr_free(message_buffer);
300 }
301 
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)302 grpc_error_handle on_handshake_next_done(
303     tsi_result result, void* user_data, const unsigned char* bytes_to_send,
304     size_t bytes_to_send_size, tsi_handshaker_result* handshaker_result) {
305   handshaker_args* args = static_cast<handshaker_args*>(user_data);
306   CHECK_NE(args, nullptr);
307   CHECK_NE(args->fixture, nullptr);
308   tsi_test_fixture* fixture = args->fixture;
309   grpc_error_handle error;
310   // Read more data if we need to.
311   if (result == TSI_INCOMPLETE_DATA) {
312     CHECK_EQ(bytes_to_send_size, 0u);
313     notification_signal(fixture);
314     return error;
315   }
316   if (result != TSI_OK) {
317     notification_signal(fixture);
318     return GRPC_ERROR_CREATE(
319         absl::StrCat("Handshake failed (", tsi_result_to_string(result), ")"));
320   }
321   // Update handshaker result.
322   if (handshaker_result != nullptr) {
323     tsi_handshaker_result** result_to_write =
324         args->is_client ? &fixture->client_result : &fixture->server_result;
325     CHECK_EQ(*result_to_write, nullptr);
326     *result_to_write = handshaker_result;
327   }
328   // Send data to peer, if needed.
329   if (bytes_to_send_size > 0) {
330     send_bytes_to_peer(fixture->channel, bytes_to_send, bytes_to_send_size,
331                        args->is_client);
332     args->transferred_data = true;
333   }
334   if (handshaker_result != nullptr) {
335     maybe_append_unused_bytes(args);
336   }
337   notification_signal(fixture);
338   return error;
339 }
340 
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)341 static void on_handshake_next_done_wrapper(
342     tsi_result result, void* user_data, const unsigned char* bytes_to_send,
343     size_t bytes_to_send_size, tsi_handshaker_result* handshaker_result) {
344   handshaker_args* args = static_cast<handshaker_args*>(user_data);
345   args->error = on_handshake_next_done(result, user_data, bytes_to_send,
346                                        bytes_to_send_size, handshaker_result);
347 }
348 
is_handshake_finished_properly(handshaker_args * args)349 static bool is_handshake_finished_properly(handshaker_args* args) {
350   CHECK_NE(args, nullptr);
351   CHECK_NE(args->fixture, nullptr);
352   tsi_test_fixture* fixture = args->fixture;
353   return (args->is_client && fixture->client_result != nullptr) ||
354          (!args->is_client && fixture->server_result != nullptr);
355 }
356 
do_handshaker_next(handshaker_args * args)357 static void do_handshaker_next(handshaker_args* args) {
358   // Initialization.
359   CHECK_NE(args, nullptr);
360   CHECK_NE(args->fixture, nullptr);
361   tsi_test_fixture* fixture = args->fixture;
362   tsi_handshaker* handshaker =
363       args->is_client ? fixture->client_handshaker : fixture->server_handshaker;
364   if (is_handshake_finished_properly(args)) {
365     return;
366   }
367   tsi_handshaker_result* handshaker_result = nullptr;
368   unsigned char* bytes_to_send = nullptr;
369   size_t bytes_to_send_size = 0;
370   tsi_result result = TSI_OK;
371   // Receive data from peer, if available.
372   do {
373     size_t buf_size = args->handshake_buffer_size;
374     receive_bytes_from_peer(fixture->channel, &args->handshake_buffer,
375                             &buf_size, args->is_client);
376     if (buf_size > 0) {
377       args->transferred_data = true;
378     }
379     // Perform handshaker next.
380     result = tsi_handshaker_next(
381         handshaker, args->handshake_buffer, buf_size,
382         const_cast<const unsigned char**>(&bytes_to_send), &bytes_to_send_size,
383         &handshaker_result, &on_handshake_next_done_wrapper, args);
384     if (result != TSI_ASYNC) {
385       args->error = on_handshake_next_done(
386           result, args, bytes_to_send, bytes_to_send_size, handshaker_result);
387       if (!args->error.ok()) {
388         return;
389       }
390     }
391   } while (result == TSI_INCOMPLETE_DATA);
392   notification_wait(fixture);
393 }
394 
tsi_test_do_handshake(tsi_test_fixture * fixture)395 void tsi_test_do_handshake(tsi_test_fixture* fixture) {
396   // Initialization.
397   setup_handshakers(fixture);
398   handshaker_args* client_args =
399       handshaker_args_create(fixture, true /* is_client */);
400   handshaker_args* server_args =
401       handshaker_args_create(fixture, false /* is_client */);
402   // Do handshake.
403   do {
404     client_args->transferred_data = false;
405     server_args->transferred_data = false;
406     do_handshaker_next(client_args);
407     if (!client_args->error.ok()) {
408       break;
409     }
410     do_handshaker_next(server_args);
411     if (!server_args->error.ok()) {
412       break;
413     }
414     // If this assertion is hit, this is likely an indication that the client
415     // and server handshakers are hanging, each thinking that the other is
416     // responsible for sending the next chunk of bytes to the other. This can
417     // happen e.g. when a bug in the handshaker code results in some bytes being
418     // dropped instead of passed to the BIO or SSL objects.
419     CHECK(client_args->transferred_data || server_args->transferred_data);
420   } while (fixture->client_result == nullptr ||
421            fixture->server_result == nullptr);
422   // Verify handshake results.
423   check_handshake_results(fixture);
424   // Cleanup.
425   handshaker_args_destroy(client_args);
426   handshaker_args_destroy(server_args);
427 }
428 
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)429 static void tsi_test_do_ping_pong(tsi_test_frame_protector_config* config,
430                                   tsi_test_channel* channel,
431                                   tsi_frame_protector* client_frame_protector,
432                                   tsi_frame_protector* server_frame_protector) {
433   CHECK_NE(config, nullptr);
434   CHECK_NE(channel, nullptr);
435   CHECK_NE(client_frame_protector, nullptr);
436   CHECK_NE(server_frame_protector, nullptr);
437   // Client sends a message to server.
438   tsi_test_frame_protector_send_message_to_peer(
439       config, channel, client_frame_protector, true /* is_client */);
440   unsigned char* server_received_message =
441       static_cast<unsigned char*>(gpr_zalloc(TSI_TEST_DEFAULT_CHANNEL_SIZE));
442   size_t server_received_message_size = 0;
443   tsi_test_frame_protector_receive_message_from_peer(
444       config, channel, server_frame_protector, server_received_message,
445       &server_received_message_size, false /* is_client */);
446   CHECK(config->client_message_size == server_received_message_size);
447   CHECK_EQ(memcmp(config->client_message, server_received_message,
448                   server_received_message_size),
449            0);
450   // Server sends a message to client.
451   tsi_test_frame_protector_send_message_to_peer(
452       config, channel, server_frame_protector, false /* is_client */);
453   unsigned char* client_received_message =
454       static_cast<unsigned char*>(gpr_zalloc(TSI_TEST_DEFAULT_CHANNEL_SIZE));
455   size_t client_received_message_size = 0;
456   tsi_test_frame_protector_receive_message_from_peer(
457       config, channel, client_frame_protector, client_received_message,
458       &client_received_message_size, true /* is_client */);
459   CHECK_EQ(config->server_message_size, client_received_message_size);
460   CHECK_EQ(memcmp(config->server_message, client_received_message,
461                   client_received_message_size),
462            0);
463   gpr_free(server_received_message);
464   gpr_free(client_received_message);
465 }
466 
tsi_test_frame_protector_do_round_trip_no_handshake(tsi_test_frame_protector_fixture * fixture)467 void tsi_test_frame_protector_do_round_trip_no_handshake(
468     tsi_test_frame_protector_fixture* fixture) {
469   CHECK_NE(fixture, nullptr);
470   tsi_test_do_ping_pong(fixture->config, fixture->channel,
471                         fixture->client_frame_protector,
472                         fixture->server_frame_protector);
473 }
474 
tsi_test_do_round_trip(tsi_test_fixture * fixture)475 void tsi_test_do_round_trip(tsi_test_fixture* fixture) {
476   // Initialization.
477   CHECK_NE(fixture, nullptr);
478   CHECK_NE(fixture->config, nullptr);
479   tsi_test_frame_protector_config* config = fixture->config;
480   tsi_frame_protector* client_frame_protector = nullptr;
481   tsi_frame_protector* server_frame_protector = nullptr;
482   // Perform handshake.
483   tsi_test_do_handshake(fixture);
484   // Create frame protectors.
485   size_t client_max_output_protected_frame_size =
486       config->client_max_output_protected_frame_size;
487   CHECK(tsi_handshaker_result_create_frame_protector(
488             fixture->client_result,
489             client_max_output_protected_frame_size == 0
490                 ? nullptr
491                 : &client_max_output_protected_frame_size,
492             &client_frame_protector) == TSI_OK);
493   size_t server_max_output_protected_frame_size =
494       config->server_max_output_protected_frame_size;
495   CHECK(tsi_handshaker_result_create_frame_protector(
496             fixture->server_result,
497             server_max_output_protected_frame_size == 0
498                 ? nullptr
499                 : &server_max_output_protected_frame_size,
500             &server_frame_protector) == TSI_OK);
501   tsi_test_do_ping_pong(config, fixture->channel, client_frame_protector,
502                         server_frame_protector);
503   // Destroy server and client frame protectors.
504   tsi_frame_protector_destroy(client_frame_protector);
505   tsi_frame_protector_destroy(server_frame_protector);
506 }
507 
generate_random_message(size_t size)508 static unsigned char* generate_random_message(size_t size) {
509   size_t i;
510   unsigned char chars[] = "abcdefghijklmnopqrstuvwxyz1234567890";
511   unsigned char* output =
512       static_cast<unsigned char*>(gpr_zalloc(sizeof(unsigned char) * size));
513   for (i = 0; i < size - 1; ++i) {
514     output[i] = chars[rand() % static_cast<int>(sizeof(chars) - 1)];
515   }
516   return output;
517 }
518 
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)519 tsi_test_frame_protector_config* tsi_test_frame_protector_config_create(
520     bool use_default_read_buffer_allocated_size,
521     bool use_default_message_buffer_allocated_size,
522     bool use_default_protected_buffer_size, bool use_default_client_message,
523     bool use_default_server_message,
524     bool use_default_client_max_output_protected_frame_size,
525     bool use_default_server_max_output_protected_frame_size) {
526   tsi_test_frame_protector_config* config =
527       static_cast<tsi_test_frame_protector_config*>(
528           gpr_zalloc(sizeof(*config)));
529   // Set the value for read_buffer_allocated_size.
530   config->read_buffer_allocated_size =
531       use_default_read_buffer_allocated_size
532           ? TSI_TEST_DEFAULT_BUFFER_SIZE
533           : TSI_TEST_SMALL_READ_BUFFER_ALLOCATED_SIZE;
534   // Set the value for message_buffer_allocated_size.
535   config->message_buffer_allocated_size =
536       use_default_message_buffer_allocated_size
537           ? TSI_TEST_DEFAULT_BUFFER_SIZE
538           : TSI_TEST_SMALL_MESSAGE_BUFFER_ALLOCATED_SIZE;
539   // Set the value for protected_buffer_size.
540   config->protected_buffer_size = use_default_protected_buffer_size
541                                       ? TSI_TEST_DEFAULT_PROTECTED_BUFFER_SIZE
542                                       : TSI_TEST_SMALL_PROTECTED_BUFFER_SIZE;
543   // Set the value for client message.
544   config->client_message_size = use_default_client_message
545                                     ? TSI_TEST_BIG_MESSAGE_SIZE
546                                     : TSI_TEST_SMALL_MESSAGE_SIZE;
547   config->client_message =
548       use_default_client_message
549           ? generate_random_message(TSI_TEST_BIG_MESSAGE_SIZE)
550           : generate_random_message(TSI_TEST_SMALL_MESSAGE_SIZE);
551   // Set the value for server message.
552   config->server_message_size = use_default_server_message
553                                     ? TSI_TEST_BIG_MESSAGE_SIZE
554                                     : TSI_TEST_SMALL_MESSAGE_SIZE;
555   config->server_message =
556       use_default_server_message
557           ? generate_random_message(TSI_TEST_BIG_MESSAGE_SIZE)
558           : generate_random_message(TSI_TEST_SMALL_MESSAGE_SIZE);
559   // Set the value for client max_output_protected_frame_size.
560   // If it is 0, we pass NULL to tsi_handshaker_result_create_frame_protector(),
561   // which then uses default protected frame size for it.
562   config->client_max_output_protected_frame_size =
563       use_default_client_max_output_protected_frame_size
564           ? 0
565           : TSI_TEST_SMALL_CLIENT_MAX_OUTPUT_PROTECTED_FRAME_SIZE;
566   // Set the value for server max_output_protected_frame_size.
567   // If it is 0, we pass NULL to tsi_handshaker_result_create_frame_protector(),
568   // which then uses default protected frame size for it.
569   config->server_max_output_protected_frame_size =
570       use_default_server_max_output_protected_frame_size
571           ? 0
572           : TSI_TEST_SMALL_SERVER_MAX_OUTPUT_PROTECTED_FRAME_SIZE;
573   return config;
574 }
575 
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)576 void tsi_test_frame_protector_config_set_buffer_size(
577     tsi_test_frame_protector_config* config, size_t read_buffer_allocated_size,
578     size_t message_buffer_allocated_size, size_t protected_buffer_size,
579     size_t client_max_output_protected_frame_size,
580     size_t server_max_output_protected_frame_size) {
581   CHECK_NE(config, nullptr);
582   config->read_buffer_allocated_size = read_buffer_allocated_size;
583   config->message_buffer_allocated_size = message_buffer_allocated_size;
584   config->protected_buffer_size = protected_buffer_size;
585   config->client_max_output_protected_frame_size =
586       client_max_output_protected_frame_size;
587   config->server_max_output_protected_frame_size =
588       server_max_output_protected_frame_size;
589 }
590 
tsi_test_frame_protector_config_destroy(tsi_test_frame_protector_config * config)591 void tsi_test_frame_protector_config_destroy(
592     tsi_test_frame_protector_config* config) {
593   if (config == nullptr) {
594     return;
595   }
596   gpr_free(config->client_message);
597   gpr_free(config->server_message);
598   gpr_free(config);
599 }
600 
tsi_test_channel_create()601 static tsi_test_channel* tsi_test_channel_create() {
602   tsi_test_channel* channel = grpc_core::Zalloc<tsi_test_channel>();
603   channel->client_channel =
604       static_cast<uint8_t*>(gpr_zalloc(TSI_TEST_DEFAULT_CHANNEL_SIZE));
605   channel->server_channel =
606       static_cast<uint8_t*>(gpr_zalloc(TSI_TEST_DEFAULT_CHANNEL_SIZE));
607   channel->bytes_written_to_client_channel = 0;
608   channel->bytes_written_to_server_channel = 0;
609   channel->bytes_read_from_client_channel = 0;
610   channel->bytes_read_from_server_channel = 0;
611   return channel;
612 }
613 
tsi_test_channel_destroy(tsi_test_channel * channel)614 static void tsi_test_channel_destroy(tsi_test_channel* channel) {
615   if (channel == nullptr) {
616     return;
617   }
618   gpr_free(channel->client_channel);
619   gpr_free(channel->server_channel);
620   gpr_free(channel);
621 }
622 
tsi_test_fixture_init(tsi_test_fixture * fixture)623 void tsi_test_fixture_init(tsi_test_fixture* fixture) {
624   memset(fixture, 0, sizeof(tsi_test_fixture));
625   fixture->config = tsi_test_frame_protector_config_create(
626       true, true, true, true, true, true, true);
627   fixture->handshake_buffer_size = TSI_TEST_DEFAULT_BUFFER_SIZE;
628   fixture->channel = tsi_test_channel_create();
629   fixture->test_unused_bytes = true;
630   fixture->has_client_finished_first = false;
631   gpr_mu_init(&fixture->mu);
632   gpr_cv_init(&fixture->cv);
633   fixture->notified = false;
634 }
635 
tsi_test_fixture_destroy(tsi_test_fixture * fixture)636 void tsi_test_fixture_destroy(tsi_test_fixture* fixture) {
637   if (fixture == nullptr) {
638     return;
639   }
640   tsi_test_frame_protector_config_destroy(fixture->config);
641   tsi_handshaker_destroy(fixture->client_handshaker);
642   tsi_handshaker_destroy(fixture->server_handshaker);
643   tsi_handshaker_result_destroy(fixture->client_result);
644   tsi_handshaker_result_destroy(fixture->server_result);
645   tsi_test_channel_destroy(fixture->channel);
646   CHECK_NE(fixture->vtable, nullptr);
647   CHECK_NE(fixture->vtable->destruct, nullptr);
648   gpr_mu_destroy(&fixture->mu);
649   gpr_cv_destroy(&fixture->cv);
650   fixture->vtable->destruct(fixture);
651 }
652 
tsi_test_frame_protector_fixture_create()653 tsi_test_frame_protector_fixture* tsi_test_frame_protector_fixture_create() {
654   tsi_test_frame_protector_fixture* fixture =
655       static_cast<tsi_test_frame_protector_fixture*>(
656           gpr_zalloc(sizeof(*fixture)));
657   fixture->config = tsi_test_frame_protector_config_create(
658       true, true, true, true, true, true, true);
659   fixture->channel = tsi_test_channel_create();
660   return fixture;
661 }
662 
tsi_test_frame_protector_fixture_init(tsi_test_frame_protector_fixture * fixture,tsi_frame_protector * client_frame_protector,tsi_frame_protector * server_frame_protector)663 void tsi_test_frame_protector_fixture_init(
664     tsi_test_frame_protector_fixture* fixture,
665     tsi_frame_protector* client_frame_protector,
666     tsi_frame_protector* server_frame_protector) {
667   CHECK_NE(fixture, nullptr);
668   fixture->client_frame_protector = client_frame_protector;
669   fixture->server_frame_protector = server_frame_protector;
670 }
671 
tsi_test_frame_protector_fixture_destroy(tsi_test_frame_protector_fixture * fixture)672 void tsi_test_frame_protector_fixture_destroy(
673     tsi_test_frame_protector_fixture* fixture) {
674   if (fixture == nullptr) {
675     return;
676   }
677   tsi_test_frame_protector_config_destroy(fixture->config);
678   tsi_test_channel_destroy(fixture->channel);
679   tsi_frame_protector_destroy(fixture->client_frame_protector);
680   tsi_frame_protector_destroy(fixture->server_frame_protector);
681   gpr_free(fixture);
682 }
683 
GenerateSelfSignedCertificate(const SelfSignedCertificateOptions & options)684 std::string GenerateSelfSignedCertificate(
685     const SelfSignedCertificateOptions& options) {
686   // Generate an RSA keypair.
687   BIGNUM* bignum = BN_new();
688   CHECK(BN_set_word(bignum, RSA_F4));
689   BIGNUM* n = BN_new();
690   CHECK(BN_set_word(n, 2048));
691   EVP_PKEY* key = EVP_PKEY_new();
692   // Create the X509 object.
693   X509* x509 = X509_new();
694 
695 #if OPENSSL_VERSION_NUMBER < 0x30000000L
696   RSA* rsa = RSA_new();
697   CHECK(RSA_generate_key_ex(rsa, /*key_size=*/2048, bignum, /*cb=*/nullptr));
698   CHECK(EVP_PKEY_assign_RSA(key, rsa));
699   CHECK(X509_set_version(x509, 2));  // TODO(gtcooke94) make a const
700 #else
701   key = EVP_RSA_gen(2048);
702   CHECK(X509_set_version(x509, X509_VERSION_3));
703 #endif
704   // Set the not_before/after fields to infinite past/future. The value for
705   // infinite future is from RFC 5280 Section 4.1.2.5.1.
706   ASN1_UTCTIME* infinite_past = ASN1_UTCTIME_new();
707   CHECK(ASN1_UTCTIME_set(infinite_past, /*posix_time=*/0));
708 #if OPENSSL_VERSION_NUMBER < 0x10100000
709   CHECK(X509_set_notBefore(x509, infinite_past));
710 #else
711   CHECK(X509_set1_notBefore(x509, infinite_past));
712 #endif
713   ASN1_UTCTIME_free(infinite_past);
714   ASN1_GENERALIZEDTIME* infinite_future = ASN1_GENERALIZEDTIME_new();
715   CHECK(ASN1_GENERALIZEDTIME_set_string(infinite_future, "99991231235959Z"));
716 #if OPENSSL_VERSION_NUMBER < 0x10100000
717   CHECK(X509_set_notAfter(x509, infinite_future));
718 #else
719   CHECK(X509_set1_notAfter(x509, infinite_future));
720 #endif
721   ASN1_GENERALIZEDTIME_free(infinite_future);
722   // Set the subject DN.
723   X509_NAME* subject_name = X509_NAME_new();
724   CHECK(X509_NAME_add_entry_by_txt(
725       subject_name, /*field=*/"CN", MBSTRING_ASC,
726       reinterpret_cast<const unsigned char*>(options.common_name.c_str()),
727       /*len=*/-1, /*loc=*/-1,
728       /*set=*/0));
729   CHECK(X509_NAME_add_entry_by_txt(
730       subject_name, /*field=*/"O", MBSTRING_ASC,
731       reinterpret_cast<const unsigned char*>(options.organization.c_str()),
732       /*len=*/-1, /*loc=*/-1,
733       /*set=*/0));
734   CHECK(X509_NAME_add_entry_by_txt(subject_name, /*field=*/"OU", MBSTRING_ASC,
735                                    reinterpret_cast<const unsigned char*>(
736                                        options.organizational_unit.c_str()),
737                                    /*len=*/-1, /*loc=*/-1,
738                                    /*set=*/0));
739   CHECK(X509_set_subject_name(x509, subject_name));
740   X509_NAME_free(subject_name);
741   // Set the public key and sign the certificate.
742   CHECK(X509_set_pubkey(x509, key));
743   CHECK(X509_sign(x509, key, EVP_sha256()));
744   // Convert to PEM.
745   BIO* bio = BIO_new(BIO_s_mem());
746   CHECK(PEM_write_bio_X509(bio, x509));
747   const uint8_t* data = nullptr;
748   size_t len = 0;
749 
750 #ifdef OPENSSL_IS_BORINGSSL
751   CHECK(BIO_mem_contents(bio, &data, &len));
752 #else
753   len = BIO_get_mem_data(bio, &data);
754 #endif
755   std::string pem = std::string(reinterpret_cast<const char*>(data), len);
756   // Cleanup all of the OpenSSL objects and return the PEM-encoded cert.
757   EVP_PKEY_free(key);
758   X509_free(x509);
759   BIO_free(bio);
760   BN_free(bignum);
761   BN_free(n);
762   return pem;
763 }
764 
ReadPemCert(absl::string_view pem_cert)765 X509* ReadPemCert(absl::string_view pem_cert) {
766   BIO* cert_bio =
767       BIO_new_mem_buf(pem_cert.data(), static_cast<int>(pem_cert.size()));
768   // Errors on BIO
769   if (cert_bio == nullptr) {
770     return nullptr;
771   }
772   X509* cert = PEM_read_bio_X509(cert_bio, nullptr, nullptr, nullptr);
773   BIO_free(cert_bio);
774   return cert;
775 }
776 
ReadCrl(absl::string_view crl_pem)777 X509_CRL* ReadCrl(absl::string_view crl_pem) {
778   BIO* crl_bio =
779       BIO_new_mem_buf(crl_pem.data(), static_cast<int>(crl_pem.size()));
780   // Errors on BIO
781   if (crl_bio == nullptr) {
782     return nullptr;
783   }
784   X509_CRL* crl = PEM_read_bio_X509_CRL(crl_bio, nullptr, nullptr, nullptr);
785   BIO_free(crl_bio);
786   return crl;
787 }
788