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_CERTIFICATE_PROVIDER_STORE_H 20 #define GRPC_SRC_CORE_EXT_XDS_CERTIFICATE_PROVIDER_STORE_H 21 22 #include <grpc/support/port_platform.h> 23 24 #include <map> 25 #include <string> 26 #include <utility> 27 28 #include "absl/base/thread_annotations.h" 29 #include "absl/strings/string_view.h" 30 31 #include <grpc/grpc_security.h> 32 33 #include "src/core/lib/gpr/useful.h" 34 #include "src/core/lib/gprpp/orphanable.h" 35 #include "src/core/lib/gprpp/ref_counted_ptr.h" 36 #include "src/core/lib/gprpp/sync.h" 37 #include "src/core/lib/gprpp/unique_type_name.h" 38 #include "src/core/lib/gprpp/validation_errors.h" 39 #include "src/core/lib/iomgr/iomgr_fwd.h" 40 #include "src/core/lib/json/json.h" 41 #include "src/core/lib/json/json_args.h" 42 #include "src/core/lib/json/json_object_loader.h" 43 #include "src/core/lib/security/certificate_provider/certificate_provider_factory.h" 44 #include "src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.h" 45 #include "src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h" 46 47 namespace grpc_core { 48 49 // Map for xDS based grpc_tls_certificate_provider instances. 50 class CertificateProviderStore 51 : public InternallyRefCounted<CertificateProviderStore> { 52 public: 53 struct PluginDefinition { 54 std::string plugin_name; 55 RefCountedPtr<CertificateProviderFactory::Config> config; 56 57 static const JsonLoaderInterface* JsonLoader(const JsonArgs&); 58 void JsonPostLoad(const Json& json, const JsonArgs& args, 59 ValidationErrors* errors); 60 }; 61 62 // Maps plugin instance (opaque) name to plugin defition. 63 typedef std::map<std::string, PluginDefinition> PluginDefinitionMap; 64 CertificateProviderStore(PluginDefinitionMap plugin_config_map)65 explicit CertificateProviderStore(PluginDefinitionMap plugin_config_map) 66 : plugin_config_map_(std::move(plugin_config_map)) {} 67 68 // If a certificate provider corresponding to the instance name \a key is 69 // found, a ref to the grpc_tls_certificate_provider is returned. If no 70 // provider is found for the key, a new provider is created from the plugin 71 // definition map. 72 // Returns nullptr on failure to get or create a new certificate provider. 73 RefCountedPtr<grpc_tls_certificate_provider> CreateOrGetCertificateProvider( 74 absl::string_view key); 75 Orphan()76 void Orphan() override { Unref(); } 77 78 private: 79 // A thin wrapper around `grpc_tls_certificate_provider` which allows removing 80 // the entry from the CertificateProviderStore when the refcount reaches zero. 81 class CertificateProviderWrapper : public grpc_tls_certificate_provider { 82 public: CertificateProviderWrapper(RefCountedPtr<grpc_tls_certificate_provider> certificate_provider,RefCountedPtr<CertificateProviderStore> store,absl::string_view key)83 CertificateProviderWrapper( 84 RefCountedPtr<grpc_tls_certificate_provider> certificate_provider, 85 RefCountedPtr<CertificateProviderStore> store, absl::string_view key) 86 : certificate_provider_(std::move(certificate_provider)), 87 store_(std::move(store)), 88 key_(key) {} 89 ~CertificateProviderWrapper()90 ~CertificateProviderWrapper() override { 91 store_->ReleaseCertificateProvider(key_, this); 92 } 93 distributor()94 RefCountedPtr<grpc_tls_certificate_distributor> distributor() 95 const override { 96 return certificate_provider_->distributor(); 97 } 98 interested_parties()99 grpc_pollset_set* interested_parties() const override { 100 return certificate_provider_->interested_parties(); 101 } 102 CompareImpl(const grpc_tls_certificate_provider * other)103 int CompareImpl(const grpc_tls_certificate_provider* other) const override { 104 // TODO(yashykt): This should probably delegate to the `Compare` method of 105 // the wrapped certificate_provider_ object. 106 return QsortCompare( 107 static_cast<const grpc_tls_certificate_provider*>(this), other); 108 } 109 110 UniqueTypeName type() const override; 111 key()112 absl::string_view key() const { return key_; } 113 114 private: 115 RefCountedPtr<grpc_tls_certificate_provider> certificate_provider_; 116 RefCountedPtr<CertificateProviderStore> store_; 117 absl::string_view key_; 118 }; 119 120 RefCountedPtr<CertificateProviderWrapper> CreateCertificateProviderLocked( 121 absl::string_view key) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_); 122 123 // Releases a previously created certificate provider from the certificate 124 // provider map if the value matches \a wrapper. 125 void ReleaseCertificateProvider(absl::string_view key, 126 CertificateProviderWrapper* wrapper); 127 128 Mutex mu_; 129 // Map of plugin configurations 130 const PluginDefinitionMap plugin_config_map_; 131 // Underlying map for the providers. 132 std::map<absl::string_view, CertificateProviderWrapper*> 133 certificate_providers_map_ ABSL_GUARDED_BY(mu_); 134 }; 135 136 } // namespace grpc_core 137 138 #endif // GRPC_SRC_CORE_EXT_XDS_CERTIFICATE_PROVIDER_STORE_H 139