• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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