diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /security/nss/gtests/ssl_gtest/ssl_fuzz_unittest.cc | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'security/nss/gtests/ssl_gtest/ssl_fuzz_unittest.cc')
-rw-r--r-- | security/nss/gtests/ssl_gtest/ssl_fuzz_unittest.cc | 223 |
1 files changed, 223 insertions, 0 deletions
diff --git a/security/nss/gtests/ssl_gtest/ssl_fuzz_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_fuzz_unittest.cc new file mode 100644 index 000000000..d144cd7d9 --- /dev/null +++ b/security/nss/gtests/ssl_gtest/ssl_fuzz_unittest.cc @@ -0,0 +1,223 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "blapi.h" +#include "ssl.h" +#include "sslimpl.h" +#include "tls_connect.h" + +#include "gtest/gtest.h" + +namespace nss_test { + +#ifdef UNSAFE_FUZZER_MODE + +const uint8_t kShortEmptyFinished[8] = {0}; +const uint8_t kLongEmptyFinished[128] = {0}; + +class TlsFuzzTest : public ::testing::Test {}; + +// Record the application data stream. +class TlsApplicationDataRecorder : public TlsRecordFilter { + public: + TlsApplicationDataRecorder() : buffer_() {} + + virtual PacketFilter::Action FilterRecord(const RecordHeader& header, + const DataBuffer& input, + DataBuffer* output) { + if (header.content_type() == kTlsApplicationDataType) { + buffer_.Append(input); + } + + return KEEP; + } + + const DataBuffer& buffer() const { return buffer_; } + + private: + DataBuffer buffer_; +}; + +// Damages an SKE or CV signature. +class TlsSignatureDamager : public TlsHandshakeFilter { + public: + TlsSignatureDamager(uint8_t type) : type_(type) {} + virtual PacketFilter::Action FilterHandshake( + const TlsHandshakeFilter::HandshakeHeader& header, + const DataBuffer& input, DataBuffer* output) { + if (header.handshake_type() != type_) { + return KEEP; + } + + *output = input; + + // Modify the last byte of the signature. + output->data()[output->len() - 1]++; + return CHANGE; + } + + private: + uint8_t type_; +}; + +void ResetState() { + // Clear the list of RSA blinding params. + BL_Cleanup(); + + // Reinit the list of RSA blinding params. + EXPECT_EQ(SECSuccess, BL_Init()); + + // Reset the RNG state. + EXPECT_EQ(SECSuccess, RNG_ResetForFuzzing()); +} + +// Ensure that ssl_Time() returns a constant value. +TEST_F(TlsFuzzTest, Fuzz_SSL_Time_Constant) { + PRInt32 now = ssl_Time(); + PR_Sleep(PR_SecondsToInterval(2)); + EXPECT_EQ(ssl_Time(), now); +} + +// Check that due to the deterministic PRNG we derive +// the same master secret in two consecutive TLS sessions. +TEST_P(TlsConnectGeneric, Fuzz_DeterministicExporter) { + const char kLabel[] = "label"; + std::vector<unsigned char> out1(32), out2(32); + + ConfigureSessionCache(RESUME_NONE, RESUME_NONE); + DisableECDHEServerKeyReuse(); + + ResetState(); + Connect(); + + // Export a key derived from the MS and nonces. + SECStatus rv = + SSL_ExportKeyingMaterial(client_->ssl_fd(), kLabel, strlen(kLabel), false, + NULL, 0, out1.data(), out1.size()); + EXPECT_EQ(SECSuccess, rv); + + Reset(); + ConfigureSessionCache(RESUME_NONE, RESUME_NONE); + DisableECDHEServerKeyReuse(); + + ResetState(); + Connect(); + + // Export another key derived from the MS and nonces. + rv = SSL_ExportKeyingMaterial(client_->ssl_fd(), kLabel, strlen(kLabel), + false, NULL, 0, out2.data(), out2.size()); + EXPECT_EQ(SECSuccess, rv); + + // The two exported keys should be the same. + EXPECT_EQ(out1, out2); +} + +// Check that due to the deterministic RNG two consecutive +// TLS sessions will have the exact same transcript. +TEST_P(TlsConnectGeneric, Fuzz_DeterministicTranscript) { + // Connect a few times and compare the transcripts byte-by-byte. + DataBuffer last; + for (size_t i = 0; i < 5; i++) { + Reset(); + ConfigureSessionCache(RESUME_NONE, RESUME_NONE); + DisableECDHEServerKeyReuse(); + + DataBuffer buffer; + client_->SetPacketFilter(new TlsConversationRecorder(buffer)); + server_->SetPacketFilter(new TlsConversationRecorder(buffer)); + + ResetState(); + Connect(); + + // Ensure the filters go away before |buffer| does. + client_->SetPacketFilter(nullptr); + server_->SetPacketFilter(nullptr); + + if (last.len() > 0) { + EXPECT_EQ(last, buffer); + } + + last = buffer; + } +} + +// Check that we can establish and use a connection +// with all supported TLS versions, STREAM and DGRAM. +// Check that records are NOT encrypted. +// Check that records don't have a MAC. +TEST_P(TlsConnectGeneric, Fuzz_ConnectSendReceive_NullCipher) { + EnsureTlsSetup(); + + // Set up app data filters. + auto client_recorder = new TlsApplicationDataRecorder(); + client_->SetPacketFilter(client_recorder); + auto server_recorder = new TlsApplicationDataRecorder(); + server_->SetPacketFilter(server_recorder); + + Connect(); + + // Construct the plaintext. + DataBuffer buf; + buf.Allocate(50); + for (size_t i = 0; i < buf.len(); ++i) { + buf.data()[i] = i & 0xff; + } + + // Send/Receive data. + client_->SendBuffer(buf); + server_->SendBuffer(buf); + Receive(buf.len()); + + // Check for plaintext on the wire. + EXPECT_EQ(buf, client_recorder->buffer()); + EXPECT_EQ(buf, server_recorder->buffer()); +} + +// Check that an invalid Finished message doesn't abort the connection. +TEST_P(TlsConnectGeneric, Fuzz_BogusClientFinished) { + EnsureTlsSetup(); + + auto i1 = new TlsInspectorReplaceHandshakeMessage( + kTlsHandshakeFinished, + DataBuffer(kShortEmptyFinished, sizeof(kShortEmptyFinished))); + client_->SetPacketFilter(i1); + Connect(); + SendReceive(); +} + +// Check that an invalid Finished message doesn't abort the connection. +TEST_P(TlsConnectGeneric, Fuzz_BogusServerFinished) { + EnsureTlsSetup(); + + auto i1 = new TlsInspectorReplaceHandshakeMessage( + kTlsHandshakeFinished, + DataBuffer(kLongEmptyFinished, sizeof(kLongEmptyFinished))); + server_->SetPacketFilter(i1); + Connect(); + SendReceive(); +} + +// Check that an invalid server auth signature doesn't abort the connection. +TEST_P(TlsConnectGeneric, Fuzz_BogusServerAuthSignature) { + EnsureTlsSetup(); + uint8_t msg_type = version_ == SSL_LIBRARY_VERSION_TLS_1_3 + ? kTlsHandshakeCertificateVerify + : kTlsHandshakeServerKeyExchange; + server_->SetPacketFilter(new TlsSignatureDamager(msg_type)); + Connect(); + SendReceive(); +} + +// Check that an invalid client auth signature doesn't abort the connection. +TEST_P(TlsConnectGeneric, Fuzz_BogusClientAuthSignature) { + EnsureTlsSetup(); + client_->SetupClientAuth(); + server_->RequestClientAuth(true); + client_->SetPacketFilter( + new TlsSignatureDamager(kTlsHandshakeCertificateVerify)); + Connect(); +} + +#endif +} |