summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorEKR <ekr@rtfm.com>2016-11-03 12:16:16 -0700
committerEKR <ekr@rtfm.com>2016-11-03 12:16:16 -0700
commitd933e5a081d839fcc9be6ad6c5817f962d024979 (patch)
treeb0ccb69c892c903977dcfb04464118826ef0170d /lib
parent6ac7b9b8062c0bca761fb7533d692ec4f623e871 (diff)
downloadnss-hg-d933e5a081d839fcc9be6ad6c5817f962d024979.tar.gz
Bug 1315735 - TLS 1.3 draft 17 - implement psk binders, remove resumption PSK, and
0-RTT Finished. r=mt Subscribers: mt Differential Revision: https://nss-dev.phacility.com/D134
Diffstat (limited to 'lib')
-rw-r--r--lib/ssl/ssl3con.c63
-rw-r--r--lib/ssl/ssl3ext.c17
-rw-r--r--lib/ssl/ssl3ext.h2
-rw-r--r--lib/ssl/sslimpl.h11
-rw-r--r--lib/ssl/tls13con.c544
-rw-r--r--lib/ssl/tls13con.h11
-rw-r--r--lib/ssl/tls13exthandle.c192
-rw-r--r--lib/ssl/tls13hkdf.c2
8 files changed, 423 insertions, 419 deletions
diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c
index 148a17b24..a7a65417c 100644
--- a/lib/ssl/ssl3con.c
+++ b/lib/ssl/ssl3con.c
@@ -3984,8 +3984,9 @@ loser:
/* 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));
@@ -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)));
@@ -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;
@@ -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);
@@ -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);
@@ -5489,6 +5490,15 @@ 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) {
@@ -5496,31 +5506,6 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type)
}
}
- /* 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;
}
@@ -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);
}
}
@@ -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)
@@ -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;
@@ -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);
@@ -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)
diff --git a/lib/ssl/ssl3ext.c b/lib/ssl/ssl3ext.c
index 088518b9c..0c1fd9674 100644
--- a/lib/ssl/ssl3ext.c
+++ b/lib/ssl/ssl3ext.c
@@ -102,7 +102,6 @@ static const ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS]
{ ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn },
{ ssl_signed_cert_timestamp_xtn, &ssl3_ClientSendSignedCertTimestampXtn },
{ ssl_tls13_key_share_xtn, &tls13_ClientSendKeyShareXtn },
- { ssl_tls13_pre_shared_key_xtn, &tls13_ClientSendPreSharedKeyXtn },
{ ssl_tls13_early_data_xtn, &tls13_ClientSendEarlyDataXtn },
/* Some servers (e.g. WebSphere Application Server 7.0 and Tomcat) will
* time out or terminate the connection if the last extension in the
@@ -113,6 +112,8 @@ static const ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS]
{ ssl_tls13_cookie_xtn, &tls13_ClientSendHrrCookieXtn },
{ ssl_tls13_psk_key_exchange_modes_xtn,
&tls13_ClientSendPskKeyExchangeModesXtn },
+ /* The pre_shared_key extension MUST be last. */
+ { ssl_tls13_pre_shared_key_xtn, &tls13_ClientSendPreSharedKeyXtn },
/* any extra entries will appear as { 0, NULL } */
};
@@ -174,6 +175,8 @@ ssl3_ParseExtensions(sslSocket *ss, SSL3Opaque **b, PRUint32 *length)
return SECFailure; /* alert already sent */
}
+ SSL_TRC(10, ("%d: SSL3[%d]: parsing extension %d",
+ SSL_GETPID(), ss->fd, extension_type));
/* Check whether an extension has been sent multiple times. */
for (cursor = PR_NEXT_LINK(&ss->ssl3.hs.remoteExtensions);
cursor != &ss->ssl3.hs.remoteExtensions;
@@ -294,6 +297,17 @@ ssl3_HandleParsedExtensions(sslSocket *ss,
return SECFailure;
}
+ /* Special check for this being the last extension if it's
+ * PreSharedKey */
+ if (ss->sec.isServer && isTLS13 &&
+ (extension->type == ssl_tls13_pre_shared_key_xtn) &&
+ (PR_NEXT_LINK(cursor) != &ss->ssl3.hs.remoteExtensions)) {
+ tls13_FatalError(ss,
+ SSL_ERROR_RX_MALFORMED_CLIENT_HELLO,
+ illegal_parameter);
+ return SECFailure;
+ }
+
/* find extension_type in table of Hello Extension Handlers */
for (handler = handlers; handler->ex_type >= 0; handler++) {
/* if found, call this handler */
@@ -311,6 +325,7 @@ ssl3_HandleParsedExtensions(sslSocket *ss,
return SECFailure;
}
}
+
}
}
return SECSuccess;
diff --git a/lib/ssl/ssl3ext.h b/lib/ssl/ssl3ext.h
index 781cd24e4..c2e80f126 100644
--- a/lib/ssl/ssl3ext.h
+++ b/lib/ssl/ssl3ext.h
@@ -95,6 +95,8 @@ struct TLSExtensionDataStr {
PRUint16 dtlsSRTPCipherSuite; /* 0 if not selected */
+ SECItem pskBinder; /* The PSK binder for the first PSK (TLS 1.3) */
+ unsigned long pskBinderPrefixLen; /* The length of the binder input. */
PRCList remoteKeyShares; /* The other side's public keys (TLS 1.3) */
};
diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h
index 06a968463..861647432 100644
--- a/lib/ssl/sslimpl.h
+++ b/lib/ssl/sslimpl.h
@@ -705,7 +705,6 @@ typedef enum {
wait_hello_done,
wait_new_session_ticket,
wait_encrypted_extensions,
- wait_0rtt_finished,
wait_invalid /* Invalid value. There is no handshake message "invalid". */
} SSL3WaitState;
@@ -745,11 +744,6 @@ typedef struct TLS13EarlyDataStr {
SECItem data; /* The data */
} TLS13EarlyData;
-typedef struct {
- PRUint8 hash[HASH_LENGTH_MAX * 2];
- unsigned int len;
-} TLS13CombinedHash;
-
typedef enum {
handshake_hash_unknown = 0,
handshake_hash_combo = 1, /* The MD5/SHA-1 combination */
@@ -854,13 +848,11 @@ typedef struct SSL3HandshakeStateStr {
* always set to NULL.*/
/* This group of values is used for TLS 1.3 and above */
- PK11Context *clientHelloHash; /* The client hello hash state, used
- * by the server for 0-RTT. */
PK11SymKey *currentSecret; /* The secret down the "left hand side"
* of the TLS 1.3 key schedule. */
PK11SymKey *resumptionPsk; /* The resumption PSK. */
- SECItem resumptionContext; /* The resumption context. */
PK11SymKey *dheSecret; /* The (EC)DHE shared secret. */
+ PK11SymKey *pskBinderKey; /* Used to compute the PSK binder. */
PK11SymKey *clientEarlyTrafficSecret; /* The secret we use for 0-RTT. */
PK11SymKey *clientHsTrafficSecret; /* The source keys for handshake */
PK11SymKey *serverHsTrafficSecret; /* traffic keys. */
@@ -1787,6 +1779,7 @@ extern SECStatus dtls_MaybeRetransmitHandshake(sslSocket *ss,
CK_MECHANISM_TYPE ssl3_Alg2Mech(SSLCipherAlgorithm calg);
SECStatus ssl3_NegotiateCipherSuite(sslSocket *ss, const SECItem *suites,
PRBool initHashes);
+SECStatus ssl3_InitHandshakeHashes(sslSocket *ss);
SECStatus ssl3_ServerCallSNICallback(sslSocket *ss);
SECStatus ssl3_SetupPendingCipherSpec(sslSocket *ss);
SECStatus ssl3_FlushHandshake(sslSocket *ss, PRInt32 flags);
diff --git a/lib/ssl/tls13con.c b/lib/ssl/tls13con.c
index 857e765bd..13918046a 100644
--- a/lib/ssl/tls13con.c
+++ b/lib/ssl/tls13con.c
@@ -22,7 +22,6 @@
#include "tls13exthandle.h"
typedef enum {
- TrafficKeyEarlyHandshake,
TrafficKeyEarlyApplicationData,
TrafficKeyHandshake,
TrafficKeyApplicationData
@@ -33,8 +32,6 @@ typedef enum {
CipherSpecWrite,
} CipherSpecDirection;
-#define MAX_FINISHED_SIZE 64
-
static SECStatus tls13_SetCipherSpec(sslSocket *ss, TrafficKeyType type,
CipherSpecDirection install,
PRBool deleteSecret);
@@ -69,38 +66,40 @@ static SECStatus
tls13_SendCertificateVerify(sslSocket *ss, SECKEYPrivateKey *privKey);
static SECStatus tls13_HandleCertificateVerify(
sslSocket *ss, SSL3Opaque *b, PRUint32 length,
- TLS13CombinedHash *hashes);
+ SSL3Hashes *hashes);
+static SECStatus tls13_RecoverWrappedSharedSecret(sslSocket *ss,
+ sslSessionID *sid);
static SECStatus
tls13_DeriveSecret(sslSocket *ss, PK11SymKey *key,
const char *prefix,
const char *suffix,
- const TLS13CombinedHash *hashes,
+ const SSL3Hashes *hashes,
PK11SymKey **dest);
static void tls13_SetNullCipherSpec(sslSocket *ss, ssl3CipherSpec **specp);
static SECStatus tls13_SendEndOfEarlyData(sslSocket *ss);
static SECStatus tls13_SendFinished(sslSocket *ss, PK11SymKey *baseKey);
+static SECStatus tls13_ComputePskBinderHash(sslSocket *ss,
+ unsigned long prefixLength,
+ SSL3Hashes *hashes);
static SECStatus tls13_VerifyFinished(sslSocket *ss, PK11SymKey *secret,
SSL3Opaque *b, PRUint32 length,
- const TLS13CombinedHash *hashes);
+ const SSL3Hashes *hashes);
static SECStatus tls13_ClientHandleFinished(sslSocket *ss,
SSL3Opaque *b, PRUint32 length,
- const TLS13CombinedHash *hashes);
+ const SSL3Hashes *hashes);
static SECStatus tls13_ServerHandleFinished(sslSocket *ss,
SSL3Opaque *b, PRUint32 length,
- const TLS13CombinedHash *hashes);
+ const SSL3Hashes *hashes);
static SECStatus tls13_HandleNewSessionTicket(sslSocket *ss, SSL3Opaque *b,
PRUint32 length);
-static void
-tls13_CombineHashes(sslSocket *ss, const PRUint8 *hhash, unsigned int hlen,
- TLS13CombinedHash *hashes);
static SECStatus tls13_ComputeHandshakeHashes(sslSocket *ss,
- TLS13CombinedHash *hashes);
-static SECStatus tls13_ComputeEarlySecrets(sslSocket *ss, PRBool setup0Rtt);
+ SSL3Hashes *hashes);
+static SECStatus tls13_ComputeEarlySecrets(sslSocket *ss);
static SECStatus tls13_ComputeHandshakeSecrets(sslSocket *ss);
static SECStatus tls13_ComputeApplicationSecrets(sslSocket *ss);
static SECStatus tls13_ComputeFinalSecrets(sslSocket *ss);
static SECStatus tls13_ComputeFinished(
- sslSocket *ss, PK11SymKey *baseKey, const TLS13CombinedHash *hashes,
+ sslSocket *ss, PK11SymKey *baseKey, const SSL3Hashes *hashes,
PRBool sending, PRUint8 *output, unsigned int *outputLen,
unsigned int maxOutputLen);
static SECStatus tls13_SendClientSecondRound(sslSocket *ss);
@@ -108,15 +107,14 @@ static SECStatus tls13_FinishHandshake(sslSocket *ss);
const char kHkdfLabelClient[] = "client";
const char kHkdfLabelServer[] = "server";
+const char kHkdfLabelPskBinderKey[] = "resumption psk binder key";
const char kHkdfLabelEarlyTrafficSecret[] = "early traffic secret";
const char kHkdfLabelHandshakeTrafficSecret[] = "handshake traffic secret";
const char kHkdfLabelApplicationTrafficSecret[] = "application traffic secret";
const char kHkdfLabelFinishedSecret[] = "finished";
const char kHkdfLabelResumptionMasterSecret[] = "resumption master secret";
const char kHkdfLabelResumptionPsk[] = "resumption psk";
-const char kHkdfLabelResumptionContext[] = "resumption context";
const char kHkdfLabelExporterMasterSecret[] = "exporter master secret";
-const char kHkdfPhaseEarlyHandshakeDataKeys[] = "early handshake key expansion";
const char kHkdfPhaseEarlyApplicationDataKeys[] = "early application data key expansion";
const char kHkdfPhaseHandshakeKeys[] = "handshake key expansion";
const char kHkdfPhaseApplicationDataKeys[] = "application data key expansion";
@@ -174,7 +172,6 @@ tls13_HandshakeState(SSL3WaitState st)
STATE_CASE(wait_server_cert);
STATE_CASE(wait_cert_request);
STATE_CASE(wait_encrypted_extensions);
- STATE_CASE(wait_0rtt_finished);
STATE_CASE(idle_handshake);
default:
break;
@@ -260,14 +257,26 @@ tls13_CheckHsState(sslSocket *ss, int err, const char *error_name,
}
SSLHashType
-tls13_GetHash(sslSocket *ss)
+tls13_GetHashForCipherSuite(ssl3CipherSuite suite)
+{
+ const ssl3CipherSuiteDef *cipherDef =
+ ssl_LookupCipherSuiteDef(suite);
+ PORT_Assert(cipherDef);
+ if (!cipherDef) {
+ return ssl_hash_none;
+ }
+ return cipherDef->prf_hash;
+}
+
+SSLHashType
+tls13_GetHash(const sslSocket *ss)
{
/* All TLS 1.3 cipher suites must have an explict PRF hash. */
PORT_Assert(ss->ssl3.hs.suite_def->prf_hash != ssl_hash_none);
return ss->ssl3.hs.suite_def->prf_hash;
}
-static unsigned int
+unsigned int
tls13_GetHashSizeForHash(SSLHashType hash)
{
switch (hash) {
@@ -282,7 +291,7 @@ tls13_GetHashSizeForHash(SSLHashType hash)
}
unsigned int
-tls13_GetHashSize(sslSocket *ss)
+tls13_GetHashSize(const sslSocket *ss)
{
return tls13_GetHashSizeForHash(tls13_GetHash(ss));
}
@@ -424,6 +433,26 @@ tls13_SetupClientHello(sslSocket *ss)
ss->statelessResume = PR_TRUE;
}
+ if (ss->statelessResume) {
+ SECStatus rv;
+
+ rv = tls13_RecoverWrappedSharedSecret(ss, ss->sec.ci.sid);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
+ return SECFailure;
+ }
+
+ rv = ssl3_SetCipherSuite(ss, ss->sec.ci.sid->u.ssl3.cipherSuite, PR_FALSE);
+ if (rv != SECSuccess)
+ return SECFailure;
+
+ rv = tls13_ComputeEarlySecrets(ss);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
+ return SECFailure;
+ }
+ }
+
return SECSuccess;
}
@@ -523,8 +552,6 @@ SECStatus
tls13_HandlePostHelloHandshakeMessage(sslSocket *ss, SSL3Opaque *b,
PRUint32 length, SSL3Hashes *hashesPtr)
{
- TLS13CombinedHash hashes;
-
if (ss->sec.isServer && ss->ssl3.hs.zeroRttIgnore != ssl_0rtt_ignore_none) {
SSL_TRC(3, ("%d: TLS13[%d]: %s successfully decrypted handshake after"
"failed 0-RTT",
@@ -542,12 +569,10 @@ tls13_HandlePostHelloHandshakeMessage(sslSocket *ss, SSL3Opaque *b,
case certificate_verify:
if (!hashesPtr) {
- FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
+ FATAL_ERROR(ss, SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY, unexpected_message);
return SECFailure;
}
- tls13_CombineHashes(ss, hashesPtr->u.raw, hashesPtr->len,
- &hashes);
- return tls13_HandleCertificateVerify(ss, b, length, &hashes);
+ return tls13_HandleCertificateVerify(ss, b, length, hashesPtr);
case encrypted_extensions:
return tls13_HandleEncryptedExtensions(ss, b, length);
@@ -557,15 +582,13 @@ tls13_HandlePostHelloHandshakeMessage(sslSocket *ss, SSL3Opaque *b,
case finished:
if (!hashesPtr) {
- FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
+ FATAL_ERROR(ss, SSL_ERROR_RX_UNEXPECTED_FINISHED, unexpected_message);
return SECFailure;
}
- tls13_CombineHashes(ss, hashesPtr->u.raw, hashesPtr->len,
- &hashes);
if (ss->sec.isServer) {
- return tls13_ServerHandleFinished(ss, b, length, &hashes);
+ return tls13_ServerHandleFinished(ss, b, length, hashesPtr);
} else {
- return tls13_ClientHandleFinished(ss, b, length, &hashes);
+ return tls13_ClientHandleFinished(ss, b, length, hashesPtr);
}
default:
@@ -645,13 +668,10 @@ tls13_RecoverWrappedSharedSecret(sslSocket *ss, sslSessionID *sid)
}
PRINT_KEY(50, (ss, "Recovered RMS", RMS));
- /* Now compute resumption_psk and resumption_context.
+ /* Now compute resumption_psk.
*
* resumption_psk = HKDF-Expand-Label(resumption_secret,
* "resumption psk", "", L)
- *
- * resumption_context = HKDF-Expand-Label(resumption_secret,
- * "resumption context", "", L)
*/
rv = tls13_HkdfExpandLabel(RMS, hashType, NULL, 0,
kHkdfLabelResumptionPsk,
@@ -663,20 +683,6 @@ tls13_RecoverWrappedSharedSecret(sslSocket *ss, sslSessionID *sid)
goto loser;
}
- if (SECITEM_AllocItem(NULL, &ss->ssl3.hs.resumptionContext,
- tls13_GetHashSizeForHash(hashType)) == NULL) {
- goto loser;
- }
-
- rv = tls13_HkdfExpandLabelRaw(RMS, hashType, NULL, 0,
- kHkdfLabelResumptionContext,
- strlen(kHkdfLabelResumptionContext),
- ss->ssl3.hs.resumptionContext.data,
- ss->ssl3.hs.resumptionContext.len);
- if (rv != SECSuccess) {
- goto loser;
- }
-
PK11_FreeSymKey(RMS);
return SECSuccess;
@@ -740,12 +746,9 @@ loser:
*/
static SECStatus
-tls13_ComputeEarlySecrets(sslSocket *ss, PRBool setup0Rtt)
+tls13_ComputeEarlySecrets(sslSocket *ss)
{
SECStatus rv = SECSuccess;
- PK11Context *ctx;
- PRUint8 hash[HASH_LENGTH_MAX];
- unsigned int len;
SSL_TRC(5, ("%d: TLS13[%d]: compute early secrets (%s)",
SSL_GETPID(), ss->fd, SSL_ROLE(ss)));
@@ -758,61 +761,37 @@ tls13_ComputeEarlySecrets(sslSocket *ss, PRBool setup0Rtt)
if (rv != SECSuccess) {
return SECFailure;
}
- if (ss->ssl3.hs.resumptionPsk) {
- PK11_FreeSymKey(ss->ssl3.hs.resumptionPsk);
- ss->ssl3.hs.resumptionPsk = NULL;
- }
- if (!ss->ssl3.hs.resumptionContext.data) {
- PORT_Assert(!setup0Rtt);
- /* If no resumption context, fill with zeroes. */
- if (SECITEM_AllocItem(NULL, &ss->ssl3.hs.resumptionContext,
- tls13_GetHashSize(ss)) == NULL) {
+ PORT_Assert(ss->statelessResume == (ss->ssl3.hs.resumptionPsk != NULL));
+ if (ss->statelessResume) {
+ PRUint8 buf[1] = { 0 };
+ SSL3Hashes hashes;
+
+ PORT_Assert(ss->ssl3.hs.resumptionPsk);
+ if (!ss->ssl3.hs.resumptionPsk) {
+ FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
return SECFailure;
}
- PORT_Memset(ss->ssl3.hs.resumptionContext.data, 0,
- ss->ssl3.hs.resumptionContext.len);
- }
-
- PRINT_BUF(50, (ss, "Resumption context",
- ss->ssl3.hs.resumptionContext.data,
- ss->ssl3.hs.resumptionContext.len));
- /* Now compute the Hash of the resumptionContext so we can cache
- * that. */
- ctx = PK11_CreateDigestContext(ssl3_HashTypeToOID(tls13_GetHash(ss)));
- if (!ctx) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
- rv |= PK11_DigestBegin(ctx);
- rv |= PK11_DigestOp(ctx,
- ss->ssl3.hs.resumptionContext.data,
- ss->ssl3.hs.resumptionContext.len);
- rv |= PK11_DigestFinal(ctx, hash, &len, sizeof(hash));
- PK11_DestroyContext(ctx, PR_TRUE);
- if (rv != SECSuccess)
- return SECFailure;
- PORT_Assert(len == tls13_GetHashSize(ss));
- PRINT_BUF(50, (ss, "Hash of resumption context", hash, len));
+ PK11_FreeSymKey(ss->ssl3.hs.resumptionPsk);
+ ss->ssl3.hs.resumptionPsk = NULL;
- /* Stuff it back into the resumptionContext. */
- SECITEM_FreeItem(&ss->ssl3.hs.resumptionContext, PR_FALSE);
- if (SECITEM_AllocItem(NULL, &ss->ssl3.hs.resumptionContext,
- tls13_GetHashSize(ss)) == NULL) {
- return SECFailure;
- }
- PORT_Memcpy(ss->ssl3.hs.resumptionContext.data, hash, len);
+ rv = PK11_HashBuf(ssl3_HashTypeToOID(tls13_GetHash(ss)),
+ hashes.u.raw, buf, 0);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
+ return SECFailure;
+ }
+ hashes.len = tls13_GetHashSize(ss);
- if (setup0Rtt) {
- /* Derive the early secret. */
rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret,
- kHkdfLabelClient,
- kHkdfLabelEarlyTrafficSecret,
- NULL,
- &ss->ssl3.hs.clientEarlyTrafficSecret);
- if (rv != SECSuccess)
+ NULL, kHkdfLabelPskBinderKey, &hashes,
+ &ss->ssl3.hs.pskBinderKey);
+ if (rv != SECSuccess) {
return SECFailure;
+ }
+ } else {
+ PORT_Assert(!ss->ssl3.hs.resumptionPsk);
}
return SECSuccess;
@@ -1282,9 +1261,8 @@ tls13_HandleClientHelloPart2(sslSocket *ss,
}
#endif
- /* Don't init hashes if this is the second ClientHello */
previousCipherSuite = ss->ssl3.hs.cipher_suite;
- rv = ssl3_NegotiateCipherSuite(ss, suites, !ss->ssl3.hs.helloRetry);
+ rv = ssl3_NegotiateCipherSuite(ss, suites, PR_FALSE);
if (rv != SECSuccess) {
FATAL_ERROR(ss, SSL_ERROR_NO_CYPHER_OVERLAP, handshake_failure);
goto loser;
@@ -1359,7 +1337,6 @@ tls13_HandleClientHelloPart2(sslSocket *ss,
FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
goto loser;
}
-
tls13_RestoreCipherInfo(ss, sid);
ss->sec.serverCert = ssl_FindServerCert(ss, &sid->certType);
@@ -1384,6 +1361,39 @@ tls13_HandleClientHelloPart2(sslSocket *ss,
tls13_NegotiateZeroRtt(ss, NULL);
}
+ /* Need to compute early secrets. */
+ rv = tls13_ComputeEarlySecrets(ss);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
+ return SECFailure;
+ }
+
+ /* Now that we have the binder key check the binder. */
+ if (ss->statelessResume) {
+ SSL3Hashes hashes;
+
+ rv = tls13_ComputePskBinderHash(ss, ss->xtnData.pskBinderPrefixLen,
+ &hashes);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
+ goto loser;
+ }
+
+ rv = tls13_VerifyFinished(ss, ss->ssl3.hs.pskBinderKey,
+ ss->xtnData.pskBinder.data,
+ ss->xtnData.pskBinder.len,
+ &hashes);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ }
+
+ /* This needs to go after we verify the psk binder. */
+ rv = ssl3_InitHandshakeHashes(ss);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
/* If this is TLS 1.3 we are expecting a ClientKeyShare
* extension. Missing/absent extension cause failure
* below. */
@@ -1416,40 +1426,24 @@ tls13_HandleClientHelloPart2(sslSocket *ss,
ss->sec.ci.sid = sid;
sid = NULL;
- rv = tls13_ComputeEarlySecrets(ss, ss->ssl3.hs.zeroRttState ==
- ssl_0rtt_accepted);
- if (rv != SECSuccess) {
- FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
- return SECFailure;
- }
-
if (ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted) {
- /* Store the handshake hash. We'll want it later. */
- ss->ssl3.hs.clientHelloHash = PK11_CloneContext(ss->ssl3.hs.sha);
- if (!ss->ssl3.hs.clientHelloHash) {
- FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
- return SECFailure;
- }
-
- rv = tls13_SetCipherSpec(ss, TrafficKeyEarlyHandshake,
- CipherSpecRead, PR_FALSE);
- if (rv != SECSuccess) {
- FATAL_ERROR(ss, PORT_GetError(), handshake_failure);
- return SECFailure;
- }
- TLS13_SET_HS_STATE(ss, wait_0rtt_finished);
- } else {
- PORT_Assert(ss->ssl3.hs.zeroRttState == ssl_0rtt_none ||
- ss->ssl3.hs.zeroRttState == ssl_0rtt_ignored);
- ssl_GetXmitBufLock(ss);
-
- rv = tls13_SendServerHelloSequence(ss);
- ssl_ReleaseXmitBufLock(ss);
+ rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret,
+ kHkdfLabelClient,
+ kHkdfLabelEarlyTrafficSecret,
+ NULL, /* Current running hash. */
+ &ss->ssl3.hs.clientEarlyTrafficSecret);
if (rv != SECSuccess) {
- FATAL_ERROR(ss, PORT_GetError(), handshake_failure);
+ FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
return SECFailure;
}
}
+ ssl_GetXmitBufLock(ss);
+ rv = tls13_SendServerHelloSequence(ss);
+ ssl_ReleaseXmitBufLock(ss);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, PORT_GetError(), handshake_failure);
+ return SECFailure;
+ }
return SECSuccess;
@@ -1534,11 +1528,6 @@ tls13_SendHelloRetryRequest(sslSocket *ss, const sslNamedGroupDef *selectedGroup
ss->ssl3.hs.zeroRttState = ssl_0rtt_ignored;
ss->ssl3.hs.zeroRttIgnore = ssl_0rtt_ignore_hrr;
}
- /* Clients will have sent Finished for 0-RTT. We won't be seeing them, so
- * we won't count them, but they will. */
- if (IS_DTLS(ss) && ss->ssl3.hs.zeroRttState == ssl_0rtt_ignored) {
- ss->ssl3.hs.recvMessageSeq++;
- }
return SECSuccess;
@@ -1961,12 +1950,6 @@ tls13_SendServerHelloSequence(sslSocket *ss)
PORT_Assert(ss->ssl3.hs.zeroRttState == ssl_0rtt_none ||
ss->ssl3.hs.zeroRttState == ssl_0rtt_ignored);
- /* If we are ignoring 0-RTT, then we will ignore a handshake
- * message. But the client will have counted them. */
- if (IS_DTLS(ss) && ss->ssl3.hs.zeroRttState == ssl_0rtt_ignored) {
- ss->ssl3.hs.recvMessageSeq++;
- }
-
rv = tls13_SetCipherSpec(ss,
TrafficKeyHandshake,
CipherSpecRead, PR_FALSE);
@@ -1992,16 +1975,15 @@ tls13_HandleServerHelloPart2(sslSocket *ss)
if (ssl3_ExtensionNegotiated(ss, ssl_tls13_pre_shared_key_xtn)) {
PORT_Assert(ss->statelessResume);
} else {
+ if (ss->ssl3.hs.currentSecret) {
+ PORT_Assert(ss->statelessResume);
+ PK11_FreeSymKey(ss->ssl3.hs.currentSecret);
+ ss->ssl3.hs.currentSecret = NULL;
+ }
ss->statelessResume = PR_FALSE;
}
if (ss->statelessResume) {
- if (ssl3_ExtensionNegotiated(ss, ssl_signature_algorithms_xtn)) {
- FATAL_ERROR(ss, SSL_ERROR_RX_UNEXPECTED_EXTENSION,
- unexpected_message);
- return SECFailure;
- }
-
if (ss->ssl3.hs.cipher_suite != sid->u.ssl3.cipherSuite) {
FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_SERVER_HELLO,
illegal_parameter);
@@ -2014,21 +1996,11 @@ tls13_HandleServerHelloPart2(sslSocket *ss)
ss->ssl3.hs.kea_def = &ss->ssl3.hs.kea_def_mutable;
if (ss->statelessResume) {
+ /* PSK */
PRBool cacheOK = PR_FALSE;
do {
ss->ssl3.hs.kea_def_mutable.authKeyType = ssl_auth_psk;
- /* If we offered early data, then we already have the shared secret
- * recovered. */
- if (ss->ssl3.hs.zeroRttState == ssl_0rtt_none) {
- rv = tls13_RecoverWrappedSharedSecret(ss, sid);
- if (rv != SECSuccess) {
- FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
- break;
- }
- } else {
- PORT_Assert(ss->ssl3.hs.currentSecret);
- }
cacheOK = PR_TRUE;
} while (0);
@@ -2046,14 +2018,7 @@ tls13_HandleServerHelloPart2(sslSocket *ss)
SSL_AtomicIncrementLong(&ssl3stats->hsh_sid_cache_hits);
SSL_AtomicIncrementLong(&ssl3stats->hsh_sid_stateless_resumes);
} else {
- if (ss->ssl3.hs.zeroRttState != ssl_0rtt_none) {
- PORT_Assert(ss->ssl3.hs.currentSecret);
- /* If we tried 0-RTT and didn't even get PSK, we need to clean
- * stuff up. */
- PK11_FreeSymKey(ss->ssl3.hs.currentSecret);
- ss->ssl3.hs.currentSecret = NULL;
- SECITEM_FreeItem(&ss->ssl3.hs.resumptionContext, PR_FALSE);
- }
+ /* !PSK */
if (ssl3_ClientExtensionAdvertised(ss, ssl_tls13_pre_shared_key_xtn)) {
SSL_AtomicIncrementLong(&ssl3stats->hsh_sid_cache_misses);
}
@@ -2076,11 +2041,11 @@ tls13_HandleServerHelloPart2(sslSocket *ss)
}
if (!ss->ssl3.hs.currentSecret) {
- PORT_Assert(!ss->statelessResume || ss->ssl3.hs.zeroRttState == ssl_0rtt_none);
+ PORT_Assert(!ss->statelessResume);
/* If we don't already have the Early Secret we need to make it
* now. */
- rv = tls13_ComputeEarlySecrets(ss, PR_FALSE);
+ rv = tls13_ComputeEarlySecrets(ss);
if (rv != SECSuccess) {
FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
return SECFailure;
@@ -2171,8 +2136,6 @@ tls13_HandleServerKeyShare(sslSocket *ss)
entry = (TLS13KeyShareEntry *)PR_NEXT_LINK(&ss->xtnData.remoteKeyShares);
PORT_Assert(PR_NEXT_LINK(&entry->link) == &ss->xtnData.remoteKeyShares);
- PORT_Assert(ssl_NamedGroupEnabled(ss, entry->group));
-
/* Now get our matching key. */
keyPair = ssl_LookupEphemeralKeyPair(ss, entry->group);
if (!keyPair) {
@@ -2180,6 +2143,8 @@ tls13_HandleServerKeyShare(sslSocket *ss)
return SECFailure;
}
+ PORT_Assert(ssl_NamedGroupEnabled(ss, entry->group));
+
rv = tls13_HandleKeyShare(ss, entry, keyPair->keys);
if (rv != SECSuccess)
return SECFailure; /* Error code set by caller. */
@@ -2262,7 +2227,7 @@ tls13_CipherSpecRelease(ssl3CipherSpec *spec)
/* Add context to the hash functions as described in
[draft-ietf-tls-tls13; Section 4.9.1] */
SECStatus
-tls13_AddContextToHashes(sslSocket *ss, const TLS13CombinedHash *hashes,
+tls13_AddContextToHashes(sslSocket *ss, const SSL3Hashes *hashes,
SSLHashType algorithm, PRBool sending,
SSL3Hashes *tbsHash)
{
@@ -2286,7 +2251,7 @@ tls13_AddContextToHashes(sslSocket *ss, const TLS13CombinedHash *hashes,
unsigned int hashlength;
/* Double check that we are doing the same hash.*/
- PORT_Assert(hashes->len == tls13_GetHashSize(ss) * 2);
+ PORT_Assert(hashes->len == tls13_GetHashSize(ss));
ctx = PK11_CreateDigestContext(ssl3_HashTypeToOID(algorithm));
if (!ctx) {
@@ -2297,13 +2262,13 @@ tls13_AddContextToHashes(sslSocket *ss, const TLS13CombinedHash *hashes,
PORT_Assert(SECFailure);
PORT_Assert(!SECSuccess);
- PRINT_BUF(50, (ss, "TLS 1.3 hash without context", hashes->hash, hashes->len));
+ PRINT_BUF(50, (ss, "TLS 1.3 hash without context", hashes->u.raw, hashes->len));
PRINT_BUF(50, (ss, "Context string", context_string, strlen(context_string)));
rv |= PK11_DigestBegin(ctx);
rv |= PK11_DigestOp(ctx, context_padding, sizeof(context_padding));
rv |= PK11_DigestOp(ctx, (unsigned char *)context_string,
strlen(context_string) + 1); /* +1 includes the terminating 0 */
- rv |= PK11_DigestOp(ctx, hashes->hash, hashes->len);
+ rv |= PK11_DigestOp(ctx, hashes->u.raw, hashes->len);
/* Update the hash in-place */
rv |= PK11_DigestFinal(ctx, tbsHash->u.raw, &hashlength, sizeof(tbsHash->u.raw));
PK11_DestroyContext(ctx, PR_TRUE);
@@ -2331,11 +2296,11 @@ static SECStatus
tls13_DeriveSecret(sslSocket *ss, PK11SymKey *key,
const char *prefix,
const char *suffix,
- const TLS13CombinedHash *hashes,
+ const SSL3Hashes *hashes,
PK11SymKey **dest)
{
SECStatus rv;
- TLS13CombinedHash hashesTmp;
+ SSL3Hashes hashesTmp;
char buf[100];
const char *label;
@@ -2365,7 +2330,7 @@ tls13_DeriveSecret(sslSocket *ss, PK11SymKey *key,
}
rv = tls13_HkdfExpandLabel(key, tls13_GetHash(ss),
- hashes->hash, hashes->len,
+ hashes->u.raw, hashes->len,
label, strlen(label),
tls13_GetHkdfMechanism(ss),
tls13_GetHashSize(ss), dest);
@@ -2419,11 +2384,6 @@ tls13_DeriveTrafficKeys(sslSocket *ss, ssl3CipherSpec *spec,
PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
switch (type) {
- case TrafficKeyEarlyHandshake:
- PORT_Assert(clientKey);
- phase = kHkdfPhaseEarlyHandshakeDataKeys;
- prkp = &ss->ssl3.hs.clientEarlyTrafficSecret;
- break;
case TrafficKeyEarlyApplicationData:
PORT_Assert(clientKey);
phase = kHkdfPhaseEarlyApplicationDataKeys;
@@ -2588,31 +2548,12 @@ tls13_SetCipherSpec(sslSocket *ss, TrafficKeyType type,
return SECSuccess;
}
-static void
-tls13_CombineHashes(sslSocket *ss, const PRUint8 *hhash,
- unsigned int hlen, TLS13CombinedHash *hashes)
-{
- PORT_Assert(hlen == tls13_GetHashSize(ss));
- PORT_Memcpy(hashes->hash, hhash, hlen);
- hashes->len = hlen;
-
- PORT_Assert(ss->ssl3.hs.resumptionContext.len == tls13_GetHashSize(ss));
- PORT_Memcpy(hashes->hash + hlen,
- ss->ssl3.hs.resumptionContext.data,
- ss->ssl3.hs.resumptionContext.len);
- hashes->len += ss->ssl3.hs.resumptionContext.len;
- PRINT_BUF(10, (NULL, "Combined handshake hash computed ",
- hashes->hash, hashes->len));
-}
-
static SECStatus
tls13_ComputeHandshakeHashes(sslSocket *ss,
- TLS13CombinedHash *hashes)
+ SSL3Hashes *hashes)
{
SECStatus rv;
PK11Context *ctx = NULL;
- PRUint8 buf[HASH_LENGTH_MAX];
- unsigned int len;
PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
if (ss->ssl3.hs.hashType == handshake_hash_unknown) {
@@ -2647,15 +2588,16 @@ tls13_ComputeHandshakeHashes(sslSocket *ss,
}
}
- rv = PK11_DigestFinal(ctx, buf, &len, sizeof(buf));
+ rv = PK11_DigestFinal(ctx, hashes->u.raw,
+ &hashes->len,
+ sizeof(hashes->u.raw));
if (rv != SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
goto loser;
}
- PORT_Assert(len == tls13_GetHashSize(ss));
+ PORT_Assert(hashes->len == tls13_GetHashSize(ss));
PK11_DestroyContext(ctx, PR_TRUE);
- tls13_CombineHashes(ss, buf, len, hashes);
return SECSuccess;
loser:
@@ -2921,7 +2863,6 @@ tls13_SendEncryptedExtensions(sslSocket *ss)
PRInt32 sent_len = 0;
PRUint32 maxBytes = 65535;
- /* TODO(ekr@rtfm.com): Implement the ticket_age xtn. */
SSL_TRC(3, ("%d: TLS13[%d]: send encrypted extensions handshake",
SSL_GETPID(), ss->fd));
@@ -2962,7 +2903,7 @@ tls13_SendCertificateVerify(sslSocket *ss, SECKEYPrivateKey *privKey)
SECItem buf = { siBuffer, NULL, 0 };
unsigned int len;
SSLHashType hashAlg;
- TLS13CombinedHash hash;
+ SSL3Hashes hash;
SSL3Hashes tbsHash; /* The hash "to be signed". */
PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
@@ -3042,7 +2983,7 @@ done:
*/
SECStatus
tls13_HandleCertificateVerify(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
- TLS13CombinedHash *hashes)
+ SSL3Hashes *hashes)
{
SECItem signed_hash = { siBuffer, NULL, 0 };
SECStatus rv;
@@ -3132,8 +3073,55 @@ tls13_HandleCertificateVerify(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
}
static SECStatus
+tls13_ComputePskBinderHash(sslSocket *ss, unsigned long prefixLength,
+ SSL3Hashes *hashes)
+{
+ SECStatus rv;
+
+ PORT_Assert(ss->ssl3.hs.hashType == handshake_hash_unknown);
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert(prefixLength <= ss->ssl3.hs.messages.len);
+
+ PRINT_BUF(10, (NULL, "Handshake hash computed over ClientHello prefix",
+ ss->ssl3.hs.messages.buf, prefixLength));
+ rv = PK11_HashBuf(ssl3_HashTypeToOID(tls13_GetHash(ss)),
+ hashes->u.raw,
+ ss->ssl3.hs.messages.buf, prefixLength);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
+ goto loser;
+ }
+ hashes->len = tls13_GetHashSize(ss);
+
+ PRINT_BUF(10, (NULL, "PSK Binder hash",
+ hashes->u.raw, hashes->len));
+
+ return SECSuccess;
+
+loser:
+ return SECFailure;
+}
+/* Compute the PSK Binder This is kind of sneaky.*/
+SECStatus
+tls13_ComputePskBinder(sslSocket *ss, PRBool sending,
+ unsigned int prefixLength,
+ PRUint8 *output, unsigned int *outputLen,
+ unsigned int maxOutputLen)
+{
+ SSL3Hashes hashes;
+ SECStatus rv;
+
+ rv = tls13_ComputePskBinderHash(ss, prefixLength, &hashes);
+ if (rv != SECSuccess)
+ return SECFailure;
+
+ return tls13_ComputeFinished(ss, ss->ssl3.hs.pskBinderKey, &hashes,
+ sending, output, outputLen, maxOutputLen);
+}
+
+static SECStatus
tls13_ComputeFinished(sslSocket *ss, PK11SymKey *baseKey,
- const TLS13CombinedHash *hashes,
+ const SSL3Hashes *hashes,
PRBool sending, PRUint8 *output, unsigned int *outputLen,
unsigned int maxOutputLen)
{
@@ -3146,7 +3134,7 @@ tls13_ComputeFinished(sslSocket *ss, PK11SymKey *baseKey,
PK11SymKey *secret = NULL;
PORT_Assert(baseKey);
- PRINT_BUF(50, (NULL, "Handshake hash", hashes->hash, hashes->len));
+ PRINT_BUF(50, (NULL, "Handshake hash", hashes->u.raw, hashes->len));
/* Now derive the appropriate finished secret from the base secret. */
rv = tls13_HkdfExpandLabel(baseKey,
@@ -3159,8 +3147,8 @@ tls13_ComputeFinished(sslSocket *ss, PK11SymKey *baseKey,
goto abort;
}
- PRINT_BUF(50, (NULL, "Handshake hash", hashes->hash, hashes->len));
- PORT_Assert(hashes->len == tls13_GetHashSize(ss) * 2);
+ PRINT_BUF(50, (NULL, "Handshake hash", hashes->u.raw, hashes->len));
+ PORT_Assert(hashes->len == tls13_GetHashSize(ss));
hmacCtx = PK11_CreateContextBySymKey(macAlg, CKA_SIGN,
secret, &param);
if (!hmacCtx) {
@@ -3171,7 +3159,7 @@ tls13_ComputeFinished(sslSocket *ss, PK11SymKey *baseKey,
if (rv != SECSuccess)
goto abort;
- rv = PK11_DigestOp(hmacCtx, hashes->hash, hashes->len);
+ rv = PK11_DigestOp(hmacCtx, hashes->u.raw, hashes->len);
if (rv != SECSuccess)
goto abort;
@@ -3202,9 +3190,9 @@ static SECStatus
tls13_SendFinished(sslSocket *ss, PK11SymKey *baseKey)
{
SECStatus rv;
- PRUint8 finishedBuf[MAX_FINISHED_SIZE];
+ PRUint8 finishedBuf[TLS13_MAX_FINISHED_SIZE];
unsigned int finishedLen;
- TLS13CombinedHash hashes;
+ SSL3Hashes hashes;
SSL_TRC(3, ("%d: TLS13[%d]: send finished handshake", SSL_GETPID(), ss->fd));
@@ -3243,10 +3231,10 @@ tls13_SendFinished(sslSocket *ss, PK11SymKey *baseKey)
static SECStatus
tls13_VerifyFinished(sslSocket *ss, PK11SymKey *secret,
SSL3Opaque *b, PRUint32 length,
- const TLS13CombinedHash *hashes)
+ const SSL3Hashes *hashes)
{
SECStatus rv;
- PRUint8 finishedBuf[MAX_FINISHED_SIZE];
+ PRUint8 finishedBuf[TLS13_MAX_FINISHED_SIZE];
unsigned int finishedLen;
if (!hashes) {
@@ -3277,14 +3265,14 @@ tls13_VerifyFinished(sslSocket *ss, PK11SymKey *secret,
static SECStatus
tls13_ClientHandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
- const TLS13CombinedHash *hashes)
+ const SSL3Hashes *hashes)
{
SECStatus rv;
PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
- SSL_TRC(3, ("%d: TLS13[%d]: server handle finished handshake",
+ SSL_TRC(3, ("%d: TLS13[%d]: client handle finished handshake",
SSL_GETPID(), ss->fd));
rv = TLS13_CHECK_HS_STATE(ss, SSL_ERROR_RX_UNEXPECTED_FINISHED,
@@ -3303,7 +3291,7 @@ tls13_ClientHandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
static SECStatus
tls13_ServerHandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
- const TLS13CombinedHash *hashes)
+ const SSL3Hashes *hashes)
{
SECStatus rv;
PK11SymKey *secret;
@@ -3314,8 +3302,7 @@ tls13_ServerHandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
SSL_TRC(3, ("%d: TLS13[%d]: server handle finished handshake",
SSL_GETPID(), ss->fd));
- rv = TLS13_CHECK_HS_STATE(ss, SSL_ERROR_RX_UNEXPECTED_FINISHED, wait_finished,
- wait_0rtt_finished);
+ rv = TLS13_CHECK_HS_STATE(ss, SSL_ERROR_RX_UNEXPECTED_FINISHED, wait_finished);
if (rv != SECSuccess) {
return SECFailure;
}
@@ -3330,46 +3317,29 @@ tls13_ServerHandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
if (rv != SECSuccess)
return SECFailure;
- if (TLS13_IN_HS_STATE(ss, wait_0rtt_finished)) {
- /* Reset the hashes. */
- PORT_Assert(ss->ssl3.hs.sha);
- PORT_Assert(ss->ssl3.hs.clientHelloHash);
- PK11_DestroyContext(ss->ssl3.hs.sha, PR_TRUE);
- ss->ssl3.hs.sha = ss->ssl3.hs.clientHelloHash;
- ss->ssl3.hs.clientHelloHash = NULL;
-
- ssl_GetXmitBufLock(ss);
- rv = tls13_SendServerHelloSequence(ss);
- ssl_ReleaseXmitBufLock(ss);
- if (rv != SECSuccess) {
- FATAL_ERROR(ss, PORT_GetError(), handshake_failure);
- return SECFailure;
- }
- } else {
- rv = tls13_SetCipherSpec(ss, TrafficKeyApplicationData,
- CipherSpecRead, PR_TRUE);
- if (rv != SECSuccess) {
- FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
- return SECFailure;
- }
+ rv = tls13_SetCipherSpec(ss, TrafficKeyApplicationData,
+ CipherSpecRead, PR_TRUE);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
+ return SECFailure;
+ }
- rv = tls13_FinishHandshake(ss);
+ rv = tls13_FinishHandshake(ss);
+ if (rv != SECSuccess) {
+ return SECFailure; /* Error code and alerts handled below */
+ }
+ ssl_GetXmitBufLock(ss);
+ if (ss->opt.enableSessionTickets) {
+ rv = tls13_SendNewSessionTicket(ss);
if (rv != SECSuccess) {
+ ssl_ReleaseXmitBufLock(ss);
return SECFailure; /* Error code and alerts handled below */
}
- ssl_GetXmitBufLock(ss);
- if (ss->opt.enableSessionTickets) {
- rv = tls13_SendNewSessionTicket(ss);
- if (rv != SECSuccess) {
- ssl_ReleaseXmitBufLock(ss);
- return SECFailure; /* Error code and alerts handled below */
- }
- rv = ssl3_FlushHandshake(ss, 0);
- }
- ssl_ReleaseXmitBufLock(ss);
- if (rv != SECSuccess)
- return SECFailure;
+ rv = ssl3_FlushHandshake(ss, 0);
}
+ ssl_ReleaseXmitBufLock(ss);
+ if (rv != SECSuccess)
+ return SECFailure;
return SECSuccess;
}
@@ -3985,7 +3955,9 @@ tls13_UnprotectRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *plaintext
if ((IS_DTLS(ss) && cText->version != kDtlsRecordVersion) ||
(!IS_DTLS(ss) && cText->version != kTlsRecordVersion)) {
/* Do we need a better error here? */
- PORT_SetError(SSL_ERROR_BAD_MAC_READ);
+ SSL_TRC(3,
+ ("%d: TLS13[%d]: record has bogus version",
+ SSL_GETPID(), ss->fd));
return SECFailure;
}
@@ -4020,6 +3992,9 @@ tls13_UnprotectRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *plaintext
/* Bogus padding. */
if (plaintext->len < 1) {
+ SSL_TRC(3,
+ ("%d: TLS13[%d]: empty record",
+ SSL_GETPID(), ss->fd, cText->type));
/* It's safe to report this specifically because it happened
* after the MAC has been verified. */
PORT_SetError(SSL_ERROR_BAD_BLOCK_PADDING);
@@ -4030,6 +4005,11 @@ tls13_UnprotectRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *plaintext
cText->type = plaintext->buf[plaintext->len - 1];
--plaintext->len;
+ SSL_TRC(10,
+ ("%d: TLS13[%d]: %s received record of length=%d type=%d",
+ SSL_GETPID(), ss->fd, SSL_ROLE(ss),
+ plaintext->len, cText->type));
+
return SECSuccess;
}
@@ -4065,7 +4045,6 @@ SECStatus
tls13_MaybeDo0RTTHandshake(sslSocket *ss)
{
SECStatus rv;
- int bufferLen = ss->ssl3.hs.messages.len;
/* Don't do anything if there is no early_data xtn, which means we're
* not doing early data. */
@@ -4076,12 +4055,6 @@ tls13_MaybeDo0RTTHandshake(sslSocket *ss)
SSL_TRC(3, ("%d: TLS13[%d]: in 0-RTT mode", SSL_GETPID(), ss->fd));
- rv = tls13_RecoverWrappedSharedSecret(ss, ss->sec.ci.sid);
- if (rv != SECSuccess) {
- FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
- return SECFailure;
- }
-
/* Set the ALPN data as if it was negotiated. We check in the ServerHello
* handler that the server negotiates the same value. */
if (ss->sec.ci.sid->u.ssl3.alpnSelection.len) {
@@ -4092,41 +4065,24 @@ tls13_MaybeDo0RTTHandshake(sslSocket *ss)
return rv;
}
- /* Need to do this first so we know the PRF for the early secret
- * computation. */
- rv = ssl3_SetCipherSuite(ss, ss->sec.ci.sid->u.ssl3.cipherSuite, PR_FALSE);
- if (rv != SECSuccess)
- return rv;
- ss->ssl3.hs.preliminaryInfo = 0; /* TODO(ekr@rtfm.com) Fill this in.
- * bug 1281255. */
- rv = tls13_ComputeEarlySecrets(ss, PR_TRUE);
- if (rv != SECSuccess) {
- FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
- return SECFailure;
- }
-
+ /* Null spec... */
ssl_GetSpecReadLock(ss);
ss->ssl3.hs.nullSpec = ss->ssl3.cwSpec;
tls13_CipherSpecAddRef(ss->ssl3.hs.nullSpec);
ssl_ReleaseSpecReadLock(ss);
- rv = tls13_SetCipherSpec(ss, TrafficKeyEarlyHandshake,
- CipherSpecWrite, PR_FALSE);
- if (rv != SECSuccess) {
- FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
- return SECFailure;
- }
+ /* Cipher suite already set in tls13_SetupClientHello. */
+ ss->ssl3.hs.preliminaryInfo = 0; /* TODO(ekr@rtfm.com) Fill this in.
+ * bug 1281255. */
- rv = tls13_SendFinished(ss, ss->ssl3.hs.clientEarlyTrafficSecret);
- if (rv != SECSuccess) {
+ rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret,
+ kHkdfLabelClient,
+ kHkdfLabelEarlyTrafficSecret,
+ NULL,
+ &ss->ssl3.hs.clientEarlyTrafficSecret);
+ if (rv != SECSuccess)
return SECFailure;
- }
-
- /* Restore the handshake hashes to where they were before we
- * sent Finished. */
- ss->ssl3.hs.messages.len = bufferLen;
- /* We can destroy the early traffic secret now. */
rv = tls13_SetCipherSpec(ss, TrafficKeyEarlyApplicationData,
CipherSpecWrite, PR_TRUE);
if (rv != SECSuccess) {
diff --git a/lib/ssl/tls13con.h b/lib/ssl/tls13con.h
index 9dcabe01b..c39c62a69 100644
--- a/lib/ssl/tls13con.h
+++ b/lib/ssl/tls13con.h
@@ -14,6 +14,8 @@ typedef enum {
EphemeralSharedSecret
} SharedSecretType;
+#define TLS13_MAX_FINISHED_SIZE 64
+
SECStatus tls13_UnprotectRecord(
sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *plaintext,
SSL3AlertDescription *alert);
@@ -34,7 +36,10 @@ PRBool tls13_InHsState(sslSocket *ss, ...);
#define TLS13_IN_HS_STATE(ss, ...) \
tls13_InHsState(ss, __VA_ARGS__, wait_invalid)
-SSLHashType tls13_GetHash(sslSocket *ss);
+SSLHashType tls13_GetHashForCipherSuite(ssl3CipherSuite suite);
+SSLHashType tls13_GetHash(const sslSocket *ss);
+unsigned int tls13_GetHashSizeForHash(SSLHashType hash);
+unsigned int tls13_GetHashSize(const sslSocket *ss);
CK_MECHANISM_TYPE tls13_GetHkdfMechanism(sslSocket *ss);
void tls13_FatalError(sslSocket *ss, PRErrorCode prError,
SSL3AlertDescription desc);
@@ -43,6 +48,10 @@ SECStatus tls13_MaybeDo0RTTHandshake(sslSocket *ss);
PRBool tls13_AllowPskCipher(const sslSocket *ss,
const ssl3CipherSuiteDef *cipher_def);
PRBool tls13_PskSuiteEnabled(sslSocket *ss);
+SECStatus tls13_ComputePskBinder(sslSocket *ss, PRBool sending,
+ unsigned int prefixLength,
+ PRUint8 *output, unsigned int *outputLen,
+ unsigned int maxOutputLen);
SECStatus tls13_HandleClientHelloPart2(sslSocket *ss,
const SECItem *suites,
sslSessionID *sid);
diff --git a/lib/ssl/tls13exthandle.c b/lib/ssl/tls13exthandle.c
index bf766a429..37e009a4e 100644
--- a/lib/ssl/tls13exthandle.c
+++ b/lib/ssl/tls13exthandle.c
@@ -427,23 +427,27 @@ loser:
/* Called by clients.
*
- * struct {
- * PskKeyExchangeMode ke_modes<1..255>;
- * PskAuthMode auth_modes<1..255>;
- * opaque identity<0..2^16-1>;
- * } PskIdentity;
+ * struct {
+ * opaque identity<0..2^16-1>;
+ * uint32 obfuscated_ticket_age;
+ * } PskIdentity;
*
- * struct {
- * select (Role) {
- * case client:
- * PskIdentity identities<2..2^16-1>;
- * case server:
- * uint16 selected_identity;
- * }
- * } PreSharedKeyExtension;
+ * opaque PskBinderEntry<32..255>;
*
+ * struct {
+ * select (Handshake.msg_type) {
+ * case client_hello:
+ * PskIdentity identities<6..2^16-1>;
+ * PskBinderEntry binders<33..2^16-1>;
+ *
+ * case server_hello:
+ * uint16 selected_identity;
+ * };
+ *
+ * } PreSharedKeyExtension;
+
* Presently the only way to get a PSK is by resumption, so this is
- * really a ticket label and there wll be at most one.
+ * really a ticket label and there will be at most one.
*/
PRInt32
tls13_ClientSendPreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData,
@@ -451,6 +455,8 @@ tls13_ClientSendPreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData,
PRUint32 maxBytes)
{
PRInt32 extension_length;
+ PRInt32 identities_length;
+ PRInt32 binders_length;
NewSessionTicket *session_ticket;
/* We only set statelessResume on the client in TLS 1.3 code. */
@@ -459,11 +465,20 @@ tls13_ClientSendPreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData,
PORT_Assert(ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_3);
+ /* The length computations are simplified by the fact that there
+ * is just one ticket at most. */
session_ticket = &ss->sec.ci.sid->u.ssl3.locked.sessionTicket;
-
+ identities_length =
+ 2 + /* vector length */
+ 2 + session_ticket->ticket.len + /* identity length + ticket len */
+ 4; /* obfuscated_ticket_age */
+ binders_length =
+ 2 + /* vector length */
+ 1 + tls13_GetHashSizeForHash(
+ tls13_GetHashForCipherSuite(ss->sec.ci.sid->u.ssl3.cipherSuite));
extension_length =
- 2 + 2 + 2 + /* Type + length + vector length */
- 2 + session_ticket->ticket.len; /* identity length + ticket len */
+ 2 + 2 + /* Type + length */
+ identities_length + binders_length;
if (maxBytes < (PRUint32)extension_length) {
PORT_Assert(0);
@@ -472,6 +487,11 @@ tls13_ClientSendPreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData,
if (append) {
SECStatus rv;
+ PRUint32 age;
+ unsigned int prefixLength;
+ PRUint8 binder[TLS13_MAX_FINISHED_SIZE];
+ unsigned int binderLen;
+
/* extension_type */
rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_pre_shared_key_xtn, 2);
if (rv != SECSuccess)
@@ -479,11 +499,37 @@ tls13_ClientSendPreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData,
rv = ssl3_ExtAppendHandshakeNumber(ss, extension_length - 4, 2);
if (rv != SECSuccess)
goto loser;
- rv = ssl3_ExtAppendHandshakeNumber(ss, extension_length - 6, 2);
+ rv = ssl3_ExtAppendHandshakeNumber(ss, identities_length - 2, 2);
if (rv != SECSuccess)
goto loser;
rv = ssl3_ExtAppendHandshakeVariable(ss, session_ticket->ticket.data,
- session_ticket->ticket.len, 2);
+ session_ticket->ticket.len, 2);
+ if (rv != SECSuccess)
+ goto loser;
+
+ /* Obfuscated age. */
+ age = ssl_Time() - session_ticket->received_timestamp;
+ age += session_ticket->ticket_age_add;
+ rv = ssl3_ExtAppendHandshakeNumber(ss, age, 4);
+ if (rv != SECSuccess)
+ goto loser;
+
+ /* Now the binders. */
+ prefixLength = ss->ssl3.hs.messages.len;
+ rv = tls13_ComputePskBinder(CONST_CAST(sslSocket, ss), PR_TRUE,
+ prefixLength, binder, &binderLen,
+ sizeof(binder));
+ if (rv != SECSuccess)
+ goto loser;
+ PORT_Assert(binderLen == tls13_GetHashSize(ss));
+ rv = ssl3_ExtAppendHandshakeNumber(ss, binders_length - 2, 2);
+ if (rv != SECSuccess)
+ goto loser;
+ rv = ssl3_ExtAppendHandshakeVariable(ss,
+ binder, binderLen, 1);
+ if (rv != SECSuccess)
+ goto loser;
+
PRINT_BUF(50, (ss, "Sending PreSharedKey value",
session_ticket->ticket.data,
session_ticket->ticket.len));
@@ -507,9 +553,10 @@ SECStatus
tls13_ServerHandlePreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
SECItem *data)
{
- PRInt32 len;
- PRBool first = PR_TRUE;
+ SECItem inner;
SECStatus rv;
+ unsigned int numIdentities = 0;
+ unsigned int numBinders = 0;
SSL_TRC(3, ("%d: SSL3[%d]: handle pre_shared_key extension",
SSL_GETPID(), ss->fd));
@@ -519,41 +566,75 @@ tls13_ServerHandlePreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData
return SECSuccess;
}
- len = ssl3_ExtConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
- if (len < 0)
- return SECFailure;
-
- if (len != data->len) {
- PORT_SetError(SSL_ERROR_MALFORMED_PRE_SHARED_KEY);
+ /* Parse the identities list. */
+ rv = ssl3_ExtConsumeHandshakeVariable(ss,
+ &inner, 2, &data->data, &data->len);
+ if (rv != SECSuccess) {
return SECFailure;
}
- while (data->len) {
+ while (inner.len) {
SECItem label;
+ PRUint32 utmp;
rv = ssl3_ExtConsumeHandshakeVariable(ss, &label, 2,
- &data->data, &data->len);
+ &inner.data, &inner.len);
if (rv != SECSuccess)
return rv;
if (!label.len) {
goto alert_loser;
}
- if (first) {
- first = PR_FALSE; /* Continue to read through the extension to check
- * the format. */
+ /* Read and discard session ticket age. Bug 1295163 */
+ rv = ssl3_ExtConsumeHandshake(ss, &utmp, 4,
+ &inner.data, &inner.len);
+ if (rv != SECSuccess)
+ return rv;
+
+ if (!numIdentities) {
PRINT_BUF(50, (ss, "Handling PreSharedKey value",
label.data, label.len));
- rv = ssl3_ProcessSessionTicketCommon(CONST_CAST(sslSocket, ss),
- &label);
+ rv = ssl3_ProcessSessionTicketCommon(
+ CONST_CAST(sslSocket, ss), &label);
/* This only happens if we have an internal error, not
* a malformed ticket. Bogus tickets just don't resume
* and return SECSuccess. */
if (rv != SECSuccess)
- return rv;
+ return SECFailure;
}
+ ++numIdentities;
}
+ xtnData->pskBinderPrefixLen = ss->ssl3.hs.messages.len - data->len;
+
+ /* Parse the binders list. */
+ rv = ssl3_ExtConsumeHandshakeVariable(ss,
+ &inner, 2, &data->data, &data->len);
+ if (rv != SECSuccess)
+ return SECFailure;
+ if (data->len) {
+ goto alert_loser;
+ }
+
+ while (inner.len) {
+ SECItem binder;
+ rv = ssl3_ExtConsumeHandshakeVariable(ss, &binder, 1,
+ &inner.data, &inner.len);
+ if (rv != SECSuccess)
+ return rv;
+ if (binder.len < 32) {
+ goto alert_loser;
+ }
+
+ if (!numBinders) {
+ xtnData->pskBinder = binder;
+ }
+ ++numBinders;
+ }
+
+ if (numBinders != numIdentities)
+ goto alert_loser;
+
/* Keep track of negotiated extensions. Note that this does not
* mean we are resuming. */
xtnData->negotiated[xtnData->numNegotiated++] = ex_type;
@@ -637,54 +718,35 @@ tls13_ClientHandlePreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData
return SECSuccess;
}
+
/*
- * struct {
- * select (Role) {
- * case client:
- * uint32 obfuscated_ticket_age;
- *
- * case server:
- * struct {};
- * }
- * } EarlyDataIndication;
+ * struct { } EarlyDataIndication;
*/
PRInt32
tls13_ClientSendEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData,
PRBool append,
PRUint32 maxBytes)
{
- PRInt32 extension_length;
SECStatus rv;
- NewSessionTicket *session_ticket;
+ PRInt32 extension_length;
if (!tls13_ClientAllow0Rtt(ss, ss->sec.ci.sid))
return 0;
- /* type + length + obfuscated ticket age. */
- extension_length = 2 + 2 + 4;
+ /* type + length */
+ extension_length = 2 + 2;
if (maxBytes < (PRUint32)extension_length) {
PORT_Assert(0);
return 0;
}
- session_ticket = &ss->sec.ci.sid->u.ssl3.locked.sessionTicket;
if (append) {
- PRUint32 age;
-
rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_early_data_xtn, 2);
if (rv != SECSuccess)
return -1;
- rv = ssl3_ExtAppendHandshakeNumber(ss, extension_length - 4, 2);
- if (rv != SECSuccess)
- return -1;
-
- /* Obfuscated age. */
- age = ssl_Time() - session_ticket->received_timestamp;
- age += session_ticket->ticket_age_add;
-
- rv = ssl3_ExtAppendHandshakeNumber(ss, age, 4);
+ rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2);
if (rv != SECSuccess)
return -1;
}
@@ -699,9 +761,6 @@ SECStatus
tls13_ServerHandleEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
SECItem *data)
{
- PRUint32 obfuscated_ticket_age;
- SECStatus rv;
-
SSL_TRC(3, ("%d: TLS13[%d]: handle early_data extension",
SSL_GETPID(), ss->fd));
@@ -710,13 +769,6 @@ tls13_ServerHandleEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData, P
return SECSuccess;
}
- /* Obfuscated ticket age. Ignore. Bug 1295163. */
- rv = ssl3_ExtConsumeHandshake(ss, &obfuscated_ticket_age, 4,
- &data->data, &data->len);
- if (rv != SECSuccess) {
- return SECFailure;
- }
-
if (data->len) {
PORT_SetError(SSL_ERROR_MALFORMED_EARLY_DATA);
return SECFailure;
diff --git a/lib/ssl/tls13hkdf.c b/lib/ssl/tls13hkdf.c
index 71fe25509..97c98a43e 100644
--- a/lib/ssl/tls13hkdf.c
+++ b/lib/ssl/tls13hkdf.c
@@ -141,7 +141,7 @@ tls13_HkdfExpandLabel(PK11SymKey *prk, SSLHashType baseHash,
const unsigned int kLabelPrefixLen = strlen(kLabelPrefix);
if (handshakeHash) {
- PORT_Assert(handshakeHashLen == kTlsHkdfInfo[baseHash].hashSize * 2);
+ PORT_Assert(handshakeHashLen == kTlsHkdfInfo[baseHash].hashSize);
} else {
PORT_Assert(!handshakeHashLen);
}