Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Bug 1446643 - Update to TLS 1.3 draft-26. r=mt
- Update version number

- Forbid negotiating < TLS 1.3 with supported_versions

- Change to version number 0303 after HRR. Plus test

- Update AAD.

https://phabricator.services.mozilla.com/D753
  • Loading branch information
ekr committed Mar 17, 2018
1 parent 55471f8 commit 59e04c7
Show file tree
Hide file tree
Showing 16 changed files with 300 additions and 120 deletions.
15 changes: 15 additions & 0 deletions cpputil/tls_parser.cc
Expand Up @@ -46,6 +46,21 @@ bool TlsParser::Read(DataBuffer* val, size_t len) {
return true;
}

bool TlsParser::ReadFromMark(DataBuffer* val, size_t len, size_t mark) {
auto saved = offset_;
offset_ = mark;

if (remaining() < len) {
offset_ = saved;
return false;
}

val->Assign(ptr(), len);

offset_ = saved;
return true;
}

bool TlsParser::ReadVariable(DataBuffer* val, size_t len_size) {
uint32_t len;
if (!Read(&len, len_size)) {
Expand Down
1 change: 1 addition & 0 deletions cpputil/tls_parser.h
Expand Up @@ -123,6 +123,7 @@ class TlsParser {
bool Read(uint32_t* val, size_t size);
// Reads len bytes into dest buffer, overwriting it.
bool Read(DataBuffer* dest, size_t len);
bool ReadFromMark(DataBuffer* val, size_t len, size_t mark);
// Reads bytes into dest buffer, overwriting it. The number of bytes is
// determined by reading from len_size bytes from the stream first.
bool ReadVariable(DataBuffer* dest, size_t len_size);
Expand Down
49 changes: 20 additions & 29 deletions gtests/ssl_gtest/ssl_agent_unittest.cc
Expand Up @@ -8,9 +8,6 @@
#include "sslerr.h"
#include "sslproto.h"

// This is an internal header, used to get TLS_1_3_DRAFT_VERSION.
#include "ssl3prot.h"

#include <memory>

#include "databuffer.h"
Expand All @@ -21,7 +18,6 @@

namespace nss_test {

static const uint8_t kD13 = TLS_1_3_DRAFT_VERSION;
// This is a 1-RTT ClientHello with ECDHE.
const static uint8_t kCannedTls13ClientHello[] = {
0x01, 0x00, 0x00, 0xcf, 0x03, 0x03, 0x6c, 0xb3, 0x46, 0x81, 0xc8, 0x1a,
Expand All @@ -42,16 +38,7 @@ const static uint8_t kCannedTls13ClientHello[] = {
0x1e, 0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x02, 0x03, 0x08, 0x04, 0x08,
0x05, 0x08, 0x06, 0x04, 0x01, 0x05, 0x01, 0x06, 0x01, 0x02, 0x01, 0x04,
0x02, 0x05, 0x02, 0x06, 0x02, 0x02, 0x02};

const static uint8_t kCannedTls13ServerHello[] = {
0x03, 0x03, 0x9c, 0xbc, 0x14, 0x9b, 0x0e, 0x2e, 0xfa, 0x0d, 0xf3,
0xf0, 0x5c, 0x70, 0x7a, 0xe0, 0xd1, 0x9b, 0x3e, 0x5a, 0x44, 0x6b,
0xdf, 0xe5, 0xc2, 0x28, 0x64, 0xf7, 0x00, 0xc1, 0x9c, 0x08, 0x76,
0x08, 0x00, 0x13, 0x01, 0x00, 0x00, 0x2e, 0x00, 0x33, 0x00, 0x24,
0x00, 0x1d, 0x00, 0x20, 0xc2, 0xcf, 0x23, 0x17, 0x64, 0x23, 0x03,
0xf0, 0xfb, 0x45, 0x98, 0x26, 0xd1, 0x65, 0x24, 0xa1, 0x6c, 0xa9,
0x80, 0x8f, 0x2c, 0xac, 0x0a, 0xea, 0x53, 0x3a, 0xcb, 0xe3, 0x08,
0x84, 0xae, 0x19, 0x00, 0x2b, 0x00, 0x02, 0x7f, kD13};
static const size_t kFirstFragmentSize = 20;
static const char *k0RttData = "ABCDEF";

TEST_P(TlsAgentTest, EarlyFinished) {
Expand All @@ -74,17 +61,19 @@ TEST_P(TlsAgentTestClient13, CannedHello) {
DataBuffer buffer;
EnsureInit();
DataBuffer server_hello;
MakeHandshakeMessage(kTlsHandshakeServerHello, kCannedTls13ServerHello,
sizeof(kCannedTls13ServerHello), &server_hello);
auto sh = MakeCannedTls13ServerHello();
MakeHandshakeMessage(kTlsHandshakeServerHello, sh.data(), sh.len(),
&server_hello);
MakeRecord(kTlsHandshakeType, SSL_LIBRARY_VERSION_TLS_1_3,
server_hello.data(), server_hello.len(), &buffer);
ProcessMessage(buffer, TlsAgent::STATE_CONNECTING);
}

TEST_P(TlsAgentTestClient13, EncryptedExtensionsInClear) {
DataBuffer server_hello;
MakeHandshakeMessage(kTlsHandshakeServerHello, kCannedTls13ServerHello,
sizeof(kCannedTls13ServerHello), &server_hello);
auto sh = MakeCannedTls13ServerHello();
MakeHandshakeMessage(kTlsHandshakeServerHello, sh.data(), sh.len(),
&server_hello);
DataBuffer encrypted_extensions;
MakeHandshakeMessage(kTlsHandshakeEncryptedExtensions, nullptr, 0,
&encrypted_extensions, 1);
Expand All @@ -100,19 +89,21 @@ TEST_P(TlsAgentTestClient13, EncryptedExtensionsInClear) {

TEST_F(TlsAgentStreamTestClient, EncryptedExtensionsInClearTwoPieces) {
DataBuffer server_hello;
MakeHandshakeMessage(kTlsHandshakeServerHello, kCannedTls13ServerHello,
sizeof(kCannedTls13ServerHello), &server_hello);
auto sh = MakeCannedTls13ServerHello();
MakeHandshakeMessage(kTlsHandshakeServerHello, sh.data(), sh.len(),
&server_hello);
DataBuffer encrypted_extensions;
MakeHandshakeMessage(kTlsHandshakeEncryptedExtensions, nullptr, 0,
&encrypted_extensions, 1);
server_hello.Append(encrypted_extensions);
DataBuffer buffer;
MakeRecord(kTlsHandshakeType, SSL_LIBRARY_VERSION_TLS_1_3,
server_hello.data(), 20, &buffer);
server_hello.data(), kFirstFragmentSize, &buffer);

DataBuffer buffer2;
MakeRecord(kTlsHandshakeType, SSL_LIBRARY_VERSION_TLS_1_3,
server_hello.data() + 20, server_hello.len() - 20, &buffer2);
server_hello.data() + kFirstFragmentSize,
server_hello.len() - kFirstFragmentSize, &buffer2);

EnsureInit();
agent_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_3,
Expand All @@ -124,15 +115,15 @@ TEST_F(TlsAgentStreamTestClient, EncryptedExtensionsInClearTwoPieces) {
}

TEST_F(TlsAgentDgramTestClient, EncryptedExtensionsInClearTwoPieces) {
auto sh = MakeCannedTls13ServerHello();
DataBuffer server_hello_frag1;
MakeHandshakeMessageFragment(
kTlsHandshakeServerHello, kCannedTls13ServerHello,
sizeof(kCannedTls13ServerHello), &server_hello_frag1, 0, 0, 20);
MakeHandshakeMessageFragment(kTlsHandshakeServerHello, sh.data(), sh.len(),
&server_hello_frag1, 0, 0, kFirstFragmentSize);
DataBuffer server_hello_frag2;
MakeHandshakeMessageFragment(
kTlsHandshakeServerHello, kCannedTls13ServerHello + 20,
sizeof(kCannedTls13ServerHello), &server_hello_frag2, 0, 20,
sizeof(kCannedTls13ServerHello) - 20);
MakeHandshakeMessageFragment(kTlsHandshakeServerHello,
sh.data() + kFirstFragmentSize, sh.len(),
&server_hello_frag2, 0, kFirstFragmentSize,
sh.len() - kFirstFragmentSize);
DataBuffer encrypted_extensions;
MakeHandshakeMessage(kTlsHandshakeEncryptedExtensions, nullptr, 0,
&encrypted_extensions, 1);
Expand Down
28 changes: 27 additions & 1 deletion gtests/ssl_gtest/ssl_hrr_unittest.cc
Expand Up @@ -568,6 +568,28 @@ void TriggerHelloRetryRequest(std::shared_ptr<TlsAgent>& client,
client->Handshake();
server->Handshake();
EXPECT_EQ(1U, cb_called);
// Stop the callback from being called in future handshakes.
EXPECT_EQ(SECSuccess,
SSL_HelloRetryRequestCallback(server->ssl_fd(), nullptr, nullptr));
}

TEST_P(TlsConnectTls13, VersionNumbersAfterRetry) {
ConfigureSelfEncrypt();
EnsureTlsSetup();
auto r = MakeTlsFilter<TlsRecordRecorder>(client_);
TriggerHelloRetryRequest(client_, server_);
Handshake();
ASSERT_GT(r->count(), 1UL);
auto ch1 = r->record(0);
if (ch1.header.is_dtls()) {
ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_1, ch1.header.version());
} else {
ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, ch1.header.version());
}
auto ch2 = r->record(1);
ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_2, ch2.header.version());

CheckConnected();
}

TEST_P(TlsConnectTls13, RetryStateless) {
Expand All @@ -578,6 +600,7 @@ TEST_P(TlsConnectTls13, RetryStateless) {
MakeNewServer();

Handshake();
CheckConnected();
SendReceive();
}

Expand Down Expand Up @@ -908,7 +931,10 @@ class HelloRetryRequestAgentTest : public TlsAgentTestClient {

hrr_data.Allocate(len + 6);
size_t i = 0;
i = hrr_data.Write(i, 0x0303, 2);
i = hrr_data.Write(i, variant_ == ssl_variant_datagram
? SSL_LIBRARY_VERSION_DTLS_1_2_WIRE
: SSL_LIBRARY_VERSION_TLS_1_2,
2);
i = hrr_data.Write(i, ssl_hello_retry_random,
sizeof(ssl_hello_retry_random));
i = hrr_data.Write(i, static_cast<uint32_t>(0), 1); // session_id
Expand Down
18 changes: 18 additions & 0 deletions gtests/ssl_gtest/tls_agent.cc
Expand Up @@ -44,6 +44,16 @@ const std::string TlsAgent::kServerEcdhRsa = "ecdh_rsa";
const std::string TlsAgent::kServerEcdhEcdsa = "ecdh_ecdsa";
const std::string TlsAgent::kServerDsa = "dsa";

static const uint8_t kCannedTls13ServerHello[] = {
0x03, 0x03, 0x9c, 0xbc, 0x14, 0x9b, 0x0e, 0x2e, 0xfa, 0x0d, 0xf3,
0xf0, 0x5c, 0x70, 0x7a, 0xe0, 0xd1, 0x9b, 0x3e, 0x5a, 0x44, 0x6b,
0xdf, 0xe5, 0xc2, 0x28, 0x64, 0xf7, 0x00, 0xc1, 0x9c, 0x08, 0x76,
0x08, 0x00, 0x13, 0x01, 0x00, 0x00, 0x2e, 0x00, 0x33, 0x00, 0x24,
0x00, 0x1d, 0x00, 0x20, 0xc2, 0xcf, 0x23, 0x17, 0x64, 0x23, 0x03,
0xf0, 0xfb, 0x45, 0x98, 0x26, 0xd1, 0x65, 0x24, 0xa1, 0x6c, 0xa9,
0x80, 0x8f, 0x2c, 0xac, 0x0a, 0xea, 0x53, 0x3a, 0xcb, 0xe3, 0x08,
0x84, 0xae, 0x19, 0x00, 0x2b, 0x00, 0x02, 0x7f, kD13};

TlsAgent::TlsAgent(const std::string& nm, Role rl, SSLProtocolVariant var)
: name_(nm),
variant_(var),
Expand Down Expand Up @@ -1146,4 +1156,12 @@ void TlsAgentTestBase::MakeTrivialHandshakeRecord(uint8_t hs_type,
}
}

DataBuffer TlsAgentTestBase::MakeCannedTls13ServerHello() {
DataBuffer sh(kCannedTls13ServerHello, sizeof(kCannedTls13ServerHello));
if (variant_ == ssl_variant_datagram) {
sh.Write(0, SSL_LIBRARY_VERSION_DTLS_1_2_WIRE, 2);
}
return sh;
}

} // namespace nss_test
6 changes: 6 additions & 0 deletions gtests/ssl_gtest/tls_agent.h
Expand Up @@ -10,6 +10,9 @@
#include "prio.h"
#include "ssl.h"

// This is an internal header, used to get TLS_1_3_DRAFT_VERSION.
#include "ssl3prot.h"

#include <functional>
#include <iostream>

Expand Down Expand Up @@ -57,6 +60,8 @@ typedef std::function<int32_t(TlsAgent* agent, const SECItem* srvNameArr,
PRUint32 srvNameArrSize)>
SniCallbackFunction;

static const uint8_t kD13 = TLS_1_3_DRAFT_VERSION;

class TlsAgent : public PollTarget {
public:
enum Role { CLIENT, SERVER };
Expand Down Expand Up @@ -442,6 +447,7 @@ class TlsAgentTestBase : public ::testing::Test {
size_t hs_len, DataBuffer* out,
uint64_t seq_num, uint32_t fragment_offset,
uint32_t fragment_length) const;
DataBuffer MakeCannedTls13ServerHello();
static void MakeTrivialHandshakeRecord(uint8_t hs_type, size_t hs_len,
DataBuffer* out);
static inline TlsAgent::Role ToRole(const std::string& str) {
Expand Down
39 changes: 29 additions & 10 deletions gtests/ssl_gtest/tls_filter.cc
Expand Up @@ -213,14 +213,14 @@ PacketFilter::Action TlsRecordFilter::FilterRecord(
}

size_t TlsRecordHeader::header_length() const {
if (!is_dtls()) {
return 5;
// If we have a header, return it's length.
if (header_.len()) {
return header_.len();
}
if (version() >= SSL_LIBRARY_VERSION_TLS_1_3 &&
content_type_ == kTlsApplicationDataType) {
return 7;
}
return 13;

// Otherwise make a dummy header and return the length.
DataBuffer buf;
return WriteHeader(&buf, 0, 0);
}

uint64_t TlsRecordHeader::RecoverSequenceNumber(uint64_t expected,
Expand Down Expand Up @@ -265,6 +265,8 @@ uint64_t TlsRecordHeader::ParseSequenceNumber(uint64_t expected, uint32_t raw,

bool TlsRecordHeader::Parse(bool is_dtls13, uint64_t seqno, TlsParser* parser,
DataBuffer* body) {
auto mark = parser->consumed();

if (!parser->Read(&content_type_)) {
return false;
}
Expand All @@ -281,6 +283,10 @@ bool TlsRecordHeader::Parse(bool is_dtls13, uint64_t seqno, TlsParser* parser,
return false;
}
sequence_number_ = ParseSequenceNumber(seqno, tmp, 30, 2);
if (!parser->ReadFromMark(&header_, parser->consumed() + 2 - mark,
mark)) {
return false;
}
return parser->ReadVariable(body, 2);
}

Expand All @@ -294,6 +300,10 @@ bool TlsRecordHeader::Parse(bool is_dtls13, uint64_t seqno, TlsParser* parser,
tmp |= (content_type_ & 0x1f) << 8;
content_type_ = kTlsApplicationDataType;
sequence_number_ = ParseSequenceNumber(seqno, tmp, 12, 1);

if (!parser->ReadFromMark(&header_, parser->consumed() - mark, mark)) {
return false;
}
return parser->Read(body, parser->remaining());
}

Expand Down Expand Up @@ -327,11 +337,14 @@ bool TlsRecordHeader::Parse(bool is_dtls13, uint64_t seqno, TlsParser* parser,
} else {
sequence_number_ = seqno;
}
if (!parser->ReadFromMark(&header_, parser->consumed() + 2 - mark, mark)) {
return false;
}
return parser->ReadVariable(body, 2);
}

size_t TlsRecordHeader::Write(DataBuffer* buffer, size_t offset,
const DataBuffer& body) const {
size_t TlsRecordHeader::WriteHeader(DataBuffer* buffer, size_t offset,
size_t body_len) const {
offset = buffer->Write(offset, content_type_, 1);
if (is_dtls() && version_ >= SSL_LIBRARY_VERSION_TLS_1_3 &&
content_type() == kTlsApplicationDataType) {
Expand All @@ -349,7 +362,13 @@ size_t TlsRecordHeader::Write(DataBuffer* buffer, size_t offset,
offset = buffer->Write(offset, sequence_number_ & 0xffffffff, 4);
}
}
offset = buffer->Write(offset, body.len(), 2);
offset = buffer->Write(offset, body_len, 2);
return offset;
}

size_t TlsRecordHeader::Write(DataBuffer* buffer, size_t offset,
const DataBuffer& body) const {
offset = WriteHeader(buffer, offset, body.len());
offset = buffer->Write(offset, body);
return offset;
}
Expand Down
12 changes: 10 additions & 2 deletions gtests/ssl_gtest/tls_filter.h
Expand Up @@ -44,23 +44,30 @@ class TlsVersioned {

class TlsRecordHeader : public TlsVersioned {
public:
TlsRecordHeader() : TlsVersioned(), content_type_(0), sequence_number_(0) {}
TlsRecordHeader()
: TlsVersioned(), content_type_(0), sequence_number_(0), header_() {}
TlsRecordHeader(SSLProtocolVariant var, uint16_t ver, uint8_t ct,
uint64_t seqno)
: TlsVersioned(var, ver), content_type_(ct), sequence_number_(seqno) {}
: TlsVersioned(var, ver),
content_type_(ct),
sequence_number_(seqno),
header_() {}

uint8_t content_type() const { return content_type_; }
uint64_t sequence_number() const { return sequence_number_; }
uint16_t epoch() const {
return static_cast<uint16_t>(sequence_number_ >> 48);
}
size_t header_length() const;
const DataBuffer& header() const { return header_; }

// Parse the header; return true if successful; body in an outparam if OK.
bool Parse(bool is_dtls13, uint64_t sequence_number, TlsParser* parser,
DataBuffer* body);
// Write the header and body to a buffer at the given offset.
// Return the offset of the end of the write.
size_t Write(DataBuffer* buffer, size_t offset, const DataBuffer& body) const;
size_t WriteHeader(DataBuffer* buffer, size_t offset, size_t body_len) const;

private:
static uint64_t RecoverSequenceNumber(uint64_t expected, uint32_t partial,
Expand All @@ -70,6 +77,7 @@ class TlsRecordHeader : public TlsVersioned {

uint8_t content_type_;
uint64_t sequence_number_;
DataBuffer header_;
};

struct TlsRecord {
Expand Down

0 comments on commit 59e04c7

Please sign in to comment.