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>
|
2017-08-04 15:13:06 +03:00
|
|
|
#include <vector>
|
2016-08-19 12:20:21 +03:00
|
|
|
#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"
|
2018-10-01 17:44:32 +03:00
|
|
|
#include "nss_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
|
|
|
}
|
|
|
|
|
2017-03-24 10:38:05 +03:00
|
|
|
TEST_P(TlsConnectGeneric, CipherSuiteMismatch) {
|
2016-10-05 18:52:14 +03:00
|
|
|
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);
|
|
|
|
}
|
2017-03-24 10:38:05 +03:00
|
|
|
ConnectExpectAlert(server_, kTlsAlertHandshakeFailure);
|
2016-10-05 18:52:14 +03:00
|
|
|
client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
|
|
|
|
server_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
|
|
|
|
}
|
|
|
|
|
2017-03-24 10:38:05 +03:00
|
|
|
class TlsAlertRecorder : public TlsRecordFilter {
|
|
|
|
public:
|
2018-03-15 19:00:48 +03:00
|
|
|
TlsAlertRecorder(const std::shared_ptr<TlsAgent>& a)
|
|
|
|
: TlsRecordFilter(a), level_(255), description_(255) {}
|
2017-03-24 10:38:05 +03:00
|
|
|
|
|
|
|
PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
|
|
|
|
const DataBuffer& input,
|
|
|
|
DataBuffer* output) override {
|
|
|
|
if (level_ != 255) { // Already captured.
|
|
|
|
return KEEP;
|
|
|
|
}
|
2018-07-06 16:56:42 +03:00
|
|
|
if (header.content_type() != ssl_ct_alert) {
|
2017-03-24 10:38:05 +03:00
|
|
|
return KEEP;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::cerr << "Alert: " << input << std::endl;
|
|
|
|
|
|
|
|
TlsParser parser(input);
|
|
|
|
EXPECT_TRUE(parser.Read(&level_));
|
|
|
|
EXPECT_TRUE(parser.Read(&description_));
|
|
|
|
return KEEP;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t level() const { return level_; }
|
|
|
|
uint8_t description() const { return description_; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
uint8_t level_;
|
|
|
|
uint8_t description_;
|
|
|
|
};
|
|
|
|
|
|
|
|
class HelloTruncator : public TlsHandshakeFilter {
|
2017-11-24 11:00:26 +03:00
|
|
|
public:
|
2018-03-15 19:00:48 +03:00
|
|
|
HelloTruncator(const std::shared_ptr<TlsAgent>& a)
|
2017-11-24 11:00:26 +03:00
|
|
|
: TlsHandshakeFilter(
|
2018-03-15 19:00:48 +03:00
|
|
|
a, {kTlsHandshakeClientHello, kTlsHandshakeServerHello}) {}
|
2017-03-24 10:38:05 +03:00
|
|
|
PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
|
|
|
|
const DataBuffer& input,
|
|
|
|
DataBuffer* output) override {
|
|
|
|
output->Assign(input.data(), input.len() - 1);
|
|
|
|
return CHANGE;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Verify that when NSS reports that an alert is sent, it is actually sent.
|
|
|
|
TEST_P(TlsConnectGeneric, CaptureAlertServer) {
|
2018-02-28 13:13:28 +03:00
|
|
|
MakeTlsFilter<HelloTruncator>(client_);
|
|
|
|
auto alert_recorder = MakeTlsFilter<TlsAlertRecorder>(server_);
|
2017-03-24 10:38:05 +03:00
|
|
|
|
2017-11-07 04:24:58 +03:00
|
|
|
ConnectExpectAlert(server_, kTlsAlertDecodeError);
|
2017-03-24 10:38:05 +03:00
|
|
|
EXPECT_EQ(kTlsAlertFatal, alert_recorder->level());
|
2017-11-07 04:24:58 +03:00
|
|
|
EXPECT_EQ(kTlsAlertDecodeError, alert_recorder->description());
|
2017-03-24 10:38:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(TlsConnectGenericPre13, CaptureAlertClient) {
|
2018-02-28 13:13:28 +03:00
|
|
|
MakeTlsFilter<HelloTruncator>(server_);
|
|
|
|
auto alert_recorder = MakeTlsFilter<TlsAlertRecorder>(client_);
|
2017-03-24 10:38:05 +03:00
|
|
|
|
|
|
|
ConnectExpectAlert(client_, kTlsAlertDecodeError);
|
|
|
|
EXPECT_EQ(kTlsAlertFatal, alert_recorder->level());
|
|
|
|
EXPECT_EQ(kTlsAlertDecodeError, alert_recorder->description());
|
|
|
|
}
|
|
|
|
|
|
|
|
// In TLS 1.3, the server can't read the client alert.
|
|
|
|
TEST_P(TlsConnectTls13, CaptureAlertClient) {
|
2018-02-28 13:13:28 +03:00
|
|
|
MakeTlsFilter<HelloTruncator>(server_);
|
|
|
|
auto alert_recorder = MakeTlsFilter<TlsAlertRecorder>(client_);
|
2017-03-24 10:38:05 +03:00
|
|
|
|
2017-11-24 11:00:26 +03:00
|
|
|
StartConnect();
|
2017-03-24 10:38:05 +03:00
|
|
|
|
|
|
|
client_->Handshake();
|
|
|
|
client_->ExpectSendAlert(kTlsAlertDecodeError);
|
|
|
|
server_->Handshake();
|
|
|
|
client_->Handshake();
|
2017-05-16 18:12:24 +03:00
|
|
|
if (variant_ == ssl_variant_stream) {
|
2017-03-24 10:38:05 +03:00
|
|
|
// DTLS just drops the alert it can't decrypt.
|
|
|
|
server_->ExpectSendAlert(kTlsAlertBadRecordMac);
|
|
|
|
}
|
|
|
|
server_->Handshake();
|
|
|
|
EXPECT_EQ(kTlsAlertFatal, alert_recorder->level());
|
|
|
|
EXPECT_EQ(kTlsAlertDecodeError, alert_recorder->description());
|
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2018-04-16 11:09:12 +03:00
|
|
|
TEST_P(TlsConnectGeneric, ConnectAlpnPriorityA) {
|
|
|
|
// "alpn" "npn"
|
|
|
|
// alpn is the fallback here. npn has the highest priority and should be
|
|
|
|
// picked.
|
|
|
|
const std::vector<uint8_t> alpn = {0x04, 0x61, 0x6c, 0x70, 0x6e,
|
|
|
|
0x03, 0x6e, 0x70, 0x6e};
|
|
|
|
EnableAlpn(alpn);
|
|
|
|
Connect();
|
|
|
|
CheckAlpn("npn");
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(TlsConnectGeneric, ConnectAlpnPriorityB) {
|
|
|
|
// "alpn" "npn" "http"
|
|
|
|
// npn has the highest priority and should be picked.
|
|
|
|
const std::vector<uint8_t> alpn = {0x04, 0x61, 0x6c, 0x70, 0x6e, 0x03, 0x6e,
|
|
|
|
0x70, 0x6e, 0x04, 0x68, 0x74, 0x74, 0x70};
|
|
|
|
EnableAlpn(alpn);
|
|
|
|
Connect();
|
|
|
|
CheckAlpn("npn");
|
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2018-04-16 11:09:12 +03:00
|
|
|
TEST_P(TlsConnectGeneric, ConnectAlpnWithCustomCallbackA) {
|
|
|
|
// "ab" "alpn"
|
|
|
|
const std::vector<uint8_t> client_alpn = {0x02, 0x61, 0x62, 0x04,
|
|
|
|
0x61, 0x6c, 0x70, 0x6e};
|
|
|
|
EnableAlpnWithCallback(client_alpn, "alpn");
|
|
|
|
Connect();
|
|
|
|
CheckAlpn("alpn");
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(TlsConnectGeneric, ConnectAlpnWithCustomCallbackB) {
|
|
|
|
// "ab" "alpn"
|
|
|
|
const std::vector<uint8_t> client_alpn = {0x02, 0x61, 0x62, 0x04,
|
|
|
|
0x61, 0x6c, 0x70, 0x6e};
|
|
|
|
EnableAlpnWithCallback(client_alpn, "ab");
|
|
|
|
Connect();
|
|
|
|
CheckAlpn("ab");
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(TlsConnectGeneric, ConnectAlpnWithCustomCallbackC) {
|
|
|
|
// "cd" "npn" "alpn"
|
|
|
|
const std::vector<uint8_t> client_alpn = {0x02, 0x63, 0x64, 0x03, 0x6e, 0x70,
|
|
|
|
0x6e, 0x04, 0x61, 0x6c, 0x70, 0x6e};
|
|
|
|
EnableAlpnWithCallback(client_alpn, "npn");
|
|
|
|
Connect();
|
|
|
|
CheckAlpn("npn");
|
|
|
|
}
|
|
|
|
|
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
|
|
|
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
|
|
|
|
2017-11-24 11:00:26 +03:00
|
|
|
class SaveTlsRecord : public TlsRecordFilter {
|
|
|
|
public:
|
2018-03-15 19:00:48 +03:00
|
|
|
SaveTlsRecord(const std::shared_ptr<TlsAgent>& a, size_t index)
|
|
|
|
: TlsRecordFilter(a), index_(index), count_(0), contents_() {}
|
2017-11-24 11:00:26 +03:00
|
|
|
|
|
|
|
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
|
2018-02-28 13:13:28 +03:00
|
|
|
auto saved = MakeTlsFilter<SaveTlsRecord>(client_, 3);
|
|
|
|
saved->EnableDecryption();
|
2017-11-24 11:00:26 +03:00
|
|
|
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
|
2018-02-28 13:13:28 +03:00
|
|
|
auto saved = MakeTlsFilter<SaveTlsRecord>(server_, 3);
|
|
|
|
saved->EnableDecryption();
|
2017-11-24 11:00:26 +03:00
|
|
|
Connect();
|
|
|
|
SendReceive();
|
|
|
|
|
|
|
|
static const uint8_t data[] = {0xde, 0xad, 0xd5};
|
|
|
|
DataBuffer buf(data, sizeof(data));
|
|
|
|
server_->SendBuffer(buf);
|
|
|
|
EXPECT_EQ(buf, saved->contents());
|
|
|
|
}
|
|
|
|
|
|
|
|
class DropTlsRecord : public TlsRecordFilter {
|
|
|
|
public:
|
2018-03-15 19:00:48 +03:00
|
|
|
DropTlsRecord(const std::shared_ptr<TlsAgent>& a, size_t index)
|
|
|
|
: TlsRecordFilter(a), index_(index), count_(0) {}
|
2017-11-24 11:00:26 +03:00
|
|
|
|
|
|
|
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
|
2018-02-28 13:13:28 +03:00
|
|
|
auto filter = MakeTlsFilter<DropTlsRecord>(server_, 2);
|
|
|
|
filter->EnableDecryption();
|
2017-11-24 11:00:26 +03:00
|
|
|
Connect();
|
|
|
|
server_->SendData(23, 23); // This should be dropped, so it won't be counted.
|
|
|
|
server_->ResetSentBytes();
|
|
|
|
SendReceive();
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(TlsConnectStreamTls13, DropRecordClient) {
|
|
|
|
EnsureTlsSetup();
|
|
|
|
// 0 = ClientHello, 1 = Finished, 2 = first write
|
2018-02-28 13:13:28 +03:00
|
|
|
auto filter = MakeTlsFilter<DropTlsRecord>(client_, 2);
|
|
|
|
filter->EnableDecryption();
|
2017-11-24 11:00:26 +03:00
|
|
|
Connect();
|
|
|
|
client_->SendData(26, 26); // This should be dropped, so it won't be counted.
|
|
|
|
client_->ResetSentBytes();
|
|
|
|
SendReceive();
|
|
|
|
}
|
|
|
|
|
2018-09-28 19:17:37 +03:00
|
|
|
// Check that a server can use 0.5 RTT if client authentication isn't enabled.
|
|
|
|
TEST_P(TlsConnectTls13, WriteBeforeClientFinished) {
|
|
|
|
EnsureTlsSetup();
|
|
|
|
StartConnect();
|
|
|
|
client_->Handshake(); // ClientHello
|
|
|
|
server_->Handshake(); // ServerHello
|
|
|
|
|
|
|
|
server_->SendData(10);
|
|
|
|
client_->ReadBytes(10); // Client should emit the Finished as a side-effect.
|
|
|
|
server_->Handshake(); // Server consumes the Finished.
|
|
|
|
CheckConnected();
|
|
|
|
}
|
|
|
|
|
|
|
|
// We don't allow 0.5 RTT if client authentication is requested.
|
|
|
|
TEST_P(TlsConnectTls13, WriteBeforeClientFinishedClientAuth) {
|
|
|
|
client_->SetupClientAuth();
|
|
|
|
server_->RequestClientAuth(false);
|
|
|
|
StartConnect();
|
|
|
|
client_->Handshake(); // ClientHello
|
|
|
|
server_->Handshake(); // ServerHello
|
|
|
|
|
|
|
|
static const uint8_t data[] = {1, 2, 3};
|
|
|
|
EXPECT_GT(0, PR_Write(server_->ssl_fd(), data, sizeof(data)));
|
|
|
|
EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError());
|
|
|
|
|
|
|
|
Handshake();
|
|
|
|
CheckConnected();
|
|
|
|
SendReceive();
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0.5 RTT should fail with client authentication required.
|
|
|
|
TEST_P(TlsConnectTls13, WriteBeforeClientFinishedClientAuthRequired) {
|
|
|
|
client_->SetupClientAuth();
|
|
|
|
server_->RequestClientAuth(true);
|
|
|
|
StartConnect();
|
|
|
|
client_->Handshake(); // ClientHello
|
|
|
|
server_->Handshake(); // ServerHello
|
|
|
|
|
|
|
|
static const uint8_t data[] = {1, 2, 3};
|
|
|
|
EXPECT_GT(0, PR_Write(server_->ssl_fd(), data, sizeof(data)));
|
|
|
|
EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError());
|
|
|
|
|
|
|
|
Handshake();
|
|
|
|
CheckConnected();
|
|
|
|
SendReceive();
|
|
|
|
}
|
|
|
|
|
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();
|
2017-06-13 15:26:51 +03:00
|
|
|
server_->SendData(50, 50);
|
|
|
|
client_->ReadBytes(20);
|
|
|
|
EXPECT_EQ(0U, client_->received_bytes());
|
|
|
|
EXPECT_EQ(SSL_ERROR_RX_SHORT_DTLS_READ, PORT_GetError());
|
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();
|
2017-06-13 15:26:51 +03:00
|
|
|
server_->SendData(50, 50);
|
2016-07-20 10:39:08 +03:00
|
|
|
// Read the first tranche.
|
2017-06-13 15:26:51 +03:00
|
|
|
client_->ReadBytes(20);
|
|
|
|
ASSERT_EQ(20U, client_->received_bytes());
|
2016-07-20 10:39:08 +03:00
|
|
|
// The second tranche should now immediately be available.
|
|
|
|
client_->ReadBytes();
|
2017-06-13 15:26:51 +03:00
|
|
|
ASSERT_EQ(50U, client_->received_bytes());
|
2016-06-02 23:33:04 +03:00
|
|
|
}
|
|
|
|
|
2017-09-05 13:52:00 +03:00
|
|
|
// We enable compression via the API but it's disabled internally,
|
|
|
|
// so we should never get it.
|
|
|
|
TEST_P(TlsConnectGeneric, ConnectWithCompressionEnabled) {
|
2016-07-20 10:39:08 +03:00
|
|
|
EnsureTlsSetup();
|
2017-09-12 15:46:59 +03:00
|
|
|
client_->SetOption(SSL_ENABLE_DEFLATE, PR_TRUE);
|
|
|
|
server_->SetOption(SSL_ENABLE_DEFLATE, PR_TRUE);
|
2016-06-02 23:33:04 +03:00
|
|
|
Connect();
|
2017-09-05 13:52:00 +03:00
|
|
|
EXPECT_FALSE(client_->is_compressed());
|
2016-07-20 10:39:08 +03:00
|
|
|
SendReceive();
|
2016-04-12 15:40:44 +03:00
|
|
|
}
|
|
|
|
|
2017-11-24 11:00:26 +03:00
|
|
|
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) {
|
2016-04-12 15:40:44 +03:00
|
|
|
Connect();
|
2017-11-24 11:00:26 +03:00
|
|
|
std::cerr << "Expiring holddown timer" << std::endl;
|
|
|
|
RunAllTimersDown();
|
2016-04-12 15:40:44 +03:00
|
|
|
SendReceive();
|
|
|
|
if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
|
2016-06-30 09:42:30 +03:00
|
|
|
// One for send, one for receive.
|
2017-11-24 11:00:26 +03:00
|
|
|
EXPECT_EQ(2, SSLInt_CountCipherSpecs(client_->ssl_fd()));
|
2016-04-12 15:40:44 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-24 11:00:26 +03:00
|
|
|
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()));
|
|
|
|
}
|
|
|
|
|
2016-08-19 12:20:21 +03:00
|
|
|
class TlsPreCCSHeaderInjector : public TlsRecordFilter {
|
|
|
|
public:
|
2018-03-15 19:00:48 +03:00
|
|
|
TlsPreCCSHeaderInjector(const std::shared_ptr<TlsAgent>& a)
|
|
|
|
: TlsRecordFilter(a) {}
|
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 {
|
2018-07-06 16:56:42 +03:00
|
|
|
if (record_header.content_type() != ssl_ct_change_cipher_spec) {
|
|
|
|
return KEEP;
|
|
|
|
}
|
2016-08-19 12:20:21 +03:00
|
|
|
|
|
|
|
std::cerr << "Injecting Finished header before CCS\n";
|
|
|
|
const uint8_t hhdr[] = {kTlsHandshakeFinished, 0x00, 0x00, 0x0c};
|
|
|
|
DataBuffer hhdr_buf(hhdr, sizeof(hhdr));
|
2018-03-20 20:17:35 +03:00
|
|
|
TlsRecordHeader nhdr(record_header.variant(), record_header.version(),
|
2018-07-06 16:56:42 +03:00
|
|
|
ssl_ct_handshake, 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) {
|
2018-02-28 13:13:28 +03:00
|
|
|
MakeTlsFilter<TlsPreCCSHeaderInjector>(client_);
|
2017-03-24 10:38:05 +03:00
|
|
|
ConnectExpectAlert(server_, kTlsAlertUnexpectedMessage);
|
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) {
|
2018-02-28 13:13:28 +03:00
|
|
|
MakeTlsFilter<TlsPreCCSHeaderInjector>(server_);
|
2017-11-24 11:00:26 +03:00
|
|
|
StartConnect();
|
2017-03-24 10:38:05 +03:00
|
|
|
ExpectAlert(client_, kTlsAlertUnexpectedMessage);
|
2016-08-19 12:20:21 +03:00
|
|
|
Handshake();
|
|
|
|
EXPECT_EQ(TlsAgent::STATE_ERROR, client_->state());
|
|
|
|
client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER);
|
|
|
|
EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state());
|
2017-03-24 10:38:05 +03:00
|
|
|
server_->Handshake(); // Make sure alert is consumed.
|
2016-08-19 12:20:21 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(TlsConnectTls13, UnknownAlert) {
|
|
|
|
Connect();
|
2017-03-24 10:38:05 +03:00
|
|
|
server_->ExpectSendAlert(0xff, kTlsAlertWarning);
|
|
|
|
client_->ExpectReceiveAlert(0xff, kTlsAlertWarning);
|
2016-08-19 12:20:21 +03:00
|
|
|
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();
|
2017-03-24 10:38:05 +03:00
|
|
|
server_->ExpectSendAlert(kTlsAlertUnexpectedMessage, kTlsAlertWarning);
|
|
|
|
client_->ExpectReceiveAlert(kTlsAlertUnexpectedMessage, kTlsAlertWarning);
|
2016-08-19 12:20:21 +03:00
|
|
|
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-12-10 01:04:28 +03:00
|
|
|
TEST_F(TlsConnectStreamTls13, Tls13FailedWriteSecondFlight) {
|
|
|
|
EnsureTlsSetup();
|
2017-11-24 11:00:26 +03:00
|
|
|
StartConnect();
|
2016-12-10 01:04:28 +03:00
|
|
|
client_->Handshake();
|
|
|
|
server_->Handshake(); // Send first flight.
|
2017-11-24 11:00:26 +03:00
|
|
|
client_->adapter()->SetWriteError(PR_IO_ERROR);
|
2016-12-10 01:04:28 +03:00
|
|
|
client_->Handshake(); // This will get an error, but shouldn't crash.
|
|
|
|
client_->CheckErrorCode(SSL_ERROR_SOCKET_WRITE_FAILURE);
|
|
|
|
}
|
|
|
|
|
2017-11-24 11:00:26 +03:00
|
|
|
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();
|
2016-12-23 08:00:57 +03:00
|
|
|
Connect();
|
2017-11-24 11:00:26 +03:00
|
|
|
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);
|
2018-02-28 13:13:28 +03:00
|
|
|
auto records = MakeTlsFilter<TlsRecordRecorder>(server_);
|
2017-11-24 11:00:26 +03:00
|
|
|
// 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());
|
2016-12-23 08:00:57 +03:00
|
|
|
}
|
|
|
|
|
2018-09-05 18:20:33 +03:00
|
|
|
// We can't test for randomness easily here, but we can test that we don't
|
|
|
|
// produce a zero value, or produce the same value twice. There are 5 values
|
|
|
|
// here: two ClientHello.random, two ServerHello.random, and one zero value.
|
|
|
|
// Matrix them and fail if any are the same.
|
|
|
|
TEST_P(TlsConnectGeneric, CheckRandoms) {
|
|
|
|
ConfigureSessionCache(RESUME_NONE, RESUME_NONE);
|
|
|
|
|
|
|
|
static const size_t random_len = 32;
|
|
|
|
uint8_t crandom1[random_len], srandom1[random_len];
|
|
|
|
uint8_t z[random_len] = {0};
|
|
|
|
|
|
|
|
auto ch = MakeTlsFilter<TlsHandshakeRecorder>(client_, ssl_hs_client_hello);
|
|
|
|
auto sh = MakeTlsFilter<TlsHandshakeRecorder>(server_, ssl_hs_server_hello);
|
|
|
|
Connect();
|
|
|
|
ASSERT_TRUE(ch->buffer().len() > (random_len + 2));
|
|
|
|
ASSERT_TRUE(sh->buffer().len() > (random_len + 2));
|
|
|
|
memcpy(crandom1, ch->buffer().data() + 2, random_len);
|
|
|
|
memcpy(srandom1, sh->buffer().data() + 2, random_len);
|
|
|
|
EXPECT_NE(0, memcmp(crandom1, srandom1, random_len));
|
|
|
|
EXPECT_NE(0, memcmp(crandom1, z, random_len));
|
|
|
|
EXPECT_NE(0, memcmp(srandom1, z, random_len));
|
|
|
|
|
|
|
|
Reset();
|
|
|
|
ch = MakeTlsFilter<TlsHandshakeRecorder>(client_, ssl_hs_client_hello);
|
|
|
|
sh = MakeTlsFilter<TlsHandshakeRecorder>(server_, ssl_hs_server_hello);
|
|
|
|
Connect();
|
|
|
|
ASSERT_TRUE(ch->buffer().len() > (random_len + 2));
|
|
|
|
ASSERT_TRUE(sh->buffer().len() > (random_len + 2));
|
|
|
|
const uint8_t* crandom2 = ch->buffer().data() + 2;
|
|
|
|
const uint8_t* srandom2 = sh->buffer().data() + 2;
|
|
|
|
|
|
|
|
EXPECT_NE(0, memcmp(crandom2, srandom2, random_len));
|
|
|
|
EXPECT_NE(0, memcmp(crandom2, z, random_len));
|
|
|
|
EXPECT_NE(0, memcmp(srandom2, z, random_len));
|
|
|
|
|
|
|
|
EXPECT_NE(0, memcmp(crandom1, crandom2, random_len));
|
|
|
|
EXPECT_NE(0, memcmp(crandom1, srandom2, random_len));
|
|
|
|
EXPECT_NE(0, memcmp(srandom1, crandom2, random_len));
|
|
|
|
EXPECT_NE(0, memcmp(srandom1, srandom2, random_len));
|
|
|
|
}
|
|
|
|
|
2017-05-16 18:12:24 +03:00
|
|
|
INSTANTIATE_TEST_CASE_P(
|
|
|
|
GenericStream, TlsConnectGeneric,
|
|
|
|
::testing::Combine(TlsConnectTestBase::kTlsVariantsStream,
|
|
|
|
TlsConnectTestBase::kTlsVAll));
|
2016-08-19 12:20:21 +03:00
|
|
|
INSTANTIATE_TEST_CASE_P(
|
|
|
|
GenericDatagram, TlsConnectGeneric,
|
2017-05-16 18:12:24 +03:00
|
|
|
::testing::Combine(TlsConnectTestBase::kTlsVariantsDatagram,
|
2016-08-19 12:20:21 +03:00
|
|
|
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);
|
2017-11-24 11:00:26 +03:00
|
|
|
INSTANTIATE_TEST_CASE_P(DatagramHolddown, TlsHolddownTest,
|
|
|
|
TlsConnectTestBase::kTlsV11Plus);
|
2016-04-12 15:40:44 +03:00
|
|
|
|
2017-05-16 18:12:24 +03:00
|
|
|
INSTANTIATE_TEST_CASE_P(
|
|
|
|
Pre12Stream, TlsConnectPre12,
|
|
|
|
::testing::Combine(TlsConnectTestBase::kTlsVariantsStream,
|
|
|
|
TlsConnectTestBase::kTlsV10V11));
|
2016-08-19 12:20:21 +03:00
|
|
|
INSTANTIATE_TEST_CASE_P(
|
|
|
|
Pre12Datagram, TlsConnectPre12,
|
2017-05-16 18:12:24 +03:00
|
|
|
::testing::Combine(TlsConnectTestBase::kTlsVariantsDatagram,
|
2016-08-19 12:20:21 +03:00
|
|
|
TlsConnectTestBase::kTlsV11));
|
2016-04-12 15:40:44 +03:00
|
|
|
|
|
|
|
INSTANTIATE_TEST_CASE_P(Version12Only, TlsConnectTls12,
|
2017-05-16 18:12:24 +03:00
|
|
|
TlsConnectTestBase::kTlsVariantsAll);
|
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,
|
2017-05-16 18:12:24 +03:00
|
|
|
TlsConnectTestBase::kTlsVariantsAll);
|
2016-06-13 18:31:45 +03:00
|
|
|
#endif
|
2016-04-12 15:40:44 +03:00
|
|
|
|
2017-05-16 18:12:24 +03:00
|
|
|
INSTANTIATE_TEST_CASE_P(
|
|
|
|
Pre13Stream, TlsConnectGenericPre13,
|
|
|
|
::testing::Combine(TlsConnectTestBase::kTlsVariantsStream,
|
|
|
|
TlsConnectTestBase::kTlsV10ToV12));
|
2016-08-19 12:20:21 +03:00
|
|
|
INSTANTIATE_TEST_CASE_P(
|
|
|
|
Pre13Datagram, TlsConnectGenericPre13,
|
2017-05-16 18:12:24 +03:00
|
|
|
::testing::Combine(TlsConnectTestBase::kTlsVariantsDatagram,
|
2016-08-19 12:20:21 +03:00
|
|
|
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,
|
2017-05-16 18:12:24 +03:00
|
|
|
::testing::Combine(TlsConnectTestBase::kTlsVariantsAll,
|
2016-08-19 12:20:21 +03:00
|
|
|
TlsConnectTestBase::kTlsV12Plus));
|
2016-06-13 18:31:45 +03:00
|
|
|
|
2018-01-23 13:48:27 +03:00
|
|
|
INSTANTIATE_TEST_CASE_P(
|
|
|
|
GenericStream, TlsConnectGenericResumption,
|
|
|
|
::testing::Combine(TlsConnectTestBase::kTlsVariantsStream,
|
|
|
|
TlsConnectTestBase::kTlsVAll,
|
|
|
|
::testing::Values(true, false)));
|
|
|
|
INSTANTIATE_TEST_CASE_P(
|
|
|
|
GenericDatagram, TlsConnectGenericResumption,
|
|
|
|
::testing::Combine(TlsConnectTestBase::kTlsVariantsDatagram,
|
|
|
|
TlsConnectTestBase::kTlsV11Plus,
|
|
|
|
::testing::Values(true, false)));
|
|
|
|
|
|
|
|
INSTANTIATE_TEST_CASE_P(
|
|
|
|
GenericStream, TlsConnectGenericResumptionToken,
|
|
|
|
::testing::Combine(TlsConnectTestBase::kTlsVariantsStream,
|
|
|
|
TlsConnectTestBase::kTlsVAll));
|
|
|
|
INSTANTIATE_TEST_CASE_P(
|
|
|
|
GenericDatagram, TlsConnectGenericResumptionToken,
|
|
|
|
::testing::Combine(TlsConnectTestBase::kTlsVariantsDatagram,
|
|
|
|
TlsConnectTestBase::kTlsV11Plus));
|
|
|
|
|
|
|
|
INSTANTIATE_TEST_CASE_P(GenericDatagram, TlsConnectTls13ResumptionToken,
|
|
|
|
TlsConnectTestBase::kTlsVariantsAll);
|
|
|
|
|
|
|
|
} // namespace nss_test
|