mirror of https://github.com/wolfSSL/wolfssl
Merge pull request #1235 from SparkiDev/tls13_draft21
Update code to support Draft 21 of TLS v1.3
This commit is contained in:
commit
21e391fbce
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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(©Into->ticketNonce, ©From->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
|
||||
|
|
|
@ -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)
|
||||
|
|
118
src/tls13.c
118
src/tls13.c
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue