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