diff options
Diffstat (limited to 'security/nss/gtests/ssl_gtest/ssl_loopback_unittest.cc')
-rw-r--r-- | security/nss/gtests/ssl_gtest/ssl_loopback_unittest.cc | 251 |
1 files changed, 42 insertions, 209 deletions
diff --git a/security/nss/gtests/ssl_gtest/ssl_loopback_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_loopback_unittest.cc index 4bc6e60ab..77703dd8e 100644 --- a/security/nss/gtests/ssl_gtest/ssl_loopback_unittest.cc +++ b/security/nss/gtests/ssl_gtest/ssl_loopback_unittest.cc @@ -6,7 +6,6 @@ #include <functional> #include <memory> -#include <vector> #include "secerr.h" #include "ssl.h" #include "sslerr.h" @@ -85,13 +84,13 @@ class TlsAlertRecorder : public TlsRecordFilter { }; class HelloTruncator : public TlsHandshakeFilter { - public: - HelloTruncator() - : TlsHandshakeFilter( - {kTlsHandshakeClientHello, kTlsHandshakeServerHello}) {} PacketFilter::Action FilterHandshake(const HandshakeHeader& header, const DataBuffer& input, DataBuffer* output) override { + if (header.handshake_type() != kTlsHandshakeClientHello && + header.handshake_type() != kTlsHandshakeServerHello) { + return KEEP; + } output->Assign(input.data(), input.len() - 1); return CHANGE; } @@ -103,9 +102,9 @@ TEST_P(TlsConnectGeneric, CaptureAlertServer) { auto alert_recorder = std::make_shared<TlsAlertRecorder>(); server_->SetPacketFilter(alert_recorder); - ConnectExpectAlert(server_, kTlsAlertDecodeError); + ConnectExpectAlert(server_, kTlsAlertIllegalParameter); EXPECT_EQ(kTlsAlertFatal, alert_recorder->level()); - EXPECT_EQ(kTlsAlertDecodeError, alert_recorder->description()); + EXPECT_EQ(kTlsAlertIllegalParameter, alert_recorder->description()); } TEST_P(TlsConnectGenericPre13, CaptureAlertClient) { @@ -124,7 +123,8 @@ TEST_P(TlsConnectTls13, CaptureAlertClient) { auto alert_recorder = std::make_shared<TlsAlertRecorder>(); client_->SetPacketFilter(alert_recorder); - StartConnect(); + server_->StartConnect(); + client_->StartConnect(); client_->Handshake(); client_->ExpectSendAlert(kTlsAlertDecodeError); @@ -166,107 +166,26 @@ TEST_P(TlsConnectDatagram, ConnectSrtp) { SendReceive(); } -TEST_P(TlsConnectGeneric, ConnectSendReceive) { - Connect(); - SendReceive(); -} - -class SaveTlsRecord : public TlsRecordFilter { - public: - SaveTlsRecord(size_t index) : index_(index), count_(0), contents_() {} - - const DataBuffer& contents() const { return contents_; } - - protected: - PacketFilter::Action FilterRecord(const TlsRecordHeader& header, - const DataBuffer& data, - DataBuffer* changed) override { - if (count_++ == index_) { - contents_ = data; - } - return KEEP; - } - - private: - const size_t index_; - size_t count_; - DataBuffer contents_; -}; - -// Check that decrypting filters work and can read any record. -// This test (currently) only works in TLS 1.3 where we can decrypt. -TEST_F(TlsConnectStreamTls13, DecryptRecordClient) { - EnsureTlsSetup(); - // 0 = ClientHello, 1 = Finished, 2 = SendReceive, 3 = SendBuffer - auto saved = std::make_shared<SaveTlsRecord>(3); - client_->SetTlsRecordFilter(saved); - Connect(); - SendReceive(); - - static const uint8_t data[] = {0xde, 0xad, 0xdc}; - DataBuffer buf(data, sizeof(data)); - client_->SendBuffer(buf); - EXPECT_EQ(buf, saved->contents()); -} - -TEST_F(TlsConnectStreamTls13, DecryptRecordServer) { - EnsureTlsSetup(); - // Disable tickets so that we are sure to not get NewSessionTicket. - EXPECT_EQ(SECSuccess, SSL_OptionSet(server_->ssl_fd(), - SSL_ENABLE_SESSION_TICKETS, PR_FALSE)); - // 0 = ServerHello, 1 = other handshake, 2 = SendReceive, 3 = SendBuffer - auto saved = std::make_shared<SaveTlsRecord>(3); - server_->SetTlsRecordFilter(saved); +// 1.3 is disabled in the next few tests because we don't +// presently support resumption in 1.3. +TEST_P(TlsConnectStreamPre13, ConnectAndClientRenegotiate) { Connect(); - SendReceive(); - - static const uint8_t data[] = {0xde, 0xad, 0xd5}; - DataBuffer buf(data, sizeof(data)); - server_->SendBuffer(buf); - EXPECT_EQ(buf, saved->contents()); + server_->PrepareForRenegotiate(); + client_->StartRenegotiate(); + Handshake(); + CheckConnected(); } -class DropTlsRecord : public TlsRecordFilter { - public: - DropTlsRecord(size_t index) : index_(index), count_(0) {} - - protected: - PacketFilter::Action FilterRecord(const TlsRecordHeader& header, - const DataBuffer& data, - DataBuffer* changed) override { - if (count_++ == index_) { - return DROP; - } - return KEEP; - } - - private: - const size_t index_; - size_t count_; -}; - -// Test that decrypting filters work correctly and are able to drop records. -TEST_F(TlsConnectStreamTls13, DropRecordServer) { - EnsureTlsSetup(); - // Disable session tickets so that the server doesn't send an extra record. - EXPECT_EQ(SECSuccess, SSL_OptionSet(server_->ssl_fd(), - SSL_ENABLE_SESSION_TICKETS, PR_FALSE)); - - // 0 = ServerHello, 1 = other handshake, 2 = first write - server_->SetTlsRecordFilter(std::make_shared<DropTlsRecord>(2)); +TEST_P(TlsConnectStreamPre13, ConnectAndServerRenegotiate) { Connect(); - server_->SendData(23, 23); // This should be dropped, so it won't be counted. - server_->ResetSentBytes(); - SendReceive(); + client_->PrepareForRenegotiate(); + server_->StartRenegotiate(); + Handshake(); + CheckConnected(); } -TEST_F(TlsConnectStreamTls13, DropRecordClient) { - EnsureTlsSetup(); - // 0 = ClientHello, 1 = Finished, 2 = first write - client_->SetTlsRecordFilter(std::make_shared<DropTlsRecord>(2)); +TEST_P(TlsConnectGeneric, ConnectSendReceive) { Connect(); - client_->SendData(26, 26); // This should be dropped, so it won't be counted. - client_->ResetSentBytes(); SendReceive(); } @@ -305,70 +224,29 @@ TEST_P(TlsConnectStream, ShortRead) { ASSERT_EQ(50U, client_->received_bytes()); } -// We enable compression via the API but it's disabled internally, -// so we should never get it. -TEST_P(TlsConnectGeneric, ConnectWithCompressionEnabled) { +TEST_P(TlsConnectGeneric, ConnectWithCompressionMaybe) { EnsureTlsSetup(); - client_->SetOption(SSL_ENABLE_DEFLATE, PR_TRUE); - server_->SetOption(SSL_ENABLE_DEFLATE, PR_TRUE); + client_->EnableCompression(); + server_->EnableCompression(); Connect(); - EXPECT_FALSE(client_->is_compressed()); + EXPECT_EQ(client_->version() < SSL_LIBRARY_VERSION_TLS_1_3 && + variant_ != ssl_variant_datagram, + client_->is_compressed()); SendReceive(); } -class TlsHolddownTest : public TlsConnectDatagram { - protected: - // This causes all timers to run to completion. It advances the clock and - // handshakes on both peers until both peers have no more timers pending, - // which should happen at the end of a handshake. This is necessary to ensure - // that the relatively long holddown timer expires, but that any other timers - // also expire and run correctly. - void RunAllTimersDown() { - while (true) { - PRIntervalTime time; - SECStatus rv = DTLS_GetHandshakeTimeout(client_->ssl_fd(), &time); - if (rv != SECSuccess) { - rv = DTLS_GetHandshakeTimeout(server_->ssl_fd(), &time); - if (rv != SECSuccess) { - break; // Neither peer has an outstanding timer. - } - } - - if (g_ssl_gtest_verbose) { - std::cerr << "Shifting timers" << std::endl; - } - ShiftDtlsTimers(); - Handshake(); - } - } -}; - -TEST_P(TlsHolddownTest, TestDtlsHolddownExpiry) { +TEST_P(TlsConnectDatagram, TestDtlsHolddownExpiry) { Connect(); - std::cerr << "Expiring holddown timer" << std::endl; - RunAllTimersDown(); + std::cerr << "Expiring holddown timer\n"; + SSLInt_ForceTimerExpiry(client_->ssl_fd()); + SSLInt_ForceTimerExpiry(server_->ssl_fd()); SendReceive(); if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) { // One for send, one for receive. - EXPECT_EQ(2, SSLInt_CountCipherSpecs(client_->ssl_fd())); + EXPECT_EQ(2, SSLInt_CountTls13CipherSpecs(client_->ssl_fd())); } } -TEST_P(TlsHolddownTest, TestDtlsHolddownExpiryResumption) { - ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); - Connect(); - SendReceive(); - - Reset(); - ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); - ExpectResumption(RESUME_TICKET); - Connect(); - RunAllTimersDown(); - SendReceive(); - // One for send, one for receive. - EXPECT_EQ(2, SSLInt_CountCipherSpecs(client_->ssl_fd())); -} - class TlsPreCCSHeaderInjector : public TlsRecordFilter { public: TlsPreCCSHeaderInjector() {} @@ -396,7 +274,8 @@ TEST_P(TlsConnectStreamPre13, ClientFinishedHeaderBeforeCCS) { TEST_P(TlsConnectStreamPre13, ServerFinishedHeaderBeforeCCS) { server_->SetPacketFilter(std::make_shared<TlsPreCCSHeaderInjector>()); - StartConnect(); + client_->StartConnect(); + server_->StartConnect(); ExpectAlert(client_, kTlsAlertUnexpectedMessage); Handshake(); EXPECT_EQ(TlsAgent::STATE_ERROR, client_->state()); @@ -427,65 +306,21 @@ TEST_P(TlsConnectTls13, AlertWrongLevel) { TEST_F(TlsConnectStreamTls13, Tls13FailedWriteSecondFlight) { EnsureTlsSetup(); - StartConnect(); + client_->StartConnect(); + server_->StartConnect(); client_->Handshake(); server_->Handshake(); // Send first flight. - client_->adapter()->SetWriteError(PR_IO_ERROR); + client_->adapter()->CloseWrites(); client_->Handshake(); // This will get an error, but shouldn't crash. client_->CheckErrorCode(SSL_ERROR_SOCKET_WRITE_FAILURE); } -TEST_P(TlsConnectDatagram, BlockedWrite) { - Connect(); - - // Mark the socket as blocked. - client_->adapter()->SetWriteError(PR_WOULD_BLOCK_ERROR); - static const uint8_t data[] = {1, 2, 3}; - int32_t rv = PR_Write(client_->ssl_fd(), data, sizeof(data)); - EXPECT_GT(0, rv); - EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError()); - - // Remove the write error and though the previous write failed, future reads - // and writes should just work as if it never happened. - client_->adapter()->SetWriteError(0); - SendReceive(); -} - -TEST_F(TlsConnectTest, ConnectSSLv3) { - ConfigureVersion(SSL_LIBRARY_VERSION_3_0); - EnableOnlyStaticRsaCiphers(); +TEST_F(TlsConnectStreamTls13, NegotiateShortHeaders) { + client_->SetShortHeadersEnabled(); + server_->SetShortHeadersEnabled(); + client_->ExpectShortHeaders(); + server_->ExpectShortHeaders(); Connect(); - CheckKeys(ssl_kea_rsa, ssl_grp_none, ssl_auth_rsa_decrypt, ssl_sig_none); -} - -TEST_F(TlsConnectTest, ConnectSSLv3ClientAuth) { - ConfigureVersion(SSL_LIBRARY_VERSION_3_0); - EnableOnlyStaticRsaCiphers(); - client_->SetupClientAuth(); - server_->RequestClientAuth(true); - Connect(); - CheckKeys(ssl_kea_rsa, ssl_grp_none, ssl_auth_rsa_decrypt, ssl_sig_none); -} - -static size_t ExpectedCbcLen(size_t in, size_t hmac = 20, size_t block = 16) { - // MAC-then-Encrypt expansion formula: - return ((in + hmac + (block - 1)) / block) * block; -} - -TEST_F(TlsConnectTest, OneNRecordSplitting) { - ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_0); - EnsureTlsSetup(); - ConnectWithCipherSuite(TLS_RSA_WITH_AES_128_CBC_SHA); - auto records = std::make_shared<TlsRecordRecorder>(); - server_->SetPacketFilter(records); - // This should be split into 1, 16384 and 20. - DataBuffer big_buffer; - big_buffer.Allocate(1 + 16384 + 20); - server_->SendBuffer(big_buffer); - ASSERT_EQ(3U, records->count()); - EXPECT_EQ(ExpectedCbcLen(1), records->record(0).buffer.len()); - EXPECT_EQ(ExpectedCbcLen(16384), records->record(1).buffer.len()); - EXPECT_EQ(ExpectedCbcLen(20), records->record(2).buffer.len()); } INSTANTIATE_TEST_CASE_P( @@ -501,8 +336,6 @@ INSTANTIATE_TEST_CASE_P(StreamOnly, TlsConnectStream, TlsConnectTestBase::kTlsVAll); INSTANTIATE_TEST_CASE_P(DatagramOnly, TlsConnectDatagram, TlsConnectTestBase::kTlsV11Plus); -INSTANTIATE_TEST_CASE_P(DatagramHolddown, TlsHolddownTest, - TlsConnectTestBase::kTlsV11Plus); INSTANTIATE_TEST_CASE_P( Pre12Stream, TlsConnectPre12, |