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_PROVIDER_H
18 #define GRPC_CORE_LIB_SECURITY_CREDENTIALS_TLS_GRPC_TLS_CERTIFICATE_PROVIDER_H
19 
20 #include <grpc/support/port_platform.h>
21 
22 #include <grpc/grpc_security.h>
23 #include <string.h>
24 
25 #include "absl/container/inlined_vector.h"
26 
27 #include "src/core/lib/gprpp/ref_counted.h"
28 #include "src/core/lib/gprpp/ref_counted_ptr.h"
29 #include "src/core/lib/gprpp/thd.h"
30 #include "src/core/lib/iomgr/load_file.h"
31 #include "src/core/lib/iomgr/pollset_set.h"
32 #include "src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.h"
33 #include "src/core/lib/security/security_connector/ssl_utils.h"
34 
35 // Interface for a grpc_tls_certificate_provider that handles the process to
36 // fetch credentials and validation contexts. Implementations are free to rely
37 // on local or remote sources to fetch the latest secrets, and free to share any
38 // state among different instances as they deem fit.
39 //
40 // On creation, grpc_tls_certificate_provider creates a
41 // grpc_tls_certificate_distributor object. When the credentials and validation
42 // contexts become valid or changed, a grpc_tls_certificate_provider should
43 // notify its distributor so as to propagate the update to the watchers.
44 struct grpc_tls_certificate_provider
45     : public grpc_core::RefCounted<grpc_tls_certificate_provider> {
46  public:
interested_partiesgrpc_tls_certificate_provider47   virtual grpc_pollset_set* interested_parties() const { return nullptr; }
48 
49   virtual grpc_core::RefCountedPtr<grpc_tls_certificate_distributor>
50   distributor() const = 0;
51 };
52 
53 namespace grpc_core {
54 
55 // A basic provider class that will get credentials from string during
56 // initialization.
57 class StaticDataCertificateProvider final
58     : public grpc_tls_certificate_provider {
59  public:
60   StaticDataCertificateProvider(
61       std::string root_certificate,
62       grpc_core::PemKeyCertPairList pem_key_cert_pairs);
63 
64   ~StaticDataCertificateProvider() override;
65 
distributor()66   RefCountedPtr<grpc_tls_certificate_distributor> distributor() const override {
67     return distributor_;
68   }
69 
70  private:
71   struct WatcherInfo {
72     bool root_being_watched = false;
73     bool identity_being_watched = false;
74   };
75   RefCountedPtr<grpc_tls_certificate_distributor> distributor_;
76   std::string root_certificate_;
77   grpc_core::PemKeyCertPairList pem_key_cert_pairs_;
78   // Guards members below.
79   grpc_core::Mutex mu_;
80   // Stores each cert_name we get from the distributor callback and its watcher
81   // information.
82   std::map<std::string, WatcherInfo> watcher_info_;
83 };
84 
85 // A provider class that will watch the credential changes on the file system.
86 class FileWatcherCertificateProvider final
87     : public grpc_tls_certificate_provider {
88  public:
89   FileWatcherCertificateProvider(std::string private_key_path,
90                                  std::string identity_certificate_path,
91                                  std::string root_cert_path,
92                                  unsigned int refresh_interval_sec);
93 
94   ~FileWatcherCertificateProvider() override;
95 
distributor()96   RefCountedPtr<grpc_tls_certificate_distributor> distributor() const override {
97     return distributor_;
98   }
99 
100  private:
101   struct WatcherInfo {
102     bool root_being_watched = false;
103     bool identity_being_watched = false;
104   };
105   // Force an update from the file system regardless of the interval.
106   void ForceUpdate();
107   // Read the root certificates from files and update the distributor.
108   absl::optional<std::string> ReadRootCertificatesFromFile(
109       const std::string& root_cert_full_path);
110   // Read the root certificates from files and update the distributor.
111   absl::optional<PemKeyCertPairList> ReadIdentityKeyCertPairFromFiles(
112       const std::string& private_key_path,
113       const std::string& identity_certificate_path);
114 
115   // Information that is used by the refreshing thread.
116   std::string private_key_path_;
117   std::string identity_certificate_path_;
118   std::string root_cert_path_;
119   unsigned int refresh_interval_sec_ = 0;
120 
121   RefCountedPtr<grpc_tls_certificate_distributor> distributor_;
122   grpc_core::Thread refresh_thread_;
123   gpr_event shutdown_event_;
124 
125   // Guards members below.
126   grpc_core::Mutex mu_;
127   // The most-recent credential data. It will be empty if the most recent read
128   // attempt failed.
129   std::string root_certificate_;
130   grpc_core::PemKeyCertPairList pem_key_cert_pairs_;
131   // Stores each cert_name we get from the distributor callback and its watcher
132   // information.
133   std::map<std::string, WatcherInfo> watcher_info_;
134 };
135 
136 }  // namespace grpc_core
137 
138 #endif  // GRPC_CORE_LIB_SECURITY_CREDENTIALS_TLS_GRPC_TLS_CERTIFICATE_PROVIDER_H
139