diff options
Diffstat (limited to 'security/nss/gtests/ssl_gtest/ssl_auth_unittest.cc')
-rw-r--r-- | security/nss/gtests/ssl_gtest/ssl_auth_unittest.cc | 173 |
1 files changed, 125 insertions, 48 deletions
diff --git a/security/nss/gtests/ssl_gtest/ssl_auth_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_auth_unittest.cc index d663d81e0..dbcbc9aa3 100644 --- a/security/nss/gtests/ssl_gtest/ssl_auth_unittest.cc +++ b/security/nss/gtests/ssl_gtest/ssl_auth_unittest.cc @@ -77,9 +77,10 @@ TEST_P(TlsConnectGeneric, ClientAuthBigRsa) { } // Offset is the position in the captured buffer where the signature sits. -static void CheckSigScheme(TlsInspectorRecordHandshakeMessage* capture, - size_t offset, TlsAgent* peer, - uint16_t expected_scheme, size_t expected_size) { +static void CheckSigScheme( + std::shared_ptr<TlsInspectorRecordHandshakeMessage>& capture, size_t offset, + std::shared_ptr<TlsAgent>& peer, uint16_t expected_scheme, + size_t expected_size) { EXPECT_LT(offset + 2U, capture->buffer().len()); uint32_t scheme = 0; @@ -95,8 +96,8 @@ static void CheckSigScheme(TlsInspectorRecordHandshakeMessage* capture, // in the default certificate. TEST_P(TlsConnectTls12, ServerAuthCheckSigAlg) { EnsureTlsSetup(); - auto capture_ske = - new TlsInspectorRecordHandshakeMessage(kTlsHandshakeServerKeyExchange); + auto capture_ske = std::make_shared<TlsInspectorRecordHandshakeMessage>( + kTlsHandshakeServerKeyExchange); server_->SetPacketFilter(capture_ske); Connect(); CheckKeys(); @@ -114,7 +115,8 @@ TEST_P(TlsConnectTls12, ServerAuthCheckSigAlg) { TEST_P(TlsConnectTls12, ClientAuthCheckSigAlg) { EnsureTlsSetup(); auto capture_cert_verify = - new TlsInspectorRecordHandshakeMessage(kTlsHandshakeCertificateVerify); + std::make_shared<TlsInspectorRecordHandshakeMessage>( + kTlsHandshakeCertificateVerify); client_->SetPacketFilter(capture_cert_verify); client_->SetupClientAuth(); server_->RequestClientAuth(true); @@ -127,7 +129,8 @@ TEST_P(TlsConnectTls12, ClientAuthCheckSigAlg) { TEST_P(TlsConnectTls12, ClientAuthBigRsaCheckSigAlg) { Reset(TlsAgent::kServerRsa, TlsAgent::kRsa2048); auto capture_cert_verify = - new TlsInspectorRecordHandshakeMessage(kTlsHandshakeCertificateVerify); + std::make_shared<TlsInspectorRecordHandshakeMessage>( + kTlsHandshakeCertificateVerify); client_->SetPacketFilter(capture_cert_verify); client_->SetupClientAuth(); server_->RequestClientAuth(true); @@ -136,6 +139,76 @@ TEST_P(TlsConnectTls12, ClientAuthBigRsaCheckSigAlg) { CheckSigScheme(capture_cert_verify, 0, server_, ssl_sig_rsa_pss_sha256, 2048); } +class TlsZeroCertificateRequestSigAlgsFilter : public TlsHandshakeFilter { + public: + virtual PacketFilter::Action FilterHandshake( + const TlsHandshakeFilter::HandshakeHeader& header, + const DataBuffer& input, DataBuffer* output) { + if (header.handshake_type() != kTlsHandshakeCertificateRequest) { + return KEEP; + } + + TlsParser parser(input); + std::cerr << "Zeroing CertReq.supported_signature_algorithms" << std::endl; + + DataBuffer cert_types; + if (!parser.ReadVariable(&cert_types, 1)) { + ADD_FAILURE(); + return KEEP; + } + + if (!parser.SkipVariable(2)) { + ADD_FAILURE(); + return KEEP; + } + + DataBuffer cas; + if (!parser.ReadVariable(&cas, 2)) { + ADD_FAILURE(); + return KEEP; + } + + size_t idx = 0; + + // Write certificate types. + idx = output->Write(idx, cert_types.len(), 1); + idx = output->Write(idx, cert_types); + + // Write zero signature algorithms. + idx = output->Write(idx, 0U, 2); + + // Write certificate authorities. + idx = output->Write(idx, cas.len(), 2); + idx = output->Write(idx, cas); + + return CHANGE; + } +}; + +// Check that we fall back to SHA-1 when the server doesn't provide any +// supported_signature_algorithms in the CertificateRequest message. +TEST_P(TlsConnectTls12, ClientAuthNoSigAlgsFallback) { + EnsureTlsSetup(); + auto filter = std::make_shared<TlsZeroCertificateRequestSigAlgsFilter>(); + server_->SetPacketFilter(filter); + auto capture_cert_verify = + std::make_shared<TlsInspectorRecordHandshakeMessage>( + kTlsHandshakeCertificateVerify); + client_->SetPacketFilter(capture_cert_verify); + client_->SetupClientAuth(); + server_->RequestClientAuth(true); + + ConnectExpectAlert(server_, kTlsAlertDecryptError); + + // We're expecting a bad signature here because we tampered with a handshake + // message (CertReq). Previously, without the SHA-1 fallback, we would've + // seen a malformed record alert. + server_->CheckErrorCode(SEC_ERROR_BAD_SIGNATURE); + client_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT); + + CheckSigScheme(capture_cert_verify, 0, server_, ssl_sig_rsa_pkcs1_sha1, 1024); +} + static const SSLSignatureScheme SignatureSchemeEcdsaSha384[] = { ssl_sig_ecdsa_secp384r1_sha384}; static const SSLSignatureScheme SignatureSchemeEcdsaSha256[] = { @@ -211,7 +284,7 @@ TEST_P(TlsConnectTls13, SignatureSchemeCurveMismatch) { Reset(TlsAgent::kServerEcdsa256); client_->SetSignatureSchemes(SignatureSchemeEcdsaSha384, PR_ARRAY_SIZE(SignatureSchemeEcdsaSha384)); - ConnectExpectFail(); + ConnectExpectAlert(server_, kTlsAlertHandshakeFailure); server_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM); client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP); } @@ -229,7 +302,7 @@ TEST_P(TlsConnectTls13, SignatureSchemeBadConfig) { Reset(TlsAgent::kServerEcdsa256); // P-256 cert can't be used. server_->SetSignatureSchemes(SignatureSchemeEcdsaSha384, PR_ARRAY_SIZE(SignatureSchemeEcdsaSha384)); - ConnectExpectFail(); + ConnectExpectAlert(server_, kTlsAlertHandshakeFailure); server_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM); client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP); } @@ -252,7 +325,7 @@ TEST_P(TlsConnectTls12Plus, SignatureAlgorithmNoOverlapEcdsa) { PR_ARRAY_SIZE(SignatureSchemeEcdsaSha384)); server_->SetSignatureSchemes(SignatureSchemeEcdsaSha256, PR_ARRAY_SIZE(SignatureSchemeEcdsaSha256)); - ConnectExpectFail(); + ConnectExpectAlert(server_, kTlsAlertHandshakeFailure); client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP); server_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM); } @@ -270,8 +343,8 @@ TEST_P(TlsConnectPre12, SignatureAlgorithmNoOverlapEcdsa) { // The signature_algorithms extension is mandatory in TLS 1.3. TEST_P(TlsConnectTls13, SignatureAlgorithmDrop) { client_->SetPacketFilter( - new TlsExtensionDropper(ssl_signature_algorithms_xtn)); - ConnectExpectFail(); + std::make_shared<TlsExtensionDropper>(ssl_signature_algorithms_xtn)); + ConnectExpectAlert(server_, kTlsAlertMissingExtension); client_->CheckErrorCode(SSL_ERROR_MISSING_EXTENSION_ALERT); server_->CheckErrorCode(SSL_ERROR_MISSING_SIGNATURE_ALGORITHMS_EXTENSION); } @@ -280,8 +353,8 @@ TEST_P(TlsConnectTls13, SignatureAlgorithmDrop) { // only fails when the Finished is checked. TEST_P(TlsConnectTls12, SignatureAlgorithmDrop) { client_->SetPacketFilter( - new TlsExtensionDropper(ssl_signature_algorithms_xtn)); - ConnectExpectFail(); + std::make_shared<TlsExtensionDropper>(ssl_signature_algorithms_xtn)); + ConnectExpectAlert(server_, kTlsAlertDecryptError); client_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT); server_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE); } @@ -298,7 +371,8 @@ class BeforeFinished : public TlsRecordFilter { enum HandshakeState { BEFORE_CCS, AFTER_CCS, DONE }; public: - BeforeFinished(TlsAgent* client, TlsAgent* server, VoidFunction before_ccs, + BeforeFinished(std::shared_ptr<TlsAgent>& client, + std::shared_ptr<TlsAgent>& server, VoidFunction before_ccs, VoidFunction before_finished) : client_(client), server_(server), @@ -307,7 +381,7 @@ class BeforeFinished : public TlsRecordFilter { state_(BEFORE_CCS) {} protected: - virtual PacketFilter::Action FilterRecord(const RecordHeader& header, + virtual PacketFilter::Action FilterRecord(const TlsRecordHeader& header, const DataBuffer& body, DataBuffer* out) { switch (state_) { @@ -321,8 +395,8 @@ class BeforeFinished : public TlsRecordFilter { // but that means that they both get processed together. DataBuffer ccs; header.Write(&ccs, 0, body); - server_->SendDirect(ccs); - client_->Handshake(); + server_.lock()->SendDirect(ccs); + client_.lock()->Handshake(); state_ = AFTER_CCS; // Request that the original record be dropped by the filter. return DROP; @@ -345,8 +419,8 @@ class BeforeFinished : public TlsRecordFilter { } private: - TlsAgent* client_; - TlsAgent* server_; + std::weak_ptr<TlsAgent> client_; + std::weak_ptr<TlsAgent> server_; VoidFunction before_ccs_; VoidFunction before_finished_; HandshakeState state_; @@ -371,7 +445,8 @@ class BeforeFinished13 : public PacketFilter { }; public: - BeforeFinished13(TlsAgent* client, TlsAgent* server, + BeforeFinished13(std::shared_ptr<TlsAgent>& client, + std::shared_ptr<TlsAgent>& server, VoidFunction before_finished) : client_(client), server_(server), @@ -385,7 +460,7 @@ class BeforeFinished13 : public PacketFilter { case 1: // Packet 1 is the server's entire first flight. Drop it. EXPECT_EQ(SECSuccess, - SSLInt_SetMTU(server_->ssl_fd(), input.len() - 1)); + SSLInt_SetMTU(server_.lock()->ssl_fd(), input.len() - 1)); return DROP; // Packet 2 is the first part of the server's retransmitted first @@ -395,7 +470,7 @@ class BeforeFinished13 : public PacketFilter { // Packet 3 is the second part of the server's retransmitted first // flight. Before passing that on, make sure that the client processes // packet 2, then call the before_finished_() callback. - client_->Handshake(); + client_.lock()->Handshake(); before_finished_(); break; @@ -406,8 +481,8 @@ class BeforeFinished13 : public PacketFilter { } private: - TlsAgent* client_; - TlsAgent* server_; + std::weak_ptr<TlsAgent> client_; + std::weak_ptr<TlsAgent> server_; VoidFunction before_finished_; size_t records_; }; @@ -421,9 +496,11 @@ static SECStatus AuthCompleteBlock(TlsAgent*, PRBool, PRBool) { // processed by the client, SSL_AuthCertificateComplete() is called. TEST_F(TlsConnectDatagram13, AuthCompleteBeforeFinished) { client_->SetAuthCertificateCallback(AuthCompleteBlock); - server_->SetPacketFilter(new BeforeFinished13(client_, server_, [this]() { - EXPECT_EQ(SECSuccess, SSL_AuthCertificateComplete(client_->ssl_fd(), 0)); - })); + server_->SetPacketFilter( + std::make_shared<BeforeFinished13>(client_, server_, [this]() { + EXPECT_EQ(SECSuccess, + SSL_AuthCertificateComplete(client_->ssl_fd(), 0)); + })); Connect(); } @@ -440,9 +517,9 @@ static void TriggerAuthComplete(PollTarget* target, Event event) { TEST_F(TlsConnectDatagram13, AuthCompleteAfterFinished) { client_->SetAuthCertificateCallback( [this](TlsAgent*, PRBool, PRBool) -> SECStatus { - Poller::Timer* timer_handle; + std::shared_ptr<Poller::Timer> timer_handle; // This is really just to unroll the stack. - Poller::Instance()->SetTimer(1U, client_, TriggerAuthComplete, + Poller::Instance()->SetTimer(1U, client_.get(), TriggerAuthComplete, &timer_handle); return SECWouldBlock; }); @@ -451,7 +528,7 @@ TEST_F(TlsConnectDatagram13, AuthCompleteAfterFinished) { TEST_P(TlsConnectGenericPre13, ClientWriteBetweenCCSAndFinishedWithFalseStart) { client_->EnableFalseStart(); - server_->SetPacketFilter(new BeforeFinished( + server_->SetPacketFilter(std::make_shared<BeforeFinished>( client_, server_, [this]() { EXPECT_TRUE(client_->can_falsestart_hook_called()); }, [this]() { @@ -467,7 +544,7 @@ TEST_P(TlsConnectGenericPre13, ClientWriteBetweenCCSAndFinishedWithFalseStart) { TEST_P(TlsConnectGenericPre13, AuthCompleteBeforeFinishedWithFalseStart) { client_->EnableFalseStart(); client_->SetAuthCertificateCallback(AuthCompleteBlock); - server_->SetPacketFilter(new BeforeFinished( + server_->SetPacketFilter(std::make_shared<BeforeFinished>( client_, server_, []() { // Do nothing before CCS @@ -514,7 +591,7 @@ TEST_P(TlsConnectGenericPre13, AuthCompleteDelayed) { EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state()); // The client should send nothing from here on. - client_->SetPacketFilter(new EnforceNoActivity()); + client_->SetPacketFilter(std::make_shared<EnforceNoActivity>()); client_->Handshake(); EXPECT_EQ(TlsAgent::STATE_CONNECTING, client_->state()); @@ -525,7 +602,7 @@ TEST_P(TlsConnectGenericPre13, AuthCompleteDelayed) { EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state()); // Remove this before closing or the close_notify alert will trigger it. - client_->SetPacketFilter(nullptr); + client_->DeletePacketFilter(); } // TLS 1.3 handles a delayed AuthComplete callback differently since the @@ -541,12 +618,12 @@ TEST_P(TlsConnectTls13, AuthCompleteDelayed) { EXPECT_EQ(TlsAgent::STATE_CONNECTING, server_->state()); // The client will send nothing until AuthCertificateComplete is called. - client_->SetPacketFilter(new EnforceNoActivity()); + client_->SetPacketFilter(std::make_shared<EnforceNoActivity>()); client_->Handshake(); EXPECT_EQ(TlsAgent::STATE_CONNECTING, client_->state()); // This should allow the handshake to complete now. - client_->SetPacketFilter(nullptr); + client_->DeletePacketFilter(); EXPECT_EQ(SECSuccess, SSL_AuthCertificateComplete(client_->ssl_fd(), 0)); client_->Handshake(); // Send Finished server_->Handshake(); // Transition to connected and send NewSessionTicket @@ -639,8 +716,8 @@ TEST_F(TlsAgentStreamTestServer, ConfigureCertRsaPss) { &ServerCertDataRsaPss)); } -// mode, version, certificate, auth type, signature scheme -typedef std::tuple<std::string, uint16_t, std::string, SSLAuthType, +// variant, version, certificate, auth type, signature scheme +typedef std::tuple<SSLProtocolVariant, uint16_t, std::string, SSLAuthType, SSLSignatureScheme> SignatureSchemeProfile; @@ -655,7 +732,7 @@ class TlsSignatureSchemeConfiguration signature_scheme_(std::get<4>(GetParam())) {} protected: - void TestSignatureSchemeConfig(TlsAgent* configPeer) { + void TestSignatureSchemeConfig(std::shared_ptr<TlsAgent>& configPeer) { EnsureTlsSetup(); configPeer->SetSignatureSchemes(&signature_scheme_, 1); Connect(); @@ -675,8 +752,8 @@ TEST_P(TlsSignatureSchemeConfiguration, SignatureSchemeConfigServer) { TEST_P(TlsSignatureSchemeConfiguration, SignatureSchemeConfigClient) { Reset(certificate_); - TlsExtensionCapture* capture = - new TlsExtensionCapture(ssl_signature_algorithms_xtn); + auto capture = + std::make_shared<TlsExtensionCapture>(ssl_signature_algorithms_xtn); client_->SetPacketFilter(capture); TestSignatureSchemeConfig(client_); @@ -701,7 +778,7 @@ TEST_P(TlsSignatureSchemeConfiguration, SignatureSchemeConfigBoth) { INSTANTIATE_TEST_CASE_P( SignatureSchemeRsa, TlsSignatureSchemeConfiguration, ::testing::Combine( - TlsConnectTestBase::kTlsModesAll, TlsConnectTestBase::kTlsV12Plus, + TlsConnectTestBase::kTlsVariantsAll, TlsConnectTestBase::kTlsV12Plus, ::testing::Values(TlsAgent::kServerRsaSign), ::testing::Values(ssl_auth_rsa_sign), ::testing::Values(ssl_sig_rsa_pkcs1_sha256, ssl_sig_rsa_pkcs1_sha384, @@ -710,42 +787,42 @@ INSTANTIATE_TEST_CASE_P( // PSS with SHA-512 needs a bigger key to work. INSTANTIATE_TEST_CASE_P( SignatureSchemeBigRsa, TlsSignatureSchemeConfiguration, - ::testing::Combine(TlsConnectTestBase::kTlsModesAll, + ::testing::Combine(TlsConnectTestBase::kTlsVariantsAll, TlsConnectTestBase::kTlsV12Plus, ::testing::Values(TlsAgent::kRsa2048), ::testing::Values(ssl_auth_rsa_sign), ::testing::Values(ssl_sig_rsa_pss_sha512))); INSTANTIATE_TEST_CASE_P( SignatureSchemeRsaSha1, TlsSignatureSchemeConfiguration, - ::testing::Combine(TlsConnectTestBase::kTlsModesAll, + ::testing::Combine(TlsConnectTestBase::kTlsVariantsAll, TlsConnectTestBase::kTlsV12, ::testing::Values(TlsAgent::kServerRsa), ::testing::Values(ssl_auth_rsa_sign), ::testing::Values(ssl_sig_rsa_pkcs1_sha1))); INSTANTIATE_TEST_CASE_P( SignatureSchemeEcdsaP256, TlsSignatureSchemeConfiguration, - ::testing::Combine(TlsConnectTestBase::kTlsModesAll, + ::testing::Combine(TlsConnectTestBase::kTlsVariantsAll, TlsConnectTestBase::kTlsV12Plus, ::testing::Values(TlsAgent::kServerEcdsa256), ::testing::Values(ssl_auth_ecdsa), ::testing::Values(ssl_sig_ecdsa_secp256r1_sha256))); INSTANTIATE_TEST_CASE_P( SignatureSchemeEcdsaP384, TlsSignatureSchemeConfiguration, - ::testing::Combine(TlsConnectTestBase::kTlsModesAll, + ::testing::Combine(TlsConnectTestBase::kTlsVariantsAll, TlsConnectTestBase::kTlsV12Plus, ::testing::Values(TlsAgent::kServerEcdsa384), ::testing::Values(ssl_auth_ecdsa), ::testing::Values(ssl_sig_ecdsa_secp384r1_sha384))); INSTANTIATE_TEST_CASE_P( SignatureSchemeEcdsaP521, TlsSignatureSchemeConfiguration, - ::testing::Combine(TlsConnectTestBase::kTlsModesAll, + ::testing::Combine(TlsConnectTestBase::kTlsVariantsAll, TlsConnectTestBase::kTlsV12Plus, ::testing::Values(TlsAgent::kServerEcdsa521), ::testing::Values(ssl_auth_ecdsa), ::testing::Values(ssl_sig_ecdsa_secp521r1_sha512))); INSTANTIATE_TEST_CASE_P( SignatureSchemeEcdsaSha1, TlsSignatureSchemeConfiguration, - ::testing::Combine(TlsConnectTestBase::kTlsModesAll, + ::testing::Combine(TlsConnectTestBase::kTlsVariantsAll, TlsConnectTestBase::kTlsV12, ::testing::Values(TlsAgent::kServerEcdsa256, TlsAgent::kServerEcdsa384), |