• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  * Copyright 2015 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 <grpc/support/port_platform.h>
20 
21 #include "src/core/lib/security/security_connector/security_connector.h"
22 
23 #include <stdbool.h>
24 
25 #include <grpc/slice_buffer.h>
26 #include <grpc/support/alloc.h>
27 #include <grpc/support/log.h>
28 #include <grpc/support/string_util.h>
29 
30 #include "src/core/ext/transport/chttp2/alpn/alpn.h"
31 #include "src/core/lib/channel/channel_args.h"
32 #include "src/core/lib/channel/handshaker.h"
33 #include "src/core/lib/gpr/env.h"
34 #include "src/core/lib/gpr/host_port.h"
35 #include "src/core/lib/gpr/string.h"
36 #include "src/core/lib/iomgr/load_file.h"
37 #include "src/core/lib/security/context/security_context.h"
38 #include "src/core/lib/security/credentials/credentials.h"
39 #include "src/core/lib/security/credentials/fake/fake_credentials.h"
40 #include "src/core/lib/security/credentials/ssl/ssl_credentials.h"
41 #include "src/core/lib/security/security_connector/load_system_roots.h"
42 #include "src/core/lib/security/transport/secure_endpoint.h"
43 #include "src/core/lib/security/transport/security_handshaker.h"
44 #include "src/core/lib/security/transport/target_authority_table.h"
45 #include "src/core/tsi/fake_transport_security.h"
46 #include "src/core/tsi/ssl_transport_security.h"
47 
48 grpc_core::DebugOnlyTraceFlag grpc_trace_security_connector_refcount(
49     false, "security_connector_refcount");
50 
51 /* -- Constants. -- */
52 
53 #ifndef INSTALL_PREFIX
54 static const char* installed_roots_path = "/usr/share/grpc/roots.pem";
55 #else
56 static const char* installed_roots_path =
57     INSTALL_PREFIX "/share/grpc/roots.pem";
58 #endif
59 
60 /** Environment variable used as a flag to enable/disable loading system root
61     certificates from the OS trust store. */
62 #ifndef GRPC_NOT_USE_SYSTEM_SSL_ROOTS_ENV_VAR
63 #define GRPC_NOT_USE_SYSTEM_SSL_ROOTS_ENV_VAR "GRPC_NOT_USE_SYSTEM_SSL_ROOTS"
64 #endif
65 
66 #ifndef TSI_OPENSSL_ALPN_SUPPORT
67 #define TSI_OPENSSL_ALPN_SUPPORT 1
68 #endif
69 
70 /* -- Overridden default roots. -- */
71 
72 static grpc_ssl_roots_override_callback ssl_roots_override_cb = nullptr;
73 
grpc_set_ssl_roots_override_callback(grpc_ssl_roots_override_callback cb)74 void grpc_set_ssl_roots_override_callback(grpc_ssl_roots_override_callback cb) {
75   ssl_roots_override_cb = cb;
76 }
77 
78 /* -- Cipher suites. -- */
79 
80 /* Defines the cipher suites that we accept by default. All these cipher suites
81    are compliant with HTTP2. */
82 #define GRPC_SSL_CIPHER_SUITES     \
83   "ECDHE-ECDSA-AES128-GCM-SHA256:" \
84   "ECDHE-ECDSA-AES256-GCM-SHA384:" \
85   "ECDHE-RSA-AES128-GCM-SHA256:"   \
86   "ECDHE-RSA-AES256-GCM-SHA384"
87 
88 static gpr_once cipher_suites_once = GPR_ONCE_INIT;
89 static const char* cipher_suites = nullptr;
90 
init_cipher_suites(void)91 static void init_cipher_suites(void) {
92   char* overridden = gpr_getenv("GRPC_SSL_CIPHER_SUITES");
93   cipher_suites = overridden != nullptr ? overridden : GRPC_SSL_CIPHER_SUITES;
94 }
95 
ssl_cipher_suites(void)96 static const char* ssl_cipher_suites(void) {
97   gpr_once_init(&cipher_suites_once, init_cipher_suites);
98   return cipher_suites;
99 }
100 
101 /* -- Common methods. -- */
102 
103 /* Returns the first property with that name. */
tsi_peer_get_property_by_name(const tsi_peer * peer,const char * name)104 const tsi_peer_property* tsi_peer_get_property_by_name(const tsi_peer* peer,
105                                                        const char* name) {
106   size_t i;
107   if (peer == nullptr) return nullptr;
108   for (i = 0; i < peer->property_count; i++) {
109     const tsi_peer_property* property = &peer->properties[i];
110     if (name == nullptr && property->name == nullptr) {
111       return property;
112     }
113     if (name != nullptr && property->name != nullptr &&
114         strcmp(property->name, name) == 0) {
115       return property;
116     }
117   }
118   return nullptr;
119 }
120 
grpc_channel_security_connector_add_handshakers(grpc_channel_security_connector * connector,grpc_handshake_manager * handshake_mgr)121 void grpc_channel_security_connector_add_handshakers(
122     grpc_channel_security_connector* connector,
123     grpc_handshake_manager* handshake_mgr) {
124   if (connector != nullptr) {
125     connector->add_handshakers(connector, handshake_mgr);
126   }
127 }
128 
grpc_server_security_connector_add_handshakers(grpc_server_security_connector * connector,grpc_handshake_manager * handshake_mgr)129 void grpc_server_security_connector_add_handshakers(
130     grpc_server_security_connector* connector,
131     grpc_handshake_manager* handshake_mgr) {
132   if (connector != nullptr) {
133     connector->add_handshakers(connector, handshake_mgr);
134   }
135 }
136 
grpc_security_connector_check_peer(grpc_security_connector * sc,tsi_peer peer,grpc_auth_context ** auth_context,grpc_closure * on_peer_checked)137 void grpc_security_connector_check_peer(grpc_security_connector* sc,
138                                         tsi_peer peer,
139                                         grpc_auth_context** auth_context,
140                                         grpc_closure* on_peer_checked) {
141   if (sc == nullptr) {
142     GRPC_CLOSURE_SCHED(on_peer_checked,
143                        GRPC_ERROR_CREATE_FROM_STATIC_STRING(
144                            "cannot check peer -- no security connector"));
145     tsi_peer_destruct(&peer);
146   } else {
147     sc->vtable->check_peer(sc, peer, auth_context, on_peer_checked);
148   }
149 }
150 
grpc_security_connector_cmp(grpc_security_connector * sc,grpc_security_connector * other)151 int grpc_security_connector_cmp(grpc_security_connector* sc,
152                                 grpc_security_connector* other) {
153   if (sc == nullptr || other == nullptr) return GPR_ICMP(sc, other);
154   int c = GPR_ICMP(sc->vtable, other->vtable);
155   if (c != 0) return c;
156   return sc->vtable->cmp(sc, other);
157 }
158 
grpc_channel_security_connector_cmp(grpc_channel_security_connector * sc1,grpc_channel_security_connector * sc2)159 int grpc_channel_security_connector_cmp(grpc_channel_security_connector* sc1,
160                                         grpc_channel_security_connector* sc2) {
161   GPR_ASSERT(sc1->channel_creds != nullptr);
162   GPR_ASSERT(sc2->channel_creds != nullptr);
163   int c = GPR_ICMP(sc1->channel_creds, sc2->channel_creds);
164   if (c != 0) return c;
165   c = GPR_ICMP(sc1->request_metadata_creds, sc2->request_metadata_creds);
166   if (c != 0) return c;
167   c = GPR_ICMP((void*)sc1->check_call_host, (void*)sc2->check_call_host);
168   if (c != 0) return c;
169   c = GPR_ICMP((void*)sc1->cancel_check_call_host,
170                (void*)sc2->cancel_check_call_host);
171   if (c != 0) return c;
172   return GPR_ICMP((void*)sc1->add_handshakers, (void*)sc2->add_handshakers);
173 }
174 
grpc_server_security_connector_cmp(grpc_server_security_connector * sc1,grpc_server_security_connector * sc2)175 int grpc_server_security_connector_cmp(grpc_server_security_connector* sc1,
176                                        grpc_server_security_connector* sc2) {
177   GPR_ASSERT(sc1->server_creds != nullptr);
178   GPR_ASSERT(sc2->server_creds != nullptr);
179   int c = GPR_ICMP(sc1->server_creds, sc2->server_creds);
180   if (c != 0) return c;
181   return GPR_ICMP((void*)sc1->add_handshakers, (void*)sc2->add_handshakers);
182 }
183 
grpc_channel_security_connector_check_call_host(grpc_channel_security_connector * sc,const char * host,grpc_auth_context * auth_context,grpc_closure * on_call_host_checked,grpc_error ** error)184 bool grpc_channel_security_connector_check_call_host(
185     grpc_channel_security_connector* sc, const char* host,
186     grpc_auth_context* auth_context, grpc_closure* on_call_host_checked,
187     grpc_error** error) {
188   if (sc == nullptr || sc->check_call_host == nullptr) {
189     *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
190         "cannot check call host -- no security connector");
191     return true;
192   }
193   return sc->check_call_host(sc, host, auth_context, on_call_host_checked,
194                              error);
195 }
196 
grpc_channel_security_connector_cancel_check_call_host(grpc_channel_security_connector * sc,grpc_closure * on_call_host_checked,grpc_error * error)197 void grpc_channel_security_connector_cancel_check_call_host(
198     grpc_channel_security_connector* sc, grpc_closure* on_call_host_checked,
199     grpc_error* error) {
200   if (sc == nullptr || sc->cancel_check_call_host == nullptr) {
201     GRPC_ERROR_UNREF(error);
202     return;
203   }
204   sc->cancel_check_call_host(sc, on_call_host_checked, error);
205 }
206 
207 #ifndef NDEBUG
grpc_security_connector_ref(grpc_security_connector * sc,const char * file,int line,const char * reason)208 grpc_security_connector* grpc_security_connector_ref(
209     grpc_security_connector* sc, const char* file, int line,
210     const char* reason) {
211   if (sc == nullptr) return nullptr;
212   if (grpc_trace_security_connector_refcount.enabled()) {
213     gpr_atm val = gpr_atm_no_barrier_load(&sc->refcount.count);
214     gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
215             "SECURITY_CONNECTOR:%p   ref %" PRIdPTR " -> %" PRIdPTR " %s", sc,
216             val, val + 1, reason);
217   }
218 #else
219 grpc_security_connector* grpc_security_connector_ref(
220     grpc_security_connector* sc) {
221   if (sc == nullptr) return nullptr;
222 #endif
223   gpr_ref(&sc->refcount);
224   return sc;
225 }
226 
227 #ifndef NDEBUG
228 void grpc_security_connector_unref(grpc_security_connector* sc,
229                                    const char* file, int line,
230                                    const char* reason) {
231   if (sc == nullptr) return;
232   if (grpc_trace_security_connector_refcount.enabled()) {
233     gpr_atm val = gpr_atm_no_barrier_load(&sc->refcount.count);
234     gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
235             "SECURITY_CONNECTOR:%p unref %" PRIdPTR " -> %" PRIdPTR " %s", sc,
236             val, val - 1, reason);
237   }
238 #else
239 void grpc_security_connector_unref(grpc_security_connector* sc) {
240   if (sc == nullptr) return;
241 #endif
242   if (gpr_unref(&sc->refcount)) sc->vtable->destroy(sc);
243 }
244 
245 static void connector_arg_destroy(void* p) {
246   GRPC_SECURITY_CONNECTOR_UNREF((grpc_security_connector*)p,
247                                 "connector_arg_destroy");
248 }
249 
250 static void* connector_arg_copy(void* p) {
251   return GRPC_SECURITY_CONNECTOR_REF((grpc_security_connector*)p,
252                                      "connector_arg_copy");
253 }
254 
255 static int connector_cmp(void* a, void* b) {
256   return grpc_security_connector_cmp(static_cast<grpc_security_connector*>(a),
257                                      static_cast<grpc_security_connector*>(b));
258 }
259 
260 static const grpc_arg_pointer_vtable connector_arg_vtable = {
261     connector_arg_copy, connector_arg_destroy, connector_cmp};
262 
263 grpc_arg grpc_security_connector_to_arg(grpc_security_connector* sc) {
264   return grpc_channel_arg_pointer_create((char*)GRPC_ARG_SECURITY_CONNECTOR, sc,
265                                          &connector_arg_vtable);
266 }
267 
268 grpc_security_connector* grpc_security_connector_from_arg(const grpc_arg* arg) {
269   if (strcmp(arg->key, GRPC_ARG_SECURITY_CONNECTOR)) return nullptr;
270   if (arg->type != GRPC_ARG_POINTER) {
271     gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type,
272             GRPC_ARG_SECURITY_CONNECTOR);
273     return nullptr;
274   }
275   return static_cast<grpc_security_connector*>(arg->value.pointer.p);
276 }
277 
278 grpc_security_connector* grpc_security_connector_find_in_args(
279     const grpc_channel_args* args) {
280   size_t i;
281   if (args == nullptr) return nullptr;
282   for (i = 0; i < args->num_args; i++) {
283     grpc_security_connector* sc =
284         grpc_security_connector_from_arg(&args->args[i]);
285     if (sc != nullptr) return sc;
286   }
287   return nullptr;
288 }
289 
290 static tsi_client_certificate_request_type
291 get_tsi_client_certificate_request_type(
292     grpc_ssl_client_certificate_request_type grpc_request_type) {
293   switch (grpc_request_type) {
294     case GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE:
295       return TSI_DONT_REQUEST_CLIENT_CERTIFICATE;
296 
297     case GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
298       return TSI_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY;
299 
300     case GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY:
301       return TSI_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY;
302 
303     case GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
304       return TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY;
305 
306     case GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY:
307       return TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY;
308 
309     default:
310       return TSI_DONT_REQUEST_CLIENT_CERTIFICATE;
311   }
312 }
313 
314 /* -- Fake implementation. -- */
315 
316 typedef struct {
317   grpc_channel_security_connector base;
318   char* target;
319   char* expected_targets;
320   bool is_lb_channel;
321   char* target_name_override;
322 } grpc_fake_channel_security_connector;
323 
324 static void fake_channel_destroy(grpc_security_connector* sc) {
325   grpc_fake_channel_security_connector* c =
326       reinterpret_cast<grpc_fake_channel_security_connector*>(sc);
327   grpc_call_credentials_unref(c->base.request_metadata_creds);
328   gpr_free(c->target);
329   gpr_free(c->expected_targets);
330   gpr_free(c->target_name_override);
331   gpr_free(c);
332 }
333 
334 static void fake_server_destroy(grpc_security_connector* sc) { gpr_free(sc); }
335 
336 static bool fake_check_target(const char* target_type, const char* target,
337                               const char* set_str) {
338   GPR_ASSERT(target_type != nullptr);
339   GPR_ASSERT(target != nullptr);
340   char** set = nullptr;
341   size_t set_size = 0;
342   gpr_string_split(set_str, ",", &set, &set_size);
343   bool found = false;
344   for (size_t i = 0; i < set_size; ++i) {
345     if (set[i] != nullptr && strcmp(target, set[i]) == 0) found = true;
346   }
347   for (size_t i = 0; i < set_size; ++i) {
348     gpr_free(set[i]);
349   }
350   gpr_free(set);
351   return found;
352 }
353 
354 static void fake_secure_name_check(const char* target,
355                                    const char* expected_targets,
356                                    bool is_lb_channel) {
357   if (expected_targets == nullptr) return;
358   char** lbs_and_backends = nullptr;
359   size_t lbs_and_backends_size = 0;
360   bool success = false;
361   gpr_string_split(expected_targets, ";", &lbs_and_backends,
362                    &lbs_and_backends_size);
363   if (lbs_and_backends_size > 2 || lbs_and_backends_size == 0) {
364     gpr_log(GPR_ERROR, "Invalid expected targets arg value: '%s'",
365             expected_targets);
366     goto done;
367   }
368   if (is_lb_channel) {
369     if (lbs_and_backends_size != 2) {
370       gpr_log(GPR_ERROR,
371               "Invalid expected targets arg value: '%s'. Expectations for LB "
372               "channels must be of the form 'be1,be2,be3,...;lb1,lb2,...",
373               expected_targets);
374       goto done;
375     }
376     if (!fake_check_target("LB", target, lbs_and_backends[1])) {
377       gpr_log(GPR_ERROR, "LB target '%s' not found in expected set '%s'",
378               target, lbs_and_backends[1]);
379       goto done;
380     }
381     success = true;
382   } else {
383     if (!fake_check_target("Backend", target, lbs_and_backends[0])) {
384       gpr_log(GPR_ERROR, "Backend target '%s' not found in expected set '%s'",
385               target, lbs_and_backends[0]);
386       goto done;
387     }
388     success = true;
389   }
390 done:
391   for (size_t i = 0; i < lbs_and_backends_size; ++i) {
392     gpr_free(lbs_and_backends[i]);
393   }
394   gpr_free(lbs_and_backends);
395   if (!success) abort();
396 }
397 
398 static void fake_check_peer(grpc_security_connector* sc, tsi_peer peer,
399                             grpc_auth_context** auth_context,
400                             grpc_closure* on_peer_checked) {
401   const char* prop_name;
402   grpc_error* error = GRPC_ERROR_NONE;
403   *auth_context = nullptr;
404   if (peer.property_count != 1) {
405     error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
406         "Fake peers should only have 1 property.");
407     goto end;
408   }
409   prop_name = peer.properties[0].name;
410   if (prop_name == nullptr ||
411       strcmp(prop_name, TSI_CERTIFICATE_TYPE_PEER_PROPERTY)) {
412     char* msg;
413     gpr_asprintf(&msg, "Unexpected property in fake peer: %s.",
414                  prop_name == nullptr ? "<EMPTY>" : prop_name);
415     error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
416     gpr_free(msg);
417     goto end;
418   }
419   if (strncmp(peer.properties[0].value.data, TSI_FAKE_CERTIFICATE_TYPE,
420               peer.properties[0].value.length)) {
421     error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
422         "Invalid value for cert type property.");
423     goto end;
424   }
425   *auth_context = grpc_auth_context_create(nullptr);
426   grpc_auth_context_add_cstring_property(
427       *auth_context, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
428       GRPC_FAKE_TRANSPORT_SECURITY_TYPE);
429 end:
430   GRPC_CLOSURE_SCHED(on_peer_checked, error);
431   tsi_peer_destruct(&peer);
432 }
433 
434 static void fake_channel_check_peer(grpc_security_connector* sc, tsi_peer peer,
435                                     grpc_auth_context** auth_context,
436                                     grpc_closure* on_peer_checked) {
437   fake_check_peer(sc, peer, auth_context, on_peer_checked);
438   grpc_fake_channel_security_connector* c =
439       reinterpret_cast<grpc_fake_channel_security_connector*>(sc);
440   fake_secure_name_check(c->target, c->expected_targets, c->is_lb_channel);
441 }
442 
443 static void fake_server_check_peer(grpc_security_connector* sc, tsi_peer peer,
444                                    grpc_auth_context** auth_context,
445                                    grpc_closure* on_peer_checked) {
446   fake_check_peer(sc, peer, auth_context, on_peer_checked);
447 }
448 
449 static int fake_channel_cmp(grpc_security_connector* sc1,
450                             grpc_security_connector* sc2) {
451   grpc_fake_channel_security_connector* c1 =
452       reinterpret_cast<grpc_fake_channel_security_connector*>(sc1);
453   grpc_fake_channel_security_connector* c2 =
454       reinterpret_cast<grpc_fake_channel_security_connector*>(sc2);
455   int c = grpc_channel_security_connector_cmp(&c1->base, &c2->base);
456   if (c != 0) return c;
457   c = strcmp(c1->target, c2->target);
458   if (c != 0) return c;
459   if (c1->expected_targets == nullptr || c2->expected_targets == nullptr) {
460     c = GPR_ICMP(c1->expected_targets, c2->expected_targets);
461   } else {
462     c = strcmp(c1->expected_targets, c2->expected_targets);
463   }
464   if (c != 0) return c;
465   return GPR_ICMP(c1->is_lb_channel, c2->is_lb_channel);
466 }
467 
468 static int fake_server_cmp(grpc_security_connector* sc1,
469                            grpc_security_connector* sc2) {
470   return grpc_server_security_connector_cmp(
471       reinterpret_cast<grpc_server_security_connector*>(sc1),
472       reinterpret_cast<grpc_server_security_connector*>(sc2));
473 }
474 
475 static bool fake_channel_check_call_host(grpc_channel_security_connector* sc,
476                                          const char* host,
477                                          grpc_auth_context* auth_context,
478                                          grpc_closure* on_call_host_checked,
479                                          grpc_error** error) {
480   grpc_fake_channel_security_connector* c =
481       reinterpret_cast<grpc_fake_channel_security_connector*>(sc);
482   char* authority_hostname = nullptr;
483   char* authority_ignored_port = nullptr;
484   char* target_hostname = nullptr;
485   char* target_ignored_port = nullptr;
486   gpr_split_host_port(host, &authority_hostname, &authority_ignored_port);
487   gpr_split_host_port(c->target, &target_hostname, &target_ignored_port);
488   if (c->target_name_override != nullptr) {
489     char* fake_security_target_name_override_hostname = nullptr;
490     char* fake_security_target_name_override_ignored_port = nullptr;
491     gpr_split_host_port(c->target_name_override,
492                         &fake_security_target_name_override_hostname,
493                         &fake_security_target_name_override_ignored_port);
494     if (strcmp(authority_hostname,
495                fake_security_target_name_override_hostname) != 0) {
496       gpr_log(GPR_ERROR,
497               "Authority (host) '%s' != Fake Security Target override '%s'",
498               host, fake_security_target_name_override_hostname);
499       abort();
500     }
501     gpr_free(fake_security_target_name_override_hostname);
502     gpr_free(fake_security_target_name_override_ignored_port);
503   } else if (strcmp(authority_hostname, target_hostname) != 0) {
504     gpr_log(GPR_ERROR, "Authority (host) '%s' != Target '%s'",
505             authority_hostname, target_hostname);
506     abort();
507   }
508   gpr_free(authority_hostname);
509   gpr_free(authority_ignored_port);
510   gpr_free(target_hostname);
511   gpr_free(target_ignored_port);
512   return true;
513 }
514 
515 static void fake_channel_cancel_check_call_host(
516     grpc_channel_security_connector* sc, grpc_closure* on_call_host_checked,
517     grpc_error* error) {
518   GRPC_ERROR_UNREF(error);
519 }
520 
521 static void fake_channel_add_handshakers(
522     grpc_channel_security_connector* sc,
523     grpc_handshake_manager* handshake_mgr) {
524   grpc_handshake_manager_add(
525       handshake_mgr,
526       grpc_security_handshaker_create(
527           tsi_create_fake_handshaker(true /* is_client */), &sc->base));
528 }
529 
530 static void fake_server_add_handshakers(grpc_server_security_connector* sc,
531                                         grpc_handshake_manager* handshake_mgr) {
532   grpc_handshake_manager_add(
533       handshake_mgr,
534       grpc_security_handshaker_create(
535           tsi_create_fake_handshaker(false /* is_client */), &sc->base));
536 }
537 
538 static grpc_security_connector_vtable fake_channel_vtable = {
539     fake_channel_destroy, fake_channel_check_peer, fake_channel_cmp};
540 
541 static grpc_security_connector_vtable fake_server_vtable = {
542     fake_server_destroy, fake_server_check_peer, fake_server_cmp};
543 
544 grpc_channel_security_connector* grpc_fake_channel_security_connector_create(
545     grpc_channel_credentials* channel_creds,
546     grpc_call_credentials* request_metadata_creds, const char* target,
547     const grpc_channel_args* args) {
548   grpc_fake_channel_security_connector* c =
549       static_cast<grpc_fake_channel_security_connector*>(
550           gpr_zalloc(sizeof(*c)));
551   gpr_ref_init(&c->base.base.refcount, 1);
552   c->base.base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME;
553   c->base.base.vtable = &fake_channel_vtable;
554   c->base.channel_creds = channel_creds;
555   c->base.request_metadata_creds =
556       grpc_call_credentials_ref(request_metadata_creds);
557   c->base.check_call_host = fake_channel_check_call_host;
558   c->base.cancel_check_call_host = fake_channel_cancel_check_call_host;
559   c->base.add_handshakers = fake_channel_add_handshakers;
560   c->target = gpr_strdup(target);
561   const char* expected_targets = grpc_fake_transport_get_expected_targets(args);
562   c->expected_targets = gpr_strdup(expected_targets);
563   c->is_lb_channel = grpc_core::FindTargetAuthorityTableInArgs(args) != nullptr;
564   const grpc_arg* target_name_override_arg =
565       grpc_channel_args_find(args, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG);
566   if (target_name_override_arg != nullptr) {
567     c->target_name_override =
568         gpr_strdup(grpc_channel_arg_get_string(target_name_override_arg));
569   }
570   return &c->base;
571 }
572 
573 grpc_server_security_connector* grpc_fake_server_security_connector_create(
574     grpc_server_credentials* server_creds) {
575   grpc_server_security_connector* c =
576       static_cast<grpc_server_security_connector*>(
577           gpr_zalloc(sizeof(grpc_server_security_connector)));
578   gpr_ref_init(&c->base.refcount, 1);
579   c->base.vtable = &fake_server_vtable;
580   c->base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME;
581   c->server_creds = server_creds;
582   c->add_handshakers = fake_server_add_handshakers;
583   return c;
584 }
585 
586 /* --- Ssl implementation. --- */
587 
588 grpc_ssl_session_cache* grpc_ssl_session_cache_create_lru(size_t capacity) {
589   tsi_ssl_session_cache* cache = tsi_ssl_session_cache_create_lru(capacity);
590   return reinterpret_cast<grpc_ssl_session_cache*>(cache);
591 }
592 
593 void grpc_ssl_session_cache_destroy(grpc_ssl_session_cache* cache) {
594   tsi_ssl_session_cache* tsi_cache =
595       reinterpret_cast<tsi_ssl_session_cache*>(cache);
596   tsi_ssl_session_cache_unref(tsi_cache);
597 }
598 
599 static void* grpc_ssl_session_cache_arg_copy(void* p) {
600   tsi_ssl_session_cache* tsi_cache =
601       reinterpret_cast<tsi_ssl_session_cache*>(p);
602   // destroy call below will unref the pointer.
603   tsi_ssl_session_cache_ref(tsi_cache);
604   return p;
605 }
606 
607 static void grpc_ssl_session_cache_arg_destroy(void* p) {
608   tsi_ssl_session_cache* tsi_cache =
609       reinterpret_cast<tsi_ssl_session_cache*>(p);
610   tsi_ssl_session_cache_unref(tsi_cache);
611 }
612 
613 static int grpc_ssl_session_cache_arg_cmp(void* p, void* q) {
614   return GPR_ICMP(p, q);
615 }
616 
617 grpc_arg grpc_ssl_session_cache_create_channel_arg(
618     grpc_ssl_session_cache* cache) {
619   static const grpc_arg_pointer_vtable vtable = {
620       grpc_ssl_session_cache_arg_copy,
621       grpc_ssl_session_cache_arg_destroy,
622       grpc_ssl_session_cache_arg_cmp,
623   };
624   return grpc_channel_arg_pointer_create(
625       const_cast<char*>(GRPC_SSL_SESSION_CACHE_ARG), cache, &vtable);
626 }
627 
628 typedef struct {
629   grpc_channel_security_connector base;
630   tsi_ssl_client_handshaker_factory* client_handshaker_factory;
631   char* target_name;
632   char* overridden_target_name;
633   const verify_peer_options* verify_options;
634 } grpc_ssl_channel_security_connector;
635 
636 typedef struct {
637   grpc_server_security_connector base;
638   tsi_ssl_server_handshaker_factory* server_handshaker_factory;
639 } grpc_ssl_server_security_connector;
640 
641 static bool server_connector_has_cert_config_fetcher(
642     grpc_ssl_server_security_connector* c) {
643   GPR_ASSERT(c != nullptr);
644   grpc_ssl_server_credentials* server_creds =
645       reinterpret_cast<grpc_ssl_server_credentials*>(c->base.server_creds);
646   GPR_ASSERT(server_creds != nullptr);
647   return server_creds->certificate_config_fetcher.cb != nullptr;
648 }
649 
650 static void ssl_channel_destroy(grpc_security_connector* sc) {
651   grpc_ssl_channel_security_connector* c =
652       reinterpret_cast<grpc_ssl_channel_security_connector*>(sc);
653   grpc_channel_credentials_unref(c->base.channel_creds);
654   grpc_call_credentials_unref(c->base.request_metadata_creds);
655   tsi_ssl_client_handshaker_factory_unref(c->client_handshaker_factory);
656   c->client_handshaker_factory = nullptr;
657   if (c->target_name != nullptr) gpr_free(c->target_name);
658   if (c->overridden_target_name != nullptr) gpr_free(c->overridden_target_name);
659   gpr_free(sc);
660 }
661 
662 static void ssl_server_destroy(grpc_security_connector* sc) {
663   grpc_ssl_server_security_connector* c =
664       reinterpret_cast<grpc_ssl_server_security_connector*>(sc);
665   grpc_server_credentials_unref(c->base.server_creds);
666   tsi_ssl_server_handshaker_factory_unref(c->server_handshaker_factory);
667   c->server_handshaker_factory = nullptr;
668   gpr_free(sc);
669 }
670 
671 static void ssl_channel_add_handshakers(grpc_channel_security_connector* sc,
672                                         grpc_handshake_manager* handshake_mgr) {
673   grpc_ssl_channel_security_connector* c =
674       reinterpret_cast<grpc_ssl_channel_security_connector*>(sc);
675   // Instantiate TSI handshaker.
676   tsi_handshaker* tsi_hs = nullptr;
677   tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker(
678       c->client_handshaker_factory,
679       c->overridden_target_name != nullptr ? c->overridden_target_name
680                                            : c->target_name,
681       &tsi_hs);
682   if (result != TSI_OK) {
683     gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
684             tsi_result_to_string(result));
685     return;
686   }
687   // Create handshakers.
688   grpc_handshake_manager_add(
689       handshake_mgr, grpc_security_handshaker_create(tsi_hs, &sc->base));
690 }
691 
692 static const char** fill_alpn_protocol_strings(size_t* num_alpn_protocols) {
693   GPR_ASSERT(num_alpn_protocols != nullptr);
694   *num_alpn_protocols = grpc_chttp2_num_alpn_versions();
695   const char** alpn_protocol_strings = static_cast<const char**>(
696       gpr_malloc(sizeof(const char*) * (*num_alpn_protocols)));
697   for (size_t i = 0; i < *num_alpn_protocols; i++) {
698     alpn_protocol_strings[i] = grpc_chttp2_get_alpn_version_index(i);
699   }
700   return alpn_protocol_strings;
701 }
702 
703 /* Attempts to replace the server_handshaker_factory with a new factory using
704  * the provided grpc_ssl_server_certificate_config. Should new factory creation
705  * fail, the existing factory will not be replaced. Returns true on success (new
706  * factory created). */
707 static bool try_replace_server_handshaker_factory(
708     grpc_ssl_server_security_connector* sc,
709     const grpc_ssl_server_certificate_config* config) {
710   if (config == nullptr) {
711     gpr_log(GPR_ERROR,
712             "Server certificate config callback returned invalid (NULL) "
713             "config.");
714     return false;
715   }
716   gpr_log(GPR_DEBUG, "Using new server certificate config (%p).", config);
717 
718   size_t num_alpn_protocols = 0;
719   const char** alpn_protocol_strings =
720       fill_alpn_protocol_strings(&num_alpn_protocols);
721   tsi_ssl_pem_key_cert_pair* cert_pairs = grpc_convert_grpc_to_tsi_cert_pairs(
722       config->pem_key_cert_pairs, config->num_key_cert_pairs);
723   tsi_ssl_server_handshaker_factory* new_handshaker_factory = nullptr;
724   grpc_ssl_server_credentials* server_creds =
725       reinterpret_cast<grpc_ssl_server_credentials*>(sc->base.server_creds);
726   tsi_result result = tsi_create_ssl_server_handshaker_factory_ex(
727       cert_pairs, config->num_key_cert_pairs, config->pem_root_certs,
728       get_tsi_client_certificate_request_type(
729           server_creds->config.client_certificate_request),
730       ssl_cipher_suites(), alpn_protocol_strings,
731       static_cast<uint16_t>(num_alpn_protocols), &new_handshaker_factory);
732   gpr_free(cert_pairs);
733   gpr_free((void*)alpn_protocol_strings);
734 
735   if (result != TSI_OK) {
736     gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
737             tsi_result_to_string(result));
738     return false;
739   }
740   tsi_ssl_server_handshaker_factory_unref(sc->server_handshaker_factory);
741   sc->server_handshaker_factory = new_handshaker_factory;
742   return true;
743 }
744 
745 /* Attempts to fetch the server certificate config if a callback is available.
746  * Current certificate config will continue to be used if the callback returns
747  * an error. Returns true if new credentials were sucessfully loaded. */
748 static bool try_fetch_ssl_server_credentials(
749     grpc_ssl_server_security_connector* sc) {
750   grpc_ssl_server_certificate_config* certificate_config = nullptr;
751   bool status;
752 
753   GPR_ASSERT(sc != nullptr);
754   if (!server_connector_has_cert_config_fetcher(sc)) return false;
755 
756   grpc_ssl_server_credentials* server_creds =
757       reinterpret_cast<grpc_ssl_server_credentials*>(sc->base.server_creds);
758   grpc_ssl_certificate_config_reload_status cb_result =
759       server_creds->certificate_config_fetcher.cb(
760           server_creds->certificate_config_fetcher.user_data,
761           &certificate_config);
762   if (cb_result == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED) {
763     gpr_log(GPR_DEBUG, "No change in SSL server credentials.");
764     status = false;
765   } else if (cb_result == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW) {
766     status = try_replace_server_handshaker_factory(sc, certificate_config);
767   } else {
768     // Log error, continue using previously-loaded credentials.
769     gpr_log(GPR_ERROR,
770             "Failed fetching new server credentials, continuing to "
771             "use previously-loaded credentials.");
772     status = false;
773   }
774 
775   if (certificate_config != nullptr) {
776     grpc_ssl_server_certificate_config_destroy(certificate_config);
777   }
778   return status;
779 }
780 
781 static void ssl_server_add_handshakers(grpc_server_security_connector* sc,
782                                        grpc_handshake_manager* handshake_mgr) {
783   grpc_ssl_server_security_connector* c =
784       reinterpret_cast<grpc_ssl_server_security_connector*>(sc);
785   // Instantiate TSI handshaker.
786   try_fetch_ssl_server_credentials(c);
787   tsi_handshaker* tsi_hs = nullptr;
788   tsi_result result = tsi_ssl_server_handshaker_factory_create_handshaker(
789       c->server_handshaker_factory, &tsi_hs);
790   if (result != TSI_OK) {
791     gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
792             tsi_result_to_string(result));
793     return;
794   }
795   // Create handshakers.
796   grpc_handshake_manager_add(
797       handshake_mgr, grpc_security_handshaker_create(tsi_hs, &sc->base));
798 }
799 
800 int grpc_ssl_host_matches_name(const tsi_peer* peer, const char* peer_name) {
801   char* allocated_name = nullptr;
802   int r;
803 
804   char* ignored_port;
805   gpr_split_host_port(peer_name, &allocated_name, &ignored_port);
806   gpr_free(ignored_port);
807   peer_name = allocated_name;
808   if (!peer_name) return 0;
809 
810   // IPv6 zone-id should not be included in comparisons.
811   char* const zone_id = strchr(allocated_name, '%');
812   if (zone_id != nullptr) *zone_id = '\0';
813 
814   r = tsi_ssl_peer_matches_name(peer, peer_name);
815   gpr_free(allocated_name);
816   return r;
817 }
818 
819 grpc_auth_context* grpc_ssl_peer_to_auth_context(const tsi_peer* peer) {
820   size_t i;
821   grpc_auth_context* ctx = nullptr;
822   const char* peer_identity_property_name = nullptr;
823 
824   /* The caller has checked the certificate type property. */
825   GPR_ASSERT(peer->property_count >= 1);
826   ctx = grpc_auth_context_create(nullptr);
827   grpc_auth_context_add_cstring_property(
828       ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
829       GRPC_SSL_TRANSPORT_SECURITY_TYPE);
830   for (i = 0; i < peer->property_count; i++) {
831     const tsi_peer_property* prop = &peer->properties[i];
832     if (prop->name == nullptr) continue;
833     if (strcmp(prop->name, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY) == 0) {
834       /* If there is no subject alt name, have the CN as the identity. */
835       if (peer_identity_property_name == nullptr) {
836         peer_identity_property_name = GRPC_X509_CN_PROPERTY_NAME;
837       }
838       grpc_auth_context_add_property(ctx, GRPC_X509_CN_PROPERTY_NAME,
839                                      prop->value.data, prop->value.length);
840     } else if (strcmp(prop->name,
841                       TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) == 0) {
842       peer_identity_property_name = GRPC_X509_SAN_PROPERTY_NAME;
843       grpc_auth_context_add_property(ctx, GRPC_X509_SAN_PROPERTY_NAME,
844                                      prop->value.data, prop->value.length);
845     } else if (strcmp(prop->name, TSI_X509_PEM_CERT_PROPERTY) == 0) {
846       grpc_auth_context_add_property(ctx, GRPC_X509_PEM_CERT_PROPERTY_NAME,
847                                      prop->value.data, prop->value.length);
848     } else if (strcmp(prop->name, TSI_SSL_SESSION_REUSED_PEER_PROPERTY) == 0) {
849       grpc_auth_context_add_property(ctx, GRPC_SSL_SESSION_REUSED_PROPERTY,
850                                      prop->value.data, prop->value.length);
851     }
852   }
853   if (peer_identity_property_name != nullptr) {
854     GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(
855                    ctx, peer_identity_property_name) == 1);
856   }
857   return ctx;
858 }
859 
860 static grpc_error* ssl_check_peer(grpc_security_connector* sc,
861                                   const char* peer_name, const tsi_peer* peer,
862                                   grpc_auth_context** auth_context) {
863 #if TSI_OPENSSL_ALPN_SUPPORT
864   /* Check the ALPN if ALPN is supported. */
865   const tsi_peer_property* p =
866       tsi_peer_get_property_by_name(peer, TSI_SSL_ALPN_SELECTED_PROTOCOL);
867   if (p == nullptr) {
868     return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
869         "Cannot check peer: missing selected ALPN property.");
870   }
871   if (!grpc_chttp2_is_alpn_version_supported(p->value.data, p->value.length)) {
872     return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
873         "Cannot check peer: invalid ALPN value.");
874   }
875 #endif /* TSI_OPENSSL_ALPN_SUPPORT */
876   /* Check the peer name if specified. */
877   if (peer_name != nullptr && !grpc_ssl_host_matches_name(peer, peer_name)) {
878     char* msg;
879     gpr_asprintf(&msg, "Peer name %s is not in peer certificate", peer_name);
880     grpc_error* error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
881     gpr_free(msg);
882     return error;
883   }
884   *auth_context = grpc_ssl_peer_to_auth_context(peer);
885   return GRPC_ERROR_NONE;
886 }
887 
888 static void ssl_channel_check_peer(grpc_security_connector* sc, tsi_peer peer,
889                                    grpc_auth_context** auth_context,
890                                    grpc_closure* on_peer_checked) {
891   grpc_ssl_channel_security_connector* c =
892       reinterpret_cast<grpc_ssl_channel_security_connector*>(sc);
893   const char* target_name = c->overridden_target_name != nullptr
894                                 ? c->overridden_target_name
895                                 : c->target_name;
896   grpc_error* error = ssl_check_peer(sc, target_name, &peer, auth_context);
897   if (error == GRPC_ERROR_NONE &&
898       c->verify_options->verify_peer_callback != nullptr) {
899     const tsi_peer_property* p =
900         tsi_peer_get_property_by_name(&peer, TSI_X509_PEM_CERT_PROPERTY);
901     if (p == nullptr) {
902       error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
903           "Cannot check peer: missing pem cert property.");
904     } else {
905       char* peer_pem = static_cast<char*>(gpr_malloc(p->value.length + 1));
906       memcpy(peer_pem, p->value.data, p->value.length);
907       peer_pem[p->value.length] = '\0';
908       int callback_status = c->verify_options->verify_peer_callback(
909           target_name, peer_pem,
910           c->verify_options->verify_peer_callback_userdata);
911       gpr_free(peer_pem);
912       if (callback_status) {
913         char* msg;
914         gpr_asprintf(&msg, "Verify peer callback returned a failure (%d)",
915                      callback_status);
916         error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
917         gpr_free(msg);
918       }
919     }
920   }
921   GRPC_CLOSURE_SCHED(on_peer_checked, error);
922   tsi_peer_destruct(&peer);
923 }
924 
925 static void ssl_server_check_peer(grpc_security_connector* sc, tsi_peer peer,
926                                   grpc_auth_context** auth_context,
927                                   grpc_closure* on_peer_checked) {
928   grpc_error* error = ssl_check_peer(sc, nullptr, &peer, auth_context);
929   tsi_peer_destruct(&peer);
930   GRPC_CLOSURE_SCHED(on_peer_checked, error);
931 }
932 
933 static int ssl_channel_cmp(grpc_security_connector* sc1,
934                            grpc_security_connector* sc2) {
935   grpc_ssl_channel_security_connector* c1 =
936       reinterpret_cast<grpc_ssl_channel_security_connector*>(sc1);
937   grpc_ssl_channel_security_connector* c2 =
938       reinterpret_cast<grpc_ssl_channel_security_connector*>(sc2);
939   int c = grpc_channel_security_connector_cmp(&c1->base, &c2->base);
940   if (c != 0) return c;
941   c = strcmp(c1->target_name, c2->target_name);
942   if (c != 0) return c;
943   return (c1->overridden_target_name == nullptr ||
944           c2->overridden_target_name == nullptr)
945              ? GPR_ICMP(c1->overridden_target_name, c2->overridden_target_name)
946              : strcmp(c1->overridden_target_name, c2->overridden_target_name);
947 }
948 
949 static int ssl_server_cmp(grpc_security_connector* sc1,
950                           grpc_security_connector* sc2) {
951   return grpc_server_security_connector_cmp(
952       reinterpret_cast<grpc_server_security_connector*>(sc1),
953       reinterpret_cast<grpc_server_security_connector*>(sc2));
954 }
955 
956 static void add_shallow_auth_property_to_peer(tsi_peer* peer,
957                                               const grpc_auth_property* prop,
958                                               const char* tsi_prop_name) {
959   tsi_peer_property* tsi_prop = &peer->properties[peer->property_count++];
960   tsi_prop->name = const_cast<char*>(tsi_prop_name);
961   tsi_prop->value.data = prop->value;
962   tsi_prop->value.length = prop->value_length;
963 }
964 
965 tsi_peer grpc_shallow_peer_from_ssl_auth_context(
966     const grpc_auth_context* auth_context) {
967   size_t max_num_props = 0;
968   grpc_auth_property_iterator it;
969   const grpc_auth_property* prop;
970   tsi_peer peer;
971   memset(&peer, 0, sizeof(peer));
972 
973   it = grpc_auth_context_property_iterator(auth_context);
974   while (grpc_auth_property_iterator_next(&it) != nullptr) max_num_props++;
975 
976   if (max_num_props > 0) {
977     peer.properties = static_cast<tsi_peer_property*>(
978         gpr_malloc(max_num_props * sizeof(tsi_peer_property)));
979     it = grpc_auth_context_property_iterator(auth_context);
980     while ((prop = grpc_auth_property_iterator_next(&it)) != nullptr) {
981       if (strcmp(prop->name, GRPC_X509_SAN_PROPERTY_NAME) == 0) {
982         add_shallow_auth_property_to_peer(
983             &peer, prop, TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY);
984       } else if (strcmp(prop->name, GRPC_X509_CN_PROPERTY_NAME) == 0) {
985         add_shallow_auth_property_to_peer(
986             &peer, prop, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY);
987       } else if (strcmp(prop->name, GRPC_X509_PEM_CERT_PROPERTY_NAME) == 0) {
988         add_shallow_auth_property_to_peer(&peer, prop,
989                                           TSI_X509_PEM_CERT_PROPERTY);
990       }
991     }
992   }
993   return peer;
994 }
995 
996 void grpc_shallow_peer_destruct(tsi_peer* peer) {
997   if (peer->properties != nullptr) gpr_free(peer->properties);
998 }
999 
1000 static bool ssl_channel_check_call_host(grpc_channel_security_connector* sc,
1001                                         const char* host,
1002                                         grpc_auth_context* auth_context,
1003                                         grpc_closure* on_call_host_checked,
1004                                         grpc_error** error) {
1005   grpc_ssl_channel_security_connector* c =
1006       reinterpret_cast<grpc_ssl_channel_security_connector*>(sc);
1007   grpc_security_status status = GRPC_SECURITY_ERROR;
1008   tsi_peer peer = grpc_shallow_peer_from_ssl_auth_context(auth_context);
1009   if (grpc_ssl_host_matches_name(&peer, host)) status = GRPC_SECURITY_OK;
1010   /* If the target name was overridden, then the original target_name was
1011      'checked' transitively during the previous peer check at the end of the
1012      handshake. */
1013   if (c->overridden_target_name != nullptr &&
1014       strcmp(host, c->target_name) == 0) {
1015     status = GRPC_SECURITY_OK;
1016   }
1017   if (status != GRPC_SECURITY_OK) {
1018     *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
1019         "call host does not match SSL server name");
1020   }
1021   grpc_shallow_peer_destruct(&peer);
1022   return true;
1023 }
1024 
1025 static void ssl_channel_cancel_check_call_host(
1026     grpc_channel_security_connector* sc, grpc_closure* on_call_host_checked,
1027     grpc_error* error) {
1028   GRPC_ERROR_UNREF(error);
1029 }
1030 
1031 static grpc_security_connector_vtable ssl_channel_vtable = {
1032     ssl_channel_destroy, ssl_channel_check_peer, ssl_channel_cmp};
1033 
1034 static grpc_security_connector_vtable ssl_server_vtable = {
1035     ssl_server_destroy, ssl_server_check_peer, ssl_server_cmp};
1036 
1037 grpc_security_status grpc_ssl_channel_security_connector_create(
1038     grpc_channel_credentials* channel_creds,
1039     grpc_call_credentials* request_metadata_creds,
1040     const grpc_ssl_config* config, const char* target_name,
1041     const char* overridden_target_name,
1042     tsi_ssl_session_cache* ssl_session_cache,
1043     grpc_channel_security_connector** sc) {
1044   tsi_result result = TSI_OK;
1045   grpc_ssl_channel_security_connector* c;
1046   char* port;
1047   bool has_key_cert_pair;
1048   tsi_ssl_client_handshaker_options options;
1049   memset(&options, 0, sizeof(options));
1050   options.alpn_protocols =
1051       fill_alpn_protocol_strings(&options.num_alpn_protocols);
1052 
1053   if (config == nullptr || target_name == nullptr) {
1054     gpr_log(GPR_ERROR, "An ssl channel needs a config and a target name.");
1055     goto error;
1056   }
1057   if (config->pem_root_certs == nullptr) {
1058     // Use default root certificates.
1059     options.pem_root_certs = grpc_core::DefaultSslRootStore::GetPemRootCerts();
1060     options.root_store = grpc_core::DefaultSslRootStore::GetRootStore();
1061     if (options.pem_root_certs == nullptr) {
1062       gpr_log(GPR_ERROR, "Could not get default pem root certs.");
1063       goto error;
1064     }
1065   } else {
1066     options.pem_root_certs = config->pem_root_certs;
1067   }
1068   c = static_cast<grpc_ssl_channel_security_connector*>(
1069       gpr_zalloc(sizeof(grpc_ssl_channel_security_connector)));
1070 
1071   gpr_ref_init(&c->base.base.refcount, 1);
1072   c->base.base.vtable = &ssl_channel_vtable;
1073   c->base.base.url_scheme = GRPC_SSL_URL_SCHEME;
1074   c->base.channel_creds = grpc_channel_credentials_ref(channel_creds);
1075   c->base.request_metadata_creds =
1076       grpc_call_credentials_ref(request_metadata_creds);
1077   c->base.check_call_host = ssl_channel_check_call_host;
1078   c->base.cancel_check_call_host = ssl_channel_cancel_check_call_host;
1079   c->base.add_handshakers = ssl_channel_add_handshakers;
1080   gpr_split_host_port(target_name, &c->target_name, &port);
1081   gpr_free(port);
1082   if (overridden_target_name != nullptr) {
1083     c->overridden_target_name = gpr_strdup(overridden_target_name);
1084   }
1085   c->verify_options = &config->verify_options;
1086 
1087   has_key_cert_pair = config->pem_key_cert_pair != nullptr &&
1088                       config->pem_key_cert_pair->private_key != nullptr &&
1089                       config->pem_key_cert_pair->cert_chain != nullptr;
1090   if (has_key_cert_pair) {
1091     options.pem_key_cert_pair = config->pem_key_cert_pair;
1092   }
1093   options.cipher_suites = ssl_cipher_suites();
1094   options.session_cache = ssl_session_cache;
1095   result = tsi_create_ssl_client_handshaker_factory_with_options(
1096       &options, &c->client_handshaker_factory);
1097   if (result != TSI_OK) {
1098     gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
1099             tsi_result_to_string(result));
1100     ssl_channel_destroy(&c->base.base);
1101     *sc = nullptr;
1102     goto error;
1103   }
1104   *sc = &c->base;
1105   gpr_free((void*)options.alpn_protocols);
1106   return GRPC_SECURITY_OK;
1107 
1108 error:
1109   gpr_free((void*)options.alpn_protocols);
1110   return GRPC_SECURITY_ERROR;
1111 }
1112 
1113 static grpc_ssl_server_security_connector*
1114 grpc_ssl_server_security_connector_initialize(
1115     grpc_server_credentials* server_creds) {
1116   grpc_ssl_server_security_connector* c =
1117       static_cast<grpc_ssl_server_security_connector*>(
1118           gpr_zalloc(sizeof(grpc_ssl_server_security_connector)));
1119   gpr_ref_init(&c->base.base.refcount, 1);
1120   c->base.base.url_scheme = GRPC_SSL_URL_SCHEME;
1121   c->base.base.vtable = &ssl_server_vtable;
1122   c->base.add_handshakers = ssl_server_add_handshakers;
1123   c->base.server_creds = grpc_server_credentials_ref(server_creds);
1124   return c;
1125 }
1126 
1127 grpc_security_status grpc_ssl_server_security_connector_create(
1128     grpc_server_credentials* gsc, grpc_server_security_connector** sc) {
1129   tsi_result result = TSI_OK;
1130   grpc_ssl_server_credentials* server_credentials =
1131       reinterpret_cast<grpc_ssl_server_credentials*>(gsc);
1132   grpc_security_status retval = GRPC_SECURITY_OK;
1133 
1134   GPR_ASSERT(server_credentials != nullptr);
1135   GPR_ASSERT(sc != nullptr);
1136 
1137   grpc_ssl_server_security_connector* c =
1138       grpc_ssl_server_security_connector_initialize(gsc);
1139   if (server_connector_has_cert_config_fetcher(c)) {
1140     // Load initial credentials from certificate_config_fetcher:
1141     if (!try_fetch_ssl_server_credentials(c)) {
1142       gpr_log(GPR_ERROR, "Failed loading SSL server credentials from fetcher.");
1143       retval = GRPC_SECURITY_ERROR;
1144     }
1145   } else {
1146     size_t num_alpn_protocols = 0;
1147     const char** alpn_protocol_strings =
1148         fill_alpn_protocol_strings(&num_alpn_protocols);
1149     result = tsi_create_ssl_server_handshaker_factory_ex(
1150         server_credentials->config.pem_key_cert_pairs,
1151         server_credentials->config.num_key_cert_pairs,
1152         server_credentials->config.pem_root_certs,
1153         get_tsi_client_certificate_request_type(
1154             server_credentials->config.client_certificate_request),
1155         ssl_cipher_suites(), alpn_protocol_strings,
1156         static_cast<uint16_t>(num_alpn_protocols),
1157         &c->server_handshaker_factory);
1158     gpr_free((void*)alpn_protocol_strings);
1159     if (result != TSI_OK) {
1160       gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
1161               tsi_result_to_string(result));
1162       retval = GRPC_SECURITY_ERROR;
1163     }
1164   }
1165 
1166   if (retval == GRPC_SECURITY_OK) {
1167     *sc = &c->base;
1168   } else {
1169     if (c != nullptr) ssl_server_destroy(&c->base.base);
1170     if (sc != nullptr) *sc = nullptr;
1171   }
1172   return retval;
1173 }
1174 
1175 namespace grpc_core {
1176 
1177 tsi_ssl_root_certs_store* DefaultSslRootStore::default_root_store_;
1178 grpc_slice DefaultSslRootStore::default_pem_root_certs_;
1179 
1180 const tsi_ssl_root_certs_store* DefaultSslRootStore::GetRootStore() {
1181   InitRootStore();
1182   return default_root_store_;
1183 }
1184 
1185 const char* DefaultSslRootStore::GetPemRootCerts() {
1186   InitRootStore();
1187   return GRPC_SLICE_IS_EMPTY(default_pem_root_certs_)
1188              ? nullptr
1189              : reinterpret_cast<const char*>
1190                    GRPC_SLICE_START_PTR(default_pem_root_certs_);
1191 }
1192 
1193 grpc_slice DefaultSslRootStore::ComputePemRootCerts() {
1194   grpc_slice result = grpc_empty_slice();
1195   char* not_use_system_roots_env_value =
1196       gpr_getenv(GRPC_NOT_USE_SYSTEM_SSL_ROOTS_ENV_VAR);
1197   const bool not_use_system_roots = gpr_is_true(not_use_system_roots_env_value);
1198   gpr_free(not_use_system_roots_env_value);
1199   // First try to load the roots from the environment.
1200   char* default_root_certs_path =
1201       gpr_getenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR);
1202   if (default_root_certs_path != nullptr) {
1203     GRPC_LOG_IF_ERROR("load_file",
1204                       grpc_load_file(default_root_certs_path, 1, &result));
1205     gpr_free(default_root_certs_path);
1206   }
1207   // Try overridden roots if needed.
1208   grpc_ssl_roots_override_result ovrd_res = GRPC_SSL_ROOTS_OVERRIDE_FAIL;
1209   if (GRPC_SLICE_IS_EMPTY(result) && ssl_roots_override_cb != nullptr) {
1210     char* pem_root_certs = nullptr;
1211     ovrd_res = ssl_roots_override_cb(&pem_root_certs);
1212     if (ovrd_res == GRPC_SSL_ROOTS_OVERRIDE_OK) {
1213       GPR_ASSERT(pem_root_certs != nullptr);
1214       result = grpc_slice_from_copied_buffer(
1215           pem_root_certs,
1216           strlen(pem_root_certs) + 1);  // nullptr terminator.
1217     }
1218     gpr_free(pem_root_certs);
1219   }
1220   // Try loading roots from OS trust store if flag is enabled.
1221   if (GRPC_SLICE_IS_EMPTY(result) && !not_use_system_roots) {
1222     result = LoadSystemRootCerts();
1223   }
1224   // Fallback to roots manually shipped with gRPC.
1225   if (GRPC_SLICE_IS_EMPTY(result) &&
1226       ovrd_res != GRPC_SSL_ROOTS_OVERRIDE_FAIL_PERMANENTLY) {
1227     GRPC_LOG_IF_ERROR("load_file",
1228                       grpc_load_file(installed_roots_path, 1, &result));
1229   }
1230   return result;
1231 }
1232 
1233 void DefaultSslRootStore::InitRootStore() {
1234   static gpr_once once = GPR_ONCE_INIT;
1235   gpr_once_init(&once, DefaultSslRootStore::InitRootStoreOnce);
1236 }
1237 
1238 void DefaultSslRootStore::InitRootStoreOnce() {
1239   default_pem_root_certs_ = ComputePemRootCerts();
1240   if (!GRPC_SLICE_IS_EMPTY(default_pem_root_certs_)) {
1241     default_root_store_ =
1242         tsi_ssl_root_certs_store_create(reinterpret_cast<const char*>(
1243             GRPC_SLICE_START_PTR(default_pem_root_certs_)));
1244   }
1245 }
1246 
1247 }  // namespace grpc_core
1248