From 7500c1e2c91a6c573470bc040dba8b4baf611219 Mon Sep 17 00:00:00 2001 From: Kuat Yessenov Date: Wed, 2 Oct 2019 11:49:46 -0700 Subject: [PATCH 1/5] tls: add local certificate presented flag for mTLS detection Signed-off-by: Kuat Yessenov --- include/envoy/ssl/connection.h | 5 +++++ source/extensions/filters/common/expr/context.cc | 4 +++- source/extensions/transport_sockets/tls/ssl_socket.cc | 5 +++++ source/extensions/transport_sockets/tls/ssl_socket.h | 1 + test/extensions/filters/common/expr/context_test.cc | 2 ++ test/extensions/transport_sockets/tls/ssl_socket_test.cc | 1 + test/mocks/ssl/mocks.h | 1 + 7 files changed, 18 insertions(+), 1 deletion(-) diff --git a/include/envoy/ssl/connection.h b/include/envoy/ssl/connection.h index d586d9fe09a57..988d74b874758 100644 --- a/include/envoy/ssl/connection.h +++ b/include/envoy/ssl/connection.h @@ -23,6 +23,11 @@ class ConnectionInfo { **/ virtual bool peerCertificatePresented() const PURE; + /** + * @return bool whether the local certificate is presented. + **/ + virtual bool localCertificatePresented() const PURE; + /** * @return std::string the URIs in the SAN field of the local certificate. Returns {} if there is * no local certificate, or no SAN field, or no URI. diff --git a/source/extensions/filters/common/expr/context.cc b/source/extensions/filters/common/expr/context.cc index cf2e3a1b06427..d7d6b65fe776b 100644 --- a/source/extensions/filters/common/expr/context.cc +++ b/source/extensions/filters/common/expr/context.cc @@ -112,6 +112,7 @@ absl::optional ConnectionWrapper::operator[](CelValue key) const { auto value = key.StringOrDie().value(); if (value == MTLS) { return CelValue::CreateBool(info_.downstreamSslConnection() != nullptr && + info_.downstreamSslConnection()->localCertificatePresented() && info_.downstreamSslConnection()->peerCertificatePresented()); } else if (value == RequestedServerName) { return CelValue::CreateString(info_.requestedServerName()); @@ -144,7 +145,8 @@ absl::optional UpstreamWrapper::operator[](CelValue key) const { } } else if (value == MTLS) { return CelValue::CreateBool(info_.upstreamSslConnection() != nullptr && - info_.upstreamSslConnection()->peerCertificatePresented()); + info_.upstreamSslConnection()->localCertificatePresented()) && + info_.upstreamSslConnection()->peerCertificatePresented(); } return {}; diff --git a/source/extensions/transport_sockets/tls/ssl_socket.cc b/source/extensions/transport_sockets/tls/ssl_socket.cc index 7737d36b160f6..ee2ba19034a4e 100644 --- a/source/extensions/transport_sockets/tls/ssl_socket.cc +++ b/source/extensions/transport_sockets/tls/ssl_socket.cc @@ -306,6 +306,11 @@ bool SslSocketInfo::peerCertificatePresented() const { return cert != nullptr; } +bool SslSocketInfo::localCertificatePresented() const { + bssl::UniquePtr cert(SSL_get_certificate(ssl_.get())); + return cert != nullptr; +} + std::vector SslSocketInfo::uriSanLocalCertificate() const { if (!cached_uri_san_local_certificate_.empty()) { return cached_uri_san_local_certificate_; diff --git a/source/extensions/transport_sockets/tls/ssl_socket.h b/source/extensions/transport_sockets/tls/ssl_socket.h index 4f7660717b807..be0f6bd438e01 100644 --- a/source/extensions/transport_sockets/tls/ssl_socket.h +++ b/source/extensions/transport_sockets/tls/ssl_socket.h @@ -47,6 +47,7 @@ class SslSocketInfo : public Envoy::Ssl::ConnectionInfo { // Ssl::ConnectionInfo bool peerCertificatePresented() const override; + bool localCertificatePresented() const override; std::vector uriSanLocalCertificate() const override; const std::string& sha256PeerCertificateDigest() const override; const std::string& serialNumberPeerCertificate() const override; diff --git a/test/extensions/filters/common/expr/context_test.cc b/test/extensions/filters/common/expr/context_test.cc index 7f11fa75bb55e..827337526895f 100644 --- a/test/extensions/filters/common/expr/context_test.cc +++ b/test/extensions/filters/common/expr/context_test.cc @@ -277,7 +277,9 @@ TEST(Context, ConnectionAttributes) { EXPECT_CALL(info, upstreamHost()).WillRepeatedly(Return(upstream_host)); EXPECT_CALL(info, requestedServerName()).WillRepeatedly(ReturnRef(sni_name)); EXPECT_CALL(*downstream_ssl_info, peerCertificatePresented()).WillRepeatedly(Return(true)); + EXPECT_CALL(*downstream_ssl_info, localCertificatePresented()).WillRepeatedly(Return(true)); EXPECT_CALL(*upstream_ssl_info, peerCertificatePresented()).WillRepeatedly(Return(true)); + EXPECT_CALL(*upstream_ssl_info, localCertificatePresented()).WillRepeatedly(Return(true)); const std::string tls_version = "TLSv1"; EXPECT_CALL(*downstream_ssl_info, tlsVersion()).WillRepeatedly(ReturnRef(tls_version)); EXPECT_CALL(*upstream_host, address()).WillRepeatedly(Return(upstream_address)); diff --git a/test/extensions/transport_sockets/tls/ssl_socket_test.cc b/test/extensions/transport_sockets/tls/ssl_socket_test.cc index aff65278f0877..29cd2fe069abe 100644 --- a/test/extensions/transport_sockets/tls/ssl_socket_test.cc +++ b/test/extensions/transport_sockets/tls/ssl_socket_test.cc @@ -343,6 +343,7 @@ void testUtil(const TestUtilOptions& options) { server_connection->ssl()->subjectPeerCertificate()); } if (!options.expectedLocalSubject().empty()) { + EXPECT_TRUE(server_connection->ssl()->localCertificatePresented()); EXPECT_EQ(options.expectedLocalSubject(), server_connection->ssl()->subjectLocalCertificate()); } diff --git a/test/mocks/ssl/mocks.h b/test/mocks/ssl/mocks.h index 041888aa99c9a..490865f8d0793 100644 --- a/test/mocks/ssl/mocks.h +++ b/test/mocks/ssl/mocks.h @@ -38,6 +38,7 @@ class MockConnectionInfo : public ConnectionInfo { ~MockConnectionInfo() override; MOCK_CONST_METHOD0(peerCertificatePresented, bool()); + MOCK_CONST_METHOD0(localCertificatePresented, bool()); MOCK_CONST_METHOD0(uriSanLocalCertificate, std::vector()); MOCK_CONST_METHOD0(sha256PeerCertificateDigest, const std::string&()); MOCK_CONST_METHOD0(serialNumberPeerCertificate, const std::string&()); From a36b321efb4a8612d78c020fbc2ac3fdf78d62bc Mon Sep 17 00:00:00 2001 From: Kuat Yessenov Date: Wed, 2 Oct 2019 11:51:58 -0700 Subject: [PATCH 2/5] typo fix Signed-off-by: Kuat Yessenov --- source/extensions/filters/common/expr/context.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/extensions/filters/common/expr/context.cc b/source/extensions/filters/common/expr/context.cc index d7d6b65fe776b..3489a7fddbd60 100644 --- a/source/extensions/filters/common/expr/context.cc +++ b/source/extensions/filters/common/expr/context.cc @@ -145,8 +145,8 @@ absl::optional UpstreamWrapper::operator[](CelValue key) const { } } else if (value == MTLS) { return CelValue::CreateBool(info_.upstreamSslConnection() != nullptr && - info_.upstreamSslConnection()->localCertificatePresented()) && - info_.upstreamSslConnection()->peerCertificatePresented(); + info_.upstreamSslConnection()->localCertificatePresented() && + info_.upstreamSslConnection()->peerCertificatePresented()); } return {}; From 193c6c1ebe2441de9af8689fd6b7334da3653895 Mon Sep 17 00:00:00 2001 From: Kuat Yessenov Date: Wed, 2 Oct 2019 12:00:49 -0700 Subject: [PATCH 3/5] fix ASAN Signed-off-by: Kuat Yessenov --- source/extensions/transport_sockets/tls/ssl_socket.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/extensions/transport_sockets/tls/ssl_socket.cc b/source/extensions/transport_sockets/tls/ssl_socket.cc index ee2ba19034a4e..6071878468ab9 100644 --- a/source/extensions/transport_sockets/tls/ssl_socket.cc +++ b/source/extensions/transport_sockets/tls/ssl_socket.cc @@ -307,7 +307,7 @@ bool SslSocketInfo::peerCertificatePresented() const { } bool SslSocketInfo::localCertificatePresented() const { - bssl::UniquePtr cert(SSL_get_certificate(ssl_.get())); + X509* cert = SSL_get_certificate(ssl_.get()); return cert != nullptr; } From 25a1057986affb02d3796c011b8f10ced04bfcab Mon Sep 17 00:00:00 2001 From: Kuat Yessenov Date: Thu, 3 Oct 2019 22:37:43 -0700 Subject: [PATCH 4/5] update to use cert callbacks Signed-off-by: Kuat Yessenov --- include/envoy/ssl/connection.h | 3 +- .../transport_sockets/tls/ssl_socket.cc | 23 +++++++++--- .../transport_sockets/tls/ssl_socket.h | 3 +- .../transport_sockets/tls/ssl_socket_test.cc | 35 ++++++++++++++++--- 4 files changed, 52 insertions(+), 12 deletions(-) diff --git a/include/envoy/ssl/connection.h b/include/envoy/ssl/connection.h index 988d74b874758..53dbf0e4ba819 100644 --- a/include/envoy/ssl/connection.h +++ b/include/envoy/ssl/connection.h @@ -24,7 +24,8 @@ class ConnectionInfo { virtual bool peerCertificatePresented() const PURE; /** - * @return bool whether the local certificate is presented. + * @return bool whether the local certificate is requested on the client by the server. This + * flag is always true on the server. **/ virtual bool localCertificatePresented() const PURE; diff --git a/source/extensions/transport_sockets/tls/ssl_socket.cc b/source/extensions/transport_sockets/tls/ssl_socket.cc index 6071878468ab9..b076a003bec0c 100644 --- a/source/extensions/transport_sockets/tls/ssl_socket.cc +++ b/source/extensions/transport_sockets/tls/ssl_socket.cc @@ -48,7 +48,7 @@ SslSocket::SslSocket(Envoy::Ssl::ContextSharedPtr ctx, InitialState state, ctx_(std::dynamic_pointer_cast(ctx)), state_(SocketState::PreHandshake) { bssl::UniquePtr ssl = ctx_->newSsl(transport_socket_options_.get()); ssl_ = ssl.get(); - info_ = std::make_shared(std::move(ssl)); + info_ = std::make_shared(std::move(ssl), state); if (state == InitialState::Client) { SSL_set_connect_state(ssl_); } else { @@ -301,15 +301,28 @@ void SslSocket::shutdownSsl() { } } +SslSocketInfo::SslSocketInfo(bssl::UniquePtr ssl, InitialState state) : ssl_(std::move(ssl)) { + if (state == InitialState::Client) { + SSL_set_cert_cb( + ssl_.get(), + [](SSL*, void* arg) -> int { + auto info = static_cast(arg); + info->local_cert_presented = true; + return 1; + }, + this); + } else { + ASSERT(state == InitialState::Server); + local_cert_presented = true; + } +} + bool SslSocketInfo::peerCertificatePresented() const { bssl::UniquePtr cert(SSL_get_peer_certificate(ssl_.get())); return cert != nullptr; } -bool SslSocketInfo::localCertificatePresented() const { - X509* cert = SSL_get_certificate(ssl_.get()); - return cert != nullptr; -} +bool SslSocketInfo::localCertificatePresented() const { return local_cert_presented; } std::vector SslSocketInfo::uriSanLocalCertificate() const { if (!cached_uri_san_local_certificate_.empty()) { diff --git a/source/extensions/transport_sockets/tls/ssl_socket.h b/source/extensions/transport_sockets/tls/ssl_socket.h index be0f6bd438e01..d67f2da0ac5dc 100644 --- a/source/extensions/transport_sockets/tls/ssl_socket.h +++ b/source/extensions/transport_sockets/tls/ssl_socket.h @@ -43,7 +43,7 @@ enum class SocketState { PreHandshake, HandshakeInProgress, HandshakeComplete, S class SslSocketInfo : public Envoy::Ssl::ConnectionInfo { public: - SslSocketInfo(bssl::UniquePtr ssl) : ssl_(std::move(ssl)) {} + SslSocketInfo(bssl::UniquePtr ssl, InitialState state); // Ssl::ConnectionInfo bool peerCertificatePresented() const override; @@ -84,6 +84,7 @@ class SslSocketInfo : public Envoy::Ssl::ConnectionInfo { mutable std::vector cached_dns_san_local_certificate_; mutable std::string cached_session_id_; mutable std::string cached_tls_version_; + bool local_cert_presented = false; }; class SslSocket : public Network::TransportSocket, diff --git a/test/extensions/transport_sockets/tls/ssl_socket_test.cc b/test/extensions/transport_sockets/tls/ssl_socket_test.cc index 29cd2fe069abe..9d833dede8ed0 100644 --- a/test/extensions/transport_sockets/tls/ssl_socket_test.cc +++ b/test/extensions/transport_sockets/tls/ssl_socket_test.cc @@ -100,7 +100,7 @@ class TestUtilOptions : public TestUtilOptionsBase { bool expect_success, Network::Address::IpVersion version) : TestUtilOptionsBase(expect_success, version), client_ctx_yaml_(client_ctx_yaml), server_ctx_yaml_(server_ctx_yaml), expect_no_cert_(false), expect_no_cert_chain_(false), - expect_private_key_method_(false), + expect_local_cert_(false), expect_private_key_method_(false), expected_server_close_event_(Network::ConnectionEvent::RemoteClose) { if (expect_success) { setExpectedServerStats("ssl.handshake"); @@ -131,6 +131,13 @@ class TestUtilOptions : public TestUtilOptionsBase { return *this; } + bool expectLocalCertPresented() const { return expect_local_cert_; } + + TestUtilOptions& setExpectLocalCertPresented() { + expect_local_cert_ = true; + return *this; + } + TestUtilOptions& setExpectedClientCertUri(const std::string& expected_client_cert_uri) { TestUtilOptionsBase::setExpectedClientCertUri(expected_client_cert_uri); return *this; @@ -230,6 +237,7 @@ class TestUtilOptions : public TestUtilOptionsBase { bool expect_no_cert_; bool expect_no_cert_chain_; + bool expect_local_cert_; bool expect_private_key_method_; Network::ConnectionEvent expected_server_close_event_; std::string expected_digest_; @@ -382,10 +390,18 @@ void testUtil(const TestUtilOptions& options) { EXPECT_EQ(EMPTY_STRING, server_connection->ssl()->subjectPeerCertificate()); EXPECT_EQ(std::vector{}, server_connection->ssl()->dnsSansPeerCertificate()); } + if (options.expectNoCertChain()) { EXPECT_EQ(EMPTY_STRING, server_connection->ssl()->urlEncodedPemEncodedPeerCertificateChain()); } + + if (options.expectLocalCertPresented()) { + EXPECT_TRUE(client_connection->ssl()->localCertificatePresented()); + } else { + EXPECT_FALSE(client_connection->ssl()->localCertificatePresented()); + } + // By default, the session is not created with session resumption. The // client should see a session ID but the server should not. EXPECT_EQ(EMPTY_STRING, server_connection->ssl()->sessionId()); @@ -890,6 +906,7 @@ TEST_P(SslSocketTest, GetCertDigestServerCertWithoutCommonName) { TestUtilOptions test_options(client_ctx_yaml, server_ctx_yaml, true, GetParam()); testUtil(test_options.setExpectedDigest(TEST_NO_SAN_CERT_HASH) + .setExpectLocalCertPresented() .setExpectedSerialNumber(TEST_NO_SAN_CERT_SERIAL)); } @@ -991,7 +1008,8 @@ TEST_P(SslSocketTest, GetNoUriWithDnsSan) { // The SAN field only has DNS, expect "" for uriSanPeerCertificate(). TestUtilOptions test_options(client_ctx_yaml, server_ctx_yaml, true, GetParam()); - testUtil(test_options.setExpectedSerialNumber(TEST_SAN_DNS_CERT_SERIAL)); + testUtil( + test_options.setExpectedSerialNumber(TEST_SAN_DNS_CERT_SERIAL).setExpectLocalCertPresented()); } TEST_P(SslSocketTest, NoCert) { @@ -1099,6 +1117,7 @@ TEST_P(SslSocketTest, GetSubjectsWithBothCerts) { TestUtilOptions test_options(client_ctx_yaml, server_ctx_yaml, true, GetParam()); testUtil(test_options.setExpectedSerialNumber(TEST_NO_SAN_CERT_SERIAL) + .setExpectLocalCertPresented() .setExpectedPeerIssuer( "CN=Test CA,OU=Lyft Engineering,O=Lyft,L=San Francisco,ST=California,C=US") .setExpectedPeerSubject( @@ -1135,6 +1154,7 @@ TEST_P(SslSocketTest, GetPeerCert) { TestEnvironment::readFileToStringForTest(TestEnvironment::substitute( "{{ test_rundir }}/test/extensions/transport_sockets/tls/test_data/no_san_cert.pem")); testUtil(test_options.setExpectedSerialNumber(TEST_NO_SAN_CERT_SERIAL) + .setExpectLocalCertPresented() .setExpectedPeerIssuer( "CN=Test CA,OU=Lyft Engineering,O=Lyft,L=San Francisco,ST=California,C=US") .setExpectedPeerSubject( @@ -1173,6 +1193,7 @@ TEST_P(SslSocketTest, GetPeerCertChain) { "{{ test_rundir " "}}/test/extensions/transport_sockets/tls/test_data/no_san_chain.pem")); testUtil(test_options.setExpectedSerialNumber(TEST_NO_SAN_CERT_SERIAL) + .setExpectLocalCertPresented() .setExpectedPeerCertChain(expected_peer_cert_chain)); } @@ -1200,6 +1221,7 @@ TEST_P(SslSocketTest, GetIssueExpireTimesPeerCert) { )EOF"; TestUtilOptions test_options(client_ctx_yaml, server_ctx_yaml, true, GetParam()); testUtil(test_options.setExpectedSerialNumber(TEST_NO_SAN_CERT_SERIAL) + .setExpectLocalCertPresented() .setExpectedValidFromTimePeerCert(TEST_NO_SAN_CERT_NOT_BEFORE) .setExpectedExpirationTimePeerCert(TEST_NO_SAN_CERT_NOT_AFTER)); } @@ -1422,6 +1444,7 @@ TEST_P(SslSocketTest, ClientCertificateHashVerification) { TestUtilOptions test_options(client_ctx_yaml, server_ctx_yaml, true, GetParam()); testUtil(test_options.setExpectedClientCertUri("spiffe://lyft.com/test-team") + .setExpectLocalCertPresented() .setExpectedSerialNumber(TEST_SAN_URI_CERT_SERIAL)); } @@ -1448,6 +1471,7 @@ TEST_P(SslSocketTest, ClientCertificateHashVerificationNoCA) { TestUtilOptions test_options(client_ctx_yaml, server_ctx_yaml, true, GetParam()); testUtil(test_options.setExpectedClientCertUri("spiffe://lyft.com/test-team") + .setExpectLocalCertPresented() .setExpectedSerialNumber(TEST_SAN_URI_CERT_SERIAL)); } @@ -3695,7 +3719,8 @@ TEST_P(SslSocketTest, RevokedCertificate) { TestUtilOptions successful_test_options(successful_client_ctx_yaml, server_ctx_yaml, true, GetParam()); - testUtil(successful_test_options.setExpectedSerialNumber(TEST_SAN_DNS2_CERT_SERIAL)); + testUtil(successful_test_options.setExpectedSerialNumber(TEST_SAN_DNS2_CERT_SERIAL) + .setExpectLocalCertPresented()); } TEST_P(SslSocketTest, RevokedCertificateCRLInTrustedCA) { @@ -4253,7 +4278,7 @@ TEST_P(SslSocketTest, RsaPrivateKeyProviderAsyncDecryptSuccess) { TestUtilOptions successful_test_options(successful_client_ctx_yaml, server_ctx_yaml, true, GetParam()); - testUtil(successful_test_options.setPrivateKeyMethodExpected(true)); + testUtil(successful_test_options.setPrivateKeyMethodExpected(true).setExpectLocalCertPresented()); } // Test synchronous signing (ECDHE). @@ -4285,7 +4310,7 @@ TEST_P(SslSocketTest, RsaPrivateKeyProviderSyncSignSuccess) { TestUtilOptions successful_test_options(successful_client_ctx_yaml, server_ctx_yaml, true, GetParam()); - testUtil(successful_test_options.setPrivateKeyMethodExpected(true)); + testUtil(successful_test_options.setPrivateKeyMethodExpected(true).setExpectLocalCertPresented()); } // Test synchronous decryption (RSA). From 51faa62458566e48ba02fbeba86977a0368b4c57 Mon Sep 17 00:00:00 2001 From: Kuat Yessenov Date: Fri, 4 Oct 2019 11:15:07 -0700 Subject: [PATCH 5/5] update tests Signed-off-by: Kuat Yessenov --- .../transport_sockets/tls/ssl_socket_test.cc | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/test/extensions/transport_sockets/tls/ssl_socket_test.cc b/test/extensions/transport_sockets/tls/ssl_socket_test.cc index 9d833dede8ed0..e48787572dea9 100644 --- a/test/extensions/transport_sockets/tls/ssl_socket_test.cc +++ b/test/extensions/transport_sockets/tls/ssl_socket_test.cc @@ -808,6 +808,7 @@ TEST_P(SslSocketTest, GetCertDigest) { TestUtilOptions test_options(client_ctx_yaml, server_ctx_yaml, true, GetParam()); testUtil(test_options.setExpectedDigest(TEST_NO_SAN_CERT_HASH) + .setExpectLocalCertPresented() .setExpectedSerialNumber(TEST_NO_SAN_CERT_SERIAL)); } @@ -879,6 +880,7 @@ TEST_P(SslSocketTest, GetCertDigestServerCertWithIntermediateCA) { TestUtilOptions test_options(client_ctx_yaml, server_ctx_yaml, true, GetParam()); testUtil(test_options.setExpectedDigest(TEST_NO_SAN_CERT_HASH) + .setExpectLocalCertPresented() .setExpectedSerialNumber(TEST_NO_SAN_CERT_SERIAL)); } @@ -935,6 +937,7 @@ TEST_P(SslSocketTest, GetUriWithUriSan) { TestUtilOptions test_options(client_ctx_yaml, server_ctx_yaml, true, GetParam()); testUtil(test_options.setExpectedClientCertUri("spiffe://lyft.com/test-team") + .setExpectLocalCertPresented() .setExpectedSerialNumber(TEST_SAN_URI_CERT_SERIAL)); } @@ -1089,6 +1092,7 @@ TEST_P(SslSocketTest, GetUriWithLocalUriSan) { TestUtilOptions test_options(client_ctx_yaml, server_ctx_yaml, true, GetParam()); testUtil(test_options.setExpectedLocalUri("spiffe://lyft.com/test-team") + .setExpectLocalCertPresented() .setExpectedSerialNumber(TEST_NO_SAN_CERT_SERIAL)); } @@ -3761,7 +3765,8 @@ TEST_P(SslSocketTest, RevokedCertificateCRLInTrustedCA) { )EOF"; TestUtilOptions successful_test_options(successful_client_ctx_yaml, server_ctx_yaml, true, GetParam()); - testUtil(successful_test_options.setExpectedSerialNumber(TEST_SAN_DNS2_CERT_SERIAL)); + testUtil(successful_test_options.setExpectedSerialNumber(TEST_SAN_DNS2_CERT_SERIAL) + .setExpectLocalCertPresented()); } TEST_P(SslSocketTest, GetRequestedServerName) { @@ -4246,7 +4251,7 @@ TEST_P(SslSocketTest, RsaPrivateKeyProviderAsyncSignSuccess) { TestUtilOptions successful_test_options(successful_client_ctx_yaml, server_ctx_yaml, true, GetParam()); - testUtil(successful_test_options.setPrivateKeyMethodExpected(true)); + testUtil(successful_test_options.setPrivateKeyMethodExpected(true).setExpectLocalCertPresented()); } // Test asynchronous decryption (RSA). @@ -4342,7 +4347,7 @@ TEST_P(SslSocketTest, RsaPrivateKeyProviderSyncDecryptSuccess) { TestUtilOptions successful_test_options(successful_client_ctx_yaml, server_ctx_yaml, true, GetParam()); - testUtil(successful_test_options.setPrivateKeyMethodExpected(true)); + testUtil(successful_test_options.setPrivateKeyMethodExpected(true).setExpectLocalCertPresented()); } // Test asynchronous signing (ECDHE) failure (invalid signature).