Merge pull request #1235 from SparkiDev/tls13_draft21

Update code to support Draft 21 of TLS v1.3
This commit is contained in:
toddouska 2017-11-17 13:11:03 -08:00 committed by GitHub
commit 21e391fbce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 156 additions and 3 deletions

View File

@ -23270,6 +23270,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
#ifdef WOLFSSL_TLS13
word32 ageAdd; /* Obfuscation of age */
byte namedGroup; /* Named group used */
#ifndef WOLFSSL_TLS13_DRAFT_18
TicketNonce ticketNonce; /* Ticket nonce */
#endif
#ifdef WOLFSSL_EARLY_DATA
word32 maxEarlyDataSz; /* Max size of early data */
#endif
@ -23325,6 +23328,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
it.timestamp = TimeNowInMilliseconds();
/* Resumption master secret. */
XMEMCPY(it.msecret, ssl->session.masterSecret, SECRET_LEN);
#ifndef WOLFSSL_TLS13_DRAFT_18
XMEMCPY(&it.ticketNonce, &ssl->session.ticketNonce,
sizeof(TicketNonce));
#endif
#endif
}
@ -23437,6 +23444,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
#endif
/* Resumption master secret. */
XMEMCPY(ssl->session.masterSecret, it->msecret, SECRET_LEN);
#ifndef WOLFSSL_TLS13_DRAFT_18
XMEMCPY(&ssl->session.ticketNonce, &it->ticketNonce,
sizeof(TicketNonce));
#endif
ssl->session.namedGroup = it->namedGroup;
#endif
}

View File

@ -9789,6 +9789,10 @@ static int GetDeepCopySession(WOLFSSL* ssl, WOLFSSL_SESSION* copyFrom)
copyInto->namedGroup = copyFrom->namedGroup;
copyInto->ticketSeen = copyFrom->ticketSeen;
copyInto->ticketAdd = copyFrom->ticketAdd;
#ifndef WOLFSSL_TLS13_DRAFT_18
XMEMCPY(&copyInto->ticketNonce, &copyFrom->ticketNonce,
sizeof(TicketNonce));
#endif
#ifdef WOLFSSL_EARLY_DATA
copyInto->maxEarlyDataSz = copyFrom->maxEarlyDataSz;
#endif
@ -10021,6 +10025,10 @@ int AddSession(WOLFSSL* ssl)
session->namedGroup = ssl->session.namedGroup;
session->ticketSeen = ssl->session.ticketSeen;
session->ticketAdd = ssl->session.ticketAdd;
#ifndef WOLFSSL_TLS13_DRAFT_18
XMEMCPY(&session->ticketNonce, &ssl->session.ticketNonce,
sizeof(TicketNonce));
#endif
#ifdef WOLFSSL_EARLY_DATA
session->maxEarlyDataSz = ssl->session.maxEarlyDataSz;
#endif

View File

@ -3093,7 +3093,7 @@ static int TLSX_SupportedCurve_Parse(WOLFSSL* ssl, byte* input, word16 length,
word16 name;
int ret;
if(!isRequest)
if(!isRequest && !IsAtLeastTLSv1_3(ssl->version))
return BUFFER_ERROR; /* servers doesn't send this extension. */
if (OPAQUE16_LEN > length || length % OPAQUE16_LEN)
@ -8172,6 +8172,7 @@ word16 TLSX_GetResponseSize(WOLFSSL* ssl, byte msgType)
#endif
#ifdef WOLFSSL_TLS13
case encrypted_extensions:
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EC_POINT_FORMATS));
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SESSION_TICKET));
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
@ -8258,6 +8259,7 @@ word16 TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType)
#endif
#ifdef WOLFSSL_TLS13
case encrypted_extensions:
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EC_POINT_FORMATS));
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SESSION_TICKET));
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)

View File

@ -169,6 +169,7 @@ static int Tls13_HKDF_Extract(byte* prk, const byte* salt, int saltLen,
* TLS v1.3 defines this function.
*
* okm The generated pseudorandom key - output key material.
* okmLen The length of generated pseudorandom key - output key material.
* prk The salt - pseudo-random key.
* prkLen The length of the salt - pseudo-random key.
* protocol The TLS protocol label.
@ -808,6 +809,62 @@ static int DeriveMasterSecret(WOLFSSL* ssl)
#endif
}
#ifndef WOLFSSL_TLS13_DRAFT_18
#if defined(HAVE_SESSION_TICKET)
/* Length of the resumption label. */
#define RESUMPTION_LABEL_SZ 10
/* Resumption label for generating PSK assocated with the ticket. */
static const byte resumptionLabel[RESUMPTION_LABEL_SZ+1] = "resumption";
/* Derive the PSK assocated with the ticket.
*
* ssl The SSL/TLS object.
* nonce The nonce to derive with.
* nonceLen The length of the nonce to derive with.
* secret The derived secret.
* returns 0 on success, otherwise failure.
*/
static int DeriveResumptionPSK(WOLFSSL* ssl, byte* nonce, byte nonceLen,
byte* secret)
{
int digestAlg;
/* Only one protocol version defined at this time. */
const byte* protocol = tls13ProtocolLabel;
word32 protocolLen = TLS13_PROTOCOL_LABEL_SZ;
WOLFSSL_MSG("Derive Resumption PSK");
switch (ssl->specs.mac_algorithm) {
#ifndef NO_SHA256
case sha256_mac:
digestAlg = WC_SHA256;
break;
#endif
#ifdef WOLFSSL_SHA384
case sha384_mac:
digestAlg = WC_SHA256;
break;
#endif
#ifdef WOLFSSL_TLS13_TLS13_SHA512
case sha512_mac:
digestAlg = WC_SHA256;
break;
#endif
default:
return BAD_FUNC_ARG;
}
return HKDF_Expand_Label(secret, ssl->specs.hash_size,
ssl->session.masterSecret, ssl->specs.hash_size,
protocol, protocolLen, resumptionLabel,
RESUMPTION_LABEL_SZ, nonce, nonceLen, digestAlg);
}
#endif /* HAVE_SESSION_TICKET */
#endif /* WOLFSSL_TLS13_DRAFT_18 */
/* Calculate the HMAC of message data to this point.
*
* ssl The SSL/TLS object.
@ -2055,8 +2112,15 @@ static int SetupPskKey(WOLFSSL* ssl, PreSharedKey* psk)
#endif
/* Resumption PSK is master secret. */
ssl->arrays->psk_keySz = ssl->specs.hash_size;
#ifdef WOLFSSL_TLS13_DRAFT_18
XMEMCPY(ssl->arrays->psk_key, ssl->session.masterSecret,
ssl->arrays->psk_keySz);
#else
if ((ret = DeriveResumptionPSK(ssl, ssl->session.ticketNonce.data,
ssl->session.ticketNonce.len, ssl->arrays->psk_key)) != 0) {
return ret;
}
#endif
}
#endif
#ifndef NO_PSK
@ -2916,8 +2980,15 @@ static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz,
/* Resumption PSK is resumption master secret. */
ssl->arrays->psk_keySz = ssl->specs.hash_size;
#ifdef WOLFSSL_TLS13_DRAFT_18
XMEMCPY(ssl->arrays->psk_key, ssl->session.masterSecret,
ssl->specs.hash_size);
ssl->arrays->psk_keySz);
#else
if ((ret = DeriveResumptionPSK(ssl, ssl->session.ticketNonce.data,
ssl->session.ticketNonce.len, ssl->arrays->psk_key)) != 0) {
return ret;
}
#endif
/* Derive the early secret using the PSK. */
ret = DeriveEarlySecret(ssl);
@ -5550,6 +5621,10 @@ static int DoTls13NewSessionTicket(WOLFSSL* ssl, const byte* input,
word32 ageAdd;
word16 length;
word32 now;
#ifndef WOLFSSL_TLS13_DRAFT_18
const byte* nonce;
byte nonceLength;
#endif
WOLFSSL_ENTER("DoTls13NewSessionTicket");
@ -5567,6 +5642,24 @@ static int DoTls13NewSessionTicket(WOLFSSL* ssl, const byte* input,
ato32(input + *inOutIdx, &ageAdd);
*inOutIdx += SESSION_ADD_SZ;
#ifndef WOLFSSL_TLS13_DRAFT_18
/* Ticket nonce. */
if ((*inOutIdx - begin) + 1 > size)
return BUFFER_ERROR;
nonceLength = input[*inOutIdx];
if (nonceLength == 0)
return INVALID_PARAMETER;
if (nonceLength > MAX_TICKET_NONCE_SZ) {
WOLFSSL_MSG("Nonce length not supported");
return INVALID_PARAMETER;
}
*inOutIdx += 1;
if ((*inOutIdx - begin) + nonceLength > size)
return BUFFER_ERROR;
nonce = input + *inOutIdx;
*inOutIdx += 1;
#endif
/* Ticket length. */
if ((*inOutIdx - begin) + LENGTH_SZ > size)
return BUFFER_ERROR;
@ -5592,6 +5685,10 @@ static int DoTls13NewSessionTicket(WOLFSSL* ssl, const byte* input,
#ifdef WOLFSSL_EARLY_DATA
ssl->session.maxEarlyDataSz = ssl->options.maxEarlyDataSz;
#endif
#ifndef WOLFSSL_TLS13_DRAFT_18
ssl->session.ticketNonce.len = nonceLength;
XMEMCPY(&ssl->session.ticketNonce.data, nonce, nonceLength);
#endif
if ((*inOutIdx - begin) + EXTS_SZ > size)
return BUFFER_ERROR;
@ -5751,6 +5848,16 @@ static int SendTls13NewSessionTicket(WOLFSSL* ssl)
}
#endif
#ifndef WOLFSSL_TLS13_DRAFT_18
/* Start ticket nonce at 0 and go up to 255. */
if (ssl->session.ticketNonce.len == 0) {
ssl->session.ticketNonce.len = DEF_TICKET_NONCE_SZ;
ssl->session.ticketNonce.data[0] = 0;
}
else
ssl->session.ticketNonce.data[0]++;
#endif
if (!ssl->options.noTicketTls13) {
if ((ret = CreateTicket(ssl)) != 0)
return ret;
@ -5768,6 +5875,10 @@ static int SendTls13NewSessionTicket(WOLFSSL* ssl)
/* Lifetime | Age Add | Ticket | Extensions */
length = SESSION_HINT_SZ + SESSION_ADD_SZ + LENGTH_SZ +
ssl->session.ticketLen + extSz;
#ifndef WOLFSSL_TLS13_DRAFT_18
/* Nonce */
length += TICKET_NONCE_LEN_SZ + DEF_TICKET_NONCE_SZ;
#endif
sendSz = idx + length + MAX_MSG_EXTRA;
/* Check buffers are big enough and grow if needed. */
@ -5788,6 +5899,11 @@ static int SendTls13NewSessionTicket(WOLFSSL* ssl)
c32toa(ssl->session.ticketAdd, output + idx);
idx += SESSION_ADD_SZ;
#ifndef WOLFSSL_TLS13_DRAFT_18
output[idx++] = ssl->session.ticketNonce.len;
output[idx++] = ssl->session.ticketNonce.data[0];
#endif
/* length */
c16toa(ssl->session.ticketLen, output + idx);
idx += LENGTH_SZ;

View File

@ -955,7 +955,7 @@ enum Misc {
#ifdef WOLFSSL_TLS13_DRAFT_18
TLS_DRAFT_MINOR = 0x12, /* Minor version number of TLS draft */
#else
TLS_DRAFT_MINOR = 0x14, /* Minor version number of TLS draft */
TLS_DRAFT_MINOR = 0x15, /* Minor version number of TLS draft */
#endif
OLD_HELLO_ID = 0x01, /* SSLv2 Client Hello Indicator */
INVALID_BYTE = 0xff, /* Used to initialize cipher specs values */
@ -1003,6 +1003,9 @@ enum Misc {
NAMED_DH_MASK = 0x100, /* Named group mask for DH parameters */
SESSION_HINT_SZ = 4, /* session timeout hint */
SESSION_ADD_SZ = 4, /* session age add */
TICKET_NONCE_LEN_SZ = 1, /* Ticket nonce length size */
DEF_TICKET_NONCE_SZ = 1, /* Default ticket nonce size */
MAX_TICKET_NONCE_SZ = 4, /* maximum ticket nonce size */
MAX_LIFETIME = 604800, /* maximum ticket lifetime */
MAX_EARLY_DATA_SZ = 4096, /* maximum early data size */
@ -2155,6 +2158,16 @@ WOLFSSL_LOCAL int TLSX_KeyShare_Establish(WOLFSSL* ssl);
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
#ifndef WOLFSSL_TLS13_DRAFT_18
/* Ticket nonce - for deriving PSK.
* Length allowed to be: 1..255. Only support 4 bytes.
*/
typedef struct TicketNonce {
byte len;
byte data[MAX_TICKET_NONCE_SZ];
} TicketNonce;
#endif
/* The PreSharedKey extension information - entry in a linked list. */
typedef struct PreSharedKey {
word16 identityLen; /* Length of identity */
@ -2675,6 +2688,9 @@ struct WOLFSSL_SESSION {
byte namedGroup;
word32 ticketSeen; /* Time ticket seen (ms) */
word32 ticketAdd; /* Added by client */
#ifndef WOLFSSL_TLS13_DRAFT_18
TicketNonce ticketNonce; /* Nonce used to derive PSK */
#endif
#endif
#ifdef WOLFSSL_EARLY_DATA
word32 maxEarlyDataSz;