34 #include "absl/status/status.h"
56 pem_key_cert_pairs_(
std::
move(pem_key_cert_pairs)) {
58 bool root_being_watched,
59 bool identity_being_watched) {
78 const bool identity_has_update = pem_key_cert_pairs.
has_value();
79 if (root_has_update || identity_has_update) {
85 if (root_being_watched && !root_has_update) {
87 "Unable to get latest root certificates.");
89 if (identity_being_watched && !identity_has_update) {
91 "Unable to get latest identity certificates.");
123 std::string root_cert_path,
unsigned int refresh_interval_sec)
124 : private_key_path_(
std::
move(private_key_path)),
125 identity_certificate_path_(
std::
move(identity_certificate_path)),
126 root_cert_path_(
std::
move(root_cert_path)),
127 refresh_interval_sec_(refresh_interval_sec),
135 auto thread_lambda = [](
void*
arg) {
143 if (
value !=
nullptr) {
150 thread_lambda,
this);
153 bool root_being_watched,
154 bool identity_being_watched) {
159 watcher_info_[cert_name];
161 !root_certificate_.empty()) {
166 !pem_key_cert_pairs_.empty()) {
167 pem_key_cert_pairs = pem_key_cert_pairs_;
171 watcher_info_.erase(cert_name);
182 "Unable to get latest root certificates.");
184 if (identity_being_watched && !pem_key_cert_pairs.
has_value()) {
186 "Unable to get latest identity certificates.");
191 identity_cert_error);
220 const bool root_cert_changed =
223 if (root_cert_changed) {
227 root_certificate_ =
"";
230 const bool identity_cert_changed =
231 (!pem_key_cert_pairs.
has_value() && !pem_key_cert_pairs_.empty()) ||
233 pem_key_cert_pairs_ != *pem_key_cert_pairs);
234 if (identity_cert_changed) {
236 pem_key_cert_pairs_ =
std::move(*pem_key_cert_pairs);
238 pem_key_cert_pairs_ = {};
241 if (root_cert_changed || identity_cert_changed) {
244 "Unable to get latest root certificates.");
247 "Unable to get latest identity certificates.");
248 for (
const auto& p : watcher_info_) {
256 root_to_report = root_certificate_;
259 identity_cert_changed) {
260 identity_to_report = pem_key_cert_pairs_;
267 const bool report_root_error =
269 const bool report_identity_error =
271 if (report_root_error || report_identity_error) {
294 root_cert_full_path.c_str(),
297 return absl::nullopt;
308 time_t GetModificationTime(
const char*
filename) {
320 struct SliceWrapper {
324 const int kNumRetryAttempts = 3;
325 for (
int i = 0;
i < kNumRetryAttempts; ++
i) {
329 time_t identity_key_ts_before =
330 GetModificationTime(private_key_path.c_str());
331 if (identity_key_ts_before == 0) {
334 "Failed to get the file's modification time of %s. Start retrying...",
335 private_key_path.c_str());
338 time_t identity_cert_ts_before =
339 GetModificationTime(identity_certificate_path.c_str());
340 if (identity_cert_ts_before == 0) {
343 "Failed to get the file's modification time of %s. Start retrying...",
344 identity_certificate_path.c_str());
348 SliceWrapper key_slice, cert_slice;
353 private_key_path.c_str(),
359 grpc_load_file(identity_certificate_path.c_str(), 0, &cert_slice.slice);
362 identity_certificate_path.c_str(),
370 identity_pairs.emplace_back(
private_key, cert_chain);
372 time_t identity_key_ts_after =
373 GetModificationTime(private_key_path.c_str());
374 if (identity_key_ts_before != identity_key_ts_after) {
376 "Last modified time before and after reading %s is not the same. "
378 private_key_path.c_str());
381 time_t identity_cert_ts_after =
382 GetModificationTime(identity_certificate_path.c_str());
383 if (identity_cert_ts_before != identity_cert_ts_after) {
385 "Last modified time before and after reading %s is not the same. "
387 identity_certificate_path.c_str());
390 return identity_pairs;
393 "All retry attempts failed. Will try again after the next interval.");
394 return absl::nullopt;
402 if (cert_chain.
empty()) {
406 if (cert_bio ==
nullptr) {
408 "Conversion from certificate string to BIO failed.");
414 if (x509 ==
nullptr) {
416 "Conversion from PEM string to X509 failed.");
420 if (public_evp_pkey ==
nullptr) {
422 "Extraction of public key from x.509 certificate failed.");
424 BIO* private_key_bio =
426 if (private_key_bio ==
nullptr) {
429 "Conversion from private key string to BIO failed.");
434 if (private_evp_pkey ==
nullptr) {
437 "Conversion from PEM string to EVP_PKEY failed.");
454 if (pem_key_cert_pairs !=
nullptr) {
456 delete pem_key_cert_pairs;
468 const char* private_key_path,
const char* identity_certificate_path,
469 const char* root_cert_path,
unsigned int refresh_interval_sec) {
472 private_key_path ==
nullptr ?
"" : private_key_path,
473 identity_certificate_path ==
nullptr ?
"" : identity_certificate_path,
474 root_cert_path ==
nullptr ?
"" : root_cert_path, refresh_interval_sec);
479 GRPC_API_TRACE(
"grpc_tls_certificate_provider_release(provider=%p)", 1,
482 if (provider !=
nullptr) provider->
Unref();