Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix the issues in DefaultCertValidator::doVerifyCertChain and ContextImpl::verifyCertChain #16982

Merged
merged 11 commits into from
Jul 15, 2021
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,8 @@ int DefaultCertValidator::doVerifyCertChain(
}

return allow_untrusted_certificate_ ? 1
: (validated != Envoy::Ssl::ClientValidationStatus::Failed);
: verify_trusted_ca_ ? validated != Envoy::Ssl::ClientValidationStatus::Failed
tyxia marked this conversation as resolved.
Show resolved Hide resolved
: validated == Envoy::Ssl::ClientValidationStatus::Validated;
}

Envoy::Ssl::ClientValidationStatus DefaultCertValidator::verifyCertificate(
Expand Down
8 changes: 6 additions & 2 deletions source/extensions/transport_sockets/tls/context_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1168,16 +1168,20 @@ bool TlsContext::isCipherEnabled(uint16_t cipher_id, uint16_t client_version) {
bool ContextImpl::verifyCertChain(X509& leaf_cert, STACK_OF(X509) & intermediates,
std::string& error_details) {
bssl::UniquePtr<X509_STORE_CTX> ctx(X509_STORE_CTX_new());

ASSERT(!tls_contexts_.empty());
// It doesn't matter which SSL context is used, because they share the same
// cert validation config.
X509_STORE* store = SSL_CTX_get_cert_store(tls_contexts_[0].ssl_ctx_.get());
SSL_CTX* ssl_ctx = tls_contexts_[0].ssl_ctx_.get();
X509_STORE* store = SSL_CTX_get_cert_store(ssl_ctx);
if (!X509_STORE_CTX_init(ctx.get(), store, &leaf_cert, &intermediates)) {
error_details = "Failed to verify certificate chain: X509_STORE_CTX_init";
return false;
}

int res = cert_validator_->doVerifyCertChain(ctx.get(), nullptr, leaf_cert, nullptr);
if (res <= 0) {
// If |SSL_VERIFY_NONE|, the error is non-fatal, but we keep the error details.
if (res <= 0 && SSL_CTX_get_verify_mode(ssl_ctx) != SSL_VERIFY_NONE) {
const int n = X509_STORE_CTX_get_error(ctx.get());
const int depth = X509_STORE_CTX_get_error_depth(ctx.get());
error_details = absl::StrCat("X509_verify_cert: certificate verification error at depth ",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,25 @@ TEST(DefaultCertValidatorTest, TestCertificateVerificationWithSANMatcher) {
EXPECT_EQ(stats.fail_verify_san_.value(), 1);
}

TEST(DefaultCertValidatorTest, TestCertificateVerificationWithNoValidationContext) {
Stats::TestUtil::TestStore test_store;
SslStats stats = generateSslStats(test_store);
// Create the default validator object.
auto default_validator =
std::make_unique<Extensions::TransportSockets::Tls::DefaultCertValidator>(
/*CertificateValidationContextConfig=*/nullptr, stats,
Event::GlobalTimeSystem().timeSystem());

EXPECT_EQ(default_validator->verifyCertificate(/*cert=*/nullptr, /*verify_san_list=*/{},
/*subject_alt_name_matchers=*/{}),
Envoy::Ssl::ClientValidationStatus::NotValidated);
X509 cert = {};
EXPECT_EQ(default_validator->doVerifyCertChain(/*store_ctx=*/nullptr,
/*ssl_extended_info=*/nullptr, /*leaf_cert=*/cert,
/*transport_socket_options=*/nullptr),
0);
}

} // namespace Tls
} // namespace TransportSockets
} // namespace Extensions
Expand Down