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