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/. */
|
|
|
|
|
|
|
|
#include "tls_connect.h"
|
2016-04-12 15:40:44 +03:00
|
|
|
extern "C" {
|
|
|
|
#include "libssl_internals.h"
|
|
|
|
}
|
2015-03-07 16:49:00 +03:00
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
|
2016-09-16 20:00:57 +03:00
|
|
|
#include "databuffer.h"
|
2015-03-07 16:49:00 +03:00
|
|
|
#include "gtest_utils.h"
|
2016-08-19 12:20:21 +03:00
|
|
|
#include "sslproto.h"
|
2015-03-07 16:49:00 +03:00
|
|
|
|
|
|
|
extern std::string g_working_dir_path;
|
|
|
|
|
|
|
|
namespace nss_test {
|
|
|
|
|
2015-03-26 22:39:25 +03:00
|
|
|
static const std::string kTlsModesStreamArr[] = {"TLS"};
|
|
|
|
::testing::internal::ParamGenerator<std::string>
|
2016-08-19 12:20:21 +03:00
|
|
|
TlsConnectTestBase::kTlsModesStream =
|
|
|
|
::testing::ValuesIn(kTlsModesStreamArr);
|
2016-04-12 15:40:44 +03:00
|
|
|
static const std::string kTlsModesDatagramArr[] = {"DTLS"};
|
|
|
|
::testing::internal::ParamGenerator<std::string>
|
2016-08-19 12:20:21 +03:00
|
|
|
TlsConnectTestBase::kTlsModesDatagram =
|
|
|
|
::testing::ValuesIn(kTlsModesDatagramArr);
|
2015-03-26 22:39:25 +03:00
|
|
|
static const std::string kTlsModesAllArr[] = {"TLS", "DTLS"};
|
|
|
|
::testing::internal::ParamGenerator<std::string>
|
2016-08-19 12:20:21 +03:00
|
|
|
TlsConnectTestBase::kTlsModesAll = ::testing::ValuesIn(kTlsModesAllArr);
|
2016-04-12 15:40:44 +03:00
|
|
|
|
2015-03-26 22:39:25 +03:00
|
|
|
static const uint16_t kTlsV10Arr[] = {SSL_LIBRARY_VERSION_TLS_1_0};
|
2016-08-19 12:20:21 +03:00
|
|
|
::testing::internal::ParamGenerator<uint16_t> TlsConnectTestBase::kTlsV10 =
|
|
|
|
::testing::ValuesIn(kTlsV10Arr);
|
2015-10-23 21:39:23 +03:00
|
|
|
static const uint16_t kTlsV11Arr[] = {SSL_LIBRARY_VERSION_TLS_1_1};
|
2016-08-19 12:20:21 +03:00
|
|
|
::testing::internal::ParamGenerator<uint16_t> TlsConnectTestBase::kTlsV11 =
|
|
|
|
::testing::ValuesIn(kTlsV11Arr);
|
2016-06-02 23:33:04 +03:00
|
|
|
static const uint16_t kTlsV12Arr[] = {SSL_LIBRARY_VERSION_TLS_1_2};
|
2016-08-19 12:20:21 +03:00
|
|
|
::testing::internal::ParamGenerator<uint16_t> TlsConnectTestBase::kTlsV12 =
|
|
|
|
::testing::ValuesIn(kTlsV12Arr);
|
2016-04-12 15:40:44 +03:00
|
|
|
static const uint16_t kTlsV10V11Arr[] = {SSL_LIBRARY_VERSION_TLS_1_0,
|
|
|
|
SSL_LIBRARY_VERSION_TLS_1_1};
|
2016-08-19 12:20:21 +03:00
|
|
|
::testing::internal::ParamGenerator<uint16_t> TlsConnectTestBase::kTlsV10V11 =
|
|
|
|
::testing::ValuesIn(kTlsV10V11Arr);
|
2016-06-02 23:33:04 +03:00
|
|
|
static const uint16_t kTlsV10ToV12Arr[] = {SSL_LIBRARY_VERSION_TLS_1_0,
|
|
|
|
SSL_LIBRARY_VERSION_TLS_1_1,
|
|
|
|
SSL_LIBRARY_VERSION_TLS_1_2};
|
2016-08-19 12:20:21 +03:00
|
|
|
::testing::internal::ParamGenerator<uint16_t> TlsConnectTestBase::kTlsV10ToV12 =
|
|
|
|
::testing::ValuesIn(kTlsV10ToV12Arr);
|
2015-03-26 22:39:25 +03:00
|
|
|
static const uint16_t kTlsV11V12Arr[] = {SSL_LIBRARY_VERSION_TLS_1_1,
|
|
|
|
SSL_LIBRARY_VERSION_TLS_1_2};
|
2016-08-19 12:20:21 +03:00
|
|
|
::testing::internal::ParamGenerator<uint16_t> TlsConnectTestBase::kTlsV11V12 =
|
|
|
|
::testing::ValuesIn(kTlsV11V12Arr);
|
2016-04-12 15:40:44 +03:00
|
|
|
|
|
|
|
static const uint16_t kTlsV11PlusArr[] = {
|
2016-08-19 12:20:21 +03:00
|
|
|
#ifndef NSS_DISABLE_TLS_1_3
|
|
|
|
SSL_LIBRARY_VERSION_TLS_1_3,
|
2016-04-12 15:40:44 +03:00
|
|
|
#endif
|
2016-08-19 12:20:21 +03:00
|
|
|
SSL_LIBRARY_VERSION_TLS_1_2, SSL_LIBRARY_VERSION_TLS_1_1};
|
|
|
|
::testing::internal::ParamGenerator<uint16_t> TlsConnectTestBase::kTlsV11Plus =
|
|
|
|
::testing::ValuesIn(kTlsV11PlusArr);
|
2016-04-12 15:40:44 +03:00
|
|
|
static const uint16_t kTlsV12PlusArr[] = {
|
2016-08-19 12:20:21 +03:00
|
|
|
#ifndef NSS_DISABLE_TLS_1_3
|
|
|
|
SSL_LIBRARY_VERSION_TLS_1_3,
|
2016-04-12 15:40:44 +03:00
|
|
|
#endif
|
2016-08-19 12:20:21 +03:00
|
|
|
SSL_LIBRARY_VERSION_TLS_1_2};
|
|
|
|
::testing::internal::ParamGenerator<uint16_t> TlsConnectTestBase::kTlsV12Plus =
|
|
|
|
::testing::ValuesIn(kTlsV12PlusArr);
|
|
|
|
static const uint16_t kTlsV13Arr[] = {SSL_LIBRARY_VERSION_TLS_1_3};
|
|
|
|
::testing::internal::ParamGenerator<uint16_t> TlsConnectTestBase::kTlsV13 =
|
|
|
|
::testing::ValuesIn(kTlsV13Arr);
|
2016-04-12 15:40:44 +03:00
|
|
|
static const uint16_t kTlsVAllArr[] = {
|
2016-08-19 12:20:21 +03:00
|
|
|
#ifndef NSS_DISABLE_TLS_1_3
|
|
|
|
SSL_LIBRARY_VERSION_TLS_1_3,
|
2016-04-12 15:40:44 +03:00
|
|
|
#endif
|
2016-08-19 12:20:21 +03:00
|
|
|
SSL_LIBRARY_VERSION_TLS_1_2, SSL_LIBRARY_VERSION_TLS_1_1,
|
|
|
|
SSL_LIBRARY_VERSION_TLS_1_0};
|
|
|
|
::testing::internal::ParamGenerator<uint16_t> TlsConnectTestBase::kTlsVAll =
|
|
|
|
::testing::ValuesIn(kTlsVAllArr);
|
|
|
|
|
|
|
|
std::string VersionString(uint16_t version) {
|
|
|
|
switch (version) {
|
|
|
|
case 0:
|
|
|
|
return "(no version)";
|
|
|
|
case SSL_LIBRARY_VERSION_TLS_1_0:
|
|
|
|
return "1.0";
|
|
|
|
case SSL_LIBRARY_VERSION_TLS_1_1:
|
|
|
|
return "1.1";
|
|
|
|
case SSL_LIBRARY_VERSION_TLS_1_2:
|
|
|
|
return "1.2";
|
|
|
|
case SSL_LIBRARY_VERSION_TLS_1_3:
|
|
|
|
return "1.3";
|
|
|
|
default:
|
|
|
|
std::cerr << "Invalid version: " << version << std::endl;
|
|
|
|
EXPECT_TRUE(false);
|
|
|
|
return "";
|
2015-03-26 22:39:25 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TlsConnectTestBase::TlsConnectTestBase(Mode mode, uint16_t version)
|
2016-08-19 12:20:21 +03:00
|
|
|
: mode_(mode),
|
|
|
|
client_(new TlsAgent(TlsAgent::kClient, TlsAgent::CLIENT, mode_)),
|
|
|
|
server_(new TlsAgent(TlsAgent::kServerRsa, TlsAgent::SERVER, mode_)),
|
|
|
|
client_model_(nullptr),
|
|
|
|
server_model_(nullptr),
|
|
|
|
version_(version),
|
|
|
|
expected_resumption_mode_(RESUME_NONE),
|
|
|
|
session_ids_(),
|
|
|
|
expect_extended_master_secret_(false),
|
|
|
|
expect_early_data_accepted_(false) {
|
2016-04-12 15:40:44 +03:00
|
|
|
std::string v;
|
|
|
|
if (mode_ == DGRAM && version_ == SSL_LIBRARY_VERSION_TLS_1_1) {
|
|
|
|
v = "1.0";
|
|
|
|
} else {
|
|
|
|
v = VersionString(version_);
|
|
|
|
}
|
|
|
|
std::cerr << "Version: " << mode_ << " " << v << std::endl;
|
2015-03-26 22:39:25 +03:00
|
|
|
}
|
2015-03-07 16:49:00 +03:00
|
|
|
|
2016-08-19 12:20:21 +03:00
|
|
|
TlsConnectTestBase::~TlsConnectTestBase() {}
|
2015-03-07 16:49:00 +03:00
|
|
|
|
2016-09-16 20:00:57 +03:00
|
|
|
// Check the group of each of the supported groups
|
|
|
|
void TlsConnectTestBase::CheckGroups(
|
|
|
|
const DataBuffer& groups, std::function<void(SSLNamedGroup)> check_group) {
|
|
|
|
DuplicateGroupChecker group_set;
|
|
|
|
uint32_t tmp = 0;
|
|
|
|
EXPECT_TRUE(groups.Read(0, 2, &tmp));
|
|
|
|
EXPECT_EQ(groups.len() - 2, static_cast<size_t>(tmp));
|
|
|
|
for (size_t i = 2; i < groups.len(); i += 2) {
|
|
|
|
EXPECT_TRUE(groups.Read(i, 2, &tmp));
|
|
|
|
SSLNamedGroup group = static_cast<SSLNamedGroup>(tmp);
|
|
|
|
group_set.AddAndCheckGroup(group);
|
|
|
|
check_group(group);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check the group of each of the shares
|
|
|
|
void TlsConnectTestBase::CheckShares(
|
|
|
|
const DataBuffer& shares, std::function<void(SSLNamedGroup)> check_group) {
|
|
|
|
DuplicateGroupChecker group_set;
|
|
|
|
uint32_t tmp = 0;
|
|
|
|
EXPECT_TRUE(shares.Read(0, 2, &tmp));
|
|
|
|
EXPECT_EQ(shares.len() - 2, static_cast<size_t>(tmp));
|
|
|
|
size_t i;
|
|
|
|
for (i = 2; i < shares.len(); i += 4 + tmp) {
|
|
|
|
ASSERT_TRUE(shares.Read(i, 2, &tmp));
|
|
|
|
SSLNamedGroup group = static_cast<SSLNamedGroup>(tmp);
|
|
|
|
group_set.AddAndCheckGroup(group);
|
|
|
|
check_group(group);
|
|
|
|
ASSERT_TRUE(shares.Read(i + 2, 2, &tmp));
|
|
|
|
}
|
|
|
|
EXPECT_EQ(shares.len(), i);
|
|
|
|
}
|
|
|
|
|
2016-04-12 15:40:44 +03:00
|
|
|
void TlsConnectTestBase::ClearStats() {
|
2015-03-07 16:49:00 +03:00
|
|
|
// Clear statistics.
|
|
|
|
SSL3Statistics* stats = SSL_GetStatistics();
|
|
|
|
memset(stats, 0, sizeof(*stats));
|
2016-04-12 15:40:44 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void TlsConnectTestBase::ClearServerCache() {
|
|
|
|
SSL_ShutdownServerSessionIDCache();
|
|
|
|
SSLInt_ClearSessionTicketKey();
|
|
|
|
SSL_ConfigServerSessionIDCache(1024, 0, 0, g_working_dir_path.c_str());
|
|
|
|
}
|
2015-03-07 16:49:00 +03:00
|
|
|
|
2016-04-12 15:40:44 +03:00
|
|
|
void TlsConnectTestBase::SetUp() {
|
|
|
|
SSL_ConfigServerSessionIDCache(1024, 0, 0, g_working_dir_path.c_str());
|
|
|
|
SSLInt_ClearSessionTicketKey();
|
|
|
|
ClearStats();
|
2015-03-07 16:49:00 +03:00
|
|
|
Init();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TlsConnectTestBase::TearDown() {
|
2015-10-23 21:39:23 +03:00
|
|
|
delete client_;
|
|
|
|
delete server_;
|
2016-06-30 09:42:30 +03:00
|
|
|
if (client_model_) {
|
|
|
|
ASSERT_NE(server_model_, nullptr);
|
|
|
|
delete client_model_;
|
|
|
|
delete server_model_;
|
|
|
|
}
|
2015-03-07 16:49:00 +03:00
|
|
|
|
|
|
|
SSL_ClearSessionCache();
|
2016-04-12 15:40:44 +03:00
|
|
|
SSLInt_ClearSessionTicketKey();
|
2015-03-07 16:49:00 +03:00
|
|
|
SSL_ShutdownServerSessionIDCache();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TlsConnectTestBase::Init() {
|
2015-04-17 14:49:43 +03:00
|
|
|
EXPECT_TRUE(client_->Init());
|
|
|
|
EXPECT_TRUE(server_->Init());
|
2015-03-07 16:49:00 +03:00
|
|
|
|
|
|
|
client_->SetPeer(server_);
|
|
|
|
server_->SetPeer(client_);
|
2015-03-26 22:39:25 +03:00
|
|
|
|
|
|
|
if (version_) {
|
|
|
|
client_->SetVersionRange(version_, version_);
|
|
|
|
server_->SetVersionRange(version_, version_);
|
|
|
|
}
|
2015-03-07 16:49:00 +03:00
|
|
|
}
|
|
|
|
|
2016-04-27 15:51:59 +03:00
|
|
|
void TlsConnectTestBase::Reset() {
|
2016-08-19 12:20:21 +03:00
|
|
|
// Take a copy of the names because they are about to disappear.
|
|
|
|
std::string server_name = server_->name();
|
|
|
|
std::string client_name = client_->name();
|
|
|
|
Reset(server_name, client_name);
|
2016-04-27 15:51:59 +03:00
|
|
|
}
|
|
|
|
|
2016-08-19 12:20:21 +03:00
|
|
|
void TlsConnectTestBase::Reset(const std::string& server_name,
|
|
|
|
const std::string& client_name) {
|
2015-03-07 16:49:00 +03:00
|
|
|
delete client_;
|
|
|
|
delete server_;
|
|
|
|
|
2016-08-19 12:20:21 +03:00
|
|
|
client_ = new TlsAgent(client_name, TlsAgent::CLIENT, mode_);
|
2016-04-27 15:51:59 +03:00
|
|
|
server_ = new TlsAgent(server_name, TlsAgent::SERVER, mode_);
|
2015-03-07 16:49:00 +03:00
|
|
|
|
|
|
|
Init();
|
|
|
|
}
|
|
|
|
|
2015-10-23 21:39:23 +03:00
|
|
|
void TlsConnectTestBase::ExpectResumption(SessionResumptionMode expected) {
|
|
|
|
expected_resumption_mode_ = expected;
|
|
|
|
if (expected != RESUME_NONE) {
|
|
|
|
client_->ExpectResumption();
|
|
|
|
server_->ExpectResumption();
|
|
|
|
}
|
2015-04-17 14:49:43 +03:00
|
|
|
}
|
|
|
|
|
2015-03-07 16:49:00 +03:00
|
|
|
void TlsConnectTestBase::EnsureTlsSetup() {
|
2016-08-19 12:20:21 +03:00
|
|
|
EXPECT_TRUE(server_->EnsureTlsSetup(server_model_ ? server_model_->ssl_fd()
|
|
|
|
: nullptr));
|
|
|
|
EXPECT_TRUE(client_->EnsureTlsSetup(client_model_ ? client_model_->ssl_fd()
|
|
|
|
: nullptr));
|
2015-03-07 16:49:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void TlsConnectTestBase::Handshake() {
|
2016-02-08 18:16:25 +03:00
|
|
|
EnsureTlsSetup();
|
|
|
|
client_->SetServerKeyBits(server_->server_key_bits());
|
2015-03-07 16:49:00 +03:00
|
|
|
client_->Handshake();
|
|
|
|
server_->Handshake();
|
|
|
|
|
2015-10-23 21:39:23 +03:00
|
|
|
ASSERT_TRUE_WAIT((client_->state() != TlsAgent::STATE_CONNECTING) &&
|
2016-08-19 12:20:21 +03:00
|
|
|
(server_->state() != TlsAgent::STATE_CONNECTING),
|
2015-03-07 16:49:00 +03:00
|
|
|
5000);
|
2015-10-23 21:39:23 +03:00
|
|
|
}
|
2015-03-26 22:39:25 +03:00
|
|
|
|
2015-10-23 21:39:23 +03:00
|
|
|
void TlsConnectTestBase::EnableExtendedMasterSecret() {
|
|
|
|
client_->EnableExtendedMasterSecret();
|
|
|
|
server_->EnableExtendedMasterSecret();
|
|
|
|
ExpectExtendedMasterSecret(true);
|
2015-03-07 16:49:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void TlsConnectTestBase::Connect() {
|
2016-06-30 09:42:30 +03:00
|
|
|
server_->StartConnect(server_model_ ? server_model_->ssl_fd() : nullptr);
|
|
|
|
client_->StartConnect(client_model_ ? client_model_->ssl_fd() : nullptr);
|
2015-03-07 16:49:00 +03:00
|
|
|
Handshake();
|
2015-10-23 21:39:23 +03:00
|
|
|
CheckConnected();
|
|
|
|
}
|
2015-03-07 16:49:00 +03:00
|
|
|
|
2016-08-19 12:20:21 +03:00
|
|
|
void TlsConnectTestBase::ConnectWithCipherSuite(uint16_t cipher_suite) {
|
2016-04-27 15:51:59 +03:00
|
|
|
EnsureTlsSetup();
|
|
|
|
client_->EnableSingleCipher(cipher_suite);
|
|
|
|
|
|
|
|
Connect();
|
|
|
|
SendReceive();
|
|
|
|
|
|
|
|
// Check that we used the right cipher suite.
|
|
|
|
uint16_t actual;
|
|
|
|
EXPECT_TRUE(client_->cipher_suite(&actual));
|
|
|
|
EXPECT_EQ(cipher_suite, actual);
|
|
|
|
EXPECT_TRUE(server_->cipher_suite(&actual));
|
|
|
|
EXPECT_EQ(cipher_suite, actual);
|
|
|
|
}
|
|
|
|
|
2015-10-23 21:39:23 +03:00
|
|
|
void TlsConnectTestBase::CheckConnected() {
|
2015-03-26 22:39:25 +03:00
|
|
|
// Check the version is as expected
|
2015-04-17 14:49:43 +03:00
|
|
|
EXPECT_EQ(client_->version(), server_->version());
|
2016-08-19 12:20:21 +03:00
|
|
|
EXPECT_EQ(std::min(client_->max_version(), server_->max_version()),
|
2015-03-26 22:39:25 +03:00
|
|
|
client_->version());
|
|
|
|
|
2015-10-23 21:39:23 +03:00
|
|
|
EXPECT_EQ(TlsAgent::STATE_CONNECTED, client_->state());
|
|
|
|
EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state());
|
2015-03-07 16:49:00 +03:00
|
|
|
|
2016-04-27 15:51:59 +03:00
|
|
|
uint16_t cipher_suite1, cipher_suite2;
|
2015-03-07 16:49:00 +03:00
|
|
|
bool ret = client_->cipher_suite(&cipher_suite1);
|
2015-04-17 14:49:43 +03:00
|
|
|
EXPECT_TRUE(ret);
|
2015-03-07 16:49:00 +03:00
|
|
|
ret = server_->cipher_suite(&cipher_suite2);
|
2015-04-17 14:49:43 +03:00
|
|
|
EXPECT_TRUE(ret);
|
|
|
|
EXPECT_EQ(cipher_suite1, cipher_suite2);
|
2015-03-07 16:49:00 +03:00
|
|
|
|
2015-03-26 22:39:25 +03:00
|
|
|
std::cerr << "Connected with version " << client_->version()
|
2016-08-19 12:20:21 +03:00
|
|
|
<< " cipher suite " << client_->cipher_suite_name() << std::endl;
|
2015-03-07 16:49:00 +03:00
|
|
|
|
2016-02-08 18:16:25 +03:00
|
|
|
if (client_->version() < SSL_LIBRARY_VERSION_TLS_1_3) {
|
|
|
|
// Check and store session ids.
|
|
|
|
std::vector<uint8_t> sid_c1 = client_->session_id();
|
|
|
|
EXPECT_EQ(32U, sid_c1.size());
|
|
|
|
std::vector<uint8_t> sid_s1 = server_->session_id();
|
|
|
|
EXPECT_EQ(32U, sid_s1.size());
|
|
|
|
EXPECT_EQ(sid_c1, sid_s1);
|
|
|
|
session_ids_.push_back(sid_c1);
|
|
|
|
}
|
2015-10-23 21:39:23 +03:00
|
|
|
|
|
|
|
CheckExtendedMasterSecret();
|
2016-06-30 09:42:30 +03:00
|
|
|
CheckEarlyDataAccepted();
|
2016-02-08 18:16:25 +03:00
|
|
|
CheckResumption(expected_resumption_mode_);
|
2016-06-30 09:42:30 +03:00
|
|
|
client_->CheckSecretsDestroyed();
|
|
|
|
server_->CheckSecretsDestroyed();
|
2016-02-08 18:16:25 +03:00
|
|
|
}
|
|
|
|
|
2016-08-19 12:20:21 +03:00
|
|
|
void TlsConnectTestBase::CheckKeys(SSLKEAType kea_type, SSLAuthType auth_type,
|
2016-08-05 19:16:01 +03:00
|
|
|
size_t kea_size) const {
|
|
|
|
if (kea_size) {
|
|
|
|
client_->CheckKEA(kea_type, kea_size);
|
|
|
|
server_->CheckKEA(kea_type, kea_size);
|
|
|
|
} else {
|
|
|
|
client_->CheckKEA(kea_type);
|
|
|
|
server_->CheckKEA(kea_type);
|
|
|
|
}
|
|
|
|
client_->CheckAuthType(auth_type);
|
|
|
|
server_->CheckAuthType(auth_type);
|
2015-03-07 16:49:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void TlsConnectTestBase::ConnectExpectFail() {
|
2015-10-23 21:39:23 +03:00
|
|
|
server_->StartConnect();
|
|
|
|
client_->StartConnect();
|
2015-03-07 16:49:00 +03:00
|
|
|
Handshake();
|
2015-10-23 21:39:23 +03:00
|
|
|
ASSERT_EQ(TlsAgent::STATE_ERROR, client_->state());
|
|
|
|
ASSERT_EQ(TlsAgent::STATE_ERROR, server_->state());
|
2015-03-07 16:49:00 +03:00
|
|
|
}
|
|
|
|
|
2015-10-23 21:39:23 +03:00
|
|
|
void TlsConnectTestBase::SetExpectedVersion(uint16_t version) {
|
|
|
|
client_->SetExpectedVersion(version);
|
|
|
|
server_->SetExpectedVersion(version);
|
2015-03-07 16:49:00 +03:00
|
|
|
}
|
|
|
|
|
2016-06-13 18:31:45 +03:00
|
|
|
void TlsConnectTestBase::DisableAllCiphers() {
|
|
|
|
EnsureTlsSetup();
|
|
|
|
client_->DisableAllCiphers();
|
|
|
|
server_->DisableAllCiphers();
|
2015-10-23 21:39:23 +03:00
|
|
|
}
|
|
|
|
|
2016-06-13 18:31:45 +03:00
|
|
|
void TlsConnectTestBase::EnableOnlyStaticRsaCiphers() {
|
|
|
|
DisableAllCiphers();
|
|
|
|
|
|
|
|
client_->EnableCiphersByKeyExchange(ssl_kea_rsa);
|
|
|
|
server_->EnableCiphersByKeyExchange(ssl_kea_rsa);
|
2015-10-23 21:39:23 +03:00
|
|
|
}
|
|
|
|
|
2016-06-13 18:31:45 +03:00
|
|
|
void TlsConnectTestBase::EnableOnlyDheCiphers() {
|
2016-09-26 03:47:58 +03:00
|
|
|
if (version_ < SSL_LIBRARY_VERSION_TLS_1_3) {
|
|
|
|
DisableAllCiphers();
|
|
|
|
client_->EnableCiphersByKeyExchange(ssl_kea_dh);
|
|
|
|
server_->EnableCiphersByKeyExchange(ssl_kea_dh);
|
|
|
|
} else {
|
|
|
|
client_->ConfigNamedGroups(kFFDHEGroups);
|
|
|
|
server_->ConfigNamedGroups(kFFDHEGroups);
|
|
|
|
}
|
2015-08-13 12:31:23 +03:00
|
|
|
}
|
2015-03-07 16:49:00 +03:00
|
|
|
|
2016-04-27 15:51:59 +03:00
|
|
|
void TlsConnectTestBase::EnableSomeEcdhCiphers() {
|
2016-09-26 03:47:58 +03:00
|
|
|
if (version_ < SSL_LIBRARY_VERSION_TLS_1_3) {
|
|
|
|
client_->EnableCiphersByAuthType(ssl_auth_ecdh_rsa);
|
|
|
|
client_->EnableCiphersByAuthType(ssl_auth_ecdh_ecdsa);
|
|
|
|
server_->EnableCiphersByAuthType(ssl_auth_ecdh_rsa);
|
|
|
|
server_->EnableCiphersByAuthType(ssl_auth_ecdh_ecdsa);
|
|
|
|
} else {
|
|
|
|
client_->ConfigNamedGroups(kECDHEGroups);
|
|
|
|
server_->ConfigNamedGroups(kECDHEGroups);
|
|
|
|
}
|
2016-04-27 15:51:59 +03:00
|
|
|
}
|
|
|
|
|
2015-03-07 16:49:00 +03:00
|
|
|
void TlsConnectTestBase::ConfigureSessionCache(SessionResumptionMode client,
|
|
|
|
SessionResumptionMode server) {
|
|
|
|
client_->ConfigureSessionCache(client);
|
|
|
|
server_->ConfigureSessionCache(server);
|
2016-06-13 18:31:45 +03:00
|
|
|
if ((server & RESUME_TICKET) != 0) {
|
|
|
|
// This is an abomination. NSS encrypts session tickets with the server's
|
|
|
|
// RSA public key. That means we need the server to have an RSA certificate
|
|
|
|
// even if it won't be used for the connection.
|
|
|
|
server_->ConfigServerCert(TlsAgent::kServerRsaDecrypt);
|
|
|
|
}
|
2015-03-07 16:49:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void TlsConnectTestBase::CheckResumption(SessionResumptionMode expected) {
|
2015-04-17 14:49:43 +03:00
|
|
|
EXPECT_NE(RESUME_BOTH, expected);
|
2015-03-07 16:49:00 +03:00
|
|
|
|
2016-09-16 20:00:57 +03:00
|
|
|
int resume_count = expected ? 1 : 0;
|
|
|
|
int stateless_count = (expected & RESUME_TICKET) ? 1 : 0;
|
2015-03-07 16:49:00 +03:00
|
|
|
|
2016-09-16 20:00:57 +03:00
|
|
|
// Note: hch == server counter; hsh == client counter.
|
2015-03-07 16:49:00 +03:00
|
|
|
SSL3Statistics* stats = SSL_GetStatistics();
|
2016-09-16 20:00:57 +03:00
|
|
|
EXPECT_EQ(resume_count, stats->hch_sid_cache_hits);
|
|
|
|
EXPECT_EQ(resume_count, stats->hsh_sid_cache_hits);
|
|
|
|
|
|
|
|
EXPECT_EQ(stateless_count, stats->hch_sid_stateless_resumes);
|
|
|
|
EXPECT_EQ(stateless_count, stats->hsh_sid_stateless_resumes);
|
|
|
|
|
|
|
|
if (expected != RESUME_NONE) {
|
|
|
|
if (client_->version() < SSL_LIBRARY_VERSION_TLS_1_3) {
|
|
|
|
// Check that the last two session ids match.
|
|
|
|
ASSERT_EQ(2U, session_ids_.size());
|
|
|
|
EXPECT_EQ(session_ids_[session_ids_.size() - 1],
|
|
|
|
session_ids_[session_ids_.size() - 2]);
|
|
|
|
} else {
|
|
|
|
// TLS 1.3 only uses tickets.
|
|
|
|
EXPECT_TRUE(expected & RESUME_TICKET);
|
|
|
|
}
|
2015-03-07 16:49:00 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TlsConnectTestBase::EnableAlpn() {
|
2016-06-30 09:42:30 +03:00
|
|
|
client_->EnableAlpn(alpn_dummy_val_, sizeof(alpn_dummy_val_));
|
|
|
|
server_->EnableAlpn(alpn_dummy_val_, sizeof(alpn_dummy_val_));
|
|
|
|
}
|
|
|
|
|
2016-08-19 12:20:21 +03:00
|
|
|
void TlsConnectTestBase::EnableAlpn(const uint8_t* val, size_t len) {
|
2016-06-30 09:42:30 +03:00
|
|
|
client_->EnableAlpn(val, len);
|
|
|
|
server_->EnableAlpn(val, len);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TlsConnectTestBase::EnsureModelSockets() {
|
|
|
|
// Make sure models agents are available.
|
|
|
|
if (!client_model_) {
|
|
|
|
ASSERT_EQ(server_model_, nullptr);
|
|
|
|
client_model_ = new TlsAgent(TlsAgent::kClient, TlsAgent::CLIENT, mode_);
|
|
|
|
server_model_ = new TlsAgent(TlsAgent::kServerRsa, TlsAgent::SERVER, mode_);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Initialise agents.
|
|
|
|
ASSERT_TRUE(client_model_->Init());
|
|
|
|
ASSERT_TRUE(server_model_->Init());
|
|
|
|
}
|
|
|
|
|
|
|
|
void TlsConnectTestBase::CheckAlpn(const std::string& val) {
|
|
|
|
client_->CheckAlpn(SSL_NEXT_PROTO_SELECTED, val);
|
|
|
|
server_->CheckAlpn(SSL_NEXT_PROTO_NEGOTIATED, val);
|
2015-03-07 16:49:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void TlsConnectTestBase::EnableSrtp() {
|
|
|
|
client_->EnableSrtp();
|
|
|
|
server_->EnableSrtp();
|
|
|
|
}
|
|
|
|
|
2015-10-23 21:39:23 +03:00
|
|
|
void TlsConnectTestBase::CheckSrtp() const {
|
2015-03-07 16:49:00 +03:00
|
|
|
client_->CheckSrtp();
|
|
|
|
server_->CheckSrtp();
|
|
|
|
}
|
|
|
|
|
2015-10-23 21:39:23 +03:00
|
|
|
void TlsConnectTestBase::SendReceive() {
|
|
|
|
client_->SendData(50);
|
|
|
|
server_->SendData(50);
|
2016-02-08 18:16:25 +03:00
|
|
|
Receive(50);
|
2015-10-23 21:39:23 +03:00
|
|
|
}
|
|
|
|
|
2016-06-30 09:42:30 +03:00
|
|
|
// Do a first connection so we can do 0-RTT on the second one.
|
|
|
|
void TlsConnectTestBase::SetupForZeroRtt() {
|
|
|
|
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
|
|
|
|
client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
|
|
|
|
SSL_LIBRARY_VERSION_TLS_1_3);
|
|
|
|
server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
|
|
|
|
SSL_LIBRARY_VERSION_TLS_1_3);
|
2016-08-19 12:20:21 +03:00
|
|
|
server_->Set0RttEnabled(true); // So we signal that we allow 0-RTT.
|
2016-06-30 09:42:30 +03:00
|
|
|
Connect();
|
2016-08-19 12:20:21 +03:00
|
|
|
SendReceive(); // Need to read so that we absorb the session ticket.
|
2016-06-30 09:42:30 +03:00
|
|
|
CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
|
|
|
|
|
|
|
|
Reset();
|
|
|
|
client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
|
|
|
|
SSL_LIBRARY_VERSION_TLS_1_3);
|
|
|
|
server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
|
|
|
|
SSL_LIBRARY_VERSION_TLS_1_3);
|
|
|
|
server_->StartConnect();
|
|
|
|
client_->StartConnect();
|
|
|
|
}
|
|
|
|
|
2016-09-26 03:47:58 +03:00
|
|
|
// Do a first connection so we can do resumption
|
|
|
|
void TlsConnectTestBase::SetupForResume() {
|
|
|
|
EnsureTlsSetup();
|
|
|
|
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
|
|
|
|
Connect();
|
|
|
|
SendReceive(); // Need to read so that we absorb the session ticket.
|
|
|
|
CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
|
|
|
|
|
|
|
|
Reset();
|
|
|
|
}
|
|
|
|
|
2016-06-30 09:42:30 +03:00
|
|
|
void TlsConnectTestBase::ZeroRttSendReceive(
|
2016-10-05 18:52:14 +03:00
|
|
|
bool expect_writable, bool expect_readable,
|
|
|
|
std::function<bool()> post_clienthello_check) {
|
2016-08-19 12:20:21 +03:00
|
|
|
const char* k0RttData = "ABCDEF";
|
2016-06-30 09:42:30 +03:00
|
|
|
const PRInt32 k0RttDataLen = static_cast<PRInt32>(strlen(k0RttData));
|
|
|
|
|
2016-08-19 12:20:21 +03:00
|
|
|
client_->Handshake(); // Send ClientHello.
|
2016-06-30 09:42:30 +03:00
|
|
|
if (post_clienthello_check) {
|
2016-08-19 12:20:21 +03:00
|
|
|
if (!post_clienthello_check()) return;
|
2016-06-30 09:42:30 +03:00
|
|
|
}
|
2016-08-19 12:20:21 +03:00
|
|
|
PRInt32 rv =
|
|
|
|
PR_Write(client_->ssl_fd(), k0RttData, k0RttDataLen); // 0-RTT write.
|
2016-10-05 18:52:14 +03:00
|
|
|
if (expect_writable) {
|
|
|
|
EXPECT_EQ(k0RttDataLen, rv);
|
|
|
|
} else {
|
|
|
|
EXPECT_EQ(SECFailure, rv);
|
|
|
|
}
|
2016-08-19 12:20:21 +03:00
|
|
|
server_->Handshake(); // Consume ClientHello, EE, Finished.
|
2016-06-30 09:42:30 +03:00
|
|
|
|
|
|
|
std::vector<uint8_t> buf(k0RttDataLen);
|
2016-08-19 12:20:21 +03:00
|
|
|
rv = PR_Read(server_->ssl_fd(), buf.data(), k0RttDataLen); // 0-RTT read
|
2016-06-30 09:42:30 +03:00
|
|
|
if (expect_readable) {
|
|
|
|
std::cerr << "0-RTT read " << rv << " bytes\n";
|
|
|
|
EXPECT_EQ(k0RttDataLen, rv);
|
|
|
|
} else {
|
|
|
|
EXPECT_EQ(SECFailure, rv);
|
|
|
|
EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Do a second read. this should fail.
|
2016-08-19 12:20:21 +03:00
|
|
|
rv = PR_Read(server_->ssl_fd(), buf.data(), k0RttDataLen);
|
2016-06-30 09:42:30 +03:00
|
|
|
EXPECT_EQ(SECFailure, rv);
|
|
|
|
EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError());
|
|
|
|
}
|
|
|
|
|
2016-02-08 18:16:25 +03:00
|
|
|
void TlsConnectTestBase::Receive(size_t amount) {
|
|
|
|
WAIT_(client_->received_bytes() == amount &&
|
2016-08-19 12:20:21 +03:00
|
|
|
server_->received_bytes() == amount,
|
|
|
|
2000);
|
2016-02-08 18:16:25 +03:00
|
|
|
ASSERT_EQ(amount, client_->received_bytes());
|
|
|
|
ASSERT_EQ(amount, server_->received_bytes());
|
|
|
|
}
|
|
|
|
|
2015-10-23 21:39:23 +03:00
|
|
|
void TlsConnectTestBase::ExpectExtendedMasterSecret(bool expected) {
|
2016-02-08 18:16:25 +03:00
|
|
|
expect_extended_master_secret_ = expected;
|
2015-10-23 21:39:23 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void TlsConnectTestBase::CheckExtendedMasterSecret() {
|
|
|
|
client_->CheckExtendedMasterSecret(expect_extended_master_secret_);
|
|
|
|
server_->CheckExtendedMasterSecret(expect_extended_master_secret_);
|
|
|
|
}
|
|
|
|
|
2016-06-30 09:42:30 +03:00
|
|
|
void TlsConnectTestBase::ExpectEarlyDataAccepted(bool expected) {
|
|
|
|
expect_early_data_accepted_ = expected;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TlsConnectTestBase::CheckEarlyDataAccepted() {
|
|
|
|
client_->CheckEarlyDataAccepted(expect_early_data_accepted_);
|
|
|
|
server_->CheckEarlyDataAccepted(expect_early_data_accepted_);
|
|
|
|
}
|
|
|
|
|
2015-03-07 16:49:00 +03:00
|
|
|
TlsConnectGeneric::TlsConnectGeneric()
|
2016-08-19 12:20:21 +03:00
|
|
|
: TlsConnectTestBase(TlsConnectTestBase::ToMode(std::get<0>(GetParam())),
|
|
|
|
std::get<1>(GetParam())) {}
|
2015-03-07 16:49:00 +03:00
|
|
|
|
2015-10-23 21:39:23 +03:00
|
|
|
TlsConnectPre12::TlsConnectPre12()
|
2016-08-19 12:20:21 +03:00
|
|
|
: TlsConnectTestBase(TlsConnectTestBase::ToMode(std::get<0>(GetParam())),
|
|
|
|
std::get<1>(GetParam())) {}
|
2015-10-23 21:39:23 +03:00
|
|
|
|
|
|
|
TlsConnectTls12::TlsConnectTls12()
|
2016-08-19 12:20:21 +03:00
|
|
|
: TlsConnectTestBase(TlsConnectTestBase::ToMode(GetParam()),
|
|
|
|
SSL_LIBRARY_VERSION_TLS_1_2) {}
|
2015-10-23 21:39:23 +03:00
|
|
|
|
2016-06-13 18:31:45 +03:00
|
|
|
TlsConnectTls12Plus::TlsConnectTls12Plus()
|
2016-08-19 12:20:21 +03:00
|
|
|
: TlsConnectTestBase(TlsConnectTestBase::ToMode(std::get<0>(GetParam())),
|
|
|
|
std::get<1>(GetParam())) {}
|
2016-06-13 18:31:45 +03:00
|
|
|
|
|
|
|
TlsConnectTls13::TlsConnectTls13()
|
2016-08-19 12:20:21 +03:00
|
|
|
: TlsConnectTestBase(TlsConnectTestBase::ToMode(GetParam()),
|
|
|
|
SSL_LIBRARY_VERSION_TLS_1_3) {}
|
2016-06-13 18:31:45 +03:00
|
|
|
|
2016-09-26 03:47:58 +03:00
|
|
|
void TlsKeyExchangeTest::EnsureKeyShareSetup() {
|
|
|
|
EnsureTlsSetup();
|
|
|
|
groups_capture_ = new TlsExtensionCapture(ssl_supported_groups_xtn);
|
|
|
|
shares_capture_ = new TlsExtensionCapture(ssl_tls13_key_share_xtn);
|
|
|
|
std::vector<PacketFilter*> captures;
|
|
|
|
captures.push_back(groups_capture_);
|
|
|
|
captures.push_back(shares_capture_);
|
|
|
|
client_->SetPacketFilter(new ChainedPacketFilter(captures));
|
|
|
|
capture_hrr_ =
|
|
|
|
new TlsInspectorRecordHandshakeMessage(kTlsHandshakeHelloRetryRequest);
|
|
|
|
server_->SetPacketFilter(capture_hrr_);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TlsKeyExchangeTest::ConfigNamedGroups(
|
|
|
|
const std::vector<SSLNamedGroup>& groups) {
|
|
|
|
client_->ConfigNamedGroups(groups);
|
|
|
|
server_->ConfigNamedGroups(groups);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<SSLNamedGroup> TlsKeyExchangeTest::GetGroupDetails(
|
|
|
|
const DataBuffer& ext) {
|
|
|
|
uint32_t tmp = 0;
|
|
|
|
EXPECT_TRUE(ext.Read(0, 2, &tmp));
|
|
|
|
EXPECT_EQ(ext.len() - 2, static_cast<size_t>(tmp));
|
|
|
|
EXPECT_TRUE(ext.len() % 2 == 0);
|
|
|
|
std::vector<SSLNamedGroup> groups;
|
|
|
|
for (size_t i = 1; i < ext.len() / 2; i += 1) {
|
|
|
|
EXPECT_TRUE(ext.Read(2 * i, 2, &tmp));
|
|
|
|
groups.push_back(static_cast<SSLNamedGroup>(tmp));
|
|
|
|
}
|
|
|
|
return groups;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<SSLNamedGroup> TlsKeyExchangeTest::GetShareDetails(
|
|
|
|
const DataBuffer& ext) {
|
|
|
|
uint32_t tmp = 0;
|
|
|
|
EXPECT_TRUE(ext.Read(0, 2, &tmp));
|
|
|
|
EXPECT_EQ(ext.len() - 2, static_cast<size_t>(tmp));
|
|
|
|
std::vector<SSLNamedGroup> shares;
|
|
|
|
size_t i = 2;
|
|
|
|
while (i < ext.len()) {
|
|
|
|
EXPECT_TRUE(ext.Read(i, 2, &tmp));
|
|
|
|
shares.push_back(static_cast<SSLNamedGroup>(tmp));
|
|
|
|
EXPECT_TRUE(ext.Read(i + 2, 2, &tmp));
|
|
|
|
i += 4 + tmp;
|
|
|
|
}
|
|
|
|
EXPECT_EQ(ext.len(), i);
|
|
|
|
return shares;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TlsKeyExchangeTest::CheckKEXDetails(
|
|
|
|
const std::vector<SSLNamedGroup>& expected_groups,
|
|
|
|
const std::vector<SSLNamedGroup>& expected_shares, bool expect_hrr) {
|
|
|
|
std::vector<SSLNamedGroup> groups =
|
|
|
|
GetGroupDetails(groups_capture_->extension());
|
|
|
|
EXPECT_EQ(expected_groups, groups);
|
|
|
|
|
|
|
|
if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
|
|
|
|
ASSERT_LT(0U, expected_shares.size());
|
|
|
|
std::vector<SSLNamedGroup> shares =
|
|
|
|
GetShareDetails(shares_capture_->extension());
|
|
|
|
EXPECT_EQ(expected_shares, shares);
|
|
|
|
} else {
|
|
|
|
EXPECT_EQ(0U, shares_capture_->extension().len());
|
|
|
|
}
|
|
|
|
|
|
|
|
EXPECT_EQ(expect_hrr, capture_hrr_->buffer().len() != 0);
|
|
|
|
}
|
|
|
|
|
2016-08-19 12:20:21 +03:00
|
|
|
} // namespace nss_test
|