• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  * Copyright 2017 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 #include <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