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