xref: /aosp_15_r20/external/grpc-grpc/test/core/tsi/transport_security_test_lib.cc (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
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 <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 
25 #include <openssl/asn1.h>
26 #include <openssl/bio.h>
27 #include <openssl/bn.h>
28 #include <openssl/evp.h>
29 #include <openssl/pem.h>
30 #include <openssl/rsa.h>
31 #include <openssl/x509.h>
32 #include <openssl/x509v3.h>
33 
34 #include <grpc/grpc.h>
35 #include <grpc/support/alloc.h>
36 #include <grpc/support/log.h>
37 
38 #include "src/core/lib/gprpp/crash.h"
39 #include "src/core/lib/gprpp/memory.h"
40 #include "src/core/lib/security/transport/tsi_error.h"
41 
notification_signal(tsi_test_fixture * fixture)42 static void notification_signal(tsi_test_fixture* fixture) {
43   gpr_mu_lock(&fixture->mu);
44   fixture->notified = true;
45   gpr_cv_signal(&fixture->cv);
46   gpr_mu_unlock(&fixture->mu);
47 }
48 
notification_wait(tsi_test_fixture * fixture)49 static void notification_wait(tsi_test_fixture* fixture) {
50   gpr_mu_lock(&fixture->mu);
51   while (!fixture->notified) {
52     gpr_cv_wait(&fixture->cv, &fixture->mu, gpr_inf_future(GPR_CLOCK_REALTIME));
53   }
54   fixture->notified = false;
55   gpr_mu_unlock(&fixture->mu);
56 }
57 
58 typedef struct handshaker_args {
59   tsi_test_fixture* fixture;
60   unsigned char* handshake_buffer;
61   size_t handshake_buffer_size;
62   bool is_client;
63   bool transferred_data;
64   bool appended_unused_bytes;
65   grpc_error_handle error;
66 } handshaker_args;
67 
handshaker_args_create(tsi_test_fixture * fixture,bool is_client)68 static handshaker_args* handshaker_args_create(tsi_test_fixture* fixture,
69                                                bool is_client) {
70   GPR_ASSERT(fixture != nullptr);
71   GPR_ASSERT(fixture->config != nullptr);
72   handshaker_args* args = new handshaker_args();
73   args->fixture = fixture;
74   args->handshake_buffer_size = fixture->handshake_buffer_size;
75   args->handshake_buffer =
76       static_cast<unsigned char*>(gpr_zalloc(args->handshake_buffer_size));
77   args->is_client = is_client;
78   args->error = absl::OkStatus();
79   return args;
80 }
81 
handshaker_args_destroy(handshaker_args * args)82 static void handshaker_args_destroy(handshaker_args* args) {
83   gpr_free(args->handshake_buffer);
84   delete args;
85 }
86 
87 static void do_handshaker_next(handshaker_args* args);
88 
setup_handshakers(tsi_test_fixture * fixture)89 static void setup_handshakers(tsi_test_fixture* fixture) {
90   GPR_ASSERT(fixture != nullptr);
91   GPR_ASSERT(fixture->vtable != nullptr);
92   GPR_ASSERT(fixture->vtable->setup_handshakers != nullptr);
93   fixture->vtable->setup_handshakers(fixture);
94 }
95 
check_unused_bytes(tsi_test_fixture * fixture)96 static void check_unused_bytes(tsi_test_fixture* fixture) {
97   tsi_handshaker_result* result_with_unused_bytes =
98       fixture->has_client_finished_first ? fixture->server_result
99                                          : fixture->client_result;
100   tsi_handshaker_result* result_without_unused_bytes =
101       fixture->has_client_finished_first ? fixture->client_result
102                                          : fixture->server_result;
103   const unsigned char* bytes = nullptr;
104   size_t bytes_size = 0;
105   GPR_ASSERT(tsi_handshaker_result_get_unused_bytes(
106                  result_with_unused_bytes, &bytes, &bytes_size) == TSI_OK);
107   GPR_ASSERT(bytes_size == strlen(TSI_TEST_UNUSED_BYTES));
108   GPR_ASSERT(memcmp(bytes, TSI_TEST_UNUSED_BYTES, bytes_size) == 0);
109   GPR_ASSERT(tsi_handshaker_result_get_unused_bytes(
110                  result_without_unused_bytes, &bytes, &bytes_size) == TSI_OK);
111   GPR_ASSERT(bytes_size == 0);
112   GPR_ASSERT(bytes == nullptr);
113 }
114 
check_handshake_results(tsi_test_fixture * fixture)115 static void check_handshake_results(tsi_test_fixture* fixture) {
116   GPR_ASSERT(fixture != nullptr);
117   GPR_ASSERT(fixture->vtable != nullptr);
118   GPR_ASSERT(fixture->vtable->check_handshaker_peers != nullptr);
119   // Check handshaker peers.
120   fixture->vtable->check_handshaker_peers(fixture);
121   // Check unused bytes.
122   if (fixture->test_unused_bytes) {
123     tsi_test_channel* channel = fixture->channel;
124     if (fixture->server_result != nullptr &&
125         fixture->client_result != nullptr) {
126       check_unused_bytes(fixture);
127     }
128     channel->bytes_written_to_server_channel = 0;
129     channel->bytes_written_to_client_channel = 0;
130     channel->bytes_read_from_client_channel = 0;
131     channel->bytes_read_from_server_channel = 0;
132   }
133 }
134 
send_bytes_to_peer(tsi_test_channel * test_channel,const unsigned char * buf,size_t buf_size,bool is_client)135 static void send_bytes_to_peer(tsi_test_channel* test_channel,
136                                const unsigned char* buf, size_t buf_size,
137                                bool is_client) {
138   GPR_ASSERT(test_channel != nullptr);
139   GPR_ASSERT(buf != nullptr);
140   uint8_t* channel =
141       is_client ? test_channel->server_channel : test_channel->client_channel;
142   GPR_ASSERT(channel != nullptr);
143   size_t* bytes_written = is_client
144                               ? &test_channel->bytes_written_to_server_channel
145                               : &test_channel->bytes_written_to_client_channel;
146   GPR_ASSERT(bytes_written != nullptr);
147   GPR_ASSERT(*bytes_written + buf_size <= 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   GPR_ASSERT(args != nullptr);
155   GPR_ASSERT(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   GPR_ASSERT(test_channel != nullptr);
174   GPR_ASSERT(*buf != nullptr);
175   GPR_ASSERT(buf_size != nullptr);
176   uint8_t* channel =
177       is_client ? test_channel->client_channel : test_channel->server_channel;
178   GPR_ASSERT(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   GPR_ASSERT(bytes_read != nullptr);
186   GPR_ASSERT(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   GPR_ASSERT(config != nullptr);
201   GPR_ASSERT(channel != nullptr);
202   GPR_ASSERT(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   GPR_ASSERT(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     GPR_ASSERT(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         GPR_ASSERT(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       GPR_ASSERT(result == TSI_OK);
240     }
241   }
242   GPR_ASSERT(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   GPR_ASSERT(config != nullptr);
252   GPR_ASSERT(channel != nullptr);
253   GPR_ASSERT(protector != nullptr);
254   GPR_ASSERT(message != nullptr);
255   GPR_ASSERT(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       GPR_ASSERT(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     GPR_ASSERT(result == TSI_OK);
295   }
296   GPR_ASSERT(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   GPR_ASSERT(args != nullptr);
307   GPR_ASSERT(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     GPR_ASSERT(bytes_to_send_size == 0);
313     notification_signal(fixture);
314     return error;
315   }
316   if (result != TSI_OK) {
317     notification_signal(fixture);
318     return grpc_set_tsi_error_result(GRPC_ERROR_CREATE("Handshake failed"),
319                                      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     GPR_ASSERT(*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   GPR_ASSERT(args != nullptr);
351   GPR_ASSERT(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   GPR_ASSERT(args != nullptr);
360   GPR_ASSERT(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     // Peform 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   // Initializaiton.
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     GPR_ASSERT(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   GPR_ASSERT(config != nullptr);
434   GPR_ASSERT(channel != nullptr);
435   GPR_ASSERT(client_frame_protector != nullptr);
436   GPR_ASSERT(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   GPR_ASSERT(config->client_message_size == server_received_message_size);
447   GPR_ASSERT(memcmp(config->client_message, server_received_message,
448                     server_received_message_size) == 0);
449   // Server sends a message to client.
450   tsi_test_frame_protector_send_message_to_peer(
451       config, channel, server_frame_protector, false /* is_client */);
452   unsigned char* client_received_message =
453       static_cast<unsigned char*>(gpr_zalloc(TSI_TEST_DEFAULT_CHANNEL_SIZE));
454   size_t client_received_message_size = 0;
455   tsi_test_frame_protector_receive_message_from_peer(
456       config, channel, client_frame_protector, client_received_message,
457       &client_received_message_size, true /* is_client */);
458   GPR_ASSERT(config->server_message_size == client_received_message_size);
459   GPR_ASSERT(memcmp(config->server_message, client_received_message,
460                     client_received_message_size) == 0);
461   gpr_free(server_received_message);
462   gpr_free(client_received_message);
463 }
464 
tsi_test_frame_protector_do_round_trip_no_handshake(tsi_test_frame_protector_fixture * fixture)465 void tsi_test_frame_protector_do_round_trip_no_handshake(
466     tsi_test_frame_protector_fixture* fixture) {
467   GPR_ASSERT(fixture != nullptr);
468   tsi_test_do_ping_pong(fixture->config, fixture->channel,
469                         fixture->client_frame_protector,
470                         fixture->server_frame_protector);
471 }
472 
tsi_test_do_round_trip(tsi_test_fixture * fixture)473 void tsi_test_do_round_trip(tsi_test_fixture* fixture) {
474   // Initialization.
475   GPR_ASSERT(fixture != nullptr);
476   GPR_ASSERT(fixture->config != nullptr);
477   tsi_test_frame_protector_config* config = fixture->config;
478   tsi_frame_protector* client_frame_protector = nullptr;
479   tsi_frame_protector* server_frame_protector = nullptr;
480   // Perform handshake.
481   tsi_test_do_handshake(fixture);
482   // Create frame protectors.
483   size_t client_max_output_protected_frame_size =
484       config->client_max_output_protected_frame_size;
485   GPR_ASSERT(tsi_handshaker_result_create_frame_protector(
486                  fixture->client_result,
487                  client_max_output_protected_frame_size == 0
488                      ? nullptr
489                      : &client_max_output_protected_frame_size,
490                  &client_frame_protector) == TSI_OK);
491   size_t server_max_output_protected_frame_size =
492       config->server_max_output_protected_frame_size;
493   GPR_ASSERT(tsi_handshaker_result_create_frame_protector(
494                  fixture->server_result,
495                  server_max_output_protected_frame_size == 0
496                      ? nullptr
497                      : &server_max_output_protected_frame_size,
498                  &server_frame_protector) == TSI_OK);
499   tsi_test_do_ping_pong(config, fixture->channel, client_frame_protector,
500                         server_frame_protector);
501   // Destroy server and client frame protectors.
502   tsi_frame_protector_destroy(client_frame_protector);
503   tsi_frame_protector_destroy(server_frame_protector);
504 }
505 
generate_random_message(size_t size)506 static unsigned char* generate_random_message(size_t size) {
507   size_t i;
508   unsigned char chars[] = "abcdefghijklmnopqrstuvwxyz1234567890";
509   unsigned char* output =
510       static_cast<unsigned char*>(gpr_zalloc(sizeof(unsigned char) * size));
511   for (i = 0; i < size - 1; ++i) {
512     output[i] = chars[rand() % static_cast<int>(sizeof(chars) - 1)];
513   }
514   return output;
515 }
516 
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)517 tsi_test_frame_protector_config* tsi_test_frame_protector_config_create(
518     bool use_default_read_buffer_allocated_size,
519     bool use_default_message_buffer_allocated_size,
520     bool use_default_protected_buffer_size, bool use_default_client_message,
521     bool use_default_server_message,
522     bool use_default_client_max_output_protected_frame_size,
523     bool use_default_server_max_output_protected_frame_size) {
524   tsi_test_frame_protector_config* config =
525       static_cast<tsi_test_frame_protector_config*>(
526           gpr_zalloc(sizeof(*config)));
527   // Set the value for read_buffer_allocated_size.
528   config->read_buffer_allocated_size =
529       use_default_read_buffer_allocated_size
530           ? TSI_TEST_DEFAULT_BUFFER_SIZE
531           : TSI_TEST_SMALL_READ_BUFFER_ALLOCATED_SIZE;
532   // Set the value for message_buffer_allocated_size.
533   config->message_buffer_allocated_size =
534       use_default_message_buffer_allocated_size
535           ? TSI_TEST_DEFAULT_BUFFER_SIZE
536           : TSI_TEST_SMALL_MESSAGE_BUFFER_ALLOCATED_SIZE;
537   // Set the value for protected_buffer_size.
538   config->protected_buffer_size = use_default_protected_buffer_size
539                                       ? TSI_TEST_DEFAULT_PROTECTED_BUFFER_SIZE
540                                       : TSI_TEST_SMALL_PROTECTED_BUFFER_SIZE;
541   // Set the value for client message.
542   config->client_message_size = use_default_client_message
543                                     ? TSI_TEST_BIG_MESSAGE_SIZE
544                                     : TSI_TEST_SMALL_MESSAGE_SIZE;
545   config->client_message =
546       use_default_client_message
547           ? generate_random_message(TSI_TEST_BIG_MESSAGE_SIZE)
548           : generate_random_message(TSI_TEST_SMALL_MESSAGE_SIZE);
549   // Set the value for server message.
550   config->server_message_size = use_default_server_message
551                                     ? TSI_TEST_BIG_MESSAGE_SIZE
552                                     : TSI_TEST_SMALL_MESSAGE_SIZE;
553   config->server_message =
554       use_default_server_message
555           ? generate_random_message(TSI_TEST_BIG_MESSAGE_SIZE)
556           : generate_random_message(TSI_TEST_SMALL_MESSAGE_SIZE);
557   // Set the value for client max_output_protected_frame_size.
558   // If it is 0, we pass NULL to tsi_handshaker_result_create_frame_protector(),
559   // which then uses default protected frame size for it.
560   config->client_max_output_protected_frame_size =
561       use_default_client_max_output_protected_frame_size
562           ? 0
563           : TSI_TEST_SMALL_CLIENT_MAX_OUTPUT_PROTECTED_FRAME_SIZE;
564   // Set the value for server max_output_protected_frame_size.
565   // If it is 0, we pass NULL to tsi_handshaker_result_create_frame_protector(),
566   // which then uses default protected frame size for it.
567   config->server_max_output_protected_frame_size =
568       use_default_server_max_output_protected_frame_size
569           ? 0
570           : TSI_TEST_SMALL_SERVER_MAX_OUTPUT_PROTECTED_FRAME_SIZE;
571   return config;
572 }
573 
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)574 void tsi_test_frame_protector_config_set_buffer_size(
575     tsi_test_frame_protector_config* config, size_t read_buffer_allocated_size,
576     size_t message_buffer_allocated_size, size_t protected_buffer_size,
577     size_t client_max_output_protected_frame_size,
578     size_t server_max_output_protected_frame_size) {
579   GPR_ASSERT(config != nullptr);
580   config->read_buffer_allocated_size = read_buffer_allocated_size;
581   config->message_buffer_allocated_size = message_buffer_allocated_size;
582   config->protected_buffer_size = protected_buffer_size;
583   config->client_max_output_protected_frame_size =
584       client_max_output_protected_frame_size;
585   config->server_max_output_protected_frame_size =
586       server_max_output_protected_frame_size;
587 }
588 
tsi_test_frame_protector_config_destroy(tsi_test_frame_protector_config * config)589 void tsi_test_frame_protector_config_destroy(
590     tsi_test_frame_protector_config* config) {
591   if (config == nullptr) {
592     return;
593   }
594   gpr_free(config->client_message);
595   gpr_free(config->server_message);
596   gpr_free(config);
597 }
598 
tsi_test_channel_create()599 static tsi_test_channel* tsi_test_channel_create() {
600   tsi_test_channel* channel = grpc_core::Zalloc<tsi_test_channel>();
601   channel->client_channel =
602       static_cast<uint8_t*>(gpr_zalloc(TSI_TEST_DEFAULT_CHANNEL_SIZE));
603   channel->server_channel =
604       static_cast<uint8_t*>(gpr_zalloc(TSI_TEST_DEFAULT_CHANNEL_SIZE));
605   channel->bytes_written_to_client_channel = 0;
606   channel->bytes_written_to_server_channel = 0;
607   channel->bytes_read_from_client_channel = 0;
608   channel->bytes_read_from_server_channel = 0;
609   return channel;
610 }
611 
tsi_test_channel_destroy(tsi_test_channel * channel)612 static void tsi_test_channel_destroy(tsi_test_channel* channel) {
613   if (channel == nullptr) {
614     return;
615   }
616   gpr_free(channel->client_channel);
617   gpr_free(channel->server_channel);
618   gpr_free(channel);
619 }
620 
tsi_test_fixture_init(tsi_test_fixture * fixture)621 void tsi_test_fixture_init(tsi_test_fixture* fixture) {
622   memset(fixture, 0, sizeof(tsi_test_fixture));
623   fixture->config = tsi_test_frame_protector_config_create(
624       true, true, true, true, true, true, true);
625   fixture->handshake_buffer_size = TSI_TEST_DEFAULT_BUFFER_SIZE;
626   fixture->channel = tsi_test_channel_create();
627   fixture->test_unused_bytes = true;
628   fixture->has_client_finished_first = false;
629   gpr_mu_init(&fixture->mu);
630   gpr_cv_init(&fixture->cv);
631   fixture->notified = false;
632 }
633 
tsi_test_fixture_destroy(tsi_test_fixture * fixture)634 void tsi_test_fixture_destroy(tsi_test_fixture* fixture) {
635   if (fixture == nullptr) {
636     return;
637   }
638   tsi_test_frame_protector_config_destroy(fixture->config);
639   tsi_handshaker_destroy(fixture->client_handshaker);
640   tsi_handshaker_destroy(fixture->server_handshaker);
641   tsi_handshaker_result_destroy(fixture->client_result);
642   tsi_handshaker_result_destroy(fixture->server_result);
643   tsi_test_channel_destroy(fixture->channel);
644   GPR_ASSERT(fixture->vtable != nullptr);
645   GPR_ASSERT(fixture->vtable->destruct != nullptr);
646   gpr_mu_destroy(&fixture->mu);
647   gpr_cv_destroy(&fixture->cv);
648   fixture->vtable->destruct(fixture);
649 }
650 
tsi_test_frame_protector_fixture_create()651 tsi_test_frame_protector_fixture* tsi_test_frame_protector_fixture_create() {
652   tsi_test_frame_protector_fixture* fixture =
653       static_cast<tsi_test_frame_protector_fixture*>(
654           gpr_zalloc(sizeof(*fixture)));
655   fixture->config = tsi_test_frame_protector_config_create(
656       true, true, true, true, true, true, true);
657   fixture->channel = tsi_test_channel_create();
658   return fixture;
659 }
660 
tsi_test_frame_protector_fixture_init(tsi_test_frame_protector_fixture * fixture,tsi_frame_protector * client_frame_protector,tsi_frame_protector * server_frame_protector)661 void tsi_test_frame_protector_fixture_init(
662     tsi_test_frame_protector_fixture* fixture,
663     tsi_frame_protector* client_frame_protector,
664     tsi_frame_protector* server_frame_protector) {
665   GPR_ASSERT(fixture != nullptr);
666   fixture->client_frame_protector = client_frame_protector;
667   fixture->server_frame_protector = server_frame_protector;
668 }
669 
tsi_test_frame_protector_fixture_destroy(tsi_test_frame_protector_fixture * fixture)670 void tsi_test_frame_protector_fixture_destroy(
671     tsi_test_frame_protector_fixture* fixture) {
672   if (fixture == nullptr) {
673     return;
674   }
675   tsi_test_frame_protector_config_destroy(fixture->config);
676   tsi_test_channel_destroy(fixture->channel);
677   tsi_frame_protector_destroy(fixture->client_frame_protector);
678   tsi_frame_protector_destroy(fixture->server_frame_protector);
679   gpr_free(fixture);
680 }
681 
GenerateSelfSignedCertificate(const SelfSignedCertificateOptions & options)682 std::string GenerateSelfSignedCertificate(
683     const SelfSignedCertificateOptions& options) {
684   // Generate an RSA keypair.
685   BIGNUM* bignum = BN_new();
686   GPR_ASSERT(BN_set_word(bignum, RSA_F4));
687   BIGNUM* n = BN_new();
688   GPR_ASSERT(BN_set_word(n, 2048));
689   EVP_PKEY* key = EVP_PKEY_new();
690   // Create the X509 object.
691   X509* x509 = X509_new();
692 
693 #if OPENSSL_VERSION_NUMBER < 0x30000000L
694   RSA* rsa = RSA_new();
695   GPR_ASSERT(
696       RSA_generate_key_ex(rsa, /*key_size=*/2048, bignum, /*cb=*/nullptr));
697   GPR_ASSERT(EVP_PKEY_assign_RSA(key, rsa));
698   GPR_ASSERT(X509_set_version(x509, 2));  // TODO(gtcooke94) make a const
699 #else
700   key = EVP_RSA_gen(2048);
701   GPR_ASSERT(X509_set_version(x509, X509_VERSION_3));
702 #endif
703   // Set the not_before/after fields to infinite past/future. The value for
704   // infinite future is from RFC 5280 Section 4.1.2.5.1.
705   ASN1_UTCTIME* infinite_past = ASN1_UTCTIME_new();
706   GPR_ASSERT(ASN1_UTCTIME_set(infinite_past, /*posix_time=*/0));
707 #if OPENSSL_VERSION_NUMBER < 0x10100000
708   GPR_ASSERT(X509_set_notBefore(x509, infinite_past));
709 #else
710   GPR_ASSERT(X509_set1_notBefore(x509, infinite_past));
711 #endif
712   ASN1_UTCTIME_free(infinite_past);
713   ASN1_GENERALIZEDTIME* infinite_future = ASN1_GENERALIZEDTIME_new();
714   GPR_ASSERT(
715       ASN1_GENERALIZEDTIME_set_string(infinite_future, "99991231235959Z"));
716 #if OPENSSL_VERSION_NUMBER < 0x10100000
717   GPR_ASSERT(X509_set_notAfter(x509, infinite_future));
718 #else
719   GPR_ASSERT(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   GPR_ASSERT(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   GPR_ASSERT(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   GPR_ASSERT(
735       X509_NAME_add_entry_by_txt(subject_name, /*field=*/"OU", MBSTRING_ASC,
736                                  reinterpret_cast<const unsigned char*>(
737                                      options.organizational_unit.c_str()),
738                                  /*len=*/-1, /*loc=*/-1,
739                                  /*set=*/0));
740   GPR_ASSERT(X509_set_subject_name(x509, subject_name));
741   X509_NAME_free(subject_name);
742   // Set the public key and sign the certificate.
743   GPR_ASSERT(X509_set_pubkey(x509, key));
744   GPR_ASSERT(X509_sign(x509, key, EVP_sha256()));
745   // Convert to PEM.
746   BIO* bio = BIO_new(BIO_s_mem());
747   GPR_ASSERT(PEM_write_bio_X509(bio, x509));
748   const uint8_t* data = nullptr;
749   size_t len = 0;
750 
751 #ifdef OPENSSL_IS_BORINGSSL
752   GPR_ASSERT(BIO_mem_contents(bio, &data, &len));
753 #else
754   len = BIO_get_mem_data(bio, &data);
755 #endif
756   std::string pem = std::string(reinterpret_cast<const char*>(data), len);
757   // Cleanup all of the OpenSSL objects and return the PEM-encoded cert.
758   EVP_PKEY_free(key);
759   X509_free(x509);
760   BIO_free(bio);
761   BN_free(bignum);
762   BN_free(n);
763   return pem;
764 }
765 
ReadPemCert(absl::string_view pem_cert)766 X509* ReadPemCert(absl::string_view pem_cert) {
767   BIO* cert_bio =
768       BIO_new_mem_buf(pem_cert.data(), static_cast<int>(pem_cert.size()));
769   // Errors on BIO
770   if (cert_bio == nullptr) {
771     return nullptr;
772   }
773   X509* cert = PEM_read_bio_X509(cert_bio, nullptr, nullptr, nullptr);
774   BIO_free(cert_bio);
775   return cert;
776 }
777 
ReadCrl(absl::string_view crl_pem)778 X509_CRL* ReadCrl(absl::string_view crl_pem) {
779   BIO* crl_bio =
780       BIO_new_mem_buf(crl_pem.data(), static_cast<int>(crl_pem.size()));
781   // Errors on BIO
782   if (crl_bio == nullptr) {
783     return nullptr;
784   }
785   X509_CRL* crl = PEM_read_bio_X509_CRL(crl_bio, nullptr, nullptr, nullptr);
786   BIO_free(crl_bio);
787   return crl;
788 }
789