Skip to content

Commit

Permalink
Bug 1315735 - TLS 1.3 draft 17 - implement psk binders, remove resump…
Browse files Browse the repository at this point in the history
…tion PSK, and

0-RTT Finished. r=mt

Subscribers: mt

Differential Revision: https://nss-dev.phacility.com/D134
  • Loading branch information
ekr committed Nov 7, 2016
1 parent ffb635f commit 6fe51c4
Show file tree
Hide file tree
Showing 18 changed files with 483 additions and 449 deletions.
16 changes: 16 additions & 0 deletions gtests/ssl_gtest/libssl_internals.c
Expand Up @@ -94,6 +94,22 @@ PRInt32 SSLInt_CountTls13CipherSpecs(PRFileDesc *fd) {
return ct;
}

void SSLInt_PrintTls13CipherSpecs(PRFileDesc *fd) {
PRCList *cur_p;

sslSocket *ss = ssl_FindSocket(fd);
if (!ss) {
return;
}

fprintf(stderr, "Cipher specs\n");
for (cur_p = PR_NEXT_LINK(&ss->ssl3.hs.cipherSpecs);
cur_p != &ss->ssl3.hs.cipherSpecs; cur_p = PR_NEXT_LINK(cur_p)) {
ssl3CipherSpec *spec = (ssl3CipherSpec *)cur_p;
fprintf(stderr, " %s\n", spec->phase);
}
}

/* Force a timer expiry by backdating when the timer was started.
* We could set the remaining time to 0 but then backoff would not
* work properly if we decide to test it. */
Expand Down
1 change: 1 addition & 0 deletions gtests/ssl_gtest/libssl_internals.h
Expand Up @@ -22,6 +22,7 @@ SECStatus SSLInt_UpdateSSLv2ClientRandom(PRFileDesc *fd, uint8_t *rnd,
PRBool SSLInt_ExtensionNegotiated(PRFileDesc *fd, PRUint16 ext);
void SSLInt_ClearSessionTicketKey();
PRInt32 SSLInt_CountTls13CipherSpecs(PRFileDesc *fd);
void SSLInt_PrintTls13CipherSpecs(PRFileDesc *fd);
void SSLInt_ForceTimerExpiry(PRFileDesc *fd);
SECStatus SSLInt_SetMTU(PRFileDesc *fd, PRUint16 mtu);
PRBool SSLInt_CheckSecretsDestroyed(PRFileDesc *fd);
Expand Down
3 changes: 2 additions & 1 deletion gtests/ssl_gtest/ssl_0rtt_unittest.cc
Expand Up @@ -200,7 +200,8 @@ TEST_P(TlsConnectTls13, TestTls13ZeroRttAlpnChangeBoth) {
CheckAlpn("b");
}

TEST_F(TlsConnectTest, DamageSecretHandleZeroRttClientFinished) {
// Re-enable when PSK binders are written.
TEST_F(TlsConnectTest, DISABLED_DamageSecretHandleZeroRttClientFinished) {
SetupForZeroRtt();
client_->Set0RttEnabled(true);
server_->Set0RttEnabled(true);
Expand Down
21 changes: 11 additions & 10 deletions gtests/ssl_gtest/ssl_agent_unittest.cc
Expand Up @@ -44,16 +44,17 @@ const static uint8_t kCannedTls13ClientHello[] = {
0x02, 0x05, 0x02, 0x06, 0x02, 0x02, 0x02};

const static uint8_t kCannedTls13ServerHello[] = {
0x7f, kD13, 0x21, 0x12, 0xa7, 0xa7, 0x0d, 0x85, 0x8b, 0xb8, 0x0c, 0xbb,
0xdc, 0xa6, 0xfd, 0x97, 0xfe, 0x31, 0x26, 0x49, 0x2d, 0xa8, 0x6c, 0x7b,
0x65, 0x30, 0x71, 0x00, 0x31, 0x03, 0x2b, 0x94, 0xe2, 0x16, 0x13, 0x01,
0x00, 0x4d, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x28, 0x00, 0x45, 0x00, 0x17,
0x00, 0x41, 0x04, 0x10, 0x97, 0x3d, 0x7a, 0xcf, 0xa2, 0x34, 0xe3, 0x69,
0xc4, 0xdd, 0x1e, 0xf2, 0xd6, 0xc0, 0x9a, 0x3e, 0xf5, 0x41, 0xf3, 0x03,
0x23, 0x94, 0xd2, 0x31, 0x85, 0xb7, 0xae, 0x5d, 0xfa, 0xc6, 0x9a, 0xd0,
0xa5, 0x44, 0xa3, 0x3a, 0xe0, 0xbb, 0x61, 0xaa, 0x0a, 0x6f, 0xe8, 0xaf,
0xdf, 0x86, 0xd8, 0x48, 0x36, 0x9c, 0x19, 0x70, 0x55, 0x84, 0xb0, 0x1c,
0x8d, 0xfc, 0x6e, 0xd8, 0x86, 0xc3, 0x95};
0x7f, kD13, 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, 0x13, 0x01,
0x00, 0x28, 0x00, 0x28, 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};
static const char *k0RttData = "ABCDEF";

TEST_P(TlsAgentTest, EarlyFinished) {
Expand Down
7 changes: 3 additions & 4 deletions gtests/ssl_gtest/ssl_extension_unittest.cc
Expand Up @@ -587,7 +587,7 @@ TEST_F(TlsExtensionTest13Stream, AddServerSignatureAlgorithmsOnResumption) {
server_->SetPacketFilter(
new TlsExtensionInjector(ssl_signature_algorithms_xtn, empty));
ConnectExpectFail();
EXPECT_EQ(SSL_ERROR_RX_UNEXPECTED_EXTENSION, client_->error_code());
EXPECT_EQ(SSL_ERROR_EXTENSION_DISALLOWED_FOR_VERSION, client_->error_code());
EXPECT_EQ(SSL_ERROR_BAD_MAC_READ, server_->error_code());
}

Expand Down Expand Up @@ -657,9 +657,8 @@ class TlsPreSharedKeyReplacer : public TlsExtensionFilter {
std::unique_ptr<DataBuffer> auth_modes_;
};

// The following three tests produce bogus (ill-formatted) PreSharedKey
// extensions so generate errors.
TEST_F(TlsExtensionTest13Stream, ResumeEmptyPskLabel) {
// TODO(ekr@rtfm.com): Update for new PSK format
TEST_F(TlsExtensionTest13Stream, DISABLED_ResumeEmptyPskLabel) {
SetupForResume();
const static uint8_t psk[1] = {0};

Expand Down
6 changes: 3 additions & 3 deletions gtests/ssl_gtest/ssl_hrr_unittest.cc
Expand Up @@ -39,7 +39,7 @@ TEST_P(TlsConnectTls13, HelloRetryRequestAbortsZeroRtt) {
client_->Handshake();
EXPECT_EQ(k0RttDataLen, PR_Write(client_->ssl_fd(), k0RttData,
k0RttDataLen)); // 0-RTT write.
EXPECT_LT(0U, capture_early_data->extension().len());
EXPECT_TRUE(capture_early_data->captured());

// Send the HelloRetryRequest
auto hrr_capture =
Expand All @@ -62,7 +62,7 @@ TEST_P(TlsConnectTls13, HelloRetryRequestAbortsZeroRtt) {
ExpectEarlyDataAccepted(false); // The server should reject 0-RTT
CheckConnected();
SendReceive();
EXPECT_EQ(0U, capture_early_data->extension().len());
EXPECT_FALSE(capture_early_data->captured());
}

class KeyShareReplayer : public TlsExtensionFilter {
Expand Down Expand Up @@ -240,7 +240,7 @@ TEST_P(HelloRetryRequestAgentTest, SendSecondHelloRetryRequest) {
// provided a share for.
TEST_P(HelloRetryRequestAgentTest, HandleBogusHelloRetryRequest) {
DataBuffer hrr;
MakeGroupHrr(ssl_grp_ec_secp256r1, &hrr);
MakeGroupHrr(ssl_grp_ec_curve25519, &hrr);
ProcessMessage(hrr, TlsAgent::STATE_ERROR,
SSL_ERROR_RX_MALFORMED_HELLO_RETRY_REQUEST);
}
Expand Down
9 changes: 7 additions & 2 deletions gtests/ssl_gtest/tls_agent.cc
Expand Up @@ -629,7 +629,11 @@ void TlsAgent::Connected() {
PRInt32 cipherSuites = SSLInt_CountTls13CipherSpecs(ssl_fd_);
// We use one ciphersuite in each direction, plus one that's kept around
// by DTLS for retransmission.
EXPECT_EQ(((mode_ == DGRAM) && (role_ == CLIENT)) ? 3 : 2, cipherSuites);
PRInt32 expected = ((mode_ == DGRAM) && (role_ == CLIENT)) ? 3 : 2;
EXPECT_EQ(expected, cipherSuites);
if (expected != cipherSuites) {
SSLInt_PrintTls13CipherSpecs(ssl_fd_);
}
}

SetState(STATE_CONNECTED);
Expand Down Expand Up @@ -859,7 +863,8 @@ void TlsAgentTestBase::EnsureInit() {
Init();
}
const std::vector<SSLNamedGroup> groups = {
ssl_grp_ec_secp256r1, ssl_grp_ec_secp384r1, ssl_grp_ffdhe_2048};
ssl_grp_ec_curve25519, ssl_grp_ec_secp256r1,
ssl_grp_ec_secp384r1, ssl_grp_ffdhe_2048};
agent_->ConfigNamedGroups(groups);
}

Expand Down
3 changes: 2 additions & 1 deletion gtests/ssl_gtest/tls_filter.cc
Expand Up @@ -431,8 +431,9 @@ PacketFilter::Action TlsExtensionFilter::FilterExtensions(

PacketFilter::Action TlsExtensionCapture::FilterExtension(
uint16_t extension_type, const DataBuffer& input, DataBuffer* output) {
if (extension_type == extension_ && (last_ || (data_.len() == 0))) {
if (extension_type == extension_ && (last_ || !captured_)) {
data_.Assign(input);
captured_ = true;
}
return KEEP;
}
Expand Down
4 changes: 3 additions & 1 deletion gtests/ssl_gtest/tls_filter.h
Expand Up @@ -235,9 +235,10 @@ class TlsExtensionFilter : public TlsHandshakeFilter {
class TlsExtensionCapture : public TlsExtensionFilter {
public:
TlsExtensionCapture(uint16_t ext, bool last = false) :
extension_(ext), last_(last), data_() {}
extension_(ext), captured_(false), last_(last), data_() {}

const DataBuffer& extension() const { return data_; }
bool captured() const { return captured_; }

protected:
PacketFilter::Action FilterExtension(uint16_t extension_type,
Expand All @@ -246,6 +247,7 @@ class TlsExtensionCapture : public TlsExtensionFilter {

private:
const uint16_t extension_;
bool captured_;
bool last_;
DataBuffer data_;
};
Expand Down
20 changes: 12 additions & 8 deletions gtests/ssl_gtest/tls_hkdf_unittest.cc
Expand Up @@ -241,16 +241,20 @@ TEST_P(TlsHkdfTest, HkdfExpandLabel) {
{/* ssl_hash_md5 */},
{/* ssl_hash_sha1 */},
{/* ssl_hash_sha224 */},
{0x66, 0x8a, 0x55, 0x1a, 0xef, 0x33, 0x7b, 0x45, 0x26, 0xa6, 0x36,
0xb1, 0xe0, 0x23, 0x48, 0x24, 0x6f, 0x34, 0xa5, 0x57, 0x11, 0x4a,
0xb5, 0x64, 0xc4, 0x5c, 0x69, 0xb4, 0x0f, 0xc8, 0x12, 0xa5},
{0x99, 0x98, 0xde, 0xbf, 0x82, 0x8d, 0xf6, 0x55, 0xa1, 0xcf, 0xa8, 0xbe,
0x12, 0x06, 0x5c, 0x8e, 0x65, 0xec, 0x80, 0xa1, 0x33, 0xed, 0x61, 0x06,
0x09, 0xc6, 0x5c, 0x08, 0xcf, 0xc9, 0x91, 0x39, 0xbe, 0xce, 0x4e, 0x4a,
0x9b, 0x67, 0x36, 0x50, 0x89, 0x98, 0x59, 0x1c, 0x5d, 0x6e, 0x9c, 0x7d}};
{0x34, 0x7c, 0x67, 0x80, 0xff, 0x0b, 0xba, 0xd7,
0x1c, 0x28, 0x3b, 0x16, 0xeb, 0x2f, 0x9c, 0xf6,
0x2d, 0x24, 0xe6, 0xcd, 0xb6, 0x13, 0xd5, 0x17,
0x76, 0x54, 0x8c, 0xb0, 0x7d, 0xcd, 0xe7, 0x4c},
{0x4b, 0x1e, 0x5e, 0xc1, 0x49, 0x30, 0x78, 0xea,
0x35, 0xbd, 0x3f, 0x01, 0x04, 0xe6, 0x1a, 0xea,
0x14, 0xcc, 0x18, 0x2a, 0xd1, 0xc4, 0x76, 0x21,
0xc4, 0x64, 0xc0, 0x4e, 0x4b, 0x36, 0x16, 0x05,
0x6f, 0x04, 0xab, 0xe9, 0x43, 0xb1, 0x2d, 0xa8,
0xa7, 0x17, 0x9a, 0x5f, 0x09, 0x91, 0x7d, 0x1f}
};

const DataBuffer expected_data(tv[hash_type_], kHashLength[hash_type_]);
HkdfExpandLabel(&k1_, hash_type_, kSessionHash, kHashLength[hash_type_] * 2,
HkdfExpandLabel(&k1_, hash_type_, kSessionHash, kHashLength[hash_type_],
kLabelMasterSecret, strlen(kLabelMasterSecret),
expected_data);
}
Expand Down
63 changes: 20 additions & 43 deletions lib/ssl/ssl3con.c
Expand Up @@ -3984,8 +3984,9 @@ ssl3_DeriveConnectionKeys(sslSocket *ss)

/* ssl3_InitHandshakeHashes creates handshake hash contexts and hashes in
* buffered messages in ss->ssl3.hs.messages. Called from
* ssl3_NegotiateCipherSuite() and ssl3_HandleServerHello. */
static SECStatus
* ssl3_NegotiateCipherSuite(), tls13_HandleClientHelloPart2(),
* and ssl3_HandleServerHello. */
SECStatus
ssl3_InitHandshakeHashes(sslSocket *ss)
{
SSL_TRC(30, ("%d: SSL3[%d]: start handshake hashes", SSL_GETPID(), ss->fd));
Expand Down Expand Up @@ -4970,6 +4971,7 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type)
unsigned paddingExtensionLen;
unsigned numCompressionMethods;
PRUint16 version;
PRInt32 flags;

SSL_TRC(3, ("%d: SSL3[%d]: send %s ClientHello handshake", SSL_GETPID(),
ss->fd, ssl_ClientHelloTypeName(type)));
Expand Down Expand Up @@ -5209,10 +5211,9 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type)
type == client_hello_initial) {
rv = tls13_SetupClientHello(ss);
if (rv != SECSuccess) {
return rv;
return SECFailure;
}
}

if (isTLS || (ss->firstHsDone && ss->peerRequestedProtection)) {
PRUint32 maxBytes = 65535; /* 2^16 - 1 */
PRInt32 extLen;
Expand Down Expand Up @@ -5453,7 +5454,7 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type)
return rv; /* err set by AppendHandshake. */
}

extLen = ssl3_CallHelloExtensionSenders(ss, PR_TRUE, maxBytes, NULL);
extLen = ssl3_AppendPaddingExtension(ss, paddingExtensionLen, maxBytes);
if (extLen < 0) {
if (sid->u.ssl3.lock) {
PR_RWLock_Unlock(sid->u.ssl3.lock);
Expand All @@ -5462,7 +5463,7 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type)
}
maxBytes -= extLen;

extLen = ssl3_AppendPaddingExtension(ss, paddingExtensionLen, maxBytes);
extLen = ssl3_CallHelloExtensionSenders(ss, PR_TRUE, maxBytes, NULL);
if (extLen < 0) {
if (sid->u.ssl3.lock) {
PR_RWLock_Unlock(sid->u.ssl3.lock);
Expand All @@ -5489,38 +5490,22 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type)
ssl_renegotiation_info_xtn;
}

flags = 0;
if (!ss->firstHsDone && !IS_DTLS(ss)) {
flags |= ssl_SEND_FLAG_CAP_RECORD_VERSION;
}
rv = ssl3_FlushHandshake(ss, flags);
if (rv != SECSuccess) {
return rv; /* error code set by ssl3_FlushHandshake */
}

if (version >= SSL_LIBRARY_VERSION_TLS_1_3) {
rv = tls13_MaybeDo0RTTHandshake(ss);
if (rv != SECSuccess) {
return SECFailure; /* error code set already. */
}
}

/* On TLS (but not DTLS), if we sent 0-RTT, then we will have data in the
* pending buffer. This just pushes a little of that out. If we didn't do
* that, we wouldn't send a ClientHello the first time and applications
* would have to push SSL_ForceHandshake() twice. This should go away once
* we have Finished stuffed in the ClientHello. */
if (!IS_DTLS(ss) && ss->ssl3.hs.zeroRttState == ssl_0rtt_sent) {
int sent;

PORT_Assert(version >= SSL_LIBRARY_VERSION_TLS_1_3);
PORT_Assert(ss->pendingBuf.len);
sent = ssl_SendSavedWriteData(ss);
if (sent < 0) {
return SECFailure;
}
} else {
PRInt32 flags = 0;
if (!ss->firstHsDone && !IS_DTLS(ss)) {
flags |= ssl_SEND_FLAG_CAP_RECORD_VERSION;
}
rv = ssl3_FlushHandshake(ss, flags);
if (rv != SECSuccess) {
return rv; /* error code set by ssl3_FlushHandshake */
}
}

ss->ssl3.hs.ws = wait_server_hello;
return SECSuccess;
}
Expand Down Expand Up @@ -11678,8 +11663,7 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
computeHashes = TLS13_IN_HS_STATE(ss, wait_cert_verify);
} else if (type == finished) {
computeHashes =
TLS13_IN_HS_STATE(ss, wait_cert_request, wait_finished,
wait_0rtt_finished);
TLS13_IN_HS_STATE(ss, wait_cert_request, wait_finished);
}
}

Expand Down Expand Up @@ -12831,7 +12815,6 @@ ssl3_InitCipherSpec(ssl3CipherSpec *spec)
SECStatus
ssl3_InitState(sslSocket *ss)
{
SECItem nullItem = { siBuffer, NULL, 0 };
PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));

if (ss->ssl3.initialized)
Expand Down Expand Up @@ -12865,11 +12848,10 @@ ssl3_InitState(sslSocket *ss)
dtls_SetMTU(ss, 0); /* Set the MTU to the highest plateau */
}

ss->ssl3.hs.clientHelloHash = NULL;
ss->ssl3.hs.currentSecret = NULL;
ss->ssl3.hs.resumptionPsk = NULL;
ss->ssl3.hs.resumptionContext = nullItem;
ss->ssl3.hs.dheSecret = NULL;
ss->ssl3.hs.pskBinderKey = NULL;
ss->ssl3.hs.clientEarlyTrafficSecret = NULL;
ss->ssl3.hs.clientHsTrafficSecret = NULL;
ss->ssl3.hs.serverHsTrafficSecret = NULL;
Expand Down Expand Up @@ -13236,11 +13218,6 @@ ssl3_DestroySSL3Info(sslSocket *ss)
ssl3_DestroyRemoteExtensions(&ss->ssl3.hs.remoteExtensions);
ssl3_ResetExtensionData(&ss->xtnData);

/* Destroy the stored hash. */
if (ss->ssl3.hs.clientHelloHash) {
PK11_DestroyContext(ss->ssl3.hs.clientHelloHash, PR_TRUE);
}

/* Destroy TLS 1.3 cipher specs */
tls13_DestroyCipherSpecs(&ss->ssl3.hs.cipherSpecs);

Expand All @@ -13251,8 +13228,8 @@ ssl3_DestroySSL3Info(sslSocket *ss)
PK11_FreeSymKey(ss->ssl3.hs.resumptionPsk);
if (ss->ssl3.hs.dheSecret)
PK11_FreeSymKey(ss->ssl3.hs.dheSecret);
if (ss->ssl3.hs.resumptionContext.data)
SECITEM_FreeItem(&ss->ssl3.hs.resumptionContext, PR_FALSE);
if (ss->ssl3.hs.pskBinderKey)
PK11_FreeSymKey(ss->ssl3.hs.pskBinderKey);
if (ss->ssl3.hs.clientEarlyTrafficSecret)
PK11_FreeSymKey(ss->ssl3.hs.clientEarlyTrafficSecret);
if (ss->ssl3.hs.clientHsTrafficSecret)
Expand Down

0 comments on commit 6fe51c4

Please sign in to comment.