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 <stdbool.h>
20 #include <stdio.h>
21 #include <string.h>
22
23 #include "src/core/lib/iomgr/load_file.h"
24 #include "src/core/lib/security/security_connector/security_connector.h"
25 #include "src/core/tsi/ssl_transport_security.h"
26 #include "src/core/tsi/transport_security.h"
27 #include "src/core/tsi/transport_security_interface.h"
28 #include "test/core/tsi/transport_security_test_lib.h"
29 #include "test/core/util/test_config.h"
30
31 #include <grpc/grpc.h>
32 #include <grpc/support/alloc.h>
33 #include <grpc/support/log.h>
34 #include <grpc/support/string_util.h>
35
36 extern "C" {
37 #include <openssl/crypto.h>
38 }
39
40 #define SSL_TSI_TEST_ALPN1 "foo"
41 #define SSL_TSI_TEST_ALPN2 "toto"
42 #define SSL_TSI_TEST_ALPN3 "baz"
43 #define SSL_TSI_TEST_ALPN_NUM 2
44 #define SSL_TSI_TEST_SERVER_KEY_CERT_PAIRS_NUM 2
45 #define SSL_TSI_TEST_BAD_SERVER_KEY_CERT_PAIRS_NUM 1
46 #define SSL_TSI_TEST_CREDENTIALS_DIR "src/core/tsi/test_creds/"
47
48 // OpenSSL 1.1 uses AES256 for encryption session ticket by default so specify
49 // different STEK size.
50 #if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(OPENSSL_IS_BORINGSSL)
51 const size_t kSessionTicketEncryptionKeySize = 80;
52 #else
53 const size_t kSessionTicketEncryptionKeySize = 48;
54 #endif
55
56 typedef enum AlpnMode {
57 NO_ALPN,
58 ALPN_CLIENT_NO_SERVER,
59 ALPN_SERVER_NO_CLIENT,
60 ALPN_CLIENT_SERVER_OK,
61 ALPN_CLIENT_SERVER_MISMATCH
62 } AlpnMode;
63
64 typedef struct ssl_alpn_lib {
65 AlpnMode alpn_mode;
66 const char** server_alpn_protocols;
67 const char** client_alpn_protocols;
68 uint16_t num_server_alpn_protocols;
69 uint16_t num_client_alpn_protocols;
70 } ssl_alpn_lib;
71
72 typedef struct ssl_key_cert_lib {
73 bool use_bad_server_cert;
74 bool use_bad_client_cert;
75 bool use_root_store;
76 char* root_cert;
77 tsi_ssl_root_certs_store* root_store;
78 tsi_ssl_pem_key_cert_pair* server_pem_key_cert_pairs;
79 tsi_ssl_pem_key_cert_pair* bad_server_pem_key_cert_pairs;
80 tsi_ssl_pem_key_cert_pair client_pem_key_cert_pair;
81 tsi_ssl_pem_key_cert_pair bad_client_pem_key_cert_pair;
82 uint16_t server_num_key_cert_pairs;
83 uint16_t bad_server_num_key_cert_pairs;
84 } ssl_key_cert_lib;
85
86 typedef struct ssl_tsi_test_fixture {
87 tsi_test_fixture base;
88 ssl_key_cert_lib* key_cert_lib;
89 ssl_alpn_lib* alpn_lib;
90 bool force_client_auth;
91 char* server_name_indication;
92 tsi_ssl_session_cache* session_cache;
93 bool session_reused;
94 const char* session_ticket_key;
95 size_t session_ticket_key_size;
96 tsi_ssl_server_handshaker_factory* server_handshaker_factory;
97 tsi_ssl_client_handshaker_factory* client_handshaker_factory;
98 } ssl_tsi_test_fixture;
99
ssl_test_setup_handshakers(tsi_test_fixture * fixture)100 static void ssl_test_setup_handshakers(tsi_test_fixture* fixture) {
101 ssl_tsi_test_fixture* ssl_fixture =
102 reinterpret_cast<ssl_tsi_test_fixture*>(fixture);
103 GPR_ASSERT(ssl_fixture != nullptr);
104 GPR_ASSERT(ssl_fixture->key_cert_lib != nullptr);
105 GPR_ASSERT(ssl_fixture->alpn_lib != nullptr);
106 ssl_key_cert_lib* key_cert_lib = ssl_fixture->key_cert_lib;
107 ssl_alpn_lib* alpn_lib = ssl_fixture->alpn_lib;
108 /* Create client handshaker factory. */
109 tsi_ssl_client_handshaker_options client_options;
110 memset(&client_options, 0, sizeof(client_options));
111 client_options.pem_root_certs = key_cert_lib->root_cert;
112 if (ssl_fixture->force_client_auth) {
113 client_options.pem_key_cert_pair =
114 key_cert_lib->use_bad_client_cert
115 ? &key_cert_lib->bad_client_pem_key_cert_pair
116 : &key_cert_lib->client_pem_key_cert_pair;
117 }
118 if (alpn_lib->alpn_mode == ALPN_CLIENT_NO_SERVER ||
119 alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_OK ||
120 alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_MISMATCH) {
121 client_options.alpn_protocols = alpn_lib->client_alpn_protocols;
122 client_options.num_alpn_protocols = alpn_lib->num_client_alpn_protocols;
123 }
124 client_options.root_store =
125 key_cert_lib->use_root_store ? key_cert_lib->root_store : nullptr;
126 if (ssl_fixture->session_cache != nullptr) {
127 client_options.session_cache = ssl_fixture->session_cache;
128 }
129 GPR_ASSERT(tsi_create_ssl_client_handshaker_factory_with_options(
130 &client_options, &ssl_fixture->client_handshaker_factory) ==
131 TSI_OK);
132 /* Create server handshaker factory. */
133 tsi_ssl_server_handshaker_options server_options;
134 memset(&server_options, 0, sizeof(server_options));
135 if (alpn_lib->alpn_mode == ALPN_SERVER_NO_CLIENT ||
136 alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_OK ||
137 alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_MISMATCH) {
138 server_options.alpn_protocols = alpn_lib->server_alpn_protocols;
139 server_options.num_alpn_protocols = alpn_lib->num_server_alpn_protocols;
140 if (alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_MISMATCH) {
141 server_options.num_alpn_protocols--;
142 }
143 }
144 server_options.pem_key_cert_pairs =
145 key_cert_lib->use_bad_server_cert
146 ? key_cert_lib->bad_server_pem_key_cert_pairs
147 : key_cert_lib->server_pem_key_cert_pairs;
148 server_options.num_key_cert_pairs =
149 key_cert_lib->use_bad_server_cert
150 ? key_cert_lib->bad_server_num_key_cert_pairs
151 : key_cert_lib->server_num_key_cert_pairs;
152 server_options.pem_client_root_certs = key_cert_lib->root_cert;
153 if (ssl_fixture->force_client_auth) {
154 server_options.client_certificate_request =
155 TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY;
156 } else {
157 server_options.client_certificate_request =
158 TSI_DONT_REQUEST_CLIENT_CERTIFICATE;
159 }
160 server_options.session_ticket_key = ssl_fixture->session_ticket_key;
161 server_options.session_ticket_key_size = ssl_fixture->session_ticket_key_size;
162 GPR_ASSERT(tsi_create_ssl_server_handshaker_factory_with_options(
163 &server_options, &ssl_fixture->server_handshaker_factory) ==
164 TSI_OK);
165 /* Create server and client handshakers. */
166 GPR_ASSERT(tsi_ssl_client_handshaker_factory_create_handshaker(
167 ssl_fixture->client_handshaker_factory,
168 ssl_fixture->server_name_indication,
169 &ssl_fixture->base.client_handshaker) == TSI_OK);
170 GPR_ASSERT(tsi_ssl_server_handshaker_factory_create_handshaker(
171 ssl_fixture->server_handshaker_factory,
172 &ssl_fixture->base.server_handshaker) == TSI_OK);
173 }
174
check_alpn(ssl_tsi_test_fixture * ssl_fixture,const tsi_peer * peer)175 static void check_alpn(ssl_tsi_test_fixture* ssl_fixture,
176 const tsi_peer* peer) {
177 GPR_ASSERT(ssl_fixture != nullptr);
178 GPR_ASSERT(ssl_fixture->alpn_lib != nullptr);
179 ssl_alpn_lib* alpn_lib = ssl_fixture->alpn_lib;
180 const tsi_peer_property* alpn_property =
181 tsi_peer_get_property_by_name(peer, TSI_SSL_ALPN_SELECTED_PROTOCOL);
182 if (alpn_lib->alpn_mode != ALPN_CLIENT_SERVER_OK) {
183 GPR_ASSERT(alpn_property == nullptr);
184 } else {
185 GPR_ASSERT(alpn_property != nullptr);
186 const char* expected_match = "baz";
187 GPR_ASSERT(memcmp(alpn_property->value.data, expected_match,
188 alpn_property->value.length) == 0);
189 }
190 }
191
192 static const tsi_peer_property*
check_basic_authenticated_peer_and_get_common_name(const tsi_peer * peer)193 check_basic_authenticated_peer_and_get_common_name(const tsi_peer* peer) {
194 const tsi_peer_property* cert_type_property =
195 tsi_peer_get_property_by_name(peer, TSI_CERTIFICATE_TYPE_PEER_PROPERTY);
196 GPR_ASSERT(cert_type_property != nullptr);
197 GPR_ASSERT(memcmp(cert_type_property->value.data, TSI_X509_CERTIFICATE_TYPE,
198 cert_type_property->value.length) == 0);
199 const tsi_peer_property* property = tsi_peer_get_property_by_name(
200 peer, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY);
201 GPR_ASSERT(property != nullptr);
202 return property;
203 }
204
check_session_reusage(ssl_tsi_test_fixture * ssl_fixture,tsi_peer * peer)205 static void check_session_reusage(ssl_tsi_test_fixture* ssl_fixture,
206 tsi_peer* peer) {
207 const tsi_peer_property* session_reused =
208 tsi_peer_get_property_by_name(peer, TSI_SSL_SESSION_REUSED_PEER_PROPERTY);
209 GPR_ASSERT(session_reused != nullptr);
210 if (ssl_fixture->session_reused) {
211 GPR_ASSERT(strncmp(session_reused->value.data, "true",
212 session_reused->value.length) == 0);
213 } else {
214 GPR_ASSERT(strncmp(session_reused->value.data, "false",
215 session_reused->value.length) == 0);
216 }
217 }
218
check_server0_peer(tsi_peer * peer)219 void check_server0_peer(tsi_peer* peer) {
220 const tsi_peer_property* property =
221 check_basic_authenticated_peer_and_get_common_name(peer);
222 const char* expected_match = "*.test.google.com.au";
223 GPR_ASSERT(memcmp(property->value.data, expected_match,
224 property->value.length) == 0);
225 GPR_ASSERT(tsi_peer_get_property_by_name(
226 peer, TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) ==
227 nullptr);
228 GPR_ASSERT(tsi_ssl_peer_matches_name(peer, "foo.test.google.com.au") == 1);
229 GPR_ASSERT(tsi_ssl_peer_matches_name(peer, "bar.test.google.com.au") == 1);
230 GPR_ASSERT(tsi_ssl_peer_matches_name(peer, "bar.test.google.blah") == 0);
231 GPR_ASSERT(tsi_ssl_peer_matches_name(peer, "foo.bar.test.google.com.au") ==
232 0);
233 GPR_ASSERT(tsi_ssl_peer_matches_name(peer, "test.google.com.au") == 0);
234 tsi_peer_destruct(peer);
235 }
236
check_subject_alt_name(tsi_peer * peer,const char * name)237 static bool check_subject_alt_name(tsi_peer* peer, const char* name) {
238 for (size_t i = 0; i < peer->property_count; i++) {
239 const tsi_peer_property* prop = &peer->properties[i];
240 if (strcmp(prop->name, TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) ==
241 0) {
242 if (memcmp(prop->value.data, name, prop->value.length) == 0) {
243 return true;
244 }
245 }
246 }
247 return false;
248 }
249
check_server1_peer(tsi_peer * peer)250 void check_server1_peer(tsi_peer* peer) {
251 const tsi_peer_property* property =
252 check_basic_authenticated_peer_and_get_common_name(peer);
253 const char* expected_match = "*.test.google.com";
254 GPR_ASSERT(memcmp(property->value.data, expected_match,
255 property->value.length) == 0);
256 GPR_ASSERT(check_subject_alt_name(peer, "*.test.google.fr") == 1);
257 GPR_ASSERT(check_subject_alt_name(peer, "waterzooi.test.google.be") == 1);
258 GPR_ASSERT(tsi_ssl_peer_matches_name(peer, "foo.test.google.fr") == 1);
259 GPR_ASSERT(tsi_ssl_peer_matches_name(peer, "bar.test.google.fr") == 1);
260 GPR_ASSERT(tsi_ssl_peer_matches_name(peer, "waterzooi.test.google.be") == 1);
261 GPR_ASSERT(tsi_ssl_peer_matches_name(peer, "foo.test.youtube.com") == 1);
262 GPR_ASSERT(tsi_ssl_peer_matches_name(peer, "bar.foo.test.google.com") == 0);
263 GPR_ASSERT(tsi_ssl_peer_matches_name(peer, "test.google.fr") == 0);
264 GPR_ASSERT(tsi_ssl_peer_matches_name(peer, "tartines.test.google.be") == 0);
265 GPR_ASSERT(tsi_ssl_peer_matches_name(peer, "tartines.youtube.com") == 0);
266 tsi_peer_destruct(peer);
267 }
268
check_client_peer(ssl_tsi_test_fixture * ssl_fixture,tsi_peer * peer)269 static void check_client_peer(ssl_tsi_test_fixture* ssl_fixture,
270 tsi_peer* peer) {
271 GPR_ASSERT(ssl_fixture != nullptr);
272 GPR_ASSERT(ssl_fixture->alpn_lib != nullptr);
273 ssl_alpn_lib* alpn_lib = ssl_fixture->alpn_lib;
274 if (!ssl_fixture->force_client_auth) {
275 GPR_ASSERT(peer->property_count ==
276 (alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_OK ? 2 : 1));
277 } else {
278 const tsi_peer_property* property =
279 check_basic_authenticated_peer_and_get_common_name(peer);
280 const char* expected_match = "testclient";
281 GPR_ASSERT(memcmp(property->value.data, expected_match,
282 property->value.length) == 0);
283 }
284 tsi_peer_destruct(peer);
285 }
286
ssl_test_check_handshaker_peers(tsi_test_fixture * fixture)287 static void ssl_test_check_handshaker_peers(tsi_test_fixture* fixture) {
288 ssl_tsi_test_fixture* ssl_fixture =
289 reinterpret_cast<ssl_tsi_test_fixture*>(fixture);
290 GPR_ASSERT(ssl_fixture != nullptr);
291 GPR_ASSERT(ssl_fixture->key_cert_lib != nullptr);
292 ssl_key_cert_lib* key_cert_lib = ssl_fixture->key_cert_lib;
293 tsi_peer peer;
294 bool expect_success =
295 !(key_cert_lib->use_bad_server_cert ||
296 (key_cert_lib->use_bad_client_cert && ssl_fixture->force_client_auth));
297 if (expect_success) {
298 GPR_ASSERT(tsi_handshaker_result_extract_peer(
299 ssl_fixture->base.client_result, &peer) == TSI_OK);
300 check_session_reusage(ssl_fixture, &peer);
301 check_alpn(ssl_fixture, &peer);
302 if (ssl_fixture->server_name_indication != nullptr) {
303 check_server1_peer(&peer);
304 } else {
305 check_server0_peer(&peer);
306 }
307 } else {
308 GPR_ASSERT(ssl_fixture->base.client_result == nullptr);
309 }
310 if (expect_success) {
311 GPR_ASSERT(tsi_handshaker_result_extract_peer(
312 ssl_fixture->base.server_result, &peer) == TSI_OK);
313 check_session_reusage(ssl_fixture, &peer);
314 check_alpn(ssl_fixture, &peer);
315 check_client_peer(ssl_fixture, &peer);
316 } else {
317 GPR_ASSERT(ssl_fixture->base.server_result == nullptr);
318 }
319 }
320
ssl_test_pem_key_cert_pair_destroy(tsi_ssl_pem_key_cert_pair kp)321 static void ssl_test_pem_key_cert_pair_destroy(tsi_ssl_pem_key_cert_pair kp) {
322 gpr_free((void*)kp.private_key);
323 gpr_free((void*)kp.cert_chain);
324 }
325
ssl_test_destruct(tsi_test_fixture * fixture)326 static void ssl_test_destruct(tsi_test_fixture* fixture) {
327 ssl_tsi_test_fixture* ssl_fixture =
328 reinterpret_cast<ssl_tsi_test_fixture*>(fixture);
329 if (ssl_fixture == nullptr) {
330 return;
331 }
332 /* Destroy ssl_alpn_lib. */
333 ssl_alpn_lib* alpn_lib = ssl_fixture->alpn_lib;
334 for (size_t i = 0; i < alpn_lib->num_server_alpn_protocols; i++) {
335 gpr_free(const_cast<char*>(alpn_lib->server_alpn_protocols[i]));
336 }
337 gpr_free(alpn_lib->server_alpn_protocols);
338 for (size_t i = 0; i < alpn_lib->num_client_alpn_protocols; i++) {
339 gpr_free(const_cast<char*>(alpn_lib->client_alpn_protocols[i]));
340 }
341 gpr_free(alpn_lib->client_alpn_protocols);
342 gpr_free(alpn_lib);
343 /* Destroy ssl_key_cert_lib. */
344 ssl_key_cert_lib* key_cert_lib = ssl_fixture->key_cert_lib;
345 for (size_t i = 0; i < key_cert_lib->server_num_key_cert_pairs; i++) {
346 ssl_test_pem_key_cert_pair_destroy(
347 key_cert_lib->server_pem_key_cert_pairs[i]);
348 }
349 gpr_free(key_cert_lib->server_pem_key_cert_pairs);
350 for (size_t i = 0; i < key_cert_lib->bad_server_num_key_cert_pairs; i++) {
351 ssl_test_pem_key_cert_pair_destroy(
352 key_cert_lib->bad_server_pem_key_cert_pairs[i]);
353 }
354 gpr_free(key_cert_lib->bad_server_pem_key_cert_pairs);
355 ssl_test_pem_key_cert_pair_destroy(key_cert_lib->client_pem_key_cert_pair);
356 ssl_test_pem_key_cert_pair_destroy(
357 key_cert_lib->bad_client_pem_key_cert_pair);
358 gpr_free(key_cert_lib->root_cert);
359 tsi_ssl_root_certs_store_destroy(key_cert_lib->root_store);
360 gpr_free(key_cert_lib);
361 if (ssl_fixture->session_cache != nullptr) {
362 tsi_ssl_session_cache_unref(ssl_fixture->session_cache);
363 }
364 /* Unreference others. */
365 tsi_ssl_server_handshaker_factory_unref(
366 ssl_fixture->server_handshaker_factory);
367 tsi_ssl_client_handshaker_factory_unref(
368 ssl_fixture->client_handshaker_factory);
369 }
370
371 static const struct tsi_test_fixture_vtable vtable = {
372 ssl_test_setup_handshakers, ssl_test_check_handshaker_peers,
373 ssl_test_destruct};
374
load_file(const char * dir_path,const char * file_name)375 static char* load_file(const char* dir_path, const char* file_name) {
376 char* file_path = static_cast<char*>(
377 gpr_zalloc(sizeof(char) * (strlen(dir_path) + strlen(file_name) + 1)));
378 memcpy(file_path, dir_path, strlen(dir_path));
379 memcpy(file_path + strlen(dir_path), file_name, strlen(file_name));
380 grpc_slice slice;
381 GPR_ASSERT(grpc_load_file(file_path, 1, &slice) == GRPC_ERROR_NONE);
382 char* data = grpc_slice_to_c_string(slice);
383 grpc_slice_unref(slice);
384 gpr_free(file_path);
385 return data;
386 }
387
ssl_tsi_test_fixture_create()388 static tsi_test_fixture* ssl_tsi_test_fixture_create() {
389 ssl_tsi_test_fixture* ssl_fixture =
390 static_cast<ssl_tsi_test_fixture*>(gpr_zalloc(sizeof(*ssl_fixture)));
391 tsi_test_fixture_init(&ssl_fixture->base);
392 ssl_fixture->base.test_unused_bytes = false;
393 ssl_fixture->base.vtable = &vtable;
394 /* Create ssl_key_cert_lib. */
395 ssl_key_cert_lib* key_cert_lib =
396 static_cast<ssl_key_cert_lib*>(gpr_zalloc(sizeof(*key_cert_lib)));
397 key_cert_lib->use_bad_server_cert = false;
398 key_cert_lib->use_bad_client_cert = false;
399 key_cert_lib->use_root_store = false;
400 key_cert_lib->server_num_key_cert_pairs =
401 SSL_TSI_TEST_SERVER_KEY_CERT_PAIRS_NUM;
402 key_cert_lib->bad_server_num_key_cert_pairs =
403 SSL_TSI_TEST_BAD_SERVER_KEY_CERT_PAIRS_NUM;
404 key_cert_lib->server_pem_key_cert_pairs =
405 static_cast<tsi_ssl_pem_key_cert_pair*>(
406 gpr_malloc(sizeof(tsi_ssl_pem_key_cert_pair) *
407 key_cert_lib->server_num_key_cert_pairs));
408 key_cert_lib->bad_server_pem_key_cert_pairs =
409 static_cast<tsi_ssl_pem_key_cert_pair*>(
410 gpr_malloc(sizeof(tsi_ssl_pem_key_cert_pair) *
411 key_cert_lib->bad_server_num_key_cert_pairs));
412 key_cert_lib->server_pem_key_cert_pairs[0].private_key =
413 load_file(SSL_TSI_TEST_CREDENTIALS_DIR, "server0.key");
414 key_cert_lib->server_pem_key_cert_pairs[0].cert_chain =
415 load_file(SSL_TSI_TEST_CREDENTIALS_DIR, "server0.pem");
416 key_cert_lib->server_pem_key_cert_pairs[1].private_key =
417 load_file(SSL_TSI_TEST_CREDENTIALS_DIR, "server1.key");
418 key_cert_lib->server_pem_key_cert_pairs[1].cert_chain =
419 load_file(SSL_TSI_TEST_CREDENTIALS_DIR, "server1.pem");
420 key_cert_lib->bad_server_pem_key_cert_pairs[0].private_key =
421 load_file(SSL_TSI_TEST_CREDENTIALS_DIR, "badserver.key");
422 key_cert_lib->bad_server_pem_key_cert_pairs[0].cert_chain =
423 load_file(SSL_TSI_TEST_CREDENTIALS_DIR, "badserver.pem");
424 key_cert_lib->client_pem_key_cert_pair.private_key =
425 load_file(SSL_TSI_TEST_CREDENTIALS_DIR, "client.key");
426 key_cert_lib->client_pem_key_cert_pair.cert_chain =
427 load_file(SSL_TSI_TEST_CREDENTIALS_DIR, "client.pem");
428 key_cert_lib->bad_client_pem_key_cert_pair.private_key =
429 load_file(SSL_TSI_TEST_CREDENTIALS_DIR, "badclient.key");
430 key_cert_lib->bad_client_pem_key_cert_pair.cert_chain =
431 load_file(SSL_TSI_TEST_CREDENTIALS_DIR, "badclient.pem");
432 key_cert_lib->root_cert = load_file(SSL_TSI_TEST_CREDENTIALS_DIR, "ca.pem");
433 key_cert_lib->root_store =
434 tsi_ssl_root_certs_store_create(key_cert_lib->root_cert);
435 GPR_ASSERT(key_cert_lib->root_store != nullptr);
436 ssl_fixture->key_cert_lib = key_cert_lib;
437 /* Create ssl_alpn_lib. */
438 ssl_alpn_lib* alpn_lib =
439 static_cast<ssl_alpn_lib*>(gpr_zalloc(sizeof(*alpn_lib)));
440 alpn_lib->server_alpn_protocols = static_cast<const char**>(
441 gpr_zalloc(sizeof(char*) * SSL_TSI_TEST_ALPN_NUM));
442 alpn_lib->client_alpn_protocols = static_cast<const char**>(
443 gpr_zalloc(sizeof(char*) * SSL_TSI_TEST_ALPN_NUM));
444 alpn_lib->server_alpn_protocols[0] = gpr_strdup(SSL_TSI_TEST_ALPN1);
445 alpn_lib->server_alpn_protocols[1] = gpr_strdup(SSL_TSI_TEST_ALPN3);
446 alpn_lib->client_alpn_protocols[0] = gpr_strdup(SSL_TSI_TEST_ALPN2);
447 alpn_lib->client_alpn_protocols[1] = gpr_strdup(SSL_TSI_TEST_ALPN3);
448 alpn_lib->num_server_alpn_protocols = SSL_TSI_TEST_ALPN_NUM;
449 alpn_lib->num_client_alpn_protocols = SSL_TSI_TEST_ALPN_NUM;
450 alpn_lib->alpn_mode = NO_ALPN;
451 ssl_fixture->alpn_lib = alpn_lib;
452 ssl_fixture->base.vtable = &vtable;
453 ssl_fixture->server_name_indication = nullptr;
454 ssl_fixture->session_reused = false;
455 ssl_fixture->session_ticket_key = nullptr;
456 ssl_fixture->session_ticket_key_size = 0;
457 ssl_fixture->force_client_auth = false;
458 return &ssl_fixture->base;
459 }
460
ssl_tsi_test_do_handshake_tiny_handshake_buffer()461 void ssl_tsi_test_do_handshake_tiny_handshake_buffer() {
462 tsi_test_fixture* fixture = ssl_tsi_test_fixture_create();
463 fixture->handshake_buffer_size = TSI_TEST_TINY_HANDSHAKE_BUFFER_SIZE;
464 tsi_test_do_handshake(fixture);
465 tsi_test_fixture_destroy(fixture);
466 }
467
ssl_tsi_test_do_handshake_small_handshake_buffer()468 void ssl_tsi_test_do_handshake_small_handshake_buffer() {
469 tsi_test_fixture* fixture = ssl_tsi_test_fixture_create();
470 fixture->handshake_buffer_size = TSI_TEST_SMALL_HANDSHAKE_BUFFER_SIZE;
471 tsi_test_do_handshake(fixture);
472 tsi_test_fixture_destroy(fixture);
473 }
474
ssl_tsi_test_do_handshake()475 void ssl_tsi_test_do_handshake() {
476 tsi_test_fixture* fixture = ssl_tsi_test_fixture_create();
477 tsi_test_do_handshake(fixture);
478 tsi_test_fixture_destroy(fixture);
479 }
480
ssl_tsi_test_do_handshake_with_root_store()481 void ssl_tsi_test_do_handshake_with_root_store() {
482 tsi_test_fixture* fixture = ssl_tsi_test_fixture_create();
483 ssl_tsi_test_fixture* ssl_fixture =
484 reinterpret_cast<ssl_tsi_test_fixture*>(fixture);
485 ssl_fixture->key_cert_lib->use_root_store = true;
486 tsi_test_do_handshake(fixture);
487 tsi_test_fixture_destroy(fixture);
488 }
489
ssl_tsi_test_do_handshake_with_client_authentication()490 void ssl_tsi_test_do_handshake_with_client_authentication() {
491 tsi_test_fixture* fixture = ssl_tsi_test_fixture_create();
492 ssl_tsi_test_fixture* ssl_fixture =
493 reinterpret_cast<ssl_tsi_test_fixture*>(fixture);
494 ssl_fixture->force_client_auth = true;
495 tsi_test_do_handshake(fixture);
496 tsi_test_fixture_destroy(fixture);
497 }
498
ssl_tsi_test_do_handshake_with_client_authentication_and_root_store()499 void ssl_tsi_test_do_handshake_with_client_authentication_and_root_store() {
500 tsi_test_fixture* fixture = ssl_tsi_test_fixture_create();
501 ssl_tsi_test_fixture* ssl_fixture =
502 reinterpret_cast<ssl_tsi_test_fixture*>(fixture);
503 ssl_fixture->force_client_auth = true;
504 ssl_fixture->key_cert_lib->use_root_store = true;
505 tsi_test_do_handshake(fixture);
506 tsi_test_fixture_destroy(fixture);
507 }
508
ssl_tsi_test_do_handshake_with_server_name_indication_exact_domain()509 void ssl_tsi_test_do_handshake_with_server_name_indication_exact_domain() {
510 /* server1 cert contains "waterzooi.test.google.be" in SAN. */
511 tsi_test_fixture* fixture = ssl_tsi_test_fixture_create();
512 ssl_tsi_test_fixture* ssl_fixture =
513 reinterpret_cast<ssl_tsi_test_fixture*>(fixture);
514 ssl_fixture->server_name_indication =
515 const_cast<char*>("waterzooi.test.google.be");
516 tsi_test_do_handshake(fixture);
517 tsi_test_fixture_destroy(fixture);
518 }
519
ssl_tsi_test_do_handshake_with_server_name_indication_wild_star_domain()520 void ssl_tsi_test_do_handshake_with_server_name_indication_wild_star_domain() {
521 /* server1 cert contains "*.test.google.fr" in SAN. */
522 tsi_test_fixture* fixture = ssl_tsi_test_fixture_create();
523 ssl_tsi_test_fixture* ssl_fixture =
524 reinterpret_cast<ssl_tsi_test_fixture*>(fixture);
525 ssl_fixture->server_name_indication =
526 const_cast<char*>("juju.test.google.fr");
527 tsi_test_do_handshake(fixture);
528 tsi_test_fixture_destroy(fixture);
529 }
530
ssl_tsi_test_do_handshake_with_bad_server_cert()531 void ssl_tsi_test_do_handshake_with_bad_server_cert() {
532 tsi_test_fixture* fixture = ssl_tsi_test_fixture_create();
533 ssl_tsi_test_fixture* ssl_fixture =
534 reinterpret_cast<ssl_tsi_test_fixture*>(fixture);
535 ssl_fixture->key_cert_lib->use_bad_server_cert = true;
536 tsi_test_do_handshake(fixture);
537 tsi_test_fixture_destroy(fixture);
538 }
539
ssl_tsi_test_do_handshake_with_bad_client_cert()540 void ssl_tsi_test_do_handshake_with_bad_client_cert() {
541 tsi_test_fixture* fixture = ssl_tsi_test_fixture_create();
542 ssl_tsi_test_fixture* ssl_fixture =
543 reinterpret_cast<ssl_tsi_test_fixture*>(fixture);
544 ssl_fixture->key_cert_lib->use_bad_client_cert = true;
545 ssl_fixture->force_client_auth = true;
546 tsi_test_do_handshake(fixture);
547 tsi_test_fixture_destroy(fixture);
548 }
549
ssl_tsi_test_do_handshake_alpn_client_no_server()550 void ssl_tsi_test_do_handshake_alpn_client_no_server() {
551 tsi_test_fixture* fixture = ssl_tsi_test_fixture_create();
552 ssl_tsi_test_fixture* ssl_fixture =
553 reinterpret_cast<ssl_tsi_test_fixture*>(fixture);
554 ssl_fixture->alpn_lib->alpn_mode = ALPN_CLIENT_NO_SERVER;
555 tsi_test_do_handshake(fixture);
556 tsi_test_fixture_destroy(fixture);
557 }
558
ssl_tsi_test_do_handshake_alpn_server_no_client()559 void ssl_tsi_test_do_handshake_alpn_server_no_client() {
560 tsi_test_fixture* fixture = ssl_tsi_test_fixture_create();
561 ssl_tsi_test_fixture* ssl_fixture =
562 reinterpret_cast<ssl_tsi_test_fixture*>(fixture);
563 ssl_fixture->alpn_lib->alpn_mode = ALPN_SERVER_NO_CLIENT;
564 tsi_test_do_handshake(fixture);
565 tsi_test_fixture_destroy(fixture);
566 }
567
ssl_tsi_test_do_handshake_alpn_client_server_mismatch()568 void ssl_tsi_test_do_handshake_alpn_client_server_mismatch() {
569 tsi_test_fixture* fixture = ssl_tsi_test_fixture_create();
570 ssl_tsi_test_fixture* ssl_fixture =
571 reinterpret_cast<ssl_tsi_test_fixture*>(fixture);
572 ssl_fixture->alpn_lib->alpn_mode = ALPN_CLIENT_SERVER_MISMATCH;
573 tsi_test_do_handshake(fixture);
574 tsi_test_fixture_destroy(fixture);
575 }
576
ssl_tsi_test_do_handshake_alpn_client_server_ok()577 void ssl_tsi_test_do_handshake_alpn_client_server_ok() {
578 tsi_test_fixture* fixture = ssl_tsi_test_fixture_create();
579 ssl_tsi_test_fixture* ssl_fixture =
580 reinterpret_cast<ssl_tsi_test_fixture*>(fixture);
581 ssl_fixture->alpn_lib->alpn_mode = ALPN_CLIENT_SERVER_OK;
582 tsi_test_do_handshake(fixture);
583 tsi_test_fixture_destroy(fixture);
584 }
585
ssl_tsi_test_do_round_trip_for_all_configs()586 void ssl_tsi_test_do_round_trip_for_all_configs() {
587 unsigned int* bit_array = static_cast<unsigned int*>(
588 gpr_zalloc(sizeof(unsigned int) * TSI_TEST_NUM_OF_ARGUMENTS));
589 const unsigned int mask = 1U << (TSI_TEST_NUM_OF_ARGUMENTS - 1);
590 for (unsigned int val = 0; val < TSI_TEST_NUM_OF_COMBINATIONS; val++) {
591 unsigned int v = val;
592 for (unsigned int ind = 0; ind < TSI_TEST_NUM_OF_ARGUMENTS; ind++) {
593 bit_array[ind] = (v & mask) ? 1 : 0;
594 v <<= 1;
595 }
596 tsi_test_fixture* fixture = ssl_tsi_test_fixture_create();
597 ssl_tsi_test_fixture* ssl_fixture =
598 reinterpret_cast<ssl_tsi_test_fixture*>(fixture);
599 tsi_test_frame_protector_config_destroy(ssl_fixture->base.config);
600 ssl_fixture->base.config = tsi_test_frame_protector_config_create(
601 bit_array[0], bit_array[1], bit_array[2], bit_array[3], bit_array[4],
602 bit_array[5], bit_array[6]);
603 tsi_test_do_round_trip(&ssl_fixture->base);
604 tsi_test_fixture_destroy(fixture);
605 }
606 gpr_free(bit_array);
607 }
608
ssl_tsi_test_do_round_trip_odd_buffer_size()609 void ssl_tsi_test_do_round_trip_odd_buffer_size() {
610 const size_t odd_sizes[] = {1025, 2051, 4103, 8207, 16409};
611 const size_t size = sizeof(odd_sizes) / sizeof(size_t);
612 for (size_t ind1 = 0; ind1 < size; ind1++) {
613 for (size_t ind2 = 0; ind2 < size; ind2++) {
614 for (size_t ind3 = 0; ind3 < size; ind3++) {
615 for (size_t ind4 = 0; ind4 < size; ind4++) {
616 for (size_t ind5 = 0; ind5 < size; ind5++) {
617 tsi_test_fixture* fixture = ssl_tsi_test_fixture_create();
618 ssl_tsi_test_fixture* ssl_fixture =
619 reinterpret_cast<ssl_tsi_test_fixture*>(fixture);
620 tsi_test_frame_protector_config_set_buffer_size(
621 ssl_fixture->base.config, odd_sizes[ind1], odd_sizes[ind2],
622 odd_sizes[ind3], odd_sizes[ind4], odd_sizes[ind5]);
623 tsi_test_do_round_trip(&ssl_fixture->base);
624 tsi_test_fixture_destroy(fixture);
625 }
626 }
627 }
628 }
629 }
630 }
631
ssl_tsi_test_do_handshake_session_cache()632 void ssl_tsi_test_do_handshake_session_cache() {
633 tsi_ssl_session_cache* session_cache = tsi_ssl_session_cache_create_lru(16);
634 char session_ticket_key[kSessionTicketEncryptionKeySize];
635 auto do_handshake = [&session_ticket_key,
636 &session_cache](bool session_reused) {
637 tsi_test_fixture* fixture = ssl_tsi_test_fixture_create();
638 ssl_tsi_test_fixture* ssl_fixture =
639 reinterpret_cast<ssl_tsi_test_fixture*>(fixture);
640 ssl_fixture->server_name_indication =
641 const_cast<char*>("waterzooi.test.google.be");
642 ssl_fixture->session_ticket_key = session_ticket_key;
643 ssl_fixture->session_ticket_key_size = sizeof(session_ticket_key);
644 tsi_ssl_session_cache_ref(session_cache);
645 ssl_fixture->session_cache = session_cache;
646 ssl_fixture->session_reused = session_reused;
647 tsi_test_do_round_trip(&ssl_fixture->base);
648 tsi_test_fixture_destroy(fixture);
649 };
650 memset(session_ticket_key, 'a', sizeof(session_ticket_key));
651 do_handshake(false);
652 do_handshake(true);
653 do_handshake(true);
654 // Changing session_ticket_key on server invalidates ticket.
655 memset(session_ticket_key, 'b', sizeof(session_ticket_key));
656 do_handshake(false);
657 do_handshake(true);
658 memset(session_ticket_key, 'c', sizeof(session_ticket_key));
659 do_handshake(false);
660 do_handshake(true);
661 tsi_ssl_session_cache_unref(session_cache);
662 }
663
664 static const tsi_ssl_handshaker_factory_vtable* original_vtable;
665 static bool handshaker_factory_destructor_called;
666
ssl_tsi_test_handshaker_factory_destructor(tsi_ssl_handshaker_factory * factory)667 static void ssl_tsi_test_handshaker_factory_destructor(
668 tsi_ssl_handshaker_factory* factory) {
669 GPR_ASSERT(factory != nullptr);
670 handshaker_factory_destructor_called = true;
671 if (original_vtable != nullptr && original_vtable->destroy != nullptr) {
672 original_vtable->destroy(factory);
673 }
674 }
675
676 static tsi_ssl_handshaker_factory_vtable test_handshaker_factory_vtable = {
677 ssl_tsi_test_handshaker_factory_destructor};
678
test_tsi_ssl_client_handshaker_factory_refcounting()679 void test_tsi_ssl_client_handshaker_factory_refcounting() {
680 int i;
681 char* cert_chain = load_file(SSL_TSI_TEST_CREDENTIALS_DIR, "client.pem");
682
683 tsi_ssl_client_handshaker_options options;
684 memset(&options, 0, sizeof(options));
685 options.pem_root_certs = cert_chain;
686 tsi_ssl_client_handshaker_factory* client_handshaker_factory;
687 GPR_ASSERT(tsi_create_ssl_client_handshaker_factory_with_options(
688 &options, &client_handshaker_factory) == TSI_OK);
689
690 handshaker_factory_destructor_called = false;
691 original_vtable = tsi_ssl_handshaker_factory_swap_vtable(
692 reinterpret_cast<tsi_ssl_handshaker_factory*>(client_handshaker_factory),
693 &test_handshaker_factory_vtable);
694
695 tsi_handshaker* handshaker[3];
696
697 for (i = 0; i < 3; ++i) {
698 GPR_ASSERT(tsi_ssl_client_handshaker_factory_create_handshaker(
699 client_handshaker_factory, "google.com", &handshaker[i]) ==
700 TSI_OK);
701 }
702
703 tsi_handshaker_destroy(handshaker[1]);
704 GPR_ASSERT(!handshaker_factory_destructor_called);
705
706 tsi_handshaker_destroy(handshaker[0]);
707 GPR_ASSERT(!handshaker_factory_destructor_called);
708
709 tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory);
710 GPR_ASSERT(!handshaker_factory_destructor_called);
711
712 tsi_handshaker_destroy(handshaker[2]);
713 GPR_ASSERT(handshaker_factory_destructor_called);
714
715 gpr_free(cert_chain);
716 }
717
test_tsi_ssl_server_handshaker_factory_refcounting()718 void test_tsi_ssl_server_handshaker_factory_refcounting() {
719 int i;
720 tsi_ssl_server_handshaker_factory* server_handshaker_factory;
721 tsi_handshaker* handshaker[3];
722 const char* cert_chain =
723 load_file(SSL_TSI_TEST_CREDENTIALS_DIR, "server0.pem");
724 tsi_ssl_pem_key_cert_pair cert_pair;
725
726 cert_pair.cert_chain = cert_chain;
727 cert_pair.private_key =
728 load_file(SSL_TSI_TEST_CREDENTIALS_DIR, "server0.key");
729
730 GPR_ASSERT(tsi_create_ssl_server_handshaker_factory(
731 &cert_pair, 1, cert_chain, 0, nullptr, nullptr, 0,
732 &server_handshaker_factory) == TSI_OK);
733
734 handshaker_factory_destructor_called = false;
735 original_vtable = tsi_ssl_handshaker_factory_swap_vtable(
736 reinterpret_cast<tsi_ssl_handshaker_factory*>(server_handshaker_factory),
737 &test_handshaker_factory_vtable);
738
739 for (i = 0; i < 3; ++i) {
740 GPR_ASSERT(tsi_ssl_server_handshaker_factory_create_handshaker(
741 server_handshaker_factory, &handshaker[i]) == TSI_OK);
742 }
743
744 tsi_handshaker_destroy(handshaker[1]);
745 GPR_ASSERT(!handshaker_factory_destructor_called);
746
747 tsi_handshaker_destroy(handshaker[0]);
748 GPR_ASSERT(!handshaker_factory_destructor_called);
749
750 tsi_ssl_server_handshaker_factory_unref(server_handshaker_factory);
751 GPR_ASSERT(!handshaker_factory_destructor_called);
752
753 tsi_handshaker_destroy(handshaker[2]);
754 GPR_ASSERT(handshaker_factory_destructor_called);
755
756 ssl_test_pem_key_cert_pair_destroy(cert_pair);
757 }
758
759 /* Attempting to create a handshaker factory with invalid parameters should fail
760 * but not crash. */
test_tsi_ssl_client_handshaker_factory_bad_params()761 void test_tsi_ssl_client_handshaker_factory_bad_params() {
762 const char* cert_chain = "This is not a valid PEM file.";
763
764 tsi_ssl_client_handshaker_factory* client_handshaker_factory;
765 tsi_ssl_client_handshaker_options options;
766 memset(&options, 0, sizeof(options));
767 options.pem_root_certs = cert_chain;
768 GPR_ASSERT(tsi_create_ssl_client_handshaker_factory_with_options(
769 &options, &client_handshaker_factory) == TSI_INVALID_ARGUMENT);
770 tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory);
771 }
772
ssl_tsi_test_handshaker_factory_internals()773 void ssl_tsi_test_handshaker_factory_internals() {
774 test_tsi_ssl_client_handshaker_factory_refcounting();
775 test_tsi_ssl_server_handshaker_factory_refcounting();
776 test_tsi_ssl_client_handshaker_factory_bad_params();
777 }
778
main(int argc,char ** argv)779 int main(int argc, char** argv) {
780 grpc_test_init(argc, argv);
781 grpc_init();
782
783 ssl_tsi_test_do_handshake_tiny_handshake_buffer();
784 ssl_tsi_test_do_handshake_small_handshake_buffer();
785 ssl_tsi_test_do_handshake();
786 ssl_tsi_test_do_handshake_with_root_store();
787 ssl_tsi_test_do_handshake_with_client_authentication();
788 ssl_tsi_test_do_handshake_with_client_authentication_and_root_store();
789 ssl_tsi_test_do_handshake_with_server_name_indication_exact_domain();
790 ssl_tsi_test_do_handshake_with_server_name_indication_wild_star_domain();
791 ssl_tsi_test_do_handshake_with_bad_server_cert();
792 ssl_tsi_test_do_handshake_with_bad_client_cert();
793 #ifdef OPENSSL_IS_BORINGSSL
794 // BoringSSL and OpenSSL have different behaviors on mismatched ALPN.
795 ssl_tsi_test_do_handshake_alpn_client_no_server();
796 ssl_tsi_test_do_handshake_alpn_client_server_mismatch();
797 #endif
798 ssl_tsi_test_do_handshake_alpn_server_no_client();
799 ssl_tsi_test_do_handshake_alpn_client_server_ok();
800 ssl_tsi_test_do_handshake_session_cache();
801 ssl_tsi_test_do_round_trip_for_all_configs();
802 ssl_tsi_test_do_round_trip_odd_buffer_size();
803 ssl_tsi_test_handshaker_factory_internals();
804 grpc_shutdown();
805 return 0;
806 }
807