Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions api/envoy/api/v2/auth/cert.proto
Original file line number Diff line number Diff line change
Expand Up @@ -238,12 +238,27 @@ message CommonTlsContext {
// Configs for fetching TLS certificates via SDS API.
repeated SdsSecretConfig tls_certificate_sds_secret_configs = 6;

message CombinedCertificateValidationContext {
// How to validate peer certificates.
CertificateValidationContext default_validation_context = 1;

// Config for fetching validation context via SDS API.
SdsSecretConfig validation_context_sds_secret_config = 2;
};

oneof validation_context_type {
// How to validate peer certificates.
CertificateValidationContext validation_context = 3;

// Config for fetching validation context via SDS API.
SdsSecretConfig validation_context_sds_secret_config = 7;

// Default certificate validation context holds default value for any field
// in CertificateValidationContext. If SDS server returns CertificateValidationContext
// that contains an empty field, e.g. verify_subject_alt_name, Envoy checks
// default_validation_context.verify_subject_alt_name, and uses this default
// value for validation.
CombinedCertificateValidationContext combined_validation_context = 8;
}

// Supplies the list of ALPN protocols that the listener should expose. In
Expand Down
1 change: 1 addition & 0 deletions include/envoy/secret/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ envoy_cc_library(
"//include/envoy/common:callback",
"//include/envoy/ssl:certificate_validation_context_config_interface",
"//include/envoy/ssl:tls_certificate_config_interface",
"@envoy_api//envoy/api/v2/auth:cert_cc",
],
)

Expand Down
5 changes: 5 additions & 0 deletions include/envoy/secret/secret_provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <functional>

#include "envoy/api/v2/auth/cert.pb.h"
#include "envoy/common/callback.h"
#include "envoy/common/pure.h"
#include "envoy/ssl/certificate_validation_context_config.h"
Expand All @@ -22,6 +23,10 @@ template <class SecretType> class SecretProvider {
*/
virtual const SecretType* secret() const PURE;

// Sets a default secret. Once the default secret is set, it will be merged with dynamic secret
// as new secret to provide.
virtual void setDefaultSecret(const envoy::api::v2::auth::Secret&) PURE;

/**
* Add secret update callback into secret provider.
* It is safe to call this method by main thread and callback is safe to be invoked
Expand Down
15 changes: 14 additions & 1 deletion source/common/secret/sds_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ class TlsCertificateSdsApi : public SdsApi, public TlsCertificateConfigProvider
Common::CallbackHandle* addUpdateCallback(std::function<void()> callback) override {
return update_callback_manager_.add(callback);
}
void setDefaultSecret(const envoy::api::v2::auth::Secret&) override {}

protected:
void setSecret(const envoy::api::v2::auth::Secret& secret) override {
Expand Down Expand Up @@ -152,14 +153,26 @@ class CertificateValidationContextSdsApi : public SdsApi,
return update_callback_manager_.add(callback);
}

void setDefaultSecret(const envoy::api::v2::auth::Secret& default_secret) override {
if (default_secret.has_validation_context()) {
default_cvc_.CopyFrom(default_secret.validation_context());
}
}

protected:
void setSecret(const envoy::api::v2::auth::Secret& secret) override {
envoy::api::v2::auth::CertificateValidationContext new_secret(default_cvc_);
new_secret.MergeFrom(secret.validation_context());
certificate_validation_context_secrets_ =
std::make_unique<Ssl::CertificateValidationContextConfigImpl>(secret.validation_context());
std::make_unique<Ssl::CertificateValidationContextConfigImpl>(new_secret);
}

private:
Ssl::CertificateValidationContextConfigPtr certificate_validation_context_secrets_;
// Default CertificateValidationContext. Everytime a dynamic CertificateValidationContext is
// received, the dynamic CertificateValidationContext and default CertificateValidationContext are
// merged into one CertificateValidationContext, which is provided as secret by this provider.
envoy::api::v2::auth::CertificateValidationContext default_cvc_;
};

} // namespace Secret
Expand Down
3 changes: 3 additions & 0 deletions source/common/secret/secret_manager_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ void SecretManagerImpl::addStaticSecret(const envoy::api::v2::auth::Secret& secr
}
break;
}
// Static secret of type
// envoy::api::v2::auth::CommonTlsContext::ValidationContextTypeCase::kCombinedValidationContext
// is not useful.
default:
throw EnvoyException("Secret type not implemented");
}
Expand Down
61 changes: 44 additions & 17 deletions source/common/ssl/context_config_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include <memory>
#include <string>

#include "envoy/api/v2/auth/cert.pb.h"

#include "common/common/assert.h"
#include "common/common/empty_string.h"
#include "common/config/datasource.h"
Expand Down Expand Up @@ -45,32 +47,57 @@ Secret::TlsCertificateConfigProviderSharedPtr getTlsCertificateConfigProvider(
return nullptr;
}

Secret::CertificateValidationContextConfigProviderSharedPtr
getCertificateValidationContextConfigProviderFromSds(
const envoy::api::v2::auth::SdsSecretConfig& sds_secret_config,
const envoy::api::v2::auth::Secret& default_secret) {
if (!sds_secret_config.has_sds_config()) {
// static secret
auto secret_provider =
factory_context.secretManager().findStaticCertificateValidationContextProvider(
sds_secret_config.name());
if (!secret_provider) {
throw EnvoyException(fmt::format("Unknown static certificate validation context: {}",
sds_secret_config.name()));
}
return secret_provider;
} else {
auto secret_provider =
factory_context.secretManager().findOrCreateCertificateValidationContextProvider(
sds_secret_config.sds_config(), sds_secret_config.name(), factory_context);
secret_provider->setDefaultSecret(default_cvc);
return secret_provider;
}
return nullptr;
}

Secret::CertificateValidationContextConfigProviderSharedPtr
getCertificateValidationContextConfigProvider(
const envoy::api::v2::auth::CommonTlsContext& config,
Server::Configuration::TransportSocketFactoryContext& factory_context) {
if (config.has_validation_context()) {
switch (config.validation_context_type_case()) {
case envoy::api::v2::auth::CommonTlsContext::ValidationContextTypeCase::kValidationContext: {
return factory_context.secretManager().createInlineCertificateValidationContextProvider(
config.validation_context());
}
if (config.has_validation_context_sds_secret_config()) {
case envoy::api::v2::auth::CommonTlsContext::ValidationContextTypeCase::
kValidationContextSdsSecretConfig: {
const auto& sds_secret_config = config.validation_context_sds_secret_config();
if (!sds_secret_config.has_sds_config()) {
// static secret
auto secret_provider =
factory_context.secretManager().findStaticCertificateValidationContextProvider(
sds_secret_config.name());
if (!secret_provider) {
throw EnvoyException(fmt::format("Unknown static certificate validation context: {}",
sds_secret_config.name()));
}
return secret_provider;
} else {
return factory_context.secretManager().findOrCreateCertificateValidationContextProvider(
sds_secret_config.sds_config(), sds_secret_config.name(), factory_context);
}
envoy::api::v2::auth::Secret default_secret;
return getCertificateValidationContextConfigProviderFromSds(sds_secret_config, default_secret);
}
case envoy::api::v2::auth::CommonTlsContext::ValidationContextTypeCase::
kCombinedValidationContext: {
envoy::api::v2::auth::Secret default_secret;
default_secret.mutable_validation_context()->CopyFrom(
config.combined_validation_context().default_validation_context());
const auto& sds_secret_config =
config.combined_validation_context().validation_context_sds_secret_config();
return getCertificateValidationContextConfigProviderFromSds(sds_secret_config, default_secret);
}
default:
return nullptr;
}
return nullptr;
}

} // namespace
Expand Down