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