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