1 //
2 //
3 // Copyright 2020 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_EXT_XDS_XDS_CERTIFICATE_PROVIDER_H
20 #define GRPC_SRC_CORE_EXT_XDS_XDS_CERTIFICATE_PROVIDER_H
21 
22 #include <grpc/support/port_platform.h>
23 
24 #include <map>
25 #include <memory>
26 #include <string>
27 #include <vector>
28 
29 #include "absl/base/thread_annotations.h"
30 #include "absl/strings/string_view.h"
31 
32 #include <grpc/grpc.h>
33 #include <grpc/grpc_security.h>
34 
35 #include "src/core/lib/gpr/useful.h"
36 #include "src/core/lib/gprpp/ref_counted_ptr.h"
37 #include "src/core/lib/gprpp/sync.h"
38 #include "src/core/lib/gprpp/unique_type_name.h"
39 #include "src/core/lib/matchers/matchers.h"
40 #include "src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.h"
41 #include "src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h"
42 
43 #define GRPC_ARG_XDS_CERTIFICATE_PROVIDER \
44   "grpc.internal.xds_certificate_provider"
45 
46 namespace grpc_core {
47 
48 class XdsCertificateProvider : public grpc_tls_certificate_provider {
49  public:
50   XdsCertificateProvider();
51   ~XdsCertificateProvider() override;
52 
ChannelArgName()53   static absl::string_view ChannelArgName() {
54     return GRPC_ARG_XDS_CERTIFICATE_PROVIDER;
55   }
56 
ChannelArgsCompare(const XdsCertificateProvider * a,const XdsCertificateProvider * b)57   static int ChannelArgsCompare(const XdsCertificateProvider* a,
58                                 const XdsCertificateProvider* b) {
59     return QsortCompare(a, b);
60   }
61 
distributor()62   RefCountedPtr<grpc_tls_certificate_distributor> distributor() const override {
63     return distributor_;
64   }
65 
66   UniqueTypeName type() const override;
67 
68   bool ProvidesRootCerts(const std::string& cert_name);
69   void UpdateRootCertNameAndDistributor(
70       const std::string& cert_name, absl::string_view root_cert_name,
71       RefCountedPtr<grpc_tls_certificate_distributor> root_cert_distributor);
72 
73   bool ProvidesIdentityCerts(const std::string& cert_name);
74   void UpdateIdentityCertNameAndDistributor(
75       const std::string& cert_name, absl::string_view identity_cert_name,
76       RefCountedPtr<grpc_tls_certificate_distributor>
77           identity_cert_distributor);
78 
79   bool GetRequireClientCertificate(const std::string& cert_name);
80   // Updating \a require_client_certificate for a non-existing \a cert_name has
81   // no effect.
82   void UpdateRequireClientCertificate(const std::string& cert_name,
83                                       bool require_client_certificate);
84 
85   std::vector<StringMatcher> GetSanMatchers(const std::string& cluster);
86   void UpdateSubjectAlternativeNameMatchers(
87       const std::string& cluster, std::vector<StringMatcher> matchers);
88 
89   grpc_arg MakeChannelArg() const;
90 
91   static RefCountedPtr<XdsCertificateProvider> GetFromChannelArgs(
92       const grpc_channel_args* args);
93 
94  private:
95   class ClusterCertificateState {
96    public:
ClusterCertificateState(XdsCertificateProvider * xds_certificate_provider)97     explicit ClusterCertificateState(
98         XdsCertificateProvider* xds_certificate_provider)
99         : xds_certificate_provider_(xds_certificate_provider) {}
100 
101     ~ClusterCertificateState();
102 
103     // Returns true if the certs aren't being watched and there are no
104     // distributors configured.
105     bool IsSafeToRemove() const;
106 
ProvidesRootCerts()107     bool ProvidesRootCerts() const { return root_cert_distributor_ != nullptr; }
ProvidesIdentityCerts()108     bool ProvidesIdentityCerts() const {
109       return identity_cert_distributor_ != nullptr;
110     }
111 
112     void UpdateRootCertNameAndDistributor(
113         const std::string& cert_name, absl::string_view root_cert_name,
114         RefCountedPtr<grpc_tls_certificate_distributor> root_cert_distributor);
115     void UpdateIdentityCertNameAndDistributor(
116         const std::string& cert_name, absl::string_view identity_cert_name,
117         RefCountedPtr<grpc_tls_certificate_distributor>
118             identity_cert_distributor);
119 
120     void UpdateRootCertWatcher(
121         const std::string& cert_name,
122         grpc_tls_certificate_distributor* root_cert_distributor);
123     void UpdateIdentityCertWatcher(
124         const std::string& cert_name,
125         grpc_tls_certificate_distributor* identity_cert_distributor);
126 
require_client_certificate()127     bool require_client_certificate() const {
128       return require_client_certificate_;
129     }
set_require_client_certificate(bool require_client_certificate)130     void set_require_client_certificate(bool require_client_certificate) {
131       require_client_certificate_ = require_client_certificate;
132     }
133 
134     void WatchStatusCallback(const std::string& cert_name,
135                              bool root_being_watched,
136                              bool identity_being_watched);
137 
138    private:
139     XdsCertificateProvider* xds_certificate_provider_;
140     bool watching_root_certs_ = false;
141     bool watching_identity_certs_ = false;
142     std::string root_cert_name_;
143     std::string identity_cert_name_;
144     RefCountedPtr<grpc_tls_certificate_distributor> root_cert_distributor_;
145     RefCountedPtr<grpc_tls_certificate_distributor> identity_cert_distributor_;
146     grpc_tls_certificate_distributor::TlsCertificatesWatcherInterface*
147         root_cert_watcher_ = nullptr;
148     grpc_tls_certificate_distributor::TlsCertificatesWatcherInterface*
149         identity_cert_watcher_ = nullptr;
150     bool require_client_certificate_ = false;
151   };
152 
CompareImpl(const grpc_tls_certificate_provider * other)153   int CompareImpl(const grpc_tls_certificate_provider* other) const override {
154     // TODO(yashykt): Maybe do something better here.
155     return QsortCompare(static_cast<const grpc_tls_certificate_provider*>(this),
156                         other);
157   }
158 
159   void WatchStatusCallback(std::string cert_name, bool root_being_watched,
160                            bool identity_being_watched);
161 
162   RefCountedPtr<grpc_tls_certificate_distributor> distributor_;
163 
164   Mutex mu_;
165   std::map<std::string /*cert_name*/, std::unique_ptr<ClusterCertificateState>>
166       certificate_state_map_ ABSL_GUARDED_BY(mu_);
167 
168   // Use a separate mutex for san_matchers_ to avoid deadlocks since
169   // san_matchers_ needs to be accessed when a handshake is being done and we
170   // run into a possible deadlock scenario if using the same mutex. The mutex
171   // deadlock cycle is formed as -
172   // WatchStatusCallback() -> SetKeyMaterials() ->
173   // TlsChannelSecurityConnector::TlsChannelCertificateWatcher::OnCertificatesChanged()
174   // -> HandshakeManager::Add() -> SecurityHandshaker::DoHandshake() ->
175   // subject_alternative_names_matchers()
176   Mutex san_matchers_mu_;
177   std::map<std::string /*cluster_name*/, std::vector<StringMatcher>>
178       san_matcher_map_ ABSL_GUARDED_BY(san_matchers_mu_);
179 };
180 
181 }  // namespace grpc_core
182 
183 #endif  // GRPC_SRC_CORE_EXT_XDS_XDS_CERTIFICATE_PROVIDER_H
184