Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / grpc-cloned / deps / grpc / src / core / lib / security / security_connector / tls / spiffe_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/spiffe_security_connector.h"
22
23 #include <stdbool.h>
24 #include <string.h>
25
26 #include <grpc/grpc.h>
27 #include <grpc/support/alloc.h>
28 #include <grpc/support/log.h>
29 #include <grpc/support/string_util.h>
30
31 #include "src/core/lib/gprpp/host_port.h"
32 #include "src/core/lib/security/credentials/ssl/ssl_credentials.h"
33 #include "src/core/lib/security/credentials/tls/spiffe_credentials.h"
34 #include "src/core/lib/security/security_connector/ssl_utils.h"
35 #include "src/core/lib/security/transport/security_handshaker.h"
36 #include "src/core/lib/slice/slice_internal.h"
37 #include "src/core/lib/transport/transport.h"
38 #include "src/core/tsi/ssl_transport_security.h"
39 #include "src/core/tsi/transport_security.h"
40
41 namespace grpc_core {
42
43 namespace {
44
45 tsi_ssl_pem_key_cert_pair* ConvertToTsiPemKeyCertPair(
46     const grpc_tls_key_materials_config::PemKeyCertPairList& cert_pair_list) {
47   tsi_ssl_pem_key_cert_pair* tsi_pairs = nullptr;
48   size_t num_key_cert_pairs = cert_pair_list.size();
49   if (num_key_cert_pairs > 0) {
50     GPR_ASSERT(cert_pair_list.data() != nullptr);
51     tsi_pairs = static_cast<tsi_ssl_pem_key_cert_pair*>(
52         gpr_zalloc(num_key_cert_pairs * sizeof(tsi_ssl_pem_key_cert_pair)));
53   }
54   for (size_t i = 0; i < num_key_cert_pairs; i++) {
55     GPR_ASSERT(cert_pair_list[i].private_key() != nullptr);
56     GPR_ASSERT(cert_pair_list[i].cert_chain() != nullptr);
57     tsi_pairs[i].cert_chain = gpr_strdup(cert_pair_list[i].cert_chain());
58     tsi_pairs[i].private_key = gpr_strdup(cert_pair_list[i].private_key());
59   }
60   return tsi_pairs;
61 }
62
63 }  // namespace
64
65 /** -- Util function to fetch SPIFFE server/channel credentials. -- */
66 grpc_status_code TlsFetchKeyMaterials(
67     const grpc_core::RefCountedPtr<grpc_tls_key_materials_config>&
68         key_materials_config,
69     const grpc_tls_credentials_options& options,
70     grpc_ssl_certificate_config_reload_status* reload_status) {
71   GPR_ASSERT(key_materials_config != nullptr);
72   bool is_key_materials_empty =
73       key_materials_config->pem_key_cert_pair_list().empty();
74   if (options.credential_reload_config() == nullptr && is_key_materials_empty) {
75     gpr_log(GPR_ERROR,
76             "Either credential reload config or key materials should be "
77             "provisioned.");
78     return GRPC_STATUS_FAILED_PRECONDITION;
79   }
80   grpc_status_code status = GRPC_STATUS_OK;
81   /* Use credential reload config to fetch credentials. */
82   if (options.credential_reload_config() != nullptr) {
83     grpc_tls_credential_reload_arg* arg =
84         grpc_core::New<grpc_tls_credential_reload_arg>();
85     arg->key_materials_config = key_materials_config.get();
86     int result = options.credential_reload_config()->Schedule(arg);
87     if (result) {
88       /* Do not support async credential reload. */
89       gpr_log(GPR_ERROR, "Async credential reload is unsupported now.");
90       status =
91           is_key_materials_empty ? GRPC_STATUS_UNIMPLEMENTED : GRPC_STATUS_OK;
92     } else {
93       GPR_ASSERT(reload_status != nullptr);
94       *reload_status = arg->status;
95       if (arg->status == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED) {
96         /* Key materials is not empty. */
97         gpr_log(GPR_DEBUG, "Credential does not change after reload.");
98       } else if (arg->status == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL) {
99         gpr_log(GPR_ERROR, "Credential reload failed with an error:");
100         if (arg->error_details != nullptr) {
101           gpr_log(GPR_ERROR, "%s", arg->error_details);
102         }
103         status = is_key_materials_empty ? GRPC_STATUS_INTERNAL : GRPC_STATUS_OK;
104       }
105     }
106     gpr_free((void*)arg->error_details);
107     grpc_core::Delete(arg);
108   }
109   return status;
110 }
111
112 SpiffeChannelSecurityConnector::SpiffeChannelSecurityConnector(
113     grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds,
114     grpc_core::RefCountedPtr<grpc_call_credentials> request_metadata_creds,
115     const char* target_name, const char* overridden_target_name)
116     : grpc_channel_security_connector(GRPC_SSL_URL_SCHEME,
117                                       std::move(channel_creds),
118                                       std::move(request_metadata_creds)),
119       overridden_target_name_(overridden_target_name == nullptr
120                                   ? nullptr
121                                   : gpr_strdup(overridden_target_name)) {
122   key_materials_config_ = grpc_tls_key_materials_config_create()->Ref();
123   check_arg_ = ServerAuthorizationCheckArgCreate(this);
124   grpc_core::StringView host;
125   grpc_core::StringView port;
126   grpc_core::SplitHostPort(target_name, &host, &port);
127   target_name_ = host.dup();
128 }
129
130 SpiffeChannelSecurityConnector::~SpiffeChannelSecurityConnector() {
131   if (client_handshaker_factory_ != nullptr) {
132     tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory_);
133   }
134   if (key_materials_config_.get() != nullptr) {
135     key_materials_config_.get()->Unref();
136   }
137   ServerAuthorizationCheckArgDestroy(check_arg_);
138 }
139
140 void SpiffeChannelSecurityConnector::add_handshakers(
141     grpc_pollset_set* interested_parties,
142     grpc_core::HandshakeManager* handshake_mgr) {
143   if (RefreshHandshakerFactory() != GRPC_SECURITY_OK) {
144     gpr_log(GPR_ERROR, "Handshaker factory refresh failed.");
145     return;
146   }
147   // Instantiate TSI handshaker.
148   tsi_handshaker* tsi_hs = nullptr;
149   tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker(
150       client_handshaker_factory_,
151       overridden_target_name_ != nullptr ? overridden_target_name_.get()
152                                          : target_name_.get(),
153       &tsi_hs);
154   if (result != TSI_OK) {
155     gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
156             tsi_result_to_string(result));
157     return;
158   }
159   // Create handshakers.
160   handshake_mgr->Add(grpc_core::SecurityHandshakerCreate(tsi_hs, this));
161 }
162
163 void SpiffeChannelSecurityConnector::check_peer(
164     tsi_peer peer, grpc_endpoint* ep,
165     grpc_core::RefCountedPtr<grpc_auth_context>* auth_context,
166     grpc_closure* on_peer_checked) {
167   const char* target_name = overridden_target_name_ != nullptr
168                                 ? overridden_target_name_.get()
169                                 : target_name_.get();
170   grpc_error* error = grpc_ssl_check_alpn(&peer);
171   if (error != GRPC_ERROR_NONE) {
172     GRPC_CLOSURE_SCHED(on_peer_checked, error);
173     tsi_peer_destruct(&peer);
174     return;
175   }
176   *auth_context = grpc_ssl_peer_to_auth_context(&peer);
177   const SpiffeCredentials* creds =
178       static_cast<const SpiffeCredentials*>(channel_creds());
179   const grpc_tls_server_authorization_check_config* config =
180       creds->options().server_authorization_check_config();
181   /* If server authorization config is not null, use it to perform
182    * server authorization check. */
183   if (config != nullptr) {
184     const tsi_peer_property* p =
185         tsi_peer_get_property_by_name(&peer, TSI_X509_PEM_CERT_PROPERTY);
186     if (p == nullptr) {
187       error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
188           "Cannot check peer: missing pem cert property.");
189     } else {
190       char* peer_pem = static_cast<char*>(gpr_malloc(p->value.length + 1));
191       memcpy(peer_pem, p->value.data, p->value.length);
192       peer_pem[p->value.length] = '\0';
193       GPR_ASSERT(check_arg_ != nullptr);
194       check_arg_->peer_cert = check_arg_->peer_cert == nullptr
195                                   ? gpr_strdup(peer_pem)
196                                   : check_arg_->peer_cert;
197       check_arg_->target_name = check_arg_->target_name == nullptr
198                                     ? gpr_strdup(target_name)
199                                     : check_arg_->target_name;
200       on_peer_checked_ = on_peer_checked;
201       gpr_free(peer_pem);
202       int callback_status = config->Schedule(check_arg_);
203       /* Server authorization check is handled asynchronously. */
204       if (callback_status) {
205         tsi_peer_destruct(&peer);
206         return;
207       }
208       /* Server authorization check is handled synchronously. */
209       error = ProcessServerAuthorizationCheckResult(check_arg_);
210     }
211   }
212   GRPC_CLOSURE_SCHED(on_peer_checked, error);
213   tsi_peer_destruct(&peer);
214 }
215
216 int SpiffeChannelSecurityConnector::cmp(
217     const grpc_security_connector* other_sc) const {
218   auto* other =
219       reinterpret_cast<const SpiffeChannelSecurityConnector*>(other_sc);
220   int c = channel_security_connector_cmp(other);
221   if (c != 0) {
222     return c;
223   }
224   return grpc_ssl_cmp_target_name(target_name_.get(), other->target_name_.get(),
225                                   overridden_target_name_.get(),
226                                   other->overridden_target_name_.get());
227 }
228
229 bool SpiffeChannelSecurityConnector::check_call_host(
230     grpc_core::StringView host, grpc_auth_context* auth_context,
231     grpc_closure* on_call_host_checked, grpc_error** error) {
232   return grpc_ssl_check_call_host(host, target_name_.get(),
233                                   overridden_target_name_.get(), auth_context,
234                                   on_call_host_checked, error);
235 }
236
237 void SpiffeChannelSecurityConnector::cancel_check_call_host(
238     grpc_closure* on_call_host_checked, grpc_error* error) {
239   GRPC_ERROR_UNREF(error);
240 }
241
242 grpc_core::RefCountedPtr<grpc_channel_security_connector>
243 SpiffeChannelSecurityConnector::CreateSpiffeChannelSecurityConnector(
244     grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds,
245     grpc_core::RefCountedPtr<grpc_call_credentials> request_metadata_creds,
246     const char* target_name, const char* overridden_target_name,
247     tsi_ssl_session_cache* ssl_session_cache) {
248   if (channel_creds == nullptr) {
249     gpr_log(GPR_ERROR,
250             "channel_creds is nullptr in "
251             "SpiffeChannelSecurityConnectorCreate()");
252     return nullptr;
253   }
254   if (target_name == nullptr) {
255     gpr_log(GPR_ERROR,
256             "target_name is nullptr in "
257             "SpiffeChannelSecurityConnectorCreate()");
258     return nullptr;
259   }
260   grpc_core::RefCountedPtr<SpiffeChannelSecurityConnector> c =
261       grpc_core::MakeRefCounted<SpiffeChannelSecurityConnector>(
262           std::move(channel_creds), std::move(request_metadata_creds),
263           target_name, overridden_target_name);
264   if (c->InitializeHandshakerFactory(ssl_session_cache) != GRPC_SECURITY_OK) {
265     gpr_log(GPR_ERROR, "Could not initialize client handshaker factory.");
266     return nullptr;
267   }
268   return c;
269 }
270
271 grpc_security_status SpiffeChannelSecurityConnector::ReplaceHandshakerFactory(
272     tsi_ssl_session_cache* ssl_session_cache) {
273   /* Free the client handshaker factory if exists. */
274   if (client_handshaker_factory_) {
275     tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory_);
276   }
277   GPR_ASSERT(!key_materials_config_->pem_key_cert_pair_list().empty());
278   tsi_ssl_pem_key_cert_pair* pem_key_cert_pair = ConvertToTsiPemKeyCertPair(
279       key_materials_config_->pem_key_cert_pair_list());
280   grpc_security_status status = grpc_ssl_tsi_client_handshaker_factory_init(
281       pem_key_cert_pair, key_materials_config_->pem_root_certs(),
282       ssl_session_cache, &client_handshaker_factory_);
283   /* Free memory. */
284   grpc_tsi_ssl_pem_key_cert_pairs_destroy(pem_key_cert_pair, 1);
285   return status;
286 }
287
288 grpc_security_status
289 SpiffeChannelSecurityConnector::InitializeHandshakerFactory(
290     tsi_ssl_session_cache* ssl_session_cache) {
291   grpc_core::MutexLock lock(&mu_);
292   const SpiffeCredentials* creds =
293       static_cast<const SpiffeCredentials*>(channel_creds());
294   grpc_tls_key_materials_config* key_materials_config =
295       creds->options().key_materials_config();
296   /* Copy key materials config from credential options. */
297   if (key_materials_config != nullptr) {
298     grpc_tls_key_materials_config::PemKeyCertPairList cert_pair_list =
299         key_materials_config->pem_key_cert_pair_list();
300     auto pem_root_certs = grpc_core::UniquePtr<char>(
301         gpr_strdup(key_materials_config->pem_root_certs()));
302     key_materials_config_->set_key_materials(std::move(pem_root_certs),
303                                              std::move(cert_pair_list));
304   }
305   grpc_ssl_certificate_config_reload_status reload_status =
306       GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
307   if (TlsFetchKeyMaterials(key_materials_config_, creds->options(),
308                            &reload_status) != GRPC_STATUS_OK) {
309     /* Raise an error if key materials are not populated. */
310     return GRPC_SECURITY_ERROR;
311   }
312   return ReplaceHandshakerFactory(ssl_session_cache);
313 }
314
315 grpc_security_status
316 SpiffeChannelSecurityConnector::RefreshHandshakerFactory() {
317   grpc_core::MutexLock lock(&mu_);
318   const SpiffeCredentials* creds =
319       static_cast<const SpiffeCredentials*>(channel_creds());
320   grpc_ssl_certificate_config_reload_status reload_status =
321       GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
322   if (TlsFetchKeyMaterials(key_materials_config_, creds->options(),
323                            &reload_status) != GRPC_STATUS_OK) {
324     return GRPC_SECURITY_ERROR;
325   }
326   if (reload_status != GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW) {
327     // Re-use existing handshaker factory.
328     return GRPC_SECURITY_OK;
329   } else {
330     return ReplaceHandshakerFactory(nullptr);
331   }
332 }
333
334 void SpiffeChannelSecurityConnector::ServerAuthorizationCheckDone(
335     grpc_tls_server_authorization_check_arg* arg) {
336   GPR_ASSERT(arg != nullptr);
337   grpc_core::ExecCtx exec_ctx;
338   grpc_error* error = ProcessServerAuthorizationCheckResult(arg);
339   SpiffeChannelSecurityConnector* connector =
340       static_cast<SpiffeChannelSecurityConnector*>(arg->cb_user_data);
341   GRPC_CLOSURE_SCHED(connector->on_peer_checked_, error);
342 }
343
344 grpc_error*
345 SpiffeChannelSecurityConnector::ProcessServerAuthorizationCheckResult(
346     grpc_tls_server_authorization_check_arg* arg) {
347   grpc_error* error = GRPC_ERROR_NONE;
348   char* msg = nullptr;
349   /* Server authorization check is cancelled by caller. */
350   if (arg->status == GRPC_STATUS_CANCELLED) {
351     gpr_asprintf(&msg,
352                  "Server authorization check is cancelled by the caller with "
353                  "error: %s",
354                  arg->error_details);
355     error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
356   } else if (arg->status == GRPC_STATUS_OK) {
357     /* Server authorization check completed successfully but returned check
358      * failure. */
359     if (!arg->success) {
360       gpr_asprintf(&msg, "Server authorization check failed with error: %s",
361                    arg->error_details);
362       error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
363     }
364     /* Server authorization check did not complete correctly. */
365   } else {
366     gpr_asprintf(
367         &msg,
368         "Server authorization check did not finish correctly with error: %s",
369         arg->error_details);
370     error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
371   }
372   gpr_free(msg);
373   return error;
374 }
375
376 grpc_tls_server_authorization_check_arg*
377 SpiffeChannelSecurityConnector::ServerAuthorizationCheckArgCreate(
378     void* user_data) {
379   grpc_tls_server_authorization_check_arg* arg =
380       grpc_core::New<grpc_tls_server_authorization_check_arg>();
381   arg->cb = ServerAuthorizationCheckDone;
382   arg->cb_user_data = user_data;
383   arg->status = GRPC_STATUS_OK;
384   return arg;
385 }
386
387 void SpiffeChannelSecurityConnector::ServerAuthorizationCheckArgDestroy(
388     grpc_tls_server_authorization_check_arg* arg) {
389   if (arg == nullptr) {
390     return;
391   }
392   gpr_free((void*)arg->target_name);
393   gpr_free((void*)arg->peer_cert);
394   gpr_free((void*)arg->error_details);
395   grpc_core::Delete(arg);
396 }
397
398 SpiffeServerSecurityConnector::SpiffeServerSecurityConnector(
399     grpc_core::RefCountedPtr<grpc_server_credentials> server_creds)
400     : grpc_server_security_connector(GRPC_SSL_URL_SCHEME,
401                                      std::move(server_creds)) {
402   key_materials_config_ = grpc_tls_key_materials_config_create()->Ref();
403 }
404
405 SpiffeServerSecurityConnector::~SpiffeServerSecurityConnector() {
406   if (server_handshaker_factory_ != nullptr) {
407     tsi_ssl_server_handshaker_factory_unref(server_handshaker_factory_);
408   }
409   if (key_materials_config_.get() != nullptr) {
410     key_materials_config_.get()->Unref();
411   }
412 }
413
414 void SpiffeServerSecurityConnector::add_handshakers(
415     grpc_pollset_set* interested_parties,
416     grpc_core::HandshakeManager* handshake_mgr) {
417   /* Refresh handshaker factory if needed. */
418   if (RefreshHandshakerFactory() != GRPC_SECURITY_OK) {
419     gpr_log(GPR_ERROR, "Handshaker factory refresh failed.");
420     return;
421   }
422   /* Create a TLS SPIFFE TSI handshaker for server. */
423   tsi_handshaker* tsi_hs = nullptr;
424   tsi_result result = tsi_ssl_server_handshaker_factory_create_handshaker(
425       server_handshaker_factory_, &tsi_hs);
426   if (result != TSI_OK) {
427     gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
428             tsi_result_to_string(result));
429     return;
430   }
431   handshake_mgr->Add(grpc_core::SecurityHandshakerCreate(tsi_hs, this));
432 }
433
434 void SpiffeServerSecurityConnector::check_peer(
435     tsi_peer peer, grpc_endpoint* ep,
436     grpc_core::RefCountedPtr<grpc_auth_context>* auth_context,
437     grpc_closure* on_peer_checked) {
438   grpc_error* error = grpc_ssl_check_alpn(&peer);
439   *auth_context = grpc_ssl_peer_to_auth_context(&peer);
440   tsi_peer_destruct(&peer);
441   GRPC_CLOSURE_SCHED(on_peer_checked, error);
442 }
443
444 int SpiffeServerSecurityConnector::cmp(
445     const grpc_security_connector* other) const {
446   return server_security_connector_cmp(
447       static_cast<const grpc_server_security_connector*>(other));
448 }
449
450 grpc_core::RefCountedPtr<grpc_server_security_connector>
451 SpiffeServerSecurityConnector::CreateSpiffeServerSecurityConnector(
452     grpc_core::RefCountedPtr<grpc_server_credentials> server_creds) {
453   if (server_creds == nullptr) {
454     gpr_log(GPR_ERROR,
455             "server_creds is nullptr in "
456             "SpiffeServerSecurityConnectorCreate()");
457     return nullptr;
458   }
459   grpc_core::RefCountedPtr<SpiffeServerSecurityConnector> c =
460       grpc_core::MakeRefCounted<SpiffeServerSecurityConnector>(
461           std::move(server_creds));
462   if (c->InitializeHandshakerFactory() != GRPC_SECURITY_OK) {
463     gpr_log(GPR_ERROR, "Could not initialize server handshaker factory.");
464     return nullptr;
465   }
466   return c;
467 }
468
469 grpc_security_status SpiffeServerSecurityConnector::ReplaceHandshakerFactory() {
470   const SpiffeServerCredentials* creds =
471       static_cast<const SpiffeServerCredentials*>(server_creds());
472   /* Free the server handshaker factory if exists. */
473   if (server_handshaker_factory_) {
474     tsi_ssl_server_handshaker_factory_unref(server_handshaker_factory_);
475   }
476   GPR_ASSERT(!key_materials_config_->pem_key_cert_pair_list().empty());
477   tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs = ConvertToTsiPemKeyCertPair(
478       key_materials_config_->pem_key_cert_pair_list());
479   size_t num_key_cert_pairs =
480       key_materials_config_->pem_key_cert_pair_list().size();
481   grpc_security_status status = grpc_ssl_tsi_server_handshaker_factory_init(
482       pem_key_cert_pairs, num_key_cert_pairs,
483       key_materials_config_->pem_root_certs(),
484       creds->options().cert_request_type(), &server_handshaker_factory_);
485   /* Free memory. */
486   grpc_tsi_ssl_pem_key_cert_pairs_destroy(pem_key_cert_pairs,
487                                           num_key_cert_pairs);
488   return status;
489 }
490
491 grpc_security_status
492 SpiffeServerSecurityConnector::InitializeHandshakerFactory() {
493   grpc_core::MutexLock lock(&mu_);
494   const SpiffeServerCredentials* creds =
495       static_cast<const SpiffeServerCredentials*>(server_creds());
496   grpc_tls_key_materials_config* key_materials_config =
497       creds->options().key_materials_config();
498   if (key_materials_config != nullptr) {
499     grpc_tls_key_materials_config::PemKeyCertPairList cert_pair_list =
500         key_materials_config->pem_key_cert_pair_list();
501     auto pem_root_certs = grpc_core::UniquePtr<char>(
502         gpr_strdup(key_materials_config->pem_root_certs()));
503     key_materials_config_->set_key_materials(std::move(pem_root_certs),
504                                              std::move(cert_pair_list));
505   }
506   grpc_ssl_certificate_config_reload_status reload_status =
507       GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
508   if (TlsFetchKeyMaterials(key_materials_config_, creds->options(),
509                            &reload_status) != GRPC_STATUS_OK) {
510     /* Raise an error if key materials are not populated. */
511     return GRPC_SECURITY_ERROR;
512   }
513   return ReplaceHandshakerFactory();
514 }
515
516 grpc_security_status SpiffeServerSecurityConnector::RefreshHandshakerFactory() {
517   grpc_core::MutexLock lock(&mu_);
518   const SpiffeServerCredentials* creds =
519       static_cast<const SpiffeServerCredentials*>(server_creds());
520   grpc_ssl_certificate_config_reload_status reload_status =
521       GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
522   if (TlsFetchKeyMaterials(key_materials_config_, creds->options(),
523                            &reload_status) != GRPC_STATUS_OK) {
524     return GRPC_SECURITY_ERROR;
525   }
526   if (reload_status != GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW) {
527     /* At this point, we should have key materials populated. */
528     return GRPC_SECURITY_OK;
529   } else {
530     return ReplaceHandshakerFactory();
531   }
532 }
533
534 }  // namespace grpc_core