diff options
Diffstat (limited to 'grpc/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc')
-rw-r--r-- | grpc/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc | 73 |
1 files changed, 61 insertions, 12 deletions
diff --git a/grpc/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc b/grpc/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc index b4b6bf55..9ee71806 100644 --- a/grpc/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc +++ b/grpc/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc @@ -18,6 +18,8 @@ #include "src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h" +#include <openssl/ssl.h> + #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> @@ -29,17 +31,16 @@ namespace grpc_core { StaticDataCertificateProvider::StaticDataCertificateProvider( - std::string root_certificate, - grpc_core::PemKeyCertPairList pem_key_cert_pairs) + std::string root_certificate, PemKeyCertPairList pem_key_cert_pairs) : distributor_(MakeRefCounted<grpc_tls_certificate_distributor>()), root_certificate_(std::move(root_certificate)), pem_key_cert_pairs_(std::move(pem_key_cert_pairs)) { distributor_->SetWatchStatusCallback([this](std::string cert_name, bool root_being_watched, bool identity_being_watched) { - grpc_core::MutexLock lock(&mu_); + MutexLock lock(&mu_); absl::optional<std::string> root_certificate; - absl::optional<grpc_core::PemKeyCertPairList> pem_key_cert_pairs; + absl::optional<PemKeyCertPairList> pem_key_cert_pairs; StaticDataCertificateProvider::WatcherInfo& info = watcher_info_[cert_name]; if (!info.root_being_watched && root_being_watched && !root_certificate_.empty()) { @@ -121,15 +122,15 @@ FileWatcherCertificateProvider::FileWatcherCertificateProvider( provider->ForceUpdate(); } }; - refresh_thread_ = grpc_core::Thread( - "FileWatcherCertificateProvider_refreshing_thread", thread_lambda, this); + refresh_thread_ = Thread("FileWatcherCertificateProvider_refreshing_thread", + thread_lambda, this); refresh_thread_.Start(); distributor_->SetWatchStatusCallback([this](std::string cert_name, bool root_being_watched, bool identity_being_watched) { - grpc_core::MutexLock lock(&mu_); + MutexLock lock(&mu_); absl::optional<std::string> root_certificate; - absl::optional<grpc_core::PemKeyCertPairList> pem_key_cert_pairs; + absl::optional<PemKeyCertPairList> pem_key_cert_pairs; FileWatcherCertificateProvider::WatcherInfo& info = watcher_info_[cert_name]; if (!info.root_being_watched && root_being_watched && @@ -178,7 +179,7 @@ FileWatcherCertificateProvider::~FileWatcherCertificateProvider() { void FileWatcherCertificateProvider::ForceUpdate() { absl::optional<std::string> root_certificate; - absl::optional<grpc_core::PemKeyCertPairList> pem_key_cert_pairs; + absl::optional<PemKeyCertPairList> pem_key_cert_pairs; if (!root_cert_path_.empty()) { root_certificate = ReadRootCertificatesFromFile(root_cert_path_); } @@ -186,7 +187,7 @@ void FileWatcherCertificateProvider::ForceUpdate() { pem_key_cert_pairs = ReadIdentityKeyCertPairFromFiles( private_key_path_, identity_certificate_path_); } - grpc_core::MutexLock lock(&mu_); + MutexLock lock(&mu_); const bool root_cert_changed = (!root_certificate.has_value() && !root_certificate_.empty()) || (root_certificate.has_value() && root_certificate_ != *root_certificate); @@ -219,7 +220,7 @@ void FileWatcherCertificateProvider::ForceUpdate() { const std::string& cert_name = p.first; const WatcherInfo& info = p.second; absl::optional<std::string> root_to_report; - absl::optional<grpc_core::PemKeyCertPairList> identity_to_report; + absl::optional<PemKeyCertPairList> identity_to_report; // Set key materials to the distributor if their contents changed. if (info.root_being_watched && !root_certificate_.empty() && root_cert_changed) { @@ -277,7 +278,7 @@ namespace { // it logs the error and returns 0. time_t GetModificationTime(const char* filename) { time_t ts = 0; - absl::Status status = grpc_core::GetFileModificationTime(filename, &ts); + absl::Status status = GetFileModificationTime(filename, &ts); return ts; } @@ -364,6 +365,54 @@ FileWatcherCertificateProvider::ReadIdentityKeyCertPairFromFiles( return absl::nullopt; } +absl::StatusOr<bool> PrivateKeyAndCertificateMatch( + absl::string_view private_key, absl::string_view cert_chain) { + if (private_key.empty()) { + return absl::InvalidArgumentError("Private key string is empty."); + } + if (cert_chain.empty()) { + return absl::InvalidArgumentError("Certificate string is empty."); + } + BIO* cert_bio = BIO_new_mem_buf(cert_chain.data(), cert_chain.size()); + if (cert_bio == nullptr) { + return absl::InvalidArgumentError( + "Conversion from certificate string to BIO failed."); + } + // Reads the first cert from the cert_chain which is expected to be the leaf + // cert + X509* x509 = PEM_read_bio_X509(cert_bio, nullptr, nullptr, nullptr); + BIO_free(cert_bio); + if (x509 == nullptr) { + return absl::InvalidArgumentError( + "Conversion from PEM string to X509 failed."); + } + EVP_PKEY* public_evp_pkey = X509_get_pubkey(x509); + X509_free(x509); + if (public_evp_pkey == nullptr) { + return absl::InvalidArgumentError( + "Extraction of public key from x.509 certificate failed."); + } + BIO* private_key_bio = + BIO_new_mem_buf(private_key.data(), private_key.size()); + if (private_key_bio == nullptr) { + EVP_PKEY_free(public_evp_pkey); + return absl::InvalidArgumentError( + "Conversion from private key string to BIO failed."); + } + EVP_PKEY* private_evp_pkey = + PEM_read_bio_PrivateKey(private_key_bio, nullptr, nullptr, nullptr); + BIO_free(private_key_bio); + if (private_evp_pkey == nullptr) { + EVP_PKEY_free(public_evp_pkey); + return absl::InvalidArgumentError( + "Conversion from PEM string to EVP_PKEY failed."); + } + bool result = EVP_PKEY_cmp(private_evp_pkey, public_evp_pkey) == 1; + EVP_PKEY_free(private_evp_pkey); + EVP_PKEY_free(public_evp_pkey); + return result; +} + } // namespace grpc_core /** -- Wrapper APIs declared in grpc_security.h -- **/ |