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