Skip to content

Commit 9a2c95b

Browse files
remove exceptions from SPIFFEValidator constructor (#40208)
the spiffe validator does not need to throw exceptions since the cert validator factory interface's createCertValidator method returns a statusor. This PR cleans up the constructor to update a status parameter instead of throwing. Risk Level: low Testing: unit test updated, integration test unaffected! Docs Changes: none Release Notes: none Platform Specific Features: none --------- Signed-off-by: antoniovleonti <[email protected]>
1 parent b04aa73 commit 9a2c95b

File tree

4 files changed

+125
-88
lines changed

4 files changed

+125
-88
lines changed

source/extensions/transport_sockets/tls/cert_validator/spiffe/spiffe_validator.cc

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
#include "source/extensions/transport_sockets/tls/cert_validator/spiffe/spiffe_validator.h"
2+
#include "spiffe_validator.h"
23

34
#include <openssl/safestack.h>
45

56
#include <cstdint>
67

8+
#include "envoy/common/exception.h"
79
#include "envoy/extensions/transport_sockets/tls/v3/common.pb.h"
810
#include "envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.pb.h"
911
#include "envoy/network/transport_socket.h"
@@ -24,6 +26,8 @@
2426
#include "source/common/tls/stats.h"
2527
#include "source/common/tls/utility.h"
2628

29+
#include "absl/status/status.h"
30+
#include "absl/status/statusor.h"
2731
#include "openssl/ssl.h"
2832
#include "openssl/x509v3.h"
2933

@@ -129,10 +133,10 @@ SPIFFEValidator::parseTrustBundles(const std::string& trust_bundle_mapping_str)
129133
return spiffe_data;
130134
}
131135

132-
void SPIFFEValidator::initializeCertificateRefresh(
136+
absl::Status SPIFFEValidator::initializeCertificateRefresh(
133137
Server::Configuration::CommonFactoryContext& context) {
134138
file_watcher_ = context.mainThreadDispatcher().createFilesystemWatcher();
135-
THROW_IF_NOT_OK(file_watcher_->addWatch(
139+
RETURN_IF_NOT_OK(file_watcher_->addWatch(
136140
trust_bundle_file_name_, Filesystem::Watcher::Events::Modified, [this](uint32_t) {
137141
ENVOY_LOG(info, "Updating SPIFFE bundle map from file '{}'", trust_bundle_file_name_);
138142

@@ -153,20 +157,22 @@ void SPIFFEValidator::initializeCertificateRefresh(
153157
}
154158
return absl::OkStatus();
155159
}));
160+
return absl::OkStatus();
156161
}
157162

158163
SPIFFEValidator::SPIFFEValidator(const Envoy::Ssl::CertificateValidationContextConfig* config,
159164
SslStats& stats,
160165
Server::Configuration::CommonFactoryContext& context,
161-
Stats::Scope& scope)
166+
Stats::Scope& scope, absl::Status& creation_status)
162167
: api_(config->api()), stats_(stats), time_source_(context.timeSource()) {
163168
ASSERT(config != nullptr);
164169
allow_expired_certificate_ = config->allowExpiredCertificate();
165170

166171
SPIFFEConfig message;
167-
THROW_IF_NOT_OK(Config::Utility::translateOpaqueConfig(
168-
config->customValidatorConfig().value().typed_config(),
169-
ProtobufMessage::getStrictValidationVisitor(), message));
172+
SET_AND_RETURN_IF_NOT_OK(Config::Utility::translateOpaqueConfig(
173+
config->customValidatorConfig().value().typed_config(),
174+
ProtobufMessage::getStrictValidationVisitor(), message),
175+
creation_status);
170176

171177
if (!config->subjectAltNameMatchers().empty()) {
172178
for (const auto& matcher : config->subjectAltNameMatchers()) {
@@ -183,11 +189,12 @@ SPIFFEValidator::SPIFFEValidator(const Envoy::Ssl::CertificateValidationContextC
183189

184190
// If a trust bundle map is provided, use that...
185191
if (message.has_trust_bundles()) {
186-
std::string trust_bundles_str = THROW_OR_RETURN_VALUE(
187-
Config::DataSource::read(message.trust_bundles(), false, config->api()), std::string);
188-
auto parse_result = parseTrustBundles(trust_bundles_str);
192+
absl::StatusOr<std::string> trust_bundles_str =
193+
Config::DataSource::read(message.trust_bundles(), false, config->api());
194+
SET_AND_RETURN_IF_NOT_OK(trust_bundles_str.status(), creation_status);
195+
auto parse_result = parseTrustBundles(*trust_bundles_str);
189196

190-
THROW_IF_NOT_OK_REF(parse_result.status());
197+
SET_AND_RETURN_IF_NOT_OK(parse_result.status(), creation_status);
191198

192199
spiffe_data_ = *parse_result;
193200

@@ -197,7 +204,7 @@ SPIFFEValidator::SPIFFEValidator(const Envoy::Ssl::CertificateValidationContextC
197204
tls_ = ThreadLocal::TypedSlot<ThreadLocalSpiffeState>::makeUnique(context.threadLocal());
198205
tls_->set([](Event::Dispatcher&) { return std::make_shared<ThreadLocalSpiffeState>(); });
199206
updateSpiffeData(spiffe_data_);
200-
initializeCertificateRefresh(context);
207+
SET_AND_RETURN_IF_NOT_OK(initializeCertificateRefresh(context), creation_status);
201208
}
202209

203210
initializeCertExpirationStats(scope, config->caCertName());
@@ -210,19 +217,21 @@ SPIFFEValidator::SPIFFEValidator(const Envoy::Ssl::CertificateValidationContextC
210217
for (auto& domain : message.trust_domains()) {
211218
if (spiffe_data_->trust_bundle_stores_.find(domain.name()) !=
212219
spiffe_data_->trust_bundle_stores_.end()) {
213-
throw EnvoyException(absl::StrCat(
220+
creation_status = absl::InvalidArgumentError(absl::StrCat(
214221
"Multiple trust bundles are given for one trust domain for ", domain.name()));
222+
return;
215223
}
216224

217-
auto cert = THROW_OR_RETURN_VALUE(
218-
Config::DataSource::read(domain.trust_bundle(), true, config->api()), std::string);
219-
bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(const_cast<char*>(cert.data()), cert.size()));
225+
auto cert = Config::DataSource::read(domain.trust_bundle(), true, config->api());
226+
SET_AND_RETURN_IF_NOT_OK(cert.status(), creation_status);
227+
bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(const_cast<char*>(cert->data()), cert->size()));
220228
RELEASE_ASSERT(bio != nullptr, "");
221229
bssl::UniquePtr<STACK_OF(X509_INFO)> list(
222230
PEM_X509_INFO_read_bio(bio.get(), nullptr, nullptr, nullptr));
223231
if (list == nullptr || sk_X509_INFO_num(list.get()) == 0) {
224-
throw EnvoyException(
232+
creation_status = absl::InvalidArgumentError(
225233
absl::StrCat("Failed to load trusted CA certificate for ", domain.name()));
234+
return;
226235
}
227236

228237
auto store = X509StorePtr(X509_STORE_new());
@@ -495,7 +504,11 @@ class SPIFFEValidatorFactory : public CertValidatorFactory {
495504
createCertValidator(const Envoy::Ssl::CertificateValidationContextConfig* config, SslStats& stats,
496505
Server::Configuration::CommonFactoryContext& context,
497506
Stats::Scope& scope) override {
498-
return std::make_unique<SPIFFEValidator>(config, stats, context, scope);
507+
absl::Status creation_status = absl::OkStatus();
508+
auto validator =
509+
std::make_unique<SPIFFEValidator>(config, stats, context, scope, creation_status);
510+
RETURN_IF_NOT_OK(creation_status);
511+
return validator;
499512
}
500513

501514
std::string name() const override { return "envoy.tls.cert_validator.spiffe"; }

source/extensions/transport_sockets/tls/cert_validator/spiffe/spiffe_validator.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ class SPIFFEValidator : public CertValidator, Logger::Loggable<Logger::Id::secre
4343
: spiffe_data_(std::make_shared<SpiffeData>()), api_(context.api()), stats_(stats),
4444
time_source_(context.timeSource()) {};
4545
SPIFFEValidator(const Envoy::Ssl::CertificateValidationContextConfig* config, SslStats& stats,
46-
Server::Configuration::CommonFactoryContext& context, Stats::Scope& scope);
46+
Server::Configuration::CommonFactoryContext& context, Stats::Scope& scope,
47+
absl::Status& creation_status);
4748

4849
~SPIFFEValidator() override = default;
4950

@@ -84,7 +85,7 @@ class SPIFFEValidator : public CertValidator, Logger::Loggable<Logger::Id::secre
8485
X509_VERIFY_PARAM* verify_param,
8586
std::string& error_details);
8687

87-
void initializeCertificateRefresh(Server::Configuration::CommonFactoryContext& context);
88+
absl::Status initializeCertificateRefresh(Server::Configuration::CommonFactoryContext& context);
8889
void initializeCertExpirationStats(Stats::Scope& scope, const std::string& cert_name);
8990
absl::StatusOr<std::shared_ptr<SpiffeData>>
9091
parseTrustBundles(const std::string& trust_bundles_str);

test/extensions/transport_sockets/tls/cert_validator/spiffe/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ envoy_extension_cc_test(
3535
"//test/mocks/server:server_factory_context_mocks",
3636
"//test/test_common:environment_lib",
3737
"//test/test_common:simulated_time_system_lib",
38+
"//test/test_common:status_utility_lib",
3839
"//test/test_common:test_runtime_lib",
3940
"//test/test_common:utility_lib",
4041
],

0 commit comments

Comments
 (0)