Imported Upstream version 1.36.0
[platform/upstream/grpc.git] / src / core / lib / security / security_connector / tls / tls_security_connector.cc
1 /*
2  *
3  * Copyright 2018 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/tls/tls_security_connector.h"
22
23 #include <stdbool.h>
24 #include <string.h>
25
26 #include "absl/strings/str_cat.h"
27 #include "absl/strings/string_view.h"
28
29 #include <grpc/grpc.h>
30 #include <grpc/support/alloc.h>
31 #include <grpc/support/log.h>
32 #include <grpc/support/string_util.h>
33
34 #include "src/core/lib/gprpp/host_port.h"
35 #include "src/core/lib/security/credentials/ssl/ssl_credentials.h"
36 #include "src/core/lib/security/credentials/tls/tls_credentials.h"
37 #include "src/core/lib/security/security_connector/ssl_utils.h"
38 #include "src/core/lib/security/transport/security_handshaker.h"
39 #include "src/core/lib/slice/slice_internal.h"
40 #include "src/core/lib/transport/transport.h"
41 #include "src/core/tsi/ssl_transport_security.h"
42 #include "src/core/tsi/transport_security.h"
43
44 namespace grpc_core {
45
46 namespace {
47
48 tsi_ssl_pem_key_cert_pair* ConvertToTsiPemKeyCertPair(
49     const grpc_core::PemKeyCertPairList& cert_pair_list) {
50   tsi_ssl_pem_key_cert_pair* tsi_pairs = nullptr;
51   size_t num_key_cert_pairs = cert_pair_list.size();
52   if (num_key_cert_pairs > 0) {
53     GPR_ASSERT(cert_pair_list.data() != nullptr);
54     tsi_pairs = static_cast<tsi_ssl_pem_key_cert_pair*>(
55         gpr_zalloc(num_key_cert_pairs * sizeof(tsi_ssl_pem_key_cert_pair)));
56   }
57   for (size_t i = 0; i < num_key_cert_pairs; i++) {
58     GPR_ASSERT(!cert_pair_list[i].private_key().empty());
59     GPR_ASSERT(!cert_pair_list[i].cert_chain().empty());
60     tsi_pairs[i].cert_chain =
61         gpr_strdup(cert_pair_list[i].cert_chain().c_str());
62     tsi_pairs[i].private_key =
63         gpr_strdup(cert_pair_list[i].private_key().c_str());
64   }
65   return tsi_pairs;
66 }
67
68 }  // namespace
69
70 // -------------------channel security connector-------------------
71 grpc_core::RefCountedPtr<grpc_channel_security_connector>
72 TlsChannelSecurityConnector::CreateTlsChannelSecurityConnector(
73     grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds,
74     grpc_core::RefCountedPtr<grpc_tls_credentials_options> options,
75     grpc_core::RefCountedPtr<grpc_call_credentials> request_metadata_creds,
76     const char* target_name, const char* overridden_target_name,
77     tsi_ssl_session_cache* ssl_session_cache) {
78   if (channel_creds == nullptr) {
79     gpr_log(GPR_ERROR,
80             "channel_creds is nullptr in "
81             "TlsChannelSecurityConnectorCreate()");
82     return nullptr;
83   }
84   if (options == nullptr) {
85     gpr_log(GPR_ERROR,
86             "options is nullptr in "
87             "TlsChannelSecurityConnectorCreate()");
88     return nullptr;
89   }
90   if (target_name == nullptr) {
91     gpr_log(GPR_ERROR,
92             "target_name is nullptr in "
93             "TlsChannelSecurityConnectorCreate()");
94     return nullptr;
95   }
96   grpc_core::RefCountedPtr<TlsChannelSecurityConnector> c =
97       grpc_core::MakeRefCounted<TlsChannelSecurityConnector>(
98           std::move(channel_creds), std::move(options),
99           std::move(request_metadata_creds), target_name,
100           overridden_target_name, ssl_session_cache);
101   return c;
102 }
103
104 TlsChannelSecurityConnector::TlsChannelSecurityConnector(
105     grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds,
106     grpc_core::RefCountedPtr<grpc_tls_credentials_options> options,
107     grpc_core::RefCountedPtr<grpc_call_credentials> request_metadata_creds,
108     const char* target_name, const char* overridden_target_name,
109     tsi_ssl_session_cache* ssl_session_cache)
110     : grpc_channel_security_connector(GRPC_SSL_URL_SCHEME,
111                                       std::move(channel_creds),
112                                       std::move(request_metadata_creds)),
113       options_(std::move(options)),
114       overridden_target_name_(
115           overridden_target_name == nullptr ? "" : overridden_target_name),
116       ssl_session_cache_(ssl_session_cache) {
117   if (ssl_session_cache_ != nullptr) {
118     tsi_ssl_session_cache_ref(ssl_session_cache_);
119   }
120   check_arg_ = ServerAuthorizationCheckArgCreate(this);
121   absl::string_view host;
122   absl::string_view port;
123   grpc_core::SplitHostPort(target_name, &host, &port);
124   target_name_ = std::string(host);
125   // Create a watcher.
126   auto watcher_ptr = absl::make_unique<TlsChannelCertificateWatcher>(this);
127   certificate_watcher_ = watcher_ptr.get();
128   // Register the watcher with the distributor.
129   grpc_tls_certificate_distributor* distributor =
130       options_->certificate_distributor();
131   absl::optional<std::string> watched_root_cert_name;
132   if (options_->watch_root_cert()) {
133     watched_root_cert_name = options_->root_cert_name();
134   }
135   absl::optional<std::string> watched_identity_cert_name;
136   if (options_->watch_identity_pair()) {
137     watched_identity_cert_name = options_->identity_cert_name();
138   }
139   // We will use the root certs stored in system default locations if not
140   // watching root certs on the client side. We will handle this case
141   // differently here, because "watching a default roots without the identity
142   // certs" is a valid case(and hence we will need to call
143   // OnCertificatesChanged), but it requires nothing from the provider, and
144   // hence no need to register the watcher.
145   bool use_default_roots = !options_->watch_root_cert();
146   if (use_default_roots && !options_->watch_identity_pair()) {
147     watcher_ptr->OnCertificatesChanged(absl::nullopt, absl::nullopt);
148   } else {
149     distributor->WatchTlsCertificates(std::move(watcher_ptr),
150                                       watched_root_cert_name,
151                                       watched_identity_cert_name);
152   }
153 }
154
155 TlsChannelSecurityConnector::~TlsChannelSecurityConnector() {
156   if (ssl_session_cache_ != nullptr) {
157     tsi_ssl_session_cache_unref(ssl_session_cache_);
158   }
159   // Cancel all the watchers.
160   grpc_tls_certificate_distributor* distributor =
161       options_->certificate_distributor();
162   if (distributor != nullptr) {
163     distributor->CancelTlsCertificatesWatch(certificate_watcher_);
164   }
165   if (client_handshaker_factory_ != nullptr) {
166     tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory_);
167   }
168   if (check_arg_ != nullptr) {
169     ServerAuthorizationCheckArgDestroy(check_arg_);
170   }
171 }
172
173 void TlsChannelSecurityConnector::add_handshakers(
174     const grpc_channel_args* args, grpc_pollset_set* /*interested_parties*/,
175     grpc_core::HandshakeManager* handshake_mgr) {
176   grpc_core::MutexLock lock(&mu_);
177   if (client_handshaker_factory_ != nullptr) {
178     // Instantiate TSI handshaker.
179     tsi_handshaker* tsi_hs = nullptr;
180     tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker(
181         client_handshaker_factory_,
182         overridden_target_name_.empty() ? target_name_.c_str()
183                                         : overridden_target_name_.c_str(),
184         &tsi_hs);
185     if (result != TSI_OK) {
186       gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
187               tsi_result_to_string(result));
188       return;
189     }
190     // Create handshakers.
191     handshake_mgr->Add(grpc_core::SecurityHandshakerCreate(tsi_hs, this, args));
192     return;
193   }
194   // TODO(ZhenLian): Implement the logic(delegation to
195   // BlockOnInitialCredentialHandshaker) when certificates are not ready.
196   gpr_log(GPR_ERROR, "%s not supported yet.",
197           "Client BlockOnInitialCredentialHandshaker");
198 }
199
200 void TlsChannelSecurityConnector::check_peer(
201     tsi_peer peer, grpc_endpoint* /*ep*/,
202     grpc_core::RefCountedPtr<grpc_auth_context>* auth_context,
203     grpc_closure* on_peer_checked) {
204   const char* target_name = overridden_target_name_.empty()
205                                 ? target_name_.c_str()
206                                 : overridden_target_name_.c_str();
207   grpc_error* error = grpc_ssl_check_alpn(&peer);
208   if (error != GRPC_ERROR_NONE) {
209     grpc_core::ExecCtx::Run(DEBUG_LOCATION, on_peer_checked, error);
210     tsi_peer_destruct(&peer);
211     return;
212   }
213   *auth_context =
214       grpc_ssl_peer_to_auth_context(&peer, GRPC_TLS_TRANSPORT_SECURITY_TYPE);
215   if (options_->server_verification_option() == GRPC_TLS_SERVER_VERIFICATION) {
216     /* Do the default host name check if specifying the target name. */
217     error = internal::TlsCheckHostName(target_name, &peer);
218     if (error != GRPC_ERROR_NONE) {
219       grpc_core::ExecCtx::Run(DEBUG_LOCATION, on_peer_checked, error);
220       tsi_peer_destruct(&peer);
221       return;
222     }
223   }
224   /* Do the custom server authorization check, if specified by the user. */
225   const grpc_tls_server_authorization_check_config* config =
226       options_->server_authorization_check_config();
227   /* If server authorization config is not null, use it to perform
228    * server authorization check. */
229   if (config != nullptr) {
230     const tsi_peer_property* p =
231         tsi_peer_get_property_by_name(&peer, TSI_X509_PEM_CERT_PROPERTY);
232     if (p == nullptr) {
233       error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
234           "Cannot check peer: missing pem cert property.");
235     } else {
236       char* peer_pem = static_cast<char*>(gpr_zalloc(p->value.length + 1));
237       memcpy(peer_pem, p->value.data, p->value.length);
238       GPR_ASSERT(check_arg_ != nullptr);
239       check_arg_->peer_cert = check_arg_->peer_cert == nullptr
240                                   ? gpr_strdup(peer_pem)
241                                   : check_arg_->peer_cert;
242       check_arg_->target_name = check_arg_->target_name == nullptr
243                                     ? gpr_strdup(target_name)
244                                     : check_arg_->target_name;
245       on_peer_checked_ = on_peer_checked;
246       gpr_free(peer_pem);
247       const tsi_peer_property* chain = tsi_peer_get_property_by_name(
248           &peer, TSI_X509_PEM_CERT_CHAIN_PROPERTY);
249       if (chain != nullptr) {
250         char* peer_pem_chain =
251             static_cast<char*>(gpr_zalloc(chain->value.length + 1));
252         memcpy(peer_pem_chain, chain->value.data, chain->value.length);
253         check_arg_->peer_cert_full_chain =
254             check_arg_->peer_cert_full_chain == nullptr
255                 ? gpr_strdup(peer_pem_chain)
256                 : check_arg_->peer_cert_full_chain;
257         gpr_free(peer_pem_chain);
258       }
259       // TODO(zhenlian) - This should be cleaned up as part of the custom
260       // verification changes. Fill in the subject alternative names
261       std::vector<char*> subject_alternative_names;
262       for (size_t i = 0; i < peer.property_count; i++) {
263         const tsi_peer_property* prop = &peer.properties[i];
264         if (strcmp(prop->name,
265                    TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) == 0) {
266           char* san = new char[prop->value.length + 1];
267           memcpy(san, prop->value.data, prop->value.length);
268           san[prop->value.length] = '\0';
269           subject_alternative_names.emplace_back(san);
270         }
271       }
272       if (check_arg_->subject_alternative_names != nullptr) {
273         for (size_t i = 0; i < check_arg_->subject_alternative_names_size;
274              ++i) {
275           delete[] check_arg_->subject_alternative_names[i];
276         }
277         delete[] check_arg_->subject_alternative_names;
278       }
279       check_arg_->subject_alternative_names_size =
280           subject_alternative_names.size();
281       if (subject_alternative_names.empty()) {
282         check_arg_->subject_alternative_names = nullptr;
283       } else {
284         check_arg_->subject_alternative_names =
285             new char*[check_arg_->subject_alternative_names_size];
286         for (size_t i = 0; i < check_arg_->subject_alternative_names_size;
287              ++i) {
288           check_arg_->subject_alternative_names[i] =
289               subject_alternative_names[i];
290         }
291       }
292       int callback_status = config->Schedule(check_arg_);
293       /* Server authorization check is handled asynchronously. */
294       if (callback_status) {
295         tsi_peer_destruct(&peer);
296         return;
297       }
298       /* Server authorization check is handled synchronously. */
299       error = ProcessServerAuthorizationCheckResult(check_arg_);
300     }
301   }
302   grpc_core::ExecCtx::Run(DEBUG_LOCATION, on_peer_checked, error);
303   tsi_peer_destruct(&peer);
304 }
305
306 int TlsChannelSecurityConnector::cmp(
307     const grpc_security_connector* other_sc) const {
308   auto* other = reinterpret_cast<const TlsChannelSecurityConnector*>(other_sc);
309   int c = channel_security_connector_cmp(other);
310   if (c != 0) {
311     return c;
312   }
313   return grpc_ssl_cmp_target_name(
314       target_name_.c_str(), other->target_name_.c_str(),
315       overridden_target_name_.c_str(), other->overridden_target_name_.c_str());
316 }
317
318 bool TlsChannelSecurityConnector::check_call_host(
319     absl::string_view host, grpc_auth_context* auth_context,
320     grpc_closure* /*on_call_host_checked*/, grpc_error** error) {
321   return grpc_ssl_check_call_host(host, target_name_.c_str(),
322                                   overridden_target_name_.c_str(), auth_context,
323                                   error);
324 }
325
326 void TlsChannelSecurityConnector::cancel_check_call_host(
327     grpc_closure* /*on_call_host_checked*/, grpc_error* error) {
328   GRPC_ERROR_UNREF(error);
329 }
330
331 void TlsChannelSecurityConnector::TlsChannelCertificateWatcher::
332     OnCertificatesChanged(
333         absl::optional<absl::string_view> root_certs,
334         absl::optional<grpc_core::PemKeyCertPairList> key_cert_pairs) {
335   GPR_ASSERT(security_connector_ != nullptr);
336   grpc_core::MutexLock lock(&security_connector_->mu_);
337   if (root_certs.has_value()) {
338     security_connector_->pem_root_certs_ = root_certs;
339   }
340   if (key_cert_pairs.has_value()) {
341     security_connector_->pem_key_cert_pair_list_ = std::move(key_cert_pairs);
342   }
343   const bool root_ready = !security_connector_->options_->watch_root_cert() ||
344                           security_connector_->pem_root_certs_.has_value();
345   const bool identity_ready =
346       !security_connector_->options_->watch_identity_pair() ||
347       security_connector_->pem_key_cert_pair_list_.has_value();
348   if (root_ready && identity_ready) {
349     if (security_connector_->UpdateHandshakerFactoryLocked() !=
350         GRPC_SECURITY_OK) {
351       gpr_log(GPR_ERROR, "Update handshaker factory failed.");
352     }
353   }
354 }
355
356 // TODO(ZhenLian): implement the logic to signal waiting handshakers once
357 // BlockOnInitialCredentialHandshaker is implemented.
358 void TlsChannelSecurityConnector::TlsChannelCertificateWatcher::OnError(
359     grpc_error* root_cert_error, grpc_error* identity_cert_error) {
360   if (root_cert_error != GRPC_ERROR_NONE) {
361     gpr_log(GPR_ERROR,
362             "TlsChannelCertificateWatcher getting root_cert_error: %s",
363             grpc_error_string(root_cert_error));
364   }
365   if (identity_cert_error != GRPC_ERROR_NONE) {
366     gpr_log(GPR_ERROR,
367             "TlsChannelCertificateWatcher getting identity_cert_error: %s",
368             grpc_error_string(identity_cert_error));
369   }
370   GRPC_ERROR_UNREF(root_cert_error);
371   GRPC_ERROR_UNREF(identity_cert_error);
372 }
373
374 // TODO(ZhenLian): implement the logic to signal waiting handshakers once
375 // BlockOnInitialCredentialHandshaker is implemented.
376 grpc_security_status
377 TlsChannelSecurityConnector::UpdateHandshakerFactoryLocked() {
378   bool skip_server_certificate_verification =
379       options_->server_verification_option() ==
380       GRPC_TLS_SKIP_ALL_SERVER_VERIFICATION;
381   /* Free the client handshaker factory if exists. */
382   if (client_handshaker_factory_ != nullptr) {
383     tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory_);
384   }
385   std::string pem_root_certs;
386   if (pem_root_certs_.has_value()) {
387     // TODO(ZhenLian): update the underlying TSI layer to use C++ types like
388     // std::string and absl::string_view to avoid making another copy here.
389     pem_root_certs = std::string(*pem_root_certs_);
390   }
391   tsi_ssl_pem_key_cert_pair* pem_key_cert_pair = nullptr;
392   if (pem_key_cert_pair_list_.has_value()) {
393     pem_key_cert_pair = ConvertToTsiPemKeyCertPair(*pem_key_cert_pair_list_);
394   }
395   bool use_default_roots = !options_->watch_root_cert();
396   grpc_security_status status = grpc_ssl_tsi_client_handshaker_factory_init(
397       pem_key_cert_pair,
398       pem_root_certs.empty() || use_default_roots ? nullptr
399                                                   : pem_root_certs.c_str(),
400       skip_server_certificate_verification,
401       grpc_get_tsi_tls_version(options_->min_tls_version()),
402       grpc_get_tsi_tls_version(options_->max_tls_version()), ssl_session_cache_,
403       &client_handshaker_factory_);
404   /* Free memory. */
405   if (pem_key_cert_pair != nullptr) {
406     grpc_tsi_ssl_pem_key_cert_pairs_destroy(pem_key_cert_pair, 1);
407   }
408   return status;
409 }
410
411 void TlsChannelSecurityConnector::ServerAuthorizationCheckDone(
412     grpc_tls_server_authorization_check_arg* arg) {
413   GPR_ASSERT(arg != nullptr);
414   grpc_core::ExecCtx exec_ctx;
415   grpc_error* error = ProcessServerAuthorizationCheckResult(arg);
416   TlsChannelSecurityConnector* connector =
417       static_cast<TlsChannelSecurityConnector*>(arg->cb_user_data);
418   grpc_core::ExecCtx::Run(DEBUG_LOCATION, connector->on_peer_checked_, error);
419 }
420
421 grpc_error* TlsChannelSecurityConnector::ProcessServerAuthorizationCheckResult(
422     grpc_tls_server_authorization_check_arg* arg) {
423   grpc_error* error = GRPC_ERROR_NONE;
424   /* Server authorization check is cancelled by caller. */
425   if (arg->status == GRPC_STATUS_CANCELLED) {
426     error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(
427         absl::StrCat("Server authorization check is cancelled by the caller "
428                      "with error: ",
429                      arg->error_details->error_details())
430             .c_str());
431   } else if (arg->status == GRPC_STATUS_OK) {
432     /* Server authorization check completed successfully but returned check
433      * failure. */
434     if (!arg->success) {
435       error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(
436           absl::StrCat("Server authorization check failed with error: ",
437                        arg->error_details->error_details())
438               .c_str());
439     }
440     /* Server authorization check did not complete correctly. */
441   } else {
442     error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(
443         absl::StrCat(
444             "Server authorization check did not finish correctly with error: ",
445             arg->error_details->error_details())
446             .c_str());
447   }
448   return error;
449 }
450
451 grpc_tls_server_authorization_check_arg*
452 TlsChannelSecurityConnector::ServerAuthorizationCheckArgCreate(
453     void* user_data) {
454   grpc_tls_server_authorization_check_arg* arg =
455       new grpc_tls_server_authorization_check_arg();
456   arg->target_name = nullptr;
457   arg->peer_cert = nullptr;
458   arg->peer_cert_full_chain = nullptr;
459   arg->subject_alternative_names = nullptr;
460   arg->subject_alternative_names_size = 0;
461   arg->error_details = new grpc_tls_error_details();
462   arg->cb = ServerAuthorizationCheckDone;
463   arg->cb_user_data = user_data;
464   arg->status = GRPC_STATUS_OK;
465   return arg;
466 }
467
468 void TlsChannelSecurityConnector::ServerAuthorizationCheckArgDestroy(
469     grpc_tls_server_authorization_check_arg* arg) {
470   if (arg == nullptr) {
471     return;
472   }
473   gpr_free(const_cast<char*>(arg->target_name));
474   gpr_free(const_cast<char*>(arg->peer_cert));
475   gpr_free(const_cast<char*>(arg->peer_cert_full_chain));
476   for (size_t i = 0; i < arg->subject_alternative_names_size; ++i) {
477     delete[] arg->subject_alternative_names[i];
478   }
479   delete[] arg->subject_alternative_names;
480   delete arg->error_details;
481   if (arg->destroy_context != nullptr) {
482     arg->destroy_context(arg->context);
483   }
484   delete arg;
485 }
486
487 // -------------------server security connector-------------------
488 grpc_core::RefCountedPtr<grpc_server_security_connector>
489 TlsServerSecurityConnector::CreateTlsServerSecurityConnector(
490     grpc_core::RefCountedPtr<grpc_server_credentials> server_creds,
491     grpc_core::RefCountedPtr<grpc_tls_credentials_options> options) {
492   if (server_creds == nullptr) {
493     gpr_log(GPR_ERROR,
494             "server_creds is nullptr in "
495             "TlsServerSecurityConnectorCreate()");
496     return nullptr;
497   }
498   if (options == nullptr) {
499     gpr_log(GPR_ERROR,
500             "options is nullptr in "
501             "TlsServerSecurityConnectorCreate()");
502     return nullptr;
503   }
504   grpc_core::RefCountedPtr<TlsServerSecurityConnector> c =
505       grpc_core::MakeRefCounted<TlsServerSecurityConnector>(
506           std::move(server_creds), std::move(options));
507   return c;
508 }
509
510 TlsServerSecurityConnector::TlsServerSecurityConnector(
511     grpc_core::RefCountedPtr<grpc_server_credentials> server_creds,
512     grpc_core::RefCountedPtr<grpc_tls_credentials_options> options)
513     : grpc_server_security_connector(GRPC_SSL_URL_SCHEME,
514                                      std::move(server_creds)),
515       options_(std::move(options)) {
516   // Create a watcher.
517   auto watcher_ptr = absl::make_unique<TlsServerCertificateWatcher>(this);
518   certificate_watcher_ = watcher_ptr.get();
519   // Register the watcher with the distributor.
520   grpc_tls_certificate_distributor* distributor =
521       options_->certificate_distributor();
522   absl::optional<std::string> watched_root_cert_name;
523   if (options_->watch_root_cert()) {
524     watched_root_cert_name = options_->root_cert_name();
525   }
526   absl::optional<std::string> watched_identity_cert_name;
527   if (options_->watch_identity_pair()) {
528     watched_identity_cert_name = options_->identity_cert_name();
529   }
530   // Server side won't use default system roots at any time.
531   distributor->WatchTlsCertificates(std::move(watcher_ptr),
532                                     watched_root_cert_name,
533                                     watched_identity_cert_name);
534 }
535
536 TlsServerSecurityConnector::~TlsServerSecurityConnector() {
537   // Cancel all the watchers.
538   grpc_tls_certificate_distributor* distributor =
539       options_->certificate_distributor();
540   distributor->CancelTlsCertificatesWatch(certificate_watcher_);
541   if (server_handshaker_factory_ != nullptr) {
542     tsi_ssl_server_handshaker_factory_unref(server_handshaker_factory_);
543   }
544 }
545
546 void TlsServerSecurityConnector::add_handshakers(
547     const grpc_channel_args* args, grpc_pollset_set* /*interested_parties*/,
548     grpc_core::HandshakeManager* handshake_mgr) {
549   grpc_core::MutexLock lock(&mu_);
550   if (server_handshaker_factory_ != nullptr) {
551     // Instantiate TSI handshaker.
552     tsi_handshaker* tsi_hs = nullptr;
553     tsi_result result = tsi_ssl_server_handshaker_factory_create_handshaker(
554         server_handshaker_factory_, &tsi_hs);
555     if (result != TSI_OK) {
556       gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
557               tsi_result_to_string(result));
558       return;
559     }
560     // Create handshakers.
561     handshake_mgr->Add(grpc_core::SecurityHandshakerCreate(tsi_hs, this, args));
562     return;
563   }
564   // TODO(ZhenLian): Implement the logic(delegation to
565   // BlockOnInitialCredentialHandshaker) when certificates are not ready.
566   gpr_log(GPR_ERROR, "%s not supported yet.",
567           "Server BlockOnInitialCredentialHandshaker");
568 }
569
570 void TlsServerSecurityConnector::check_peer(
571     tsi_peer peer, grpc_endpoint* /*ep*/,
572     grpc_core::RefCountedPtr<grpc_auth_context>* auth_context,
573     grpc_closure* on_peer_checked) {
574   grpc_error* error = grpc_ssl_check_alpn(&peer);
575   *auth_context =
576       grpc_ssl_peer_to_auth_context(&peer, GRPC_TLS_TRANSPORT_SECURITY_TYPE);
577   tsi_peer_destruct(&peer);
578   grpc_core::ExecCtx::Run(DEBUG_LOCATION, on_peer_checked, error);
579 }
580
581 int TlsServerSecurityConnector::cmp(
582     const grpc_security_connector* other) const {
583   return server_security_connector_cmp(
584       static_cast<const grpc_server_security_connector*>(other));
585 }
586
587 void TlsServerSecurityConnector::TlsServerCertificateWatcher::
588     OnCertificatesChanged(
589         absl::optional<absl::string_view> root_certs,
590         absl::optional<grpc_core::PemKeyCertPairList> key_cert_pairs) {
591   GPR_ASSERT(security_connector_ != nullptr);
592   grpc_core::MutexLock lock(&security_connector_->mu_);
593   if (root_certs.has_value()) {
594     security_connector_->pem_root_certs_ = root_certs;
595   }
596   if (key_cert_pairs.has_value()) {
597     security_connector_->pem_key_cert_pair_list_ = std::move(key_cert_pairs);
598   }
599   bool root_being_watched = security_connector_->options_->watch_root_cert();
600   bool root_has_value = security_connector_->pem_root_certs_.has_value();
601   bool identity_being_watched =
602       security_connector_->options_->watch_identity_pair();
603   bool identity_has_value =
604       security_connector_->pem_key_cert_pair_list_.has_value();
605   if ((root_being_watched && root_has_value && identity_being_watched &&
606        identity_has_value) ||
607       (root_being_watched && root_has_value && !identity_being_watched) ||
608       (!root_being_watched && identity_being_watched && identity_has_value)) {
609     if (security_connector_->UpdateHandshakerFactoryLocked() !=
610         GRPC_SECURITY_OK) {
611       gpr_log(GPR_ERROR, "Update handshaker factory failed.");
612     }
613   }
614 }
615
616 // TODO(ZhenLian): implement the logic to signal waiting handshakers once
617 // BlockOnInitialCredentialHandshaker is implemented.
618 void TlsServerSecurityConnector::TlsServerCertificateWatcher::OnError(
619     grpc_error* root_cert_error, grpc_error* identity_cert_error) {
620   if (root_cert_error != GRPC_ERROR_NONE) {
621     gpr_log(GPR_ERROR,
622             "TlsServerCertificateWatcher getting root_cert_error: %s",
623             grpc_error_string(root_cert_error));
624   }
625   if (identity_cert_error != GRPC_ERROR_NONE) {
626     gpr_log(GPR_ERROR,
627             "TlsServerCertificateWatcher getting identity_cert_error: %s",
628             grpc_error_string(identity_cert_error));
629   }
630   GRPC_ERROR_UNREF(root_cert_error);
631   GRPC_ERROR_UNREF(identity_cert_error);
632 }
633
634 // TODO(ZhenLian): implement the logic to signal waiting handshakers once
635 // BlockOnInitialCredentialHandshaker is implemented.
636 grpc_security_status
637 TlsServerSecurityConnector::UpdateHandshakerFactoryLocked() {
638   /* Free the server handshaker factory if exists. */
639   if (server_handshaker_factory_ != nullptr) {
640     tsi_ssl_server_handshaker_factory_unref(server_handshaker_factory_);
641   }
642   // The identity certs on the server side shouldn't be empty.
643   GPR_ASSERT(pem_key_cert_pair_list_.has_value());
644   GPR_ASSERT(!(*pem_key_cert_pair_list_).empty());
645   std::string pem_root_certs;
646   if (pem_root_certs_.has_value()) {
647     // TODO(ZhenLian): update the underlying TSI layer to use C++ types like
648     // std::string and absl::string_view to avoid making another copy here.
649     pem_root_certs = std::string(*pem_root_certs_);
650   }
651   tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs = nullptr;
652   pem_key_cert_pairs = ConvertToTsiPemKeyCertPair(*pem_key_cert_pair_list_);
653   size_t num_key_cert_pairs = (*pem_key_cert_pair_list_).size();
654   grpc_security_status status = grpc_ssl_tsi_server_handshaker_factory_init(
655       pem_key_cert_pairs, num_key_cert_pairs,
656       pem_root_certs.empty() ? nullptr : pem_root_certs.c_str(),
657       options_->cert_request_type(),
658       grpc_get_tsi_tls_version(options_->min_tls_version()),
659       grpc_get_tsi_tls_version(options_->max_tls_version()),
660       &server_handshaker_factory_);
661   /* Free memory. */
662   grpc_tsi_ssl_pem_key_cert_pairs_destroy(pem_key_cert_pairs,
663                                           num_key_cert_pairs);
664   return status;
665 }
666
667 namespace internal {
668
669 grpc_error* TlsCheckHostName(const char* peer_name, const tsi_peer* peer) {
670   /* Check the peer name if specified. */
671   if (peer_name != nullptr && !grpc_ssl_host_matches_name(peer, peer_name)) {
672     return GRPC_ERROR_CREATE_FROM_COPIED_STRING(
673         absl::StrCat("Peer name ", peer_name, " is not in peer certificate")
674             .c_str());
675   }
676   return GRPC_ERROR_NONE;
677 }
678
679 }  // namespace internal
680
681 }  // namespace grpc_core