Home | History | Annotate | Download | only in security_connector
      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 
     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 
     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 
     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. */
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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
    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