1 // 2 // 3 // Copyright 2023 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 #ifndef GRPC_SRC_CORE_LIB_SECURITY_CREDENTIALS_TLS_GRPC_TLS_CRL_PROVIDER_H 20 #define GRPC_SRC_CORE_LIB_SECURITY_CREDENTIALS_TLS_GRPC_TLS_CRL_PROVIDER_H 21 22 #include <grpc/event_engine/event_engine.h> 23 #include <grpc/grpc_crl_provider.h> 24 #include <grpc/support/port_platform.h> 25 #include <openssl/crypto.h> 26 27 #include <chrono> 28 #include <functional> 29 #include <memory> 30 #include <optional> 31 #include <string> 32 #include <utility> 33 34 #include "absl/base/thread_annotations.h" 35 #include "absl/container/flat_hash_map.h" 36 #include "absl/status/status.h" 37 #include "absl/status/statusor.h" 38 #include "absl/strings/string_view.h" 39 #include "absl/types/optional.h" 40 #include "src/core/util/directory_reader.h" 41 #include "src/core/util/sync.h" 42 #include "src/core/util/time.h" 43 44 namespace grpc_core { 45 namespace experimental { 46 47 class StaticCrlProvider : public CrlProvider { 48 public: 49 // Each element of the input vector is expected to be the raw contents of a 50 // CRL file. StaticCrlProvider(absl::flat_hash_map<std::string,std::shared_ptr<Crl>> crls)51 explicit StaticCrlProvider( 52 absl::flat_hash_map<std::string, std::shared_ptr<Crl>> crls) 53 : crls_(std::move(crls)) {} 54 std::shared_ptr<Crl> GetCrl(const CertificateInfo& certificate_info) override; 55 56 private: 57 const absl::flat_hash_map<std::string, std::shared_ptr<Crl>> crls_; 58 }; 59 60 class CrlImpl : public Crl { 61 public: 62 static absl::StatusOr<std::unique_ptr<CrlImpl>> Create(X509_CRL* crl); 63 // Takes ownership of the X509_CRL pointer. CrlImpl(X509_CRL * crl,absl::string_view issuer)64 CrlImpl(X509_CRL* crl, absl::string_view issuer) 65 : crl_(crl), issuer_(issuer) {} 66 ~CrlImpl() override; 67 // Returns a string view representation of the issuer pulled from the CRL. Issuer()68 absl::string_view Issuer() override { return issuer_; } 69 // The caller should not take ownership of the returned pointer. crl()70 X509_CRL* crl() const { return crl_; } 71 72 private: 73 X509_CRL* crl_; 74 const std::string issuer_; 75 }; 76 77 class CertificateInfoImpl : public CertificateInfo { 78 public: 79 explicit CertificateInfoImpl(absl::string_view issuer, 80 absl::string_view authority_key_identifier = "") issuer_(issuer)81 : issuer_(issuer), authority_key_identifier_(authority_key_identifier) {} Issuer()82 absl::string_view Issuer() const override { return issuer_; } AuthorityKeyIdentifier()83 absl::string_view AuthorityKeyIdentifier() const override { 84 return authority_key_identifier_; 85 } 86 87 private: 88 const std::string issuer_; 89 const std::string authority_key_identifier_; 90 }; 91 92 // Defining this here lets us hide implementation details (and includes) from 93 // the header in include 94 class DirectoryReloaderCrlProvider 95 : public CrlProvider, 96 public std::enable_shared_from_this<DirectoryReloaderCrlProvider> { 97 public: 98 DirectoryReloaderCrlProvider( 99 std::chrono::seconds duration, std::function<void(absl::Status)> callback, 100 std::shared_ptr<grpc_event_engine::experimental::EventEngine> 101 event_engine, 102 std::shared_ptr<DirectoryReader> directory_impl); 103 104 ~DirectoryReloaderCrlProvider() override; 105 std::shared_ptr<Crl> GetCrl(const CertificateInfo& certificate_info) override; 106 // Reads the configured directory and updates the internal crls_ map, called 107 // asynchronously by event engine then schedules the timer for the next 108 // update. 109 void UpdateAndStartTimer(); 110 111 private: 112 // Reads the configured directory and updates the internal crls_ map, called 113 // asynchronously by event engine. 114 absl::Status Update(); 115 Duration refresh_duration_; 116 std::function<void(::absl::Status)> reload_error_callback_; 117 std::shared_ptr<grpc_event_engine::experimental::EventEngine> event_engine_; 118 std::shared_ptr<DirectoryReader> crl_directory_; 119 // guards the crls_ map 120 Mutex mu_; 121 absl::flat_hash_map<::std::string, ::std::shared_ptr<Crl>> crls_ 122 ABSL_GUARDED_BY(mu_); 123 absl::optional<grpc_event_engine::experimental::EventEngine::TaskHandle> 124 refresh_handle_; 125 }; 126 127 } // namespace experimental 128 } // namespace grpc_core 129 130 #endif // GRPC_SRC_CORE_LIB_SECURITY_CREDENTIALS_TLS_GRPC_TLS_CRL_PROVIDER_H