Line data Source code
1 : #include "source/common/ssl/tls_certificate_config_impl.h" 2 : 3 : #include "envoy/common/exception.h" 4 : #include "envoy/extensions/transport_sockets/tls/v3/cert.pb.h" 5 : #include "envoy/server/transport_socket_config.h" 6 : 7 : #include "source/common/common/empty_string.h" 8 : #include "source/common/common/fmt.h" 9 : #include "source/common/config/datasource.h" 10 : 11 : namespace Envoy { 12 : namespace Ssl { 13 : 14 : namespace { 15 : std::vector<uint8_t> readOcspStaple(const envoy::config::core::v3::DataSource& source, 16 0 : Api::Api& api) { 17 0 : std::string staple = Config::DataSource::read(source, true, api); 18 0 : if (source.specifier_case() == 19 0 : envoy::config::core::v3::DataSource::SpecifierCase::kInlineString) { 20 0 : throwEnvoyExceptionOrPanic("OCSP staple cannot be provided via inline_string"); 21 0 : } 22 : 23 0 : return {staple.begin(), staple.end()}; 24 0 : } 25 : } // namespace 26 : 27 : static const std::string INLINE_STRING = "<inline>"; 28 : 29 : TlsCertificateConfigImpl::TlsCertificateConfigImpl( 30 : const envoy::extensions::transport_sockets::tls::v3::TlsCertificate& config, 31 : Server::Configuration::TransportSocketFactoryContext& factory_context, Api::Api& api) 32 : : certificate_chain_(Config::DataSource::read(config.certificate_chain(), true, api)), 33 : certificate_chain_path_( 34 : Config::DataSource::getPath(config.certificate_chain()) 35 : .value_or(certificate_chain_.empty() ? EMPTY_STRING : INLINE_STRING)), 36 : private_key_(Config::DataSource::read(config.private_key(), true, api)), 37 : private_key_path_(Config::DataSource::getPath(config.private_key()) 38 : .value_or(private_key_.empty() ? EMPTY_STRING : INLINE_STRING)), 39 : pkcs12_(Config::DataSource::read(config.pkcs12(), true, api)), 40 : pkcs12_path_(Config::DataSource::getPath(config.pkcs12()) 41 : .value_or(pkcs12_.empty() ? EMPTY_STRING : INLINE_STRING)), 42 : password_(Config::DataSource::read(config.password(), true, api)), 43 : password_path_(Config::DataSource::getPath(config.password()) 44 : .value_or(password_.empty() ? EMPTY_STRING : INLINE_STRING)), 45 : ocsp_staple_(readOcspStaple(config.ocsp_staple(), api)), 46 : ocsp_staple_path_(Config::DataSource::getPath(config.ocsp_staple()) 47 : .value_or(ocsp_staple_.empty() ? EMPTY_STRING : INLINE_STRING)), 48 0 : private_key_method_(nullptr) { 49 0 : if (config.has_pkcs12()) { 50 0 : if (config.has_private_key()) { 51 0 : throwEnvoyExceptionOrPanic( 52 0 : fmt::format("Certificate configuration can't have both pkcs12 and private_key")); 53 0 : } 54 0 : if (config.has_certificate_chain()) { 55 0 : throwEnvoyExceptionOrPanic( 56 0 : fmt::format("Certificate configuration can't have both pkcs12 and certificate_chain")); 57 0 : } 58 0 : if (config.has_private_key_provider()) { 59 0 : throwEnvoyExceptionOrPanic( 60 0 : fmt::format("Certificate configuration can't have both pkcs12 and private_key_provider")); 61 0 : } 62 0 : } else { 63 0 : if (config.has_private_key_provider()) { 64 0 : private_key_method_ = 65 0 : factory_context.sslContextManager() 66 0 : .privateKeyMethodManager() 67 0 : .createPrivateKeyMethodProvider(config.private_key_provider(), factory_context); 68 0 : if (private_key_method_ == nullptr || 69 0 : (!private_key_method_->isAvailable() && !config.private_key_provider().fallback())) { 70 0 : throwEnvoyExceptionOrPanic(fmt::format("Failed to load private key provider: {}", 71 0 : config.private_key_provider().provider_name())); 72 0 : } 73 : 74 0 : if (!private_key_method_->isAvailable()) { 75 0 : private_key_method_ = nullptr; 76 0 : } 77 0 : } 78 0 : if (certificate_chain_.empty()) { 79 0 : throwEnvoyExceptionOrPanic( 80 0 : fmt::format("Failed to load incomplete certificate from {}: certificate chain not set", 81 0 : certificate_chain_path_)); 82 0 : } 83 : 84 0 : if (private_key_.empty() && private_key_method_ == nullptr) { 85 0 : throwEnvoyExceptionOrPanic( 86 0 : fmt::format("Failed to load incomplete private key from path: {}", private_key_path_)); 87 0 : } 88 0 : } 89 0 : } 90 : 91 : } // namespace Ssl 92 : } // namespace Envoy