1 // 2 // Copyright 2020 gRPC authors. 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #ifndef GRPC_SRC_CORE_LIB_SECURITY_CREDENTIALS_TLS_GRPC_TLS_CERTIFICATE_DISTRIBUTOR_H 18 #define GRPC_SRC_CORE_LIB_SECURITY_CREDENTIALS_TLS_GRPC_TLS_CERTIFICATE_DISTRIBUTOR_H 19 20 #include <grpc/support/port_platform.h> 21 22 #include <functional> 23 #include <map> 24 #include <memory> 25 #include <set> 26 #include <string> 27 #include <utility> 28 29 #include "absl/base/thread_annotations.h" 30 #include "absl/strings/string_view.h" 31 #include "absl/types/optional.h" 32 #include "src/core/lib/iomgr/error.h" 33 #include "src/core/lib/security/security_connector/ssl_utils.h" 34 #include "src/core/util/ref_counted.h" 35 #include "src/core/util/sync.h" 36 37 struct grpc_tls_identity_pairs { 38 grpc_core::PemKeyCertPairList pem_key_cert_pairs; 39 }; 40 41 // TLS certificate distributor. 42 struct grpc_tls_certificate_distributor 43 : public grpc_core::RefCounted<grpc_tls_certificate_distributor> { 44 public: 45 // Interface for watching TLS certificates update. 46 class TlsCertificatesWatcherInterface { 47 public: 48 virtual ~TlsCertificatesWatcherInterface() = default; 49 50 // Handles the delivery of the updated root and identity certificates. 51 // An absl::nullopt value indicates no corresponding contents for 52 // root_certs or key_cert_pairs. Note that we will send updates of the 53 // latest contents for both root and identity certificates, even when only 54 // one side of it got updated. 55 // 56 // @param root_certs the contents of the reloaded root certs. 57 // @param key_cert_pairs the contents of the reloaded identity key-cert 58 // pairs. 59 virtual void OnCertificatesChanged( 60 absl::optional<absl::string_view> root_certs, 61 absl::optional<grpc_core::PemKeyCertPairList> key_cert_pairs) = 0; 62 63 // Handles an error that occurs while attempting to fetch certificate data. 64 // Note that if a watcher sees an error, it simply means the Provider is 65 // having problems renewing new data. If the watcher has previously received 66 // several OnCertificatesChanged, all the data received from that function 67 // is valid. 68 // In that case, watcher might simply log the error. If the watcher hasn't 69 // received any OnCertificatesChanged before the error occurs, no valid 70 // data is available yet, and the watcher should either fail or "waiting" 71 // for the valid data in a non-blocking way. 72 // 73 // @param root_cert_error the error occurred while reloading root 74 // certificates. 75 // @param identity_cert_error the error occurred while reloading identity 76 // certificates. 77 virtual void OnError(grpc_error_handle root_cert_error, 78 grpc_error_handle identity_cert_error) = 0; 79 }; 80 81 // Sets the key materials based on their certificate name. 82 // 83 // @param cert_name The name of the certificates being updated. 84 // @param pem_root_certs The content of root certificates. 85 // @param pem_key_cert_pairs The content of identity key-cert pairs. 86 void SetKeyMaterials( 87 const std::string& cert_name, absl::optional<std::string> pem_root_certs, 88 absl::optional<grpc_core::PemKeyCertPairList> pem_key_cert_pairs); 89 90 bool HasRootCerts(const std::string& root_cert_name); 91 92 bool HasKeyCertPairs(const std::string& identity_cert_name); 93 94 // Propagates the error that the caller (e.g. Producer) encounters to all the 95 // watchers watching a particular certificate name. 96 // 97 // @param cert_name The watching cert name of the watchers that the caller 98 // wants to notify when encountering error. 99 // @param root_cert_error The error that the caller encounters when reloading 100 // root certs. 101 // @param identity_cert_error The error that the caller encounters when 102 // reloading identity certs. 103 void SetErrorForCert(const std::string& cert_name, 104 absl::optional<grpc_error_handle> root_cert_error, 105 absl::optional<grpc_error_handle> identity_cert_error); 106 107 // Propagates the error that the caller (e.g. Producer) encounters to all 108 // watchers. 109 // 110 // @param error The error that the caller encounters. 111 void SetError(grpc_error_handle error); 112 113 // Sets the TLS certificate watch status callback function. The 114 // grpc_tls_certificate_distributor will invoke this callback when a new 115 // certificate name is watched by a newly registered watcher, or when a 116 // certificate name is no longer watched by any watchers. 117 // Note that when the callback shows a cert is no longer being watched, the 118 // distributor will delete the corresponding certificate data from its cache, 119 // and clear the corresponding error, if there is any. This means that if the 120 // callback subsequently says the same cert is now being watched again, the 121 // provider must re-provide the credentials or re-invoke the errors to the 122 // distributor, to indicate a successful or failed reloading. 123 // @param callback The callback function being set by the caller, e.g the 124 // Producer. Note that this callback will be invoked for each certificate 125 // name. 126 // 127 // For the parameters in the callback function: 128 // string_value The name of the certificates being watched. 129 // bool_value_1 If the root certificates with the specific name are being 130 // watched. bool_value_2 If the identity certificates with the specific name 131 // are being watched. SetWatchStatusCallbackgrpc_tls_certificate_distributor132 void SetWatchStatusCallback( 133 std::function<void(std::string, bool, bool)> callback) { 134 grpc_core::MutexLock lock(&callback_mu_); 135 watch_status_callback_ = std::move(callback); 136 }; 137 138 // Registers a watcher. The caller may keep a raw pointer to the watcher, 139 // which may be used only for cancellation. (Because the caller does not own 140 // the watcher, the pointer must not be used for any other purpose.) At least 141 // one of root_cert_name and identity_cert_name must be specified. 142 // 143 // @param watcher The watcher being registered. 144 // @param root_cert_name The name of the root certificates that will be 145 // watched. If set to absl::nullopt, the root certificates won't be watched. 146 // @param identity_cert_name The name of the identity certificates that will 147 // be watched. If set to absl::nullopt, the identity certificates won't be 148 // watched. 149 void WatchTlsCertificates( 150 std::unique_ptr<TlsCertificatesWatcherInterface> watcher, 151 absl::optional<std::string> root_cert_name, 152 absl::optional<std::string> identity_cert_name); 153 154 // Cancels a watcher. 155 // 156 // @param watcher The watcher being cancelled. 157 void CancelTlsCertificatesWatch(TlsCertificatesWatcherInterface* watcher); 158 159 private: 160 // Contains the information about each watcher. 161 struct WatcherInfo { 162 std::unique_ptr<TlsCertificatesWatcherInterface> watcher; 163 absl::optional<std::string> root_cert_name; 164 absl::optional<std::string> identity_cert_name; 165 }; 166 // CertificateInfo contains the credential contents and some additional 167 // watcher information. 168 // Note that having errors doesn't indicate the corresponding credentials are 169 // invalid. For example, if root_cert_error != nullptr but pem_root_certs has 170 // value, it simply means an error occurs while trying to fetch the latest 171 // root certs, while pem_root_certs still contains the valid old data. 172 struct CertificateInfo { 173 // The contents of the root certificates. 174 std::string pem_root_certs; 175 // The contents of the identity key-certificate pairs. 176 grpc_core::PemKeyCertPairList pem_key_cert_pairs; 177 // The root cert reloading error propagated by the caller. 178 grpc_error_handle root_cert_error; 179 // The identity cert reloading error propagated by the caller. 180 grpc_error_handle identity_cert_error; 181 // The set of watchers watching root certificates. 182 // This is mainly used for quickly looking up the affected watchers while 183 // performing a credential reloading. 184 std::set<TlsCertificatesWatcherInterface*> root_cert_watchers; 185 // The set of watchers watching identity certificates. This is mainly used 186 // for quickly looking up the affected watchers while performing a 187 // credential reloading. 188 std::set<TlsCertificatesWatcherInterface*> identity_cert_watchers; 189 ~CertificateInfogrpc_tls_certificate_distributor::CertificateInfo190 ~CertificateInfo() {} SetRootErrorgrpc_tls_certificate_distributor::CertificateInfo191 void SetRootError(grpc_error_handle error) { root_cert_error = error; } SetIdentityErrorgrpc_tls_certificate_distributor::CertificateInfo192 void SetIdentityError(grpc_error_handle error) { 193 identity_cert_error = error; 194 } 195 }; 196 197 grpc_core::Mutex mu_; 198 // We need a dedicated mutex for watch_status_callback_ for allowing 199 // callers(e.g. Producer) to directly set key materials in the callback 200 // functions. 201 grpc_core::Mutex callback_mu_; 202 // Stores information about each watcher. 203 std::map<TlsCertificatesWatcherInterface*, WatcherInfo> watchers_ 204 ABSL_GUARDED_BY(mu_); 205 // The callback to notify the caller, e.g. the Producer, that the watch status 206 // is changed. 207 std::function<void(std::string, bool, bool)> watch_status_callback_ 208 ABSL_GUARDED_BY(callback_mu_); 209 // Stores the names of each certificate, and their corresponding credential 210 // contents as well as some additional watcher information. 211 std::map<std::string, CertificateInfo> certificate_info_map_ 212 ABSL_GUARDED_BY(mu_); 213 }; 214 215 #endif // GRPC_SRC_CORE_LIB_SECURITY_CREDENTIALS_TLS_GRPC_TLS_CERTIFICATE_DISTRIBUTOR_H 216