Line data Source code
1 : #include "source/common/secret/secret_manager_impl.h" 2 : 3 : #include "envoy/admin/v3/config_dump.pb.h" 4 : #include "envoy/common/exception.h" 5 : #include "envoy/config/core/v3/base.pb.h" 6 : #include "envoy/config/core/v3/config_source.pb.h" 7 : #include "envoy/extensions/transport_sockets/tls/v3/cert.pb.h" 8 : 9 : #include "source/common/common/assert.h" 10 : #include "source/common/common/logger.h" 11 : #include "source/common/protobuf/utility.h" 12 : #include "source/common/secret/sds_api.h" 13 : #include "source/common/secret/secret_provider_impl.h" 14 : #include "source/common/ssl/certificate_validation_context_config_impl.h" 15 : #include "source/common/ssl/tls_certificate_config_impl.h" 16 : 17 : namespace Envoy { 18 : namespace Secret { 19 : 20 257 : SecretManagerImpl::SecretManagerImpl(OptRef<Server::ConfigTracker> config_tracker) { 21 257 : if (config_tracker.has_value()) { 22 257 : config_tracker_entry_ = 23 257 : config_tracker->add("secrets", [this](const Matchers::StringMatcher& name_matcher) { 24 98 : return dumpSecretConfigs(name_matcher); 25 98 : }); 26 257 : } 27 257 : } 28 : 29 : absl::Status SecretManagerImpl::addStaticSecret( 30 70 : const envoy::extensions::transport_sockets::tls::v3::Secret& secret) { 31 70 : switch (secret.type_case()) { 32 70 : case envoy::extensions::transport_sockets::tls::v3::Secret::TypeCase::kTlsCertificate: { 33 70 : auto secret_provider = 34 70 : std::make_shared<TlsCertificateConfigProviderImpl>(secret.tls_certificate()); 35 70 : if (!static_tls_certificate_providers_.insert(std::make_pair(secret.name(), secret_provider)) 36 70 : .second) { 37 0 : return absl::InvalidArgumentError( 38 0 : absl::StrCat("Duplicate static TlsCertificate secret name ", secret.name())); 39 0 : } 40 70 : break; 41 70 : } 42 70 : case envoy::extensions::transport_sockets::tls::v3::Secret::TypeCase::kValidationContext: { 43 0 : auto secret_provider = std::make_shared<CertificateValidationContextConfigProviderImpl>( 44 0 : secret.validation_context()); 45 0 : if (!static_certificate_validation_context_providers_ 46 0 : .insert(std::make_pair(secret.name(), secret_provider)) 47 0 : .second) { 48 0 : return absl::InvalidArgumentError(absl::StrCat( 49 0 : "Duplicate static CertificateValidationContext secret name ", secret.name())); 50 0 : } 51 0 : break; 52 0 : } 53 0 : case envoy::extensions::transport_sockets::tls::v3::Secret::TypeCase::kSessionTicketKeys: { 54 0 : auto secret_provider = 55 0 : std::make_shared<TlsSessionTicketKeysConfigProviderImpl>(secret.session_ticket_keys()); 56 0 : if (!static_session_ticket_keys_providers_ 57 0 : .insert(std::make_pair(secret.name(), secret_provider)) 58 0 : .second) { 59 0 : return absl::InvalidArgumentError( 60 0 : absl::StrCat("Duplicate static TlsSessionTicketKeys secret name ", secret.name())); 61 0 : } 62 0 : break; 63 0 : } 64 0 : case envoy::extensions::transport_sockets::tls::v3::Secret::TypeCase::kGenericSecret: { 65 0 : auto secret_provider = 66 0 : std::make_shared<GenericSecretConfigProviderImpl>(secret.generic_secret()); 67 0 : if (!static_generic_secret_providers_.insert(std::make_pair(secret.name(), secret_provider)) 68 0 : .second) { 69 0 : return absl::InvalidArgumentError( 70 0 : absl::StrCat("Duplicate static GenericSecret secret name ", secret.name())); 71 0 : } 72 0 : break; 73 0 : } 74 0 : default: 75 0 : return absl::InvalidArgumentError("Secret type not implemented"); 76 70 : } 77 70 : return absl::OkStatus(); 78 70 : } 79 : 80 : TlsCertificateConfigProviderSharedPtr 81 0 : SecretManagerImpl::findStaticTlsCertificateProvider(const std::string& name) const { 82 0 : auto secret = static_tls_certificate_providers_.find(name); 83 0 : return (secret != static_tls_certificate_providers_.end()) ? secret->second : nullptr; 84 0 : } 85 : 86 : CertificateValidationContextConfigProviderSharedPtr 87 0 : SecretManagerImpl::findStaticCertificateValidationContextProvider(const std::string& name) const { 88 0 : auto secret = static_certificate_validation_context_providers_.find(name); 89 0 : return (secret != static_certificate_validation_context_providers_.end()) ? secret->second 90 0 : : nullptr; 91 0 : } 92 : 93 : TlsSessionTicketKeysConfigProviderSharedPtr 94 0 : SecretManagerImpl::findStaticTlsSessionTicketKeysContextProvider(const std::string& name) const { 95 0 : auto secret = static_session_ticket_keys_providers_.find(name); 96 0 : return (secret != static_session_ticket_keys_providers_.end()) ? secret->second : nullptr; 97 0 : } 98 : 99 : GenericSecretConfigProviderSharedPtr 100 0 : SecretManagerImpl::findStaticGenericSecretProvider(const std::string& name) const { 101 0 : auto secret = static_generic_secret_providers_.find(name); 102 0 : return (secret != static_generic_secret_providers_.end()) ? secret->second : nullptr; 103 0 : } 104 : 105 : TlsCertificateConfigProviderSharedPtr SecretManagerImpl::createInlineTlsCertificateProvider( 106 0 : const envoy::extensions::transport_sockets::tls::v3::TlsCertificate& tls_certificate) { 107 0 : return std::make_shared<TlsCertificateConfigProviderImpl>(tls_certificate); 108 0 : } 109 : 110 : CertificateValidationContextConfigProviderSharedPtr 111 : SecretManagerImpl::createInlineCertificateValidationContextProvider( 112 : const envoy::extensions::transport_sockets::tls::v3::CertificateValidationContext& 113 0 : certificate_validation_context) { 114 0 : return std::make_shared<CertificateValidationContextConfigProviderImpl>( 115 0 : certificate_validation_context); 116 0 : } 117 : 118 : TlsSessionTicketKeysConfigProviderSharedPtr 119 : SecretManagerImpl::createInlineTlsSessionTicketKeysProvider( 120 : const envoy::extensions::transport_sockets::tls::v3::TlsSessionTicketKeys& 121 0 : tls_session_ticket_keys) { 122 0 : return std::make_shared<TlsSessionTicketKeysConfigProviderImpl>(tls_session_ticket_keys); 123 0 : } 124 : 125 : GenericSecretConfigProviderSharedPtr SecretManagerImpl::createInlineGenericSecretProvider( 126 0 : const envoy::extensions::transport_sockets::tls::v3::GenericSecret& generic_secret) { 127 0 : return std::make_shared<GenericSecretConfigProviderImpl>(generic_secret); 128 0 : } 129 : 130 : TlsCertificateConfigProviderSharedPtr SecretManagerImpl::findOrCreateTlsCertificateProvider( 131 : const envoy::config::core::v3::ConfigSource& sds_config_source, const std::string& config_name, 132 : Server::Configuration::TransportSocketFactoryContext& secret_provider_context, 133 0 : Init::Manager& init_manager) { 134 0 : return certificate_providers_.findOrCreate(sds_config_source, config_name, 135 0 : secret_provider_context, init_manager); 136 0 : } 137 : 138 : CertificateValidationContextConfigProviderSharedPtr 139 : SecretManagerImpl::findOrCreateCertificateValidationContextProvider( 140 : const envoy::config::core::v3::ConfigSource& sds_config_source, const std::string& config_name, 141 : Server::Configuration::TransportSocketFactoryContext& secret_provider_context, 142 0 : Init::Manager& init_manager) { 143 0 : return validation_context_providers_.findOrCreate(sds_config_source, config_name, 144 0 : secret_provider_context, init_manager); 145 0 : } 146 : 147 : TlsSessionTicketKeysConfigProviderSharedPtr 148 : SecretManagerImpl::findOrCreateTlsSessionTicketKeysContextProvider( 149 : const envoy::config::core::v3::ConfigSource& sds_config_source, const std::string& config_name, 150 : Server::Configuration::TransportSocketFactoryContext& secret_provider_context, 151 0 : Init::Manager& init_manager) { 152 0 : return session_ticket_keys_providers_.findOrCreate(sds_config_source, config_name, 153 0 : secret_provider_context, init_manager); 154 0 : } 155 : 156 : GenericSecretConfigProviderSharedPtr SecretManagerImpl::findOrCreateGenericSecretProvider( 157 : const envoy::config::core::v3::ConfigSource& sds_config_source, const std::string& config_name, 158 : Server::Configuration::TransportSocketFactoryContext& secret_provider_context, 159 0 : Init::Manager& init_manager) { 160 0 : return generic_secret_providers_.findOrCreate(sds_config_source, config_name, 161 0 : secret_provider_context, init_manager); 162 0 : } 163 : 164 : ProtobufTypes::MessagePtr 165 98 : SecretManagerImpl::dumpSecretConfigs(const Matchers::StringMatcher& name_matcher) { 166 98 : auto config_dump = std::make_unique<envoy::admin::v3::SecretsConfigDump>(); 167 : // Handle static tls key/cert providers. 168 98 : for (const auto& cert_iter : static_tls_certificate_providers_) { 169 70 : const auto& tls_cert = cert_iter.second; 170 70 : ASSERT(tls_cert != nullptr); 171 70 : envoy::extensions::transport_sockets::tls::v3::Secret dump_secret; 172 70 : dump_secret.set_name(cert_iter.first); 173 70 : dump_secret.mutable_tls_certificate()->MergeFrom(*tls_cert->secret()); 174 70 : if (!name_matcher.match(dump_secret.name())) { 175 0 : continue; 176 0 : } 177 70 : MessageUtil::redact(dump_secret); 178 70 : auto static_secret = config_dump->mutable_static_secrets()->Add(); 179 70 : static_secret->set_name(cert_iter.first); 180 70 : static_secret->mutable_secret()->PackFrom(dump_secret); 181 70 : } 182 : 183 : // Handle static certificate validation context providers. 184 98 : for (const auto& context_iter : static_certificate_validation_context_providers_) { 185 0 : const auto& validation_context = context_iter.second; 186 0 : ASSERT(validation_context != nullptr); 187 0 : envoy::extensions::transport_sockets::tls::v3::Secret dump_secret; 188 0 : dump_secret.set_name(context_iter.first); 189 0 : dump_secret.mutable_validation_context()->MergeFrom(*validation_context->secret()); 190 0 : if (!name_matcher.match(dump_secret.name())) { 191 0 : continue; 192 0 : } 193 0 : auto static_secret = config_dump->mutable_static_secrets()->Add(); 194 0 : static_secret->set_name(context_iter.first); 195 0 : static_secret->mutable_secret()->PackFrom(dump_secret); 196 0 : } 197 : 198 : // Handle static session keys providers. 199 98 : for (const auto& context_iter : static_session_ticket_keys_providers_) { 200 0 : const auto& session_ticket_keys = context_iter.second; 201 0 : ASSERT(session_ticket_keys != nullptr); 202 0 : envoy::extensions::transport_sockets::tls::v3::Secret dump_secret; 203 0 : dump_secret.set_name(context_iter.first); 204 0 : for (const auto& key : session_ticket_keys->secret()->keys()) { 205 0 : dump_secret.mutable_session_ticket_keys()->add_keys()->MergeFrom(key); 206 0 : } 207 0 : if (!name_matcher.match(dump_secret.name())) { 208 0 : continue; 209 0 : } 210 0 : MessageUtil::redact(dump_secret); 211 0 : auto static_secret = config_dump->mutable_static_secrets()->Add(); 212 0 : static_secret->set_name(context_iter.first); 213 0 : static_secret->mutable_secret()->PackFrom(dump_secret); 214 0 : } 215 : 216 : // Handle static generic secret providers. 217 98 : for (const auto& secret_iter : static_generic_secret_providers_) { 218 0 : const auto& generic_secret = secret_iter.second; 219 0 : ASSERT(generic_secret != nullptr); 220 0 : envoy::extensions::transport_sockets::tls::v3::Secret dump_secret; 221 0 : dump_secret.set_name(secret_iter.first); 222 0 : dump_secret.mutable_generic_secret()->MergeFrom(*generic_secret->secret()); 223 0 : if (!name_matcher.match(dump_secret.name())) { 224 0 : continue; 225 0 : } 226 0 : auto static_secret = config_dump->mutable_static_secrets()->Add(); 227 0 : static_secret->set_name(secret_iter.first); 228 0 : MessageUtil::redact(dump_secret); 229 0 : static_secret->mutable_secret()->PackFrom(dump_secret); 230 0 : } 231 : 232 : // Handle dynamic tls_certificate providers. 233 98 : const auto providers = certificate_providers_.allSecretProviders(); 234 98 : for (const auto& cert_secrets : providers) { 235 0 : const auto& secret_data = cert_secrets->secretData(); 236 0 : const auto& tls_cert = cert_secrets->secret(); 237 0 : const bool secret_ready = tls_cert != nullptr; 238 0 : envoy::extensions::transport_sockets::tls::v3::Secret secret; 239 0 : secret.set_name(secret_data.resource_name_); 240 0 : ProtobufWkt::Timestamp last_updated_ts; 241 0 : TimestampUtil::systemClockToTimestamp(secret_data.last_updated_, last_updated_ts); 242 0 : secret.set_name(secret_data.resource_name_); 243 0 : if (secret_ready) { 244 0 : secret.mutable_tls_certificate()->MergeFrom(*tls_cert); 245 0 : } 246 0 : if (!name_matcher.match(secret.name())) { 247 0 : continue; 248 0 : } 249 0 : MessageUtil::redact(secret); 250 0 : envoy::admin::v3::SecretsConfigDump::DynamicSecret* dump_secret; 251 0 : if (secret_ready) { 252 0 : dump_secret = config_dump->mutable_dynamic_active_secrets()->Add(); 253 0 : } else { 254 0 : dump_secret = config_dump->mutable_dynamic_warming_secrets()->Add(); 255 0 : } 256 0 : dump_secret->set_name(secret_data.resource_name_); 257 0 : dump_secret->set_version_info(secret_data.version_info_); 258 0 : *dump_secret->mutable_last_updated() = last_updated_ts; 259 0 : dump_secret->mutable_secret()->PackFrom(secret); 260 0 : } 261 : 262 : // Handling dynamic cert validation context providers. 263 98 : const auto context_secret_provider = validation_context_providers_.allSecretProviders(); 264 98 : for (const auto& validation_context_secret : context_secret_provider) { 265 0 : const auto& secret_data = validation_context_secret->secretData(); 266 0 : const auto& validation_context = validation_context_secret->secret(); 267 0 : const bool secret_ready = validation_context != nullptr; 268 : 269 0 : envoy::extensions::transport_sockets::tls::v3::Secret secret; 270 : 271 0 : if (secret_ready) { 272 0 : secret.mutable_validation_context()->MergeFrom(*validation_context); 273 0 : } 274 0 : secret.set_name(secret_data.resource_name_); 275 0 : if (!name_matcher.match(secret.name())) { 276 0 : continue; 277 0 : } 278 0 : ProtobufWkt::Timestamp last_updated_ts; 279 0 : envoy::admin::v3::SecretsConfigDump::DynamicSecret* dump_secret; 280 0 : TimestampUtil::systemClockToTimestamp(secret_data.last_updated_, last_updated_ts); 281 0 : if (secret_ready) { 282 0 : dump_secret = config_dump->mutable_dynamic_active_secrets()->Add(); 283 0 : } else { 284 0 : dump_secret = config_dump->mutable_dynamic_warming_secrets()->Add(); 285 0 : } 286 0 : dump_secret->set_version_info(secret_data.version_info_); 287 0 : *dump_secret->mutable_last_updated() = last_updated_ts; 288 0 : dump_secret->set_name(secret_data.resource_name_); 289 0 : dump_secret->mutable_secret()->PackFrom(secret); 290 0 : } 291 : 292 : // Handle dynamic session keys providers providers. 293 98 : const auto stek_providers = session_ticket_keys_providers_.allSecretProviders(); 294 98 : for (const auto& stek_secrets : stek_providers) { 295 0 : const auto& secret_data = stek_secrets->secretData(); 296 0 : const auto& tls_stek = stek_secrets->secret(); 297 0 : const bool secret_ready = tls_stek != nullptr; 298 0 : envoy::extensions::transport_sockets::tls::v3::Secret secret; 299 0 : secret.set_name(secret_data.resource_name_); 300 0 : if (secret_ready) { 301 0 : secret.mutable_session_ticket_keys()->MergeFrom(*tls_stek); 302 0 : } 303 0 : if (!name_matcher.match(secret.name())) { 304 0 : continue; 305 0 : } 306 0 : ProtobufWkt::Timestamp last_updated_ts; 307 0 : TimestampUtil::systemClockToTimestamp(secret_data.last_updated_, last_updated_ts); 308 0 : envoy::admin::v3::SecretsConfigDump::DynamicSecret* dump_secret; 309 0 : if (secret_ready) { 310 0 : dump_secret = config_dump->mutable_dynamic_active_secrets()->Add(); 311 0 : } else { 312 0 : dump_secret = config_dump->mutable_dynamic_warming_secrets()->Add(); 313 0 : } 314 0 : dump_secret->set_name(secret_data.resource_name_); 315 0 : dump_secret->set_version_info(secret_data.version_info_); 316 0 : *dump_secret->mutable_last_updated() = last_updated_ts; 317 0 : MessageUtil::redact(secret); 318 0 : dump_secret->mutable_secret()->PackFrom(secret); 319 0 : } 320 : 321 : // Handle dynamic generic secret providers. 322 98 : const auto generic_secret_providers = generic_secret_providers_.allSecretProviders(); 323 98 : for (const auto& provider : generic_secret_providers) { 324 0 : const auto& secret_data = provider->secretData(); 325 0 : const auto& generic_secret = provider->secret(); 326 0 : const bool secret_ready = generic_secret != nullptr; 327 0 : envoy::extensions::transport_sockets::tls::v3::Secret secret; 328 0 : secret.set_name(secret_data.resource_name_); 329 0 : if (secret_ready) { 330 0 : secret.mutable_generic_secret()->MergeFrom(*generic_secret); 331 0 : } 332 0 : if (!name_matcher.match(secret.name())) { 333 0 : continue; 334 0 : } 335 0 : ProtobufWkt::Timestamp last_updated_ts; 336 0 : TimestampUtil::systemClockToTimestamp(secret_data.last_updated_, last_updated_ts); 337 0 : envoy::admin::v3::SecretsConfigDump::DynamicSecret* dump_secret; 338 0 : if (secret_ready) { 339 0 : dump_secret = config_dump->mutable_dynamic_active_secrets()->Add(); 340 0 : } else { 341 0 : dump_secret = config_dump->mutable_dynamic_warming_secrets()->Add(); 342 0 : } 343 0 : dump_secret->set_name(secret_data.resource_name_); 344 0 : dump_secret->set_version_info(secret_data.version_info_); 345 0 : *dump_secret->mutable_last_updated() = last_updated_ts; 346 0 : MessageUtil::redact(secret); 347 0 : dump_secret->mutable_secret()->PackFrom(secret); 348 0 : } 349 : 350 98 : return config_dump; 351 98 : } 352 : 353 : } // namespace Secret 354 : } // namespace Envoy