• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_CORE_EXT_XDS_XDS_CERTIFICATE_PROVIDER_H
20 #define GRPC_CORE_EXT_XDS_XDS_CERTIFICATE_PROVIDER_H
21 
22 #include <grpc/support/port_platform.h>
23 
24 #include "src/core/ext/xds/xds_api.h"
25 #include "src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h"
26 
27 #define GRPC_ARG_XDS_CERTIFICATE_PROVIDER \
28   "grpc.internal.xds_certificate_provider"
29 
30 namespace grpc_core {
31 
32 class XdsCertificateProvider : public grpc_tls_certificate_provider {
33  public:
34   XdsCertificateProvider();
35   ~XdsCertificateProvider() override;
36 
distributor()37   grpc_core::RefCountedPtr<grpc_tls_certificate_distributor> distributor()
38       const override {
39     return distributor_;
40   }
41 
42   bool ProvidesRootCerts(const std::string& cert_name);
43   void UpdateRootCertNameAndDistributor(
44       const std::string& cert_name, absl::string_view root_cert_name,
45       RefCountedPtr<grpc_tls_certificate_distributor> root_cert_distributor);
46 
47   bool ProvidesIdentityCerts(const std::string& cert_name);
48   void UpdateIdentityCertNameAndDistributor(
49       const std::string& cert_name, absl::string_view identity_cert_name,
50       RefCountedPtr<grpc_tls_certificate_distributor>
51           identity_cert_distributor);
52 
53   bool GetRequireClientCertificate(const std::string& cert_name);
54   // Updating \a require_client_certificate for a non-existing \a cert_name has
55   // no effect.
56   void UpdateRequireClientCertificate(const std::string& cert_name,
57                                       bool require_client_certificate);
58 
59   std::vector<StringMatcher> GetSanMatchers(const std::string& cluster);
60   void UpdateSubjectAlternativeNameMatchers(
61       const std::string& cluster, std::vector<StringMatcher> matchers);
62 
63   grpc_arg MakeChannelArg() const;
64 
65   static RefCountedPtr<XdsCertificateProvider> GetFromChannelArgs(
66       const grpc_channel_args* args);
67 
68  private:
69   class ClusterCertificateState {
70    public:
ClusterCertificateState(XdsCertificateProvider * xds_certificate_provider)71     explicit ClusterCertificateState(
72         XdsCertificateProvider* xds_certificate_provider)
73         : xds_certificate_provider_(xds_certificate_provider) {}
74 
75     ~ClusterCertificateState();
76 
77     // Returns true if the certs aren't being watched and there are no
78     // distributors configured.
79     bool IsSafeToRemove() const;
80 
ProvidesRootCerts()81     bool ProvidesRootCerts() const { return root_cert_distributor_ != nullptr; }
ProvidesIdentityCerts()82     bool ProvidesIdentityCerts() const {
83       return identity_cert_distributor_ != nullptr;
84     }
85 
86     void UpdateRootCertNameAndDistributor(
87         const std::string& cert_name, absl::string_view root_cert_name,
88         RefCountedPtr<grpc_tls_certificate_distributor> root_cert_distributor);
89     void UpdateIdentityCertNameAndDistributor(
90         const std::string& cert_name, absl::string_view identity_cert_name,
91         RefCountedPtr<grpc_tls_certificate_distributor>
92             identity_cert_distributor);
93 
94     void UpdateRootCertWatcher(
95         const std::string& cert_name,
96         grpc_tls_certificate_distributor* root_cert_distributor);
97     void UpdateIdentityCertWatcher(
98         const std::string& cert_name,
99         grpc_tls_certificate_distributor* identity_cert_distributor);
100 
require_client_certificate()101     bool require_client_certificate() const {
102       return require_client_certificate_;
103     }
set_require_client_certificate(bool require_client_certificate)104     void set_require_client_certificate(bool require_client_certificate) {
105       require_client_certificate_ = require_client_certificate;
106     }
107 
108     void WatchStatusCallback(const std::string& cert_name,
109                              bool root_being_watched,
110                              bool identity_being_watched);
111 
112    private:
113     XdsCertificateProvider* xds_certificate_provider_;
114     bool watching_root_certs_ = false;
115     bool watching_identity_certs_ = false;
116     std::string root_cert_name_;
117     std::string identity_cert_name_;
118     RefCountedPtr<grpc_tls_certificate_distributor> root_cert_distributor_;
119     RefCountedPtr<grpc_tls_certificate_distributor> identity_cert_distributor_;
120     grpc_tls_certificate_distributor::TlsCertificatesWatcherInterface*
121         root_cert_watcher_ = nullptr;
122     grpc_tls_certificate_distributor::TlsCertificatesWatcherInterface*
123         identity_cert_watcher_ = nullptr;
124     bool require_client_certificate_ = false;
125   };
126 
127   void WatchStatusCallback(std::string cert_name, bool root_being_watched,
128                            bool identity_being_watched);
129 
130   Mutex mu_;
131   std::map<std::string /*cert_name*/, std::unique_ptr<ClusterCertificateState>>
132       certificate_state_map_;
133 
134   // Use a separate mutex for san_matchers_ to avoid deadlocks since
135   // san_matchers_ needs to be accessed when a handshake is being done and we
136   // run into a possible deadlock scenario if using the same mutex. The mutex
137   // deadlock cycle is formed as -
138   // WatchStatusCallback() -> SetKeyMaterials() ->
139   // TlsChannelSecurityConnector::TlsChannelCertificateWatcher::OnCertificatesChanged()
140   // -> HandshakeManager::Add() -> SecurityHandshaker::DoHandshake() ->
141   // subject_alternative_names_matchers()
142   Mutex san_matchers_mu_;
143   std::map<std::string /*cluster_name*/, std::vector<StringMatcher>>
144       san_matcher_map_;
145 
146   RefCountedPtr<grpc_tls_certificate_distributor> distributor_;
147 };
148 
149 }  // namespace grpc_core
150 
151 #endif  // GRPC_CORE_EXT_XDS_XDS_CERTIFICATE_PROVIDER_H
152