1
1
#include " source/extensions/transport_sockets/tls/cert_validator/spiffe/spiffe_validator.h"
2
+ #include " spiffe_validator.h"
2
3
3
4
#include < openssl/safestack.h>
4
5
5
6
#include < cstdint>
6
7
8
+ #include " envoy/common/exception.h"
7
9
#include " envoy/extensions/transport_sockets/tls/v3/common.pb.h"
8
10
#include " envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.pb.h"
9
11
#include " envoy/network/transport_socket.h"
24
26
#include " source/common/tls/stats.h"
25
27
#include " source/common/tls/utility.h"
26
28
29
+ #include " absl/status/status.h"
30
+ #include " absl/status/statusor.h"
27
31
#include " openssl/ssl.h"
28
32
#include " openssl/x509v3.h"
29
33
@@ -129,10 +133,10 @@ SPIFFEValidator::parseTrustBundles(const std::string& trust_bundle_mapping_str)
129
133
return spiffe_data;
130
134
}
131
135
132
- void SPIFFEValidator::initializeCertificateRefresh (
136
+ absl::Status SPIFFEValidator::initializeCertificateRefresh (
133
137
Server::Configuration::CommonFactoryContext& context) {
134
138
file_watcher_ = context.mainThreadDispatcher ().createFilesystemWatcher ();
135
- THROW_IF_NOT_OK (file_watcher_->addWatch (
139
+ RETURN_IF_NOT_OK (file_watcher_->addWatch (
136
140
trust_bundle_file_name_, Filesystem::Watcher::Events::Modified, [this ](uint32_t ) {
137
141
ENVOY_LOG (info, " Updating SPIFFE bundle map from file '{}'" , trust_bundle_file_name_);
138
142
@@ -153,20 +157,22 @@ void SPIFFEValidator::initializeCertificateRefresh(
153
157
}
154
158
return absl::OkStatus ();
155
159
}));
160
+ return absl::OkStatus ();
156
161
}
157
162
158
163
SPIFFEValidator::SPIFFEValidator (const Envoy::Ssl::CertificateValidationContextConfig* config,
159
164
SslStats& stats,
160
165
Server::Configuration::CommonFactoryContext& context,
161
- Stats::Scope& scope)
166
+ Stats::Scope& scope, absl::Status& creation_status )
162
167
: api_(config->api ()), stats_(stats), time_source_(context.timeSource()) {
163
168
ASSERT (config != nullptr );
164
169
allow_expired_certificate_ = config->allowExpiredCertificate ();
165
170
166
171
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);
170
176
171
177
if (!config->subjectAltNameMatchers ().empty ()) {
172
178
for (const auto & matcher : config->subjectAltNameMatchers ()) {
@@ -183,11 +189,12 @@ SPIFFEValidator::SPIFFEValidator(const Envoy::Ssl::CertificateValidationContextC
183
189
184
190
// If a trust bundle map is provided, use that...
185
191
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);
189
196
190
- THROW_IF_NOT_OK_REF (parse_result.status ());
197
+ SET_AND_RETURN_IF_NOT_OK (parse_result.status (), creation_status );
191
198
192
199
spiffe_data_ = *parse_result;
193
200
@@ -197,7 +204,7 @@ SPIFFEValidator::SPIFFEValidator(const Envoy::Ssl::CertificateValidationContextC
197
204
tls_ = ThreadLocal::TypedSlot<ThreadLocalSpiffeState>::makeUnique (context.threadLocal ());
198
205
tls_->set ([](Event::Dispatcher&) { return std::make_shared<ThreadLocalSpiffeState>(); });
199
206
updateSpiffeData (spiffe_data_);
200
- initializeCertificateRefresh (context);
207
+ SET_AND_RETURN_IF_NOT_OK ( initializeCertificateRefresh (context), creation_status );
201
208
}
202
209
203
210
initializeCertExpirationStats (scope, config->caCertName ());
@@ -210,19 +217,21 @@ SPIFFEValidator::SPIFFEValidator(const Envoy::Ssl::CertificateValidationContextC
210
217
for (auto & domain : message.trust_domains ()) {
211
218
if (spiffe_data_->trust_bundle_stores_ .find (domain.name ()) !=
212
219
spiffe_data_->trust_bundle_stores_ .end ()) {
213
- throw EnvoyException (absl::StrCat (
220
+ creation_status = absl::InvalidArgumentError (absl::StrCat (
214
221
" Multiple trust bundles are given for one trust domain for " , domain.name ()));
222
+ return ;
215
223
}
216
224
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 ()));
220
228
RELEASE_ASSERT (bio != nullptr , " " );
221
229
bssl::UniquePtr<STACK_OF (X509_INFO)> list (
222
230
PEM_X509_INFO_read_bio (bio.get (), nullptr , nullptr , nullptr ));
223
231
if (list == nullptr || sk_X509_INFO_num (list.get ()) == 0 ) {
224
- throw EnvoyException (
232
+ creation_status = absl::InvalidArgumentError (
225
233
absl::StrCat (" Failed to load trusted CA certificate for " , domain.name ()));
234
+ return ;
226
235
}
227
236
228
237
auto store = X509StorePtr (X509_STORE_new ());
@@ -495,7 +504,11 @@ class SPIFFEValidatorFactory : public CertValidatorFactory {
495
504
createCertValidator (const Envoy::Ssl::CertificateValidationContextConfig* config, SslStats& stats,
496
505
Server::Configuration::CommonFactoryContext& context,
497
506
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;
499
512
}
500
513
501
514
std::string name () const override { return " envoy.tls.cert_validator.spiffe" ; }
0 commit comments