2015-03-07 16:49:00 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=2 et sw=2 tw=80: */
|
|
|
|
/* 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/. */
|
|
|
|
|
2016-08-19 12:20:21 +03:00
|
|
|
#include <functional>
|
|
|
|
#include <memory>
|
|
|
|
#include "secerr.h"
|
2016-09-16 20:00:57 +03:00
|
|
|
#include "ssl.h"
|
2015-10-23 21:39:23 +03:00
|
|
|
#include "sslerr.h"
|
2014-09-23 23:28:23 +04:00
|
|
|
#include "sslproto.h"
|
2015-10-05 23:42:28 +03:00
|
|
|
|
2015-10-23 21:39:23 +03:00
|
|
|
extern "C" {
|
|
|
|
// This is not something that should make you happy.
|
|
|
|
#include "libssl_internals.h"
|
|
|
|
}
|
|
|
|
|
2016-08-19 12:20:21 +03:00
|
|
|
#include "gtest_utils.h"
|
2016-04-27 15:51:59 +03:00
|
|
|
#include "scoped_ptrs.h"
|
2015-03-07 16:49:00 +03:00
|
|
|
#include "tls_connect.h"
|
2016-08-19 12:20:21 +03:00
|
|
|
#include "tls_filter.h"
|
|
|
|
#include "tls_parser.h"
|
2015-01-16 13:40:18 +03:00
|
|
|
|
2014-09-23 23:28:23 +04:00
|
|
|
namespace nss_test {
|
|
|
|
|
|
|
|
TEST_P(TlsConnectGeneric, SetupOnly) {}
|
|
|
|
|
|
|
|
TEST_P(TlsConnectGeneric, Connect) {
|
2015-10-23 21:39:23 +03:00
|
|
|
SetExpectedVersion(std::get<1>(GetParam()));
|
2014-09-23 23:28:23 +04:00
|
|
|
Connect();
|
2016-10-15 09:45:05 +03:00
|
|
|
CheckKeys();
|
2014-09-23 23:28:23 +04:00
|
|
|
}
|
|
|
|
|
2015-10-23 21:39:23 +03:00
|
|
|
TEST_P(TlsConnectGeneric, ConnectEcdsa) {
|
|
|
|
SetExpectedVersion(std::get<1>(GetParam()));
|
2016-08-19 12:20:21 +03:00
|
|
|
Reset(TlsAgent::kServerEcdsa256);
|
2015-10-23 21:39:23 +03:00
|
|
|
Connect();
|
2016-02-08 18:16:25 +03:00
|
|
|
CheckKeys(ssl_kea_ecdh, ssl_auth_ecdsa);
|
2015-10-23 21:39:23 +03:00
|
|
|
}
|
|
|
|
|
2016-10-05 18:52:14 +03:00
|
|
|
TEST_P(TlsConnectGenericPre13, CipherSuiteMismatch) {
|
|
|
|
EnsureTlsSetup();
|
|
|
|
if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
|
|
|
|
client_->EnableSingleCipher(TLS_AES_128_GCM_SHA256);
|
|
|
|
server_->EnableSingleCipher(TLS_AES_256_GCM_SHA384);
|
|
|
|
} else {
|
|
|
|
client_->EnableSingleCipher(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA);
|
|
|
|
server_->EnableSingleCipher(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA);
|
|
|
|
}
|
|
|
|
ConnectExpectFail();
|
|
|
|
client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
|
|
|
|
server_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
|
|
|
|
}
|
|
|
|
|
2016-07-20 10:39:08 +03:00
|
|
|
TEST_P(TlsConnectGenericPre13, ConnectFalseStart) {
|
|
|
|
client_->EnableFalseStart();
|
|
|
|
Connect();
|
|
|
|
SendReceive();
|
2016-02-08 18:16:25 +03:00
|
|
|
}
|
|
|
|
|
2016-07-20 10:39:08 +03:00
|
|
|
TEST_P(TlsConnectGeneric, ConnectAlpn) {
|
|
|
|
EnableAlpn();
|
|
|
|
Connect();
|
|
|
|
CheckAlpn("a");
|
2016-02-08 18:16:25 +03:00
|
|
|
}
|
|
|
|
|
2016-07-20 10:39:08 +03:00
|
|
|
TEST_P(TlsConnectGeneric, ConnectAlpnClone) {
|
|
|
|
EnsureModelSockets();
|
2016-09-16 20:00:57 +03:00
|
|
|
client_model_->EnableAlpn(alpn_dummy_val_, sizeof(alpn_dummy_val_));
|
|
|
|
server_model_->EnableAlpn(alpn_dummy_val_, sizeof(alpn_dummy_val_));
|
2016-07-20 10:39:08 +03:00
|
|
|
Connect();
|
|
|
|
CheckAlpn("a");
|
2016-02-08 18:16:25 +03:00
|
|
|
}
|
|
|
|
|
2016-07-20 10:39:08 +03:00
|
|
|
TEST_P(TlsConnectDatagram, ConnectSrtp) {
|
|
|
|
EnableSrtp();
|
|
|
|
Connect();
|
|
|
|
CheckSrtp();
|
|
|
|
SendReceive();
|
2016-02-08 18:16:25 +03:00
|
|
|
}
|
|
|
|
|
2016-07-20 10:39:08 +03:00
|
|
|
// 1.3 is disabled in the next few tests because we don't
|
|
|
|
// presently support resumption in 1.3.
|
|
|
|
TEST_P(TlsConnectStreamPre13, ConnectAndClientRenegotiate) {
|
|
|
|
Connect();
|
|
|
|
server_->PrepareForRenegotiate();
|
|
|
|
client_->StartRenegotiate();
|
|
|
|
Handshake();
|
|
|
|
CheckConnected();
|
2016-02-08 18:16:25 +03:00
|
|
|
}
|
2016-04-12 15:40:44 +03:00
|
|
|
|
2016-07-20 10:39:08 +03:00
|
|
|
TEST_P(TlsConnectStreamPre13, ConnectAndServerRenegotiate) {
|
2016-04-12 15:40:44 +03:00
|
|
|
Connect();
|
2016-07-20 10:39:08 +03:00
|
|
|
client_->PrepareForRenegotiate();
|
|
|
|
server_->StartRenegotiate();
|
|
|
|
Handshake();
|
|
|
|
CheckConnected();
|
|
|
|
}
|
2016-04-12 15:40:44 +03:00
|
|
|
|
2016-07-20 10:39:08 +03:00
|
|
|
TEST_P(TlsConnectGeneric, ConnectSendReceive) {
|
2016-04-12 15:40:44 +03:00
|
|
|
Connect();
|
|
|
|
SendReceive();
|
2016-07-20 10:39:08 +03:00
|
|
|
}
|
2016-06-02 23:33:04 +03:00
|
|
|
|
2016-07-20 10:39:08 +03:00
|
|
|
// The next two tests takes advantage of the fact that we
|
|
|
|
// automatically read the first 1024 bytes, so if
|
|
|
|
// we provide 1200 bytes, they overrun the read buffer
|
|
|
|
// provided by the calling test.
|
2016-04-27 15:51:59 +03:00
|
|
|
|
2016-07-20 10:39:08 +03:00
|
|
|
// DTLS should return an error.
|
|
|
|
TEST_P(TlsConnectDatagram, ShortRead) {
|
|
|
|
Connect();
|
2016-08-30 08:58:30 +03:00
|
|
|
client_->ExpectReadWriteError();
|
2016-07-20 10:39:08 +03:00
|
|
|
server_->SendData(1200, 1200);
|
2016-08-19 12:20:21 +03:00
|
|
|
client_->WaitForErrorCode(SSL_ERROR_RX_SHORT_DTLS_READ, 2000);
|
2016-04-12 15:40:44 +03:00
|
|
|
|
2016-07-20 10:39:08 +03:00
|
|
|
// Now send and receive another packet.
|
2016-08-19 12:20:21 +03:00
|
|
|
server_->ResetSentBytes(); // Reset the counter.
|
2016-07-20 10:39:08 +03:00
|
|
|
SendReceive();
|
2016-06-02 23:33:04 +03:00
|
|
|
}
|
|
|
|
|
2016-07-20 10:39:08 +03:00
|
|
|
// TLS should get the write in two chunks.
|
|
|
|
TEST_P(TlsConnectStream, ShortRead) {
|
|
|
|
// This test behaves oddly with TLS 1.0 because of 1/n+1 splitting,
|
|
|
|
// so skip in that case.
|
2016-08-19 12:20:21 +03:00
|
|
|
if (version_ < SSL_LIBRARY_VERSION_TLS_1_1) return;
|
2016-06-02 23:33:04 +03:00
|
|
|
|
|
|
|
Connect();
|
2016-07-20 10:39:08 +03:00
|
|
|
server_->SendData(1200, 1200);
|
|
|
|
// Read the first tranche.
|
|
|
|
WAIT_(client_->received_bytes() == 1024, 2000);
|
|
|
|
ASSERT_EQ(1024U, client_->received_bytes());
|
|
|
|
// The second tranche should now immediately be available.
|
|
|
|
client_->ReadBytes();
|
|
|
|
ASSERT_EQ(1200U, client_->received_bytes());
|
2016-06-02 23:33:04 +03:00
|
|
|
}
|
|
|
|
|
2016-08-19 12:20:21 +03:00
|
|
|
TEST_P(TlsConnectGeneric, ConnectWithCompressionMaybe) {
|
2016-07-20 10:39:08 +03:00
|
|
|
EnsureTlsSetup();
|
|
|
|
client_->EnableCompression();
|
|
|
|
server_->EnableCompression();
|
2016-06-02 23:33:04 +03:00
|
|
|
Connect();
|
2016-08-19 12:20:21 +03:00
|
|
|
EXPECT_EQ(client_->version() < SSL_LIBRARY_VERSION_TLS_1_3 && mode_ != DGRAM,
|
|
|
|
client_->is_compressed());
|
2016-07-20 10:39:08 +03:00
|
|
|
SendReceive();
|
2016-04-12 15:40:44 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(TlsConnectDatagram, TestDtlsHolddownExpiry) {
|
|
|
|
Connect();
|
|
|
|
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) {
|
2016-06-30 09:42:30 +03:00
|
|
|
// One for send, one for receive.
|
|
|
|
EXPECT_EQ(2, SSLInt_CountTls13CipherSpecs(client_->ssl_fd()));
|
2016-04-12 15:40:44 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-19 12:20:21 +03:00
|
|
|
class TlsPreCCSHeaderInjector : public TlsRecordFilter {
|
|
|
|
public:
|
|
|
|
TlsPreCCSHeaderInjector() {}
|
2016-12-02 14:20:41 +03:00
|
|
|
virtual PacketFilter::Action FilterRecord(
|
|
|
|
const TlsRecordHeader& record_header, const DataBuffer& input,
|
|
|
|
size_t* offset, DataBuffer* output) override {
|
2016-08-19 12:20:21 +03:00
|
|
|
if (record_header.content_type() != kTlsChangeCipherSpecType) return KEEP;
|
|
|
|
|
|
|
|
std::cerr << "Injecting Finished header before CCS\n";
|
|
|
|
const uint8_t hhdr[] = {kTlsHandshakeFinished, 0x00, 0x00, 0x0c};
|
|
|
|
DataBuffer hhdr_buf(hhdr, sizeof(hhdr));
|
2016-12-02 14:20:41 +03:00
|
|
|
TlsRecordHeader nhdr(record_header.version(), kTlsHandshakeType, 0);
|
2016-08-19 12:20:21 +03:00
|
|
|
*offset = nhdr.Write(output, *offset, hhdr_buf);
|
|
|
|
*offset = record_header.Write(output, *offset, input);
|
2016-04-27 15:51:59 +03:00
|
|
|
return CHANGE;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2016-08-19 12:20:21 +03:00
|
|
|
TEST_P(TlsConnectStreamPre13, ClientFinishedHeaderBeforeCCS) {
|
|
|
|
client_->SetPacketFilter(new TlsPreCCSHeaderInjector());
|
2016-04-27 15:51:59 +03:00
|
|
|
ConnectExpectFail();
|
2016-08-19 12:20:21 +03:00
|
|
|
client_->CheckErrorCode(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT);
|
|
|
|
server_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER);
|
2016-04-27 15:51:59 +03:00
|
|
|
}
|
|
|
|
|
2016-08-19 12:20:21 +03:00
|
|
|
TEST_P(TlsConnectStreamPre13, ServerFinishedHeaderBeforeCCS) {
|
|
|
|
server_->SetPacketFilter(new TlsPreCCSHeaderInjector());
|
|
|
|
client_->StartConnect();
|
|
|
|
server_->StartConnect();
|
|
|
|
Handshake();
|
|
|
|
EXPECT_EQ(TlsAgent::STATE_ERROR, client_->state());
|
|
|
|
client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER);
|
|
|
|
EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(TlsConnectTls13, UnknownAlert) {
|
|
|
|
Connect();
|
|
|
|
SSLInt_SendAlert(server_->ssl_fd(), kTlsAlertWarning,
|
|
|
|
0xff); // Unknown value.
|
2016-08-30 08:58:30 +03:00
|
|
|
client_->ExpectReadWriteError();
|
2016-08-19 12:20:21 +03:00
|
|
|
client_->WaitForErrorCode(SSL_ERROR_RX_UNKNOWN_ALERT, 2000);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(TlsConnectTls13, AlertWrongLevel) {
|
|
|
|
Connect();
|
|
|
|
SSLInt_SendAlert(server_->ssl_fd(), kTlsAlertWarning,
|
|
|
|
kTlsAlertUnexpectedMessage);
|
2016-08-30 08:58:30 +03:00
|
|
|
client_->ExpectReadWriteError();
|
2016-08-19 12:20:21 +03:00
|
|
|
client_->WaitForErrorCode(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT, 2000);
|
2016-04-27 15:51:59 +03:00
|
|
|
}
|
|
|
|
|
2016-04-12 15:40:44 +03:00
|
|
|
INSTANTIATE_TEST_CASE_P(GenericStream, TlsConnectGeneric,
|
2016-08-19 12:20:21 +03:00
|
|
|
::testing::Combine(TlsConnectTestBase::kTlsModesStream,
|
|
|
|
TlsConnectTestBase::kTlsVAll));
|
|
|
|
INSTANTIATE_TEST_CASE_P(
|
|
|
|
GenericDatagram, TlsConnectGeneric,
|
|
|
|
::testing::Combine(TlsConnectTestBase::kTlsModesDatagram,
|
|
|
|
TlsConnectTestBase::kTlsV11Plus));
|
2016-04-12 15:40:44 +03:00
|
|
|
|
|
|
|
INSTANTIATE_TEST_CASE_P(StreamOnly, TlsConnectStream,
|
|
|
|
TlsConnectTestBase::kTlsVAll);
|
|
|
|
INSTANTIATE_TEST_CASE_P(DatagramOnly, TlsConnectDatagram,
|
|
|
|
TlsConnectTestBase::kTlsV11Plus);
|
|
|
|
|
2015-10-23 21:39:23 +03:00
|
|
|
INSTANTIATE_TEST_CASE_P(Pre12Stream, TlsConnectPre12,
|
2016-08-19 12:20:21 +03:00
|
|
|
::testing::Combine(TlsConnectTestBase::kTlsModesStream,
|
|
|
|
TlsConnectTestBase::kTlsV10V11));
|
|
|
|
INSTANTIATE_TEST_CASE_P(
|
|
|
|
Pre12Datagram, TlsConnectPre12,
|
|
|
|
::testing::Combine(TlsConnectTestBase::kTlsModesDatagram,
|
|
|
|
TlsConnectTestBase::kTlsV11));
|
2016-04-12 15:40:44 +03:00
|
|
|
|
|
|
|
INSTANTIATE_TEST_CASE_P(Version12Only, TlsConnectTls12,
|
|
|
|
TlsConnectTestBase::kTlsModesAll);
|
2016-08-19 12:20:21 +03:00
|
|
|
#ifndef NSS_DISABLE_TLS_1_3
|
2016-06-13 18:31:45 +03:00
|
|
|
INSTANTIATE_TEST_CASE_P(Version13Only, TlsConnectTls13,
|
|
|
|
TlsConnectTestBase::kTlsModesAll);
|
|
|
|
#endif
|
2016-04-12 15:40:44 +03:00
|
|
|
|
|
|
|
INSTANTIATE_TEST_CASE_P(Pre13Stream, TlsConnectGenericPre13,
|
2016-08-19 12:20:21 +03:00
|
|
|
::testing::Combine(TlsConnectTestBase::kTlsModesStream,
|
|
|
|
TlsConnectTestBase::kTlsV10ToV12));
|
|
|
|
INSTANTIATE_TEST_CASE_P(
|
|
|
|
Pre13Datagram, TlsConnectGenericPre13,
|
|
|
|
::testing::Combine(TlsConnectTestBase::kTlsModesDatagram,
|
|
|
|
TlsConnectTestBase::kTlsV11V12));
|
2016-04-12 15:40:44 +03:00
|
|
|
INSTANTIATE_TEST_CASE_P(Pre13StreamOnly, TlsConnectStreamPre13,
|
2016-06-02 23:33:04 +03:00
|
|
|
TlsConnectTestBase::kTlsV10ToV12);
|
2016-06-13 18:31:45 +03:00
|
|
|
|
|
|
|
INSTANTIATE_TEST_CASE_P(Version12Plus, TlsConnectTls12Plus,
|
2016-08-19 12:20:21 +03:00
|
|
|
::testing::Combine(TlsConnectTestBase::kTlsModesAll,
|
|
|
|
TlsConnectTestBase::kTlsV12Plus));
|
2016-06-13 18:31:45 +03:00
|
|
|
|
2014-09-23 23:28:23 +04:00
|
|
|
} // namespace nspr_test
|