Merge pull request #1318 from SparkiDev/tls13_draft22
Changes for TLS v1.3 Draft 22
This commit is contained in:
commit
54acc2df51
@ -330,7 +330,7 @@ then
|
||||
fi
|
||||
|
||||
|
||||
# Post-handshake Authentication
|
||||
# Hello Retry Request Cookie
|
||||
AC_ARG_ENABLE([hrrcookie],
|
||||
[AS_HELP_STRING([--enable-hrrcookie],[Enable the server to send Cookie Extension in HRR with state (default: disabled)])],
|
||||
[ ENABLED_SEND_HRR_COOKIE=$enableval ],
|
||||
|
@ -6005,8 +6005,13 @@ static void AddRecordHeader(byte* output, word32 length, byte type, WOLFSSL* ssl
|
||||
rl->type = type;
|
||||
rl->pvMajor = ssl->version.major; /* type and version same in each */
|
||||
#ifdef WOLFSSL_TLS13
|
||||
if (IsAtLeastTLSv1_3(ssl->version))
|
||||
if (IsAtLeastTLSv1_3(ssl->version)) {
|
||||
#ifdef WOLFSSL_TLS13_DRAFT_18
|
||||
rl->pvMinor = TLSv1_MINOR;
|
||||
#else
|
||||
rl->pvMinor = TLSv1_2_MINOR;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
#endif
|
||||
rl->pvMinor = ssl->version.minor;
|
||||
@ -6490,7 +6495,12 @@ static int GetRecordHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
#else
|
||||
if (rh->pvMajor != ssl->version.major ||
|
||||
(rh->pvMinor != ssl->version.minor &&
|
||||
(!IsAtLeastTLSv1_3(ssl->version) || rh->pvMinor != TLSv1_MINOR)))
|
||||
#ifdef WOLFSSL_TLS13_DRAFT_18
|
||||
(!IsAtLeastTLSv1_3(ssl->version) || rh->pvMinor != TLSv1_MINOR)
|
||||
#else
|
||||
(!IsAtLeastTLSv1_3(ssl->version) || rh->pvMinor != TLSv1_2_MINOR)
|
||||
#endif
|
||||
))
|
||||
#endif
|
||||
{
|
||||
if (ssl->options.side == WOLFSSL_SERVER_END &&
|
||||
@ -11918,7 +11928,14 @@ int ProcessReply(WOLFSSL* ssl)
|
||||
/* decrypt message */
|
||||
case decryptMessage:
|
||||
|
||||
if (IsEncryptionOn(ssl, 0) && ssl->keys.decryptedCur == 0) {
|
||||
#if !defined(WOLFSSL_TLS13) || defined(WOLFSSL_TLS13_DRAFT_18)
|
||||
if (IsEncryptionOn(ssl, 0) && ssl->keys.decryptedCur == 0)
|
||||
#else
|
||||
if (IsEncryptionOn(ssl, 0) && ssl->keys.decryptedCur == 0 &&
|
||||
(!IsAtLeastTLSv1_3(ssl->version) ||
|
||||
ssl->curRL.type != change_cipher_spec))
|
||||
#endif
|
||||
{
|
||||
bufferStatic* in = &ssl->buffers.inputBuffer;
|
||||
|
||||
ret = SanityCheckCipherText(ssl, ssl->curSize);
|
||||
@ -12005,7 +12022,14 @@ int ProcessReply(WOLFSSL* ssl)
|
||||
/* verify digest of message */
|
||||
case verifyMessage:
|
||||
|
||||
if (IsEncryptionOn(ssl, 0) && ssl->keys.decryptedCur == 0) {
|
||||
#if !defined(WOLFSSL_TLS13) || defined(WOLFSSL_TLS13_DRAFT_18)
|
||||
if (IsEncryptionOn(ssl, 0) && ssl->keys.decryptedCur == 0)
|
||||
#else
|
||||
if (IsEncryptionOn(ssl, 0) && ssl->keys.decryptedCur == 0 &&
|
||||
(!IsAtLeastTLSv1_3(ssl->version) ||
|
||||
ssl->curRL.type != change_cipher_spec))
|
||||
#endif
|
||||
{
|
||||
if (!atomicUser) {
|
||||
ret = VerifyMac(ssl, ssl->buffers.inputBuffer.buffer +
|
||||
ssl->buffers.inputBuffer.idx,
|
||||
@ -12123,6 +12147,26 @@ int ProcessReply(WOLFSSL* ssl)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_TLS13
|
||||
#ifdef WOLFSSL_TLS13_DRAFT_18
|
||||
if (IsAtLeastTLSv1_3(ssl->version)) {
|
||||
SendAlert(ssl, alert_fatal, illegal_parameter);
|
||||
return UNKNOWN_RECORD_TYPE;
|
||||
}
|
||||
#else
|
||||
if (IsAtLeastTLSv1_3(ssl->version)) {
|
||||
word32 i = ssl->buffers.inputBuffer.idx;
|
||||
if (ssl->curSize != 1 ||
|
||||
ssl->buffers.inputBuffer.buffer[i] != 1) {
|
||||
SendAlert(ssl, alert_fatal, illegal_parameter);
|
||||
return UNKNOWN_RECORD_TYPE;
|
||||
}
|
||||
ssl->buffers.inputBuffer.idx++;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
ret = SanityCheckMsgReceived(ssl, change_cipher_hs);
|
||||
if (ret != 0) {
|
||||
if (!ssl->options.dtls) {
|
||||
|
23
src/ssl.c
23
src/ssl.c
@ -9445,22 +9445,8 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
||||
FALL_THROUGH;
|
||||
|
||||
case ACCEPT_CLIENT_HELLO_DONE :
|
||||
if (ssl->options.serverState == SERVER_HELLO_RETRY_REQUEST) {
|
||||
if ((ssl->error = SendTls13HelloRetryRequest(ssl)) != 0) {
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
ssl->options.acceptState = ACCEPT_HELLO_RETRY_REQUEST_DONE;
|
||||
WOLFSSL_MSG("accept state ACCEPT_HELLO_RETRY_REQUEST_DONE");
|
||||
FALL_THROUGH;
|
||||
|
||||
case ACCEPT_HELLO_RETRY_REQUEST_DONE :
|
||||
if (ssl->options.serverState == SERVER_HELLO_RETRY_REQUEST) {
|
||||
if ( (ssl->error = ProcessReply(ssl)) < 0) {
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
if (ssl->options.tls1_3) {
|
||||
return wolfSSL_accept_TLSv13(ssl);
|
||||
}
|
||||
#endif
|
||||
ssl->options.acceptState = ACCEPT_FIRST_REPLY_DONE;
|
||||
@ -9468,11 +9454,6 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
||||
FALL_THROUGH;
|
||||
|
||||
case ACCEPT_FIRST_REPLY_DONE :
|
||||
#ifdef WOLFSSL_TLS13
|
||||
if (ssl->options.tls1_3) {
|
||||
return wolfSSL_accept_TLSv13(ssl);
|
||||
}
|
||||
#endif
|
||||
if ( (ssl->error = SendServerHello(ssl)) != 0) {
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
|
214
src/tls.c
214
src/tls.c
@ -4507,64 +4507,90 @@ int TLSX_UseQSHScheme(TLSX** extensions, word16 name, byte* pKey, word16 pkeySz,
|
||||
/* Return the size of the SupportedVersions extension's data.
|
||||
*
|
||||
* data The SSL/TLS object.
|
||||
* msgType The type of the message this extension is being written into.
|
||||
* returns the length of data that will be in the extension.
|
||||
*/
|
||||
static word16 TLSX_SupportedVersions_GetSize(void* data)
|
||||
static word16 TLSX_SupportedVersions_GetSize(void* data, byte msgType)
|
||||
{
|
||||
WOLFSSL* ssl = (WOLFSSL*)data;
|
||||
|
||||
/* TLS v1.2 and TLS v1.3 */
|
||||
int cnt = 2;
|
||||
if (msgType == client_hello) {
|
||||
/* TLS v1.2 and TLS v1.3 */
|
||||
int cnt = 2;
|
||||
|
||||
#ifndef NO_OLD_TLS
|
||||
/* TLS v1 and TLS v1.1 */
|
||||
cnt += 2;
|
||||
/* TLS v1 and TLS v1.1 */
|
||||
cnt += 2;
|
||||
#endif
|
||||
|
||||
if (!ssl->options.downgrade)
|
||||
cnt = 1;
|
||||
if (!ssl->options.downgrade)
|
||||
cnt = 1;
|
||||
|
||||
return (word16)(OPAQUE8_LEN + cnt * OPAQUE16_LEN);
|
||||
return (word16)(OPAQUE8_LEN + cnt * OPAQUE16_LEN);
|
||||
}
|
||||
#ifndef WOLFSSL_TLS13_DRAFT_18
|
||||
else if (msgType == server_hello || msgType == hello_retry_request)
|
||||
return OPAQUE16_LEN;
|
||||
#endif
|
||||
else
|
||||
return SANITY_MSG_E;
|
||||
}
|
||||
|
||||
/* Writes the SupportedVersions extension into the buffer.
|
||||
*
|
||||
* data The SSL/TLS object.
|
||||
* output The buffer to write the extension into.
|
||||
* msgType The type of the message this extension is being written into.
|
||||
* returns the length of data that was written.
|
||||
*/
|
||||
static word16 TLSX_SupportedVersions_Write(void* data, byte* output)
|
||||
static word16 TLSX_SupportedVersions_Write(void* data, byte* output,
|
||||
byte msgType)
|
||||
{
|
||||
WOLFSSL* ssl = (WOLFSSL*)data;
|
||||
ProtocolVersion pv = ssl->ctx->method->version;
|
||||
ProtocolVersion pv;
|
||||
int i;
|
||||
/* TLS v1.2 and TLS v1.3 */
|
||||
int cnt = 2;
|
||||
int cnt;
|
||||
|
||||
if (msgType == client_hello) {
|
||||
pv = ssl->ctx->method->version;
|
||||
/* TLS v1.2 and TLS v1.3 */
|
||||
cnt = 2;
|
||||
|
||||
#ifndef NO_OLD_TLS
|
||||
/* TLS v1 and TLS v1.1 */
|
||||
cnt += 2;
|
||||
/* TLS v1 and TLS v1.1 */
|
||||
cnt += 2;
|
||||
#endif
|
||||
|
||||
if (!ssl->options.downgrade)
|
||||
cnt = 1;
|
||||
if (!ssl->options.downgrade)
|
||||
cnt = 1;
|
||||
|
||||
*(output++) = (byte)(cnt * OPAQUE16_LEN);
|
||||
for (i = 0; i < cnt; i++) {
|
||||
/* TODO: [TLS13] Remove code when TLS v1.3 becomes an RFC. */
|
||||
if (pv.minor - i == TLSv1_3_MINOR) {
|
||||
/* The TLS draft major number. */
|
||||
*(output++) = TLS_DRAFT_MAJOR;
|
||||
/* Version of draft supported. */
|
||||
*(output++) = TLS_DRAFT_MINOR;
|
||||
continue;
|
||||
*(output++) = (byte)(cnt * OPAQUE16_LEN);
|
||||
for (i = 0; i < cnt; i++) {
|
||||
/* TODO: [TLS13] Remove code when TLS v1.3 becomes an RFC. */
|
||||
if (pv.minor - i == TLSv1_3_MINOR) {
|
||||
/* The TLS draft major number. */
|
||||
*(output++) = TLS_DRAFT_MAJOR;
|
||||
/* Version of draft supported. */
|
||||
*(output++) = TLS_DRAFT_MINOR;
|
||||
continue;
|
||||
}
|
||||
|
||||
*(output++) = pv.major;
|
||||
*(output++) = pv.minor - i;
|
||||
}
|
||||
|
||||
*(output++) = pv.major;
|
||||
*(output++) = (byte)(pv.minor - i);
|
||||
return (word16)(OPAQUE8_LEN + cnt * OPAQUE16_LEN);
|
||||
}
|
||||
#ifndef WOLFSSL_TLS13_DRAFT_18
|
||||
else if (msgType == server_hello || msgType == hello_retry_request) {
|
||||
output[0] = ssl->version.major;
|
||||
output[1] = ssl->version.minor;
|
||||
|
||||
return (word16)(OPAQUE8_LEN + cnt * OPAQUE16_LEN);
|
||||
return OPAQUE16_LEN;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
return SANITY_MSG_E;
|
||||
}
|
||||
|
||||
/* Parse the SupportedVersions extension.
|
||||
@ -4572,10 +4598,11 @@ static word16 TLSX_SupportedVersions_Write(void* data, byte* output)
|
||||
* ssl The SSL/TLS object.
|
||||
* input The buffer with the extension data.
|
||||
* length The length of the extension data.
|
||||
* msgType The type of the message this extension is being parsed from.
|
||||
* returns 0 on success, otherwise failure.
|
||||
*/
|
||||
static int TLSX_SupportedVersions_Parse(WOLFSSL *ssl, byte* input,
|
||||
word16 length)
|
||||
word16 length, byte msgType)
|
||||
{
|
||||
ProtocolVersion pv = ssl->ctx->method->version;
|
||||
int i;
|
||||
@ -4583,22 +4610,69 @@ static int TLSX_SupportedVersions_Parse(WOLFSSL *ssl, byte* input,
|
||||
int len;
|
||||
byte major, minor;
|
||||
|
||||
/* Must contain a length and at least one version. */
|
||||
if (length < OPAQUE8_LEN + OPAQUE16_LEN || (length & 1) != 1)
|
||||
return BUFFER_ERROR;
|
||||
if (msgType == client_hello) {
|
||||
/* Must contain a length and at least one version. */
|
||||
if (length < OPAQUE8_LEN + OPAQUE16_LEN || (length & 1) != 1)
|
||||
return BUFFER_ERROR;
|
||||
|
||||
len = *input;
|
||||
len = *input;
|
||||
|
||||
/* Protocol version array must fill rest of data. */
|
||||
if (length != OPAQUE8_LEN + len)
|
||||
return BUFFER_ERROR;
|
||||
/* Protocol version array must fill rest of data. */
|
||||
if (length != OPAQUE8_LEN + len)
|
||||
return BUFFER_ERROR;
|
||||
|
||||
input++;
|
||||
input++;
|
||||
|
||||
/* Find first match. */
|
||||
for (i = 0; i < len; i += OPAQUE16_LEN) {
|
||||
major = input[i];
|
||||
minor = input[i + OPAQUE8_LEN];
|
||||
/* Find first match. */
|
||||
for (i = 0; i < len; i += OPAQUE16_LEN) {
|
||||
major = input[i];
|
||||
minor = input[i + OPAQUE8_LEN];
|
||||
|
||||
/* TODO: [TLS13] Remove code when TLS v1.3 becomes an RFC. */
|
||||
if (major == TLS_DRAFT_MAJOR && minor == TLS_DRAFT_MINOR) {
|
||||
major = SSLv3_MAJOR;
|
||||
minor = TLSv1_3_MINOR;
|
||||
}
|
||||
|
||||
if (major != pv.major)
|
||||
continue;
|
||||
|
||||
/* No upgrade allowed. */
|
||||
if (ssl->version.minor > minor)
|
||||
continue;
|
||||
/* Check downgrade. */
|
||||
if (ssl->version.minor < minor) {
|
||||
if (!ssl->options.downgrade)
|
||||
continue;
|
||||
|
||||
#ifdef NO_OLD_TLS
|
||||
if (minor < TLSv1_2_MINOR)
|
||||
continue;
|
||||
#endif
|
||||
/* Downgrade the version. */
|
||||
ssl->version.minor = minor;
|
||||
}
|
||||
|
||||
if (minor >= TLSv1_3_MINOR) {
|
||||
ssl->options.tls1_3 = 1;
|
||||
TLSX_Push(&ssl->extensions, TLSX_SUPPORTED_VERSIONS, ssl,
|
||||
ssl->heap);
|
||||
#ifndef WOLFSSL_TLS13_DRAFT_18
|
||||
TLSX_SetResponse(ssl, TLSX_SUPPORTED_VERSIONS);
|
||||
#endif
|
||||
}
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifndef WOLFSSL_TLS13_DRAFT_18
|
||||
else if (msgType == server_hello || msgType == hello_retry_request) {
|
||||
/* Must contain one version. */
|
||||
if (length != OPAQUE16_LEN)
|
||||
return BUFFER_ERROR;
|
||||
|
||||
major = input[0];
|
||||
minor = input[OPAQUE8_LEN];
|
||||
|
||||
/* TODO: [TLS13] Remove code when TLS v1.3 becomes an RFC. */
|
||||
if (major == TLS_DRAFT_MAJOR && minor == TLS_DRAFT_MINOR) {
|
||||
@ -4607,32 +4681,30 @@ static int TLSX_SupportedVersions_Parse(WOLFSSL *ssl, byte* input,
|
||||
}
|
||||
|
||||
if (major != pv.major)
|
||||
continue;
|
||||
return VERSION_ERROR;
|
||||
|
||||
/* No upgrade allowed. */
|
||||
if (ssl->version.minor > minor)
|
||||
continue;
|
||||
if (ssl->version.minor < minor)
|
||||
return VERSION_ERROR;
|
||||
|
||||
/* Check downgrade. */
|
||||
if (ssl->version.minor < minor) {
|
||||
if (ssl->version.minor > minor) {
|
||||
if (!ssl->options.downgrade)
|
||||
continue;
|
||||
return VERSION_ERROR;
|
||||
|
||||
#ifdef NO_OLD_TLS
|
||||
if (minor < TLSv1_2_MINOR)
|
||||
continue;
|
||||
return VERSION_ERROR;
|
||||
#endif
|
||||
/* Downgrade the version. */
|
||||
ssl->version.minor = minor;
|
||||
}
|
||||
|
||||
if (minor >= TLSv1_3_MINOR) {
|
||||
ssl->options.tls1_3 = 1;
|
||||
TLSX_Push(&ssl->extensions, TLSX_SUPPORTED_VERSIONS, input,
|
||||
ssl->heap);
|
||||
}
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
return SANITY_MSG_E;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -4659,9 +4731,9 @@ static int TLSX_SetSupportedVersions(TLSX** extensions, const void* data,
|
||||
|
||||
#else
|
||||
|
||||
#define SV_GET_SIZE(a) 0
|
||||
#define SV_WRITE(a, b) 0
|
||||
#define SV_PARSE(a, b, c) 0
|
||||
#define SV_GET_SIZE(a, b) 0
|
||||
#define SV_WRITE(a, b, c) 0
|
||||
#define SV_PARSE(a, b, c, d) 0
|
||||
|
||||
#endif /* WOLFSSL_TLS13 */
|
||||
|
||||
@ -7197,7 +7269,7 @@ static word16 TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType)
|
||||
|
||||
#ifdef WOLFSSL_TLS13
|
||||
case TLSX_SUPPORTED_VERSIONS:
|
||||
length += SV_GET_SIZE(extension->data);
|
||||
length += SV_GET_SIZE(extension->data, msgType);
|
||||
break;
|
||||
|
||||
case TLSX_COOKIE:
|
||||
@ -7344,7 +7416,7 @@ static word16 TLSX_Write(TLSX* list, byte* output, byte* semaphore,
|
||||
#ifdef WOLFSSL_TLS13
|
||||
case TLSX_SUPPORTED_VERSIONS:
|
||||
WOLFSSL_MSG("Supported Versions extension to write");
|
||||
offset += SV_WRITE(extension->data, output + offset);
|
||||
offset += SV_WRITE(extension->data, output + offset, msgType);
|
||||
break;
|
||||
|
||||
case TLSX_COOKIE:
|
||||
@ -8152,6 +8224,10 @@ word16 TLSX_GetResponseSize(WOLFSSL* ssl, byte msgType)
|
||||
#ifdef WOLFSSL_TLS13
|
||||
if (ssl->options.tls1_3) {
|
||||
XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
|
||||
#ifndef WOLFSSL_TLS13_DRAFT_18
|
||||
TURN_OFF(semaphore,
|
||||
TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
|
||||
#endif
|
||||
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
|
||||
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
||||
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
|
||||
@ -8168,6 +8244,9 @@ word16 TLSX_GetResponseSize(WOLFSSL* ssl, byte msgType)
|
||||
#ifdef WOLFSSL_TLS13
|
||||
case hello_retry_request:
|
||||
XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
|
||||
#ifndef WOLFSSL_TLS13_DRAFT_18
|
||||
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
|
||||
#endif
|
||||
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
|
||||
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_COOKIE));
|
||||
break;
|
||||
@ -8175,6 +8254,7 @@ word16 TLSX_GetResponseSize(WOLFSSL* ssl, byte msgType)
|
||||
#ifdef WOLFSSL_TLS13
|
||||
case encrypted_extensions:
|
||||
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EC_POINT_FORMATS));
|
||||
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
|
||||
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SESSION_TICKET));
|
||||
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
|
||||
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
||||
@ -8240,6 +8320,10 @@ word16 TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType)
|
||||
#ifdef WOLFSSL_TLS13
|
||||
if (ssl->options.tls1_3) {
|
||||
XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
|
||||
#ifndef WOLFSSL_TLS13_DRAFT_18
|
||||
TURN_OFF(semaphore,
|
||||
TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
|
||||
#endif
|
||||
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
|
||||
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
||||
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
|
||||
@ -8256,12 +8340,16 @@ word16 TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType)
|
||||
#ifdef WOLFSSL_TLS13
|
||||
case hello_retry_request:
|
||||
XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
|
||||
#ifndef WOLFSSL_TLS13_DRAFT_18
|
||||
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
|
||||
#endif
|
||||
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_TLS13
|
||||
case encrypted_extensions:
|
||||
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EC_POINT_FORMATS));
|
||||
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
|
||||
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SESSION_TICKET));
|
||||
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
|
||||
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
||||
@ -8521,10 +8609,16 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
|
||||
WOLFSSL_MSG("Supported Versions extension received");
|
||||
|
||||
if (IsAtLeastTLSv1_3(ssl->version) &&
|
||||
msgType != client_hello) {
|
||||
#ifdef WOLFSSL_TLS13_DRAFT_18
|
||||
msgType != client_hello
|
||||
#else
|
||||
msgType != client_hello && msgType != server_hello &&
|
||||
msgType != hello_retry_request
|
||||
#endif
|
||||
) {
|
||||
return EXT_NOT_ALLOWED;
|
||||
}
|
||||
ret = SV_PARSE(ssl, input + offset, size);
|
||||
ret = SV_PARSE(ssl, input + offset, size, msgType);
|
||||
break;
|
||||
|
||||
case TLSX_COOKIE:
|
||||
|
411
src/tls13.c
411
src/tls13.c
@ -1367,7 +1367,11 @@ static void AddTls13RecordHeader(byte* output, word32 length, byte type,
|
||||
rl = (RecordLayerHeader*)output;
|
||||
rl->type = type;
|
||||
rl->pvMajor = ssl->version.major;
|
||||
#ifdef WOLFSSL_TLS13_DRAFT_18
|
||||
rl->pvMinor = TLSv1_MINOR;
|
||||
#else
|
||||
rl->pvMinor = TLSv1_2_MINOR;
|
||||
#endif
|
||||
c16toa((word16)length, rl->length);
|
||||
}
|
||||
|
||||
@ -2263,9 +2267,17 @@ int SendTls13ClientHello(WOLFSSL* ssl)
|
||||
return SUITES_ERROR;
|
||||
}
|
||||
|
||||
/* Version | Random | Session Id | Cipher Suites | Compression | Ext */
|
||||
/* Version | Random | Session Id | Cipher Suites | Compression */
|
||||
length = VERSION_SZ + RAN_LEN + ENUM_LEN + ssl->suites->suiteSz +
|
||||
SUITE_LEN + COMP_LEN + ENUM_LEN;
|
||||
#ifndef WOLFSSL_TLS13_DRAFT_18
|
||||
#if defined(WOLFSSL_TLS13_MIDDLEBOX_COMPAT)
|
||||
length += ID_LEN;
|
||||
#else
|
||||
if (ssl->session.sessionIDSz > 0)
|
||||
length += ssl->session.sessionIDSz;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Auto populate extensions supported unless user defined. */
|
||||
if ((ret = TLSX_PopulateExtensions(ssl, 0)) != 0)
|
||||
@ -2319,8 +2331,25 @@ int SendTls13ClientHello(WOLFSSL* ssl)
|
||||
XMEMCPY(output + idx, ssl->arrays->clientRandom, RAN_LEN);
|
||||
idx += RAN_LEN;
|
||||
|
||||
#ifdef WOLFSSL_TLS13_DRAFT_18
|
||||
/* TLS v1.3 does not use session id - 0 length. */
|
||||
output[idx++] = 0;
|
||||
#else
|
||||
if (ssl->session.sessionIDSz > 0) {
|
||||
output[idx++] = ID_LEN;
|
||||
XMEMCPY(output + idx, ssl->session.sessionID, ssl->session.sessionIDSz);
|
||||
idx += ID_LEN;
|
||||
}
|
||||
else {
|
||||
#ifdef WOLFSSL_TLS13_MIDDLEBOX_COMPAT
|
||||
output[idx++] = ID_LEN;
|
||||
XMEMCPY(output + idx, ssl->arrays->clientRandom, ID_LEN);
|
||||
idx += ID_LEN;
|
||||
#else
|
||||
output[idx++] = 0;
|
||||
#endif /* WOLFSSL_TLS13_MIDDLEBOX_COMPAT */
|
||||
}
|
||||
#endif /* WOLFSSL_TLS13_DRAFT_18 */
|
||||
|
||||
/* Cipher suites */
|
||||
c16toa(ssl->suites->suiteSz, output + idx);
|
||||
@ -2477,6 +2506,7 @@ static int RestartHandshakeHash(WOLFSSL* ssl)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_TLS13_DRAFT_18
|
||||
/* Parse and handle a HelloRetryRequest message.
|
||||
* Only a client will receive this message.
|
||||
*
|
||||
@ -2515,16 +2545,6 @@ static int DoTls13HelloRetryRequest(WOLFSSL* ssl, const byte* input,
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
#ifndef WOLFSSL_TLS13_DRAFT_18
|
||||
/* Set the cipher suite from the message. */
|
||||
ssl->options.cipherSuite0 = input[i++];
|
||||
ssl->options.cipherSuite = input[i++];
|
||||
|
||||
ret = SetCipherSpecs(ssl);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
#endif
|
||||
|
||||
/* Length of extension data. */
|
||||
ato16(&input[i], &totalExtSz);
|
||||
i += OPAQUE16_LEN;
|
||||
@ -2547,14 +2567,24 @@ static int DoTls13HelloRetryRequest(WOLFSSL* ssl, const byte* input,
|
||||
ssl->options.tls1_3 = 1;
|
||||
ssl->options.serverState = SERVER_HELLO_RETRY_REQUEST;
|
||||
|
||||
#ifndef WOLFSSL_TLS13_DRAFT_18
|
||||
ret = RestartHandshakeHash(ssl);
|
||||
#endif
|
||||
|
||||
WOLFSSL_LEAVE("DoTls13HelloRetryRequest", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef WOLFSSL_TLS13_DRAFT_18
|
||||
/* The value in the random field of a ServerHello to indicate
|
||||
* HelloRetryRequest.
|
||||
*/
|
||||
static byte helloRetryRequestRandom[] = {
|
||||
0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11,
|
||||
0xBE, 0x1D, 0x8C, 0x02, 0x1E, 0x65, 0xB8, 0x91,
|
||||
0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, 0x8C, 0x5E,
|
||||
0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Handle the ServerHello message from the server.
|
||||
* Only a client will receive this message.
|
||||
@ -2573,11 +2603,16 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
word32 i = *inOutIdx;
|
||||
word32 begin = i;
|
||||
int ret;
|
||||
#ifndef WOLFSSL_TLS13_DRAFT_18
|
||||
byte sessIdSz;
|
||||
byte b;
|
||||
#endif
|
||||
word16 totalExtSz;
|
||||
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
||||
TLSX* ext;
|
||||
PreSharedKey* psk = NULL;
|
||||
#endif
|
||||
byte extMsgType = server_hello;
|
||||
|
||||
WOLFSSL_ENTER("DoTls13ServerHello");
|
||||
|
||||
@ -2593,6 +2628,7 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
/* Protocol version */
|
||||
XMEMCPY(&pv, input + i, OPAQUE16_LEN);
|
||||
i += OPAQUE16_LEN;
|
||||
#ifdef WOLFSSL_TLS13_DRAFT_18
|
||||
ret = CheckVersion(ssl, pv);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
@ -2605,19 +2641,77 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
WOLFSSL_MSG("CLient using higher version, fatal error");
|
||||
return VERSION_ERROR;
|
||||
}
|
||||
#else
|
||||
if (pv.major != ssl->version.major || pv.minor != TLSv1_2_MINOR)
|
||||
return VERSION_ERROR;
|
||||
#endif
|
||||
|
||||
/* Random, cipher suite and extensions length check. */
|
||||
if ((i - begin) + RAN_LEN + OPAQUE16_LEN + OPAQUE16_LEN > helloSz)
|
||||
#ifdef WOLFSSL_TLS13_DRAFT_18
|
||||
/* Random length check */
|
||||
if ((i - begin) + RAN_LEN > helloSz)
|
||||
return BUFFER_ERROR;
|
||||
#else
|
||||
/* Random and session id length check */
|
||||
if ((i - begin) + RAN_LEN + ENUM_LEN > helloSz)
|
||||
return BUFFER_ERROR;
|
||||
|
||||
if (XMEMCMP(input + i, helloRetryRequestRandom, RAN_LEN) == 0)
|
||||
extMsgType = hello_retry_request;
|
||||
#endif
|
||||
|
||||
/* Server random - keep for debugging. */
|
||||
XMEMCPY(ssl->arrays->serverRandom, input + i, RAN_LEN);
|
||||
i += RAN_LEN;
|
||||
|
||||
#ifndef WOLFSSL_TLS13_DRAFT_18
|
||||
/* Session id */
|
||||
sessIdSz = input[i++];
|
||||
if ((i - begin) + sessIdSz > helloSz)
|
||||
return BUFFER_ERROR;
|
||||
#ifdef WOLFSSL_TLS13_MIDDLEBOX_COMPAT
|
||||
if (sessIdSz == 0)
|
||||
return INVALID_PARAMETER;
|
||||
if (ssl->session.sessionIDSz != 0) {
|
||||
if (ssl->session.sessionIDSz != sessIdSz ||
|
||||
XMEMCMP(ssl->session.sessionID, input + i, sessIdSz) != 0) {
|
||||
return INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
else if (XMEMCMP(ssl->arrays->clientRandom, input + i, sessIdSz) != 0)
|
||||
return INVALID_PARAMETER;
|
||||
#else
|
||||
if (sessIdSz != ssl->session.sessionIDSz || (sessIdSz > 0 &&
|
||||
XMEMCMP(ssl->session.sessionID, input + i, sessIdSz) != 0)) {
|
||||
WOLFSSL_MSG("Server sent different session id");
|
||||
return INVALID_PARAMETER;
|
||||
}
|
||||
#endif /* WOLFSSL_TLS13_MIDDLEBOX_COMPAT */
|
||||
i += sessIdSz;
|
||||
#endif /* WOLFSSL_TLS13_DRAFT_18 */
|
||||
|
||||
#ifdef WOLFSSL_TLS13_DRAFT_18
|
||||
/* Ciphersuite and extensions length check */
|
||||
if ((i - begin) + OPAQUE16_LEN + OPAQUE16_LEN > helloSz)
|
||||
return BUFFER_ERROR;
|
||||
#else
|
||||
/* Ciphersuite, compression and extensions length check */
|
||||
if ((i - begin) + OPAQUE16_LEN + OPAQUE16_LEN + OPAQUE16_LEN > helloSz)
|
||||
return BUFFER_ERROR;
|
||||
#endif
|
||||
|
||||
/* Set the cipher suite from the message. */
|
||||
ssl->options.cipherSuite0 = input[i++];
|
||||
ssl->options.cipherSuite = input[i++];
|
||||
|
||||
#ifndef WOLFSSL_TLS13_DRAFT_18
|
||||
/* Compression */
|
||||
b = input[i++];
|
||||
if (b != 0) {
|
||||
WOLFSSL_MSG("Must be no compression types in list");
|
||||
return INVALID_PARAMETER;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Get extension length and length check. */
|
||||
ato16(&input[i], &totalExtSz);
|
||||
i += OPAQUE16_LEN;
|
||||
@ -2625,7 +2719,7 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
return BUFFER_ERROR;
|
||||
|
||||
/* Parse and handle extensions. */
|
||||
ret = TLSX_Parse(ssl, (byte *) input + i, totalExtSz, server_hello, NULL);
|
||||
ret = TLSX_Parse(ssl, (byte *) input + i, totalExtSz, extMsgType, NULL);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
@ -2649,21 +2743,37 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
return ret;
|
||||
|
||||
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
||||
ext = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY);
|
||||
if (ext != NULL)
|
||||
psk = (PreSharedKey*)ext->data;
|
||||
while (psk != NULL && !psk->chosen)
|
||||
psk = psk->next;
|
||||
if (psk == NULL) {
|
||||
ssl->options.resuming = 0;
|
||||
ssl->arrays->psk_keySz = 0;
|
||||
XMEMSET(ssl->arrays->psk_key, 0, MAX_PSK_KEY_LEN);
|
||||
#ifndef WOLFSSL_TLS13_DRAFT_18
|
||||
if (extMsgType == server_hello)
|
||||
#endif
|
||||
{
|
||||
ext = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY);
|
||||
if (ext != NULL)
|
||||
psk = (PreSharedKey*)ext->data;
|
||||
while (psk != NULL && !psk->chosen)
|
||||
psk = psk->next;
|
||||
if (psk == NULL) {
|
||||
ssl->options.resuming = 0;
|
||||
ssl->arrays->psk_keySz = 0;
|
||||
XMEMSET(ssl->arrays->psk_key, 0, MAX_PSK_KEY_LEN);
|
||||
}
|
||||
else if ((ret = SetupPskKey(ssl, psk)) != 0)
|
||||
return ret;
|
||||
}
|
||||
else if ((ret = SetupPskKey(ssl, psk)) != 0)
|
||||
return ret;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_TLS13_DRAFT_18
|
||||
ssl->keys.encryptionOn = 1;
|
||||
#else
|
||||
if (extMsgType == server_hello)
|
||||
ssl->keys.encryptionOn = 1;
|
||||
else {
|
||||
ssl->options.tls1_3 = 1;
|
||||
ssl->options.serverState = SERVER_HELLO_RETRY_REQUEST;
|
||||
|
||||
ret = RestartHandshakeHash(ssl);
|
||||
}
|
||||
#endif
|
||||
|
||||
WOLFSSL_LEAVE("DoTls13ServerHello", ret);
|
||||
|
||||
@ -3166,15 +3276,30 @@ static int CheckCookie(WOLFSSL* ssl, byte* cookie, byte cookieSz)
|
||||
|
||||
/* Length of the KeyShare Extension */
|
||||
#define HRR_KEY_SHARE_SZ (OPAQUE16_LEN + OPAQUE16_LEN + OPAQUE16_LEN)
|
||||
/* Length of the Supported Vresions Extension */
|
||||
#define HRR_VERSIONS_SZ (OPAQUE16_LEN + OPAQUE16_LEN + OPAQUE16_LEN)
|
||||
/* Length of the Cookie Extension excluding cookie data */
|
||||
#define HRR_COOKIE_HDR_SZ (OPAQUE16_LEN + OPAQUE16_LEN + OPAQUE16_LEN)
|
||||
#ifdef WOLFSSL_TLS13_DRAFT_18
|
||||
/* PV | CipherSuite | Ext Len */
|
||||
#define HRR_BODY_SZ (OPAQUE16_LEN + OPAQUE16_LEN + OPAQUE16_LEN)
|
||||
/* HH | PV | CipherSuite | Ext Len | Key Share | Cookie */
|
||||
#define MAX_HRR_SZ (HANDSHAKE_HEADER_SZ + \
|
||||
HRR_BODY_SZ + \
|
||||
HRR_KEY_SHARE_SZ + \
|
||||
#define MAX_HRR_SZ (HANDSHAKE_HEADER_SZ + \
|
||||
HRR_BODY_SZ + \
|
||||
HRR_KEY_SHARE_SZ + \
|
||||
HRR_COOKIE_HDR_SZ)
|
||||
#else
|
||||
/* PV | Random | Session Id | CipherSuite | Compression | Ext Len */
|
||||
#define HRR_BODY_SZ (VERSION_SZ + RAN_LEN + ENUM_LEN + ID_LEN + \
|
||||
SUITE_LEN + COMP_LEN + OPAQUE16_LEN)
|
||||
/* HH | PV | CipherSuite | Ext Len | Key Share | Supported Version | Cookie */
|
||||
#define MAX_HRR_SZ (HANDSHAKE_HEADER_SZ + \
|
||||
HRR_BODY_SZ + \
|
||||
HRR_KEY_SHARE_SZ + \
|
||||
HRR_VERSIONS_SZ + \
|
||||
HRR_COOKIE_HDR_SZ)
|
||||
#endif
|
||||
|
||||
/* Restart the Hanshake hash from the cookie value.
|
||||
*
|
||||
* ssl SSL/TLS object.
|
||||
@ -3211,11 +3336,18 @@ static int RestartHandshakeHashWithCookie(WOLFSSL* ssl, Cookie* cookie)
|
||||
return ret;
|
||||
|
||||
/* Reconstruct the HelloRetryMessage for handshake hash. */
|
||||
#ifdef WOLFSSL_TLS13_DRAFT_18
|
||||
length = HRR_BODY_SZ + HRR_COOKIE_HDR_SZ + cookie->len;
|
||||
#else
|
||||
length = HRR_BODY_SZ - ID_LEN + ssl->session.sessionIDSz +
|
||||
HRR_COOKIE_HDR_SZ + cookie->len;
|
||||
length += HRR_VERSIONS_SZ;
|
||||
#endif
|
||||
if (cookieDataSz > hashSz + OPAQUE16_LEN) {
|
||||
keyShareExt = 1;
|
||||
length += HRR_KEY_SHARE_SZ;
|
||||
}
|
||||
#ifdef WOLFSSL_TLS13_DRAFT_18
|
||||
AddTls13HandShakeHeader(hrr, length, 0, 0, hello_retry_request, ssl);
|
||||
|
||||
idx += hashSz;
|
||||
@ -3238,6 +3370,39 @@ static int RestartHandshakeHashWithCookie(WOLFSSL* ssl, Cookie* cookie)
|
||||
length -= HRR_BODY_SZ;
|
||||
c16toa(length, hrr + hrrIdx);
|
||||
hrrIdx += 2;
|
||||
#else
|
||||
AddTls13HandShakeHeader(hrr, length, 0, 0, server_hello, ssl);
|
||||
|
||||
idx += hashSz;
|
||||
hrrIdx = HANDSHAKE_HEADER_SZ;
|
||||
|
||||
/* The negotiated protocol version. */
|
||||
hrr[hrrIdx++] = ssl->version.major;
|
||||
hrr[hrrIdx++] = TLSv1_2_MINOR;
|
||||
|
||||
/* HelloRetryRequest message has fixed value for random. */
|
||||
XMEMCPY(hrr + hrrIdx, helloRetryRequestRandom, RAN_LEN);
|
||||
hrrIdx += RAN_LEN;
|
||||
|
||||
hrr[hrrIdx++] = ssl->session.sessionIDSz;
|
||||
if (ssl->session.sessionIDSz > 0) {
|
||||
XMEMCPY(hrr + hrrIdx, ssl->session.sessionID, ssl->session.sessionIDSz);
|
||||
hrrIdx += ssl->session.sessionIDSz;
|
||||
}
|
||||
|
||||
/* Cipher Suite */
|
||||
hrr[hrrIdx++] = cookieData[idx++];
|
||||
hrr[hrrIdx++] = cookieData[idx++];
|
||||
|
||||
/* Compression not supported in TLS v1.3. */
|
||||
hrr[hrrIdx++] = 0;
|
||||
|
||||
/* Extensions' length */
|
||||
length -= HRR_BODY_SZ - ID_LEN + ssl->session.sessionIDSz;
|
||||
c16toa(length, hrr + hrrIdx);
|
||||
hrrIdx += 2;
|
||||
|
||||
#endif
|
||||
/* Optional KeyShare Extension */
|
||||
if (keyShareExt) {
|
||||
c16toa(TLSX_KEY_SHARE, hrr + hrrIdx);
|
||||
@ -3247,6 +3412,14 @@ static int RestartHandshakeHashWithCookie(WOLFSSL* ssl, Cookie* cookie)
|
||||
hrr[hrrIdx++] = cookieData[idx++];
|
||||
hrr[hrrIdx++] = cookieData[idx++];
|
||||
}
|
||||
#ifndef WOLFSSL_TLS13_DRAFT_18
|
||||
c16toa(TLSX_SUPPORTED_VERSIONS, hrr + hrrIdx);
|
||||
hrrIdx += 2;
|
||||
c16toa(OPAQUE16_LEN, hrr + hrrIdx);
|
||||
hrrIdx += 2;
|
||||
hrr[hrrIdx++] = ssl->version.major;
|
||||
hrr[hrrIdx++] = ssl->version.minor;
|
||||
#endif
|
||||
/* Mandatory Cookie Extension */
|
||||
c16toa(TLSX_COOKIE, hrr + hrrIdx);
|
||||
hrrIdx += 2;
|
||||
@ -3322,12 +3495,23 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
WOLFSSL_BUFFER(ssl->arrays->clientRandom, RAN_LEN);
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_TLS13_DRAFT_18
|
||||
/* Session id - empty in TLS v1.3 */
|
||||
sessIdSz = input[i++];
|
||||
if (sessIdSz > 0) {
|
||||
WOLFSSL_MSG("Client sent session id - not supported");
|
||||
return BUFFER_ERROR;
|
||||
}
|
||||
#else
|
||||
sessIdSz = input[i++];
|
||||
if (sessIdSz != ID_LEN && sessIdSz != 0)
|
||||
return INVALID_PARAMETER;
|
||||
ssl->session.sessionIDSz = sessIdSz;
|
||||
if (sessIdSz == ID_LEN) {
|
||||
XMEMCPY(ssl->session.sessionID, input + i, sessIdSz);
|
||||
i += ID_LEN;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Cipher suites */
|
||||
if ((i - begin) + OPAQUE16_LEN > helloSz)
|
||||
@ -3457,6 +3641,7 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_TLS13_DRAFT_18
|
||||
/* Send the HelloRetryRequest message to indicate the negotiated protocol
|
||||
* version and security parameters the server is willing to use.
|
||||
* Only a server will send this message.
|
||||
@ -3475,24 +3660,14 @@ int SendTls13HelloRetryRequest(WOLFSSL* ssl)
|
||||
|
||||
WOLFSSL_ENTER("SendTls13HelloRetryRequest");
|
||||
|
||||
#ifndef WOLFSSL_TLS13_DRAFT_18
|
||||
if ((ret = RestartHandshakeHash(ssl)) < 0)
|
||||
return ret;
|
||||
#endif
|
||||
|
||||
/* Get the length of the extensions that will be written. */
|
||||
len = TLSX_GetResponseSize(ssl, hello_retry_request);
|
||||
/* There must be extensions sent to indicate what client needs to do. */
|
||||
if (len == 0)
|
||||
return MISSING_HANDSHAKE_DATA;
|
||||
|
||||
#ifndef WOLFSSL_TLS13_DRAFT_18
|
||||
/* Protocol version + CipherSuite + Extensions */
|
||||
length = OPAQUE16_LEN + OPAQUE16_LEN + len;
|
||||
#else
|
||||
/* Protocol version + Extensions */
|
||||
length = OPAQUE16_LEN + len;
|
||||
#endif
|
||||
sendSz = idx + length;
|
||||
|
||||
/* Check buffers are big enough and grow if needed. */
|
||||
@ -3516,12 +3691,6 @@ int SendTls13HelloRetryRequest(WOLFSSL* ssl)
|
||||
output[idx++] = TLS_DRAFT_MAJOR;
|
||||
output[idx++] = TLS_DRAFT_MINOR;
|
||||
|
||||
#ifndef WOLFSSL_TLS13_DRAFT_18
|
||||
/* Chosen cipher suite */
|
||||
output[idx++] = ssl->options.cipherSuite0;
|
||||
output[idx++] = ssl->options.cipherSuite;
|
||||
#endif
|
||||
|
||||
/* Add TLS extensions. */
|
||||
TLSX_WriteResponse(ssl, output + idx, hello_retry_request);
|
||||
idx += len;
|
||||
@ -3534,7 +3703,6 @@ int SendTls13HelloRetryRequest(WOLFSSL* ssl)
|
||||
ssl->heap);
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((ret = HashOutput(ssl, output, idx, 0)) != 0)
|
||||
return ret;
|
||||
|
||||
@ -3547,6 +3715,7 @@ int SendTls13HelloRetryRequest(WOLFSSL* ssl)
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* WOLFSSL_TLS13_DRAFT_18 */
|
||||
|
||||
/* Send TLS v1.3 ServerHello message to client.
|
||||
* Only a server will send this message.
|
||||
@ -3554,7 +3723,10 @@ int SendTls13HelloRetryRequest(WOLFSSL* ssl)
|
||||
* ssl The SSL/TLS object.
|
||||
* returns 0 on success, otherwise failure.
|
||||
*/
|
||||
static int SendTls13ServerHello(WOLFSSL* ssl)
|
||||
#ifdef WOLFSSL_TLS13_DRAFT_18
|
||||
static
|
||||
#endif
|
||||
int SendTls13ServerHello(WOLFSSL* ssl, byte extMsgType)
|
||||
{
|
||||
byte* output;
|
||||
word32 length;
|
||||
@ -3564,9 +3736,24 @@ static int SendTls13ServerHello(WOLFSSL* ssl)
|
||||
|
||||
WOLFSSL_ENTER("SendTls13ServerHello");
|
||||
|
||||
#ifndef WOLFSSL_TLS13_DRAFT_18
|
||||
if (extMsgType == hello_retry_request) {
|
||||
if ((ret = RestartHandshakeHash(ssl)) < 0)
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_TLS13_DRAFT_18
|
||||
/* Protocol version, server random, cipher suite and extensions. */
|
||||
length = VERSION_SZ + RAN_LEN + SUITE_LEN +
|
||||
TLSX_GetResponseSize(ssl, server_hello);
|
||||
#else
|
||||
/* Protocol version, server random, session id, cipher suite, compression
|
||||
* and extensions.
|
||||
*/
|
||||
length = VERSION_SZ + RAN_LEN + ENUM_LEN + ssl->session.sessionIDSz +
|
||||
SUITE_LEN + COMP_LEN + TLSX_GetResponseSize(ssl, extMsgType);
|
||||
#endif
|
||||
sendSz = idx + length;
|
||||
|
||||
/* Check buffers are big enough and grow if needed. */
|
||||
@ -3580,6 +3767,7 @@ static int SendTls13ServerHello(WOLFSSL* ssl)
|
||||
/* Put the record and handshake headers on. */
|
||||
AddTls13Headers(output, length, server_hello, ssl);
|
||||
|
||||
#ifdef WOLFSSL_TLS13_DRAFT_18
|
||||
/* TODO: [TLS13] Replace existing code with code in comment.
|
||||
* Use the TLS v1.3 draft version for now.
|
||||
*
|
||||
@ -3590,10 +3778,23 @@ static int SendTls13ServerHello(WOLFSSL* ssl)
|
||||
/* The negotiated protocol version. */
|
||||
output[idx++] = TLS_DRAFT_MAJOR;
|
||||
output[idx++] = TLS_DRAFT_MINOR;
|
||||
#else
|
||||
/* The protocol version must be TLS v1.2 for middleboxes. */
|
||||
output[idx++] = ssl->version.major;
|
||||
output[idx++] = TLSv1_2_MINOR;
|
||||
#endif
|
||||
|
||||
/* Generate server random. */
|
||||
if ((ret = wc_RNG_GenerateBlock(ssl->rng, output + idx, RAN_LEN)) != 0)
|
||||
return ret;
|
||||
if (extMsgType == server_hello) {
|
||||
/* Generate server random. */
|
||||
if ((ret = wc_RNG_GenerateBlock(ssl->rng, output + idx, RAN_LEN)) != 0)
|
||||
return ret;
|
||||
}
|
||||
#ifndef WOLFSSL_TLS13_DRAFT_18
|
||||
else {
|
||||
/* HelloRetryRequest message has fixed value for random. */
|
||||
XMEMCPY(output + idx, helloRetryRequestRandom, RAN_LEN);
|
||||
}
|
||||
#endif
|
||||
/* Store in SSL for debugging. */
|
||||
XMEMCPY(ssl->arrays->serverRandom, output + idx, RAN_LEN);
|
||||
idx += RAN_LEN;
|
||||
@ -3603,12 +3804,25 @@ static int SendTls13ServerHello(WOLFSSL* ssl)
|
||||
WOLFSSL_BUFFER(ssl->arrays->serverRandom, RAN_LEN);
|
||||
#endif
|
||||
|
||||
#ifndef WOLFSSL_TLS13_DRAFT_18
|
||||
output[idx++] = ssl->session.sessionIDSz;
|
||||
if (ssl->session.sessionIDSz > 0) {
|
||||
XMEMCPY(output + idx, ssl->session.sessionID, ssl->session.sessionIDSz);
|
||||
idx += ssl->session.sessionIDSz;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Chosen cipher suite */
|
||||
output[idx++] = ssl->options.cipherSuite0;
|
||||
output[idx++] = ssl->options.cipherSuite;
|
||||
|
||||
#ifndef WOLFSSL_TLS13_DRAFT_18
|
||||
/* Compression not supported in TLS v1.3. */
|
||||
output[idx++] = 0;
|
||||
#endif
|
||||
|
||||
/* Extensions */
|
||||
TLSX_WriteResponse(ssl, output + idx, server_hello);
|
||||
TLSX_WriteResponse(ssl, output + idx, extMsgType);
|
||||
|
||||
ssl->buffers.outputBuffer.length += sendSz;
|
||||
|
||||
@ -3624,7 +3838,12 @@ static int SendTls13ServerHello(WOLFSSL* ssl)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_TLS13_DRAFT_18
|
||||
ssl->options.serverState = SERVER_HELLO_COMPLETE;
|
||||
#else
|
||||
if (extMsgType == server_hello)
|
||||
ssl->options.serverState = SERVER_HELLO_COMPLETE;
|
||||
#endif
|
||||
|
||||
if (!ssl->options.groupMessages)
|
||||
ret = SendBuffered(ssl);
|
||||
@ -5647,8 +5866,6 @@ static int DoTls13NewSessionTicket(WOLFSSL* ssl, const byte* input,
|
||||
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;
|
||||
@ -5687,7 +5904,8 @@ static int DoTls13NewSessionTicket(WOLFSSL* ssl, const byte* input,
|
||||
#endif
|
||||
#ifndef WOLFSSL_TLS13_DRAFT_18
|
||||
ssl->session.ticketNonce.len = nonceLength;
|
||||
XMEMCPY(&ssl->session.ticketNonce.data, nonce, nonceLength);
|
||||
if (nonceLength > 0)
|
||||
XMEMCPY(&ssl->session.ticketNonce.data, nonce, nonceLength);
|
||||
#endif
|
||||
|
||||
if ((*inOutIdx - begin) + EXTS_SZ > size)
|
||||
@ -5967,11 +6185,19 @@ static int SanityCheckTls13MsgReceived(WOLFSSL* ssl, byte type)
|
||||
|
||||
#ifndef NO_WOLFSSL_CLIENT
|
||||
case server_hello:
|
||||
#ifdef WOLFSSL_TLS13_DRAFT_18
|
||||
if (ssl->msgsReceived.got_server_hello) {
|
||||
WOLFSSL_MSG("Duplicate ServerHello received");
|
||||
return DUPLICATE_MSG_E;
|
||||
}
|
||||
ssl->msgsReceived.got_server_hello = 1;
|
||||
#else
|
||||
if (ssl->msgsReceived.got_server_hello == 2) {
|
||||
WOLFSSL_MSG("Duplicate ServerHello received");
|
||||
return DUPLICATE_MSG_E;
|
||||
}
|
||||
ssl->msgsReceived.got_server_hello++;
|
||||
#endif
|
||||
|
||||
break;
|
||||
#endif
|
||||
@ -6172,10 +6398,12 @@ int DoTls13HandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
switch (type) {
|
||||
|
||||
#ifndef NO_WOLFSSL_CLIENT
|
||||
#ifdef WOLFSSL_TLS13_DRAFT_18
|
||||
case hello_retry_request:
|
||||
WOLFSSL_MSG("processing hello rety request");
|
||||
ret = DoTls13HelloRetryRequest(ssl, input, inOutIdx, size);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case server_hello:
|
||||
WOLFSSL_MSG("processing server hello");
|
||||
@ -6499,6 +6727,14 @@ int wolfSSL_connect_TLSv13(WOLFSSL* ssl)
|
||||
WOLFSSL_MSG("connect state: CLIENT_HELLO_SENT");
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
if (ssl->earlyData) {
|
||||
#if !defined(WOLFSSL_TLS13_DRAFT_18) && \
|
||||
defined(WOLFSSL_TLS13_MIDDLEBOX_COMPAT)
|
||||
if ((ssl->error = SendChangeCipher(ssl)) != 0) {
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
ssl->options.sentChangeCipher = 1;
|
||||
#endif
|
||||
ssl->options.handShakeState = CLIENT_HELLO_COMPLETE;
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
@ -6539,6 +6775,16 @@ int wolfSSL_connect_TLSv13(WOLFSSL* ssl)
|
||||
|
||||
if (ssl->options.serverState == SERVER_HELLO_RETRY_REQUEST) {
|
||||
ssl->options.serverState = NULL_STATE;
|
||||
#if !defined(WOLFSSL_TLS13_DRAFT_18) && \
|
||||
defined(WOLFSSL_TLS13_MIDDLEBOX_COMPAT)
|
||||
if (!ssl->options.sentChangeCipher) {
|
||||
if ((ssl->error = SendChangeCipher(ssl)) != 0) {
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
ssl->options.sentChangeCipher = 1;
|
||||
}
|
||||
#endif
|
||||
/* Try again with different security parameters. */
|
||||
if ((ssl->error = SendTls13ClientHello(ssl)) != 0) {
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
@ -6590,6 +6836,16 @@ int wolfSSL_connect_TLSv13(WOLFSSL* ssl)
|
||||
FALL_THROUGH;
|
||||
|
||||
case FIRST_REPLY_FIRST:
|
||||
#if !defined(WOLFSSL_TLS13_DRAFT_18) && \
|
||||
defined(WOLFSSL_TLS13_MIDDLEBOX_COMPAT)
|
||||
if (!ssl->options.sentChangeCipher) {
|
||||
if ((ssl->error = SendChangeCipher(ssl)) != 0) {
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
ssl->options.sentChangeCipher = 1;
|
||||
}
|
||||
#endif
|
||||
#ifndef NO_CERTS
|
||||
if (!ssl->options.resuming && ssl->options.sendVerify) {
|
||||
ssl->error = SendTls13Certificate(ssl);
|
||||
@ -7013,32 +7269,53 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
|
||||
|
||||
case ACCEPT_BEGIN :
|
||||
/* get response */
|
||||
while (ssl->options.clientState < CLIENT_HELLO_COMPLETE)
|
||||
while (ssl->options.clientState < CLIENT_HELLO_COMPLETE) {
|
||||
if ((ssl->error = ProcessReply(ssl)) < 0) {
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
ssl->options.acceptState = ACCEPT_CLIENT_HELLO_DONE;
|
||||
WOLFSSL_MSG("accept state ACCEPT_CLIENT_HELLO_DONE");
|
||||
FALL_THROUGH;
|
||||
|
||||
case ACCEPT_CLIENT_HELLO_DONE :
|
||||
#ifdef WOLFSSL_TLS13_DRAFT_18
|
||||
if (ssl->options.serverState == SERVER_HELLO_RETRY_REQUEST) {
|
||||
if ((ssl->error = SendTls13HelloRetryRequest(ssl)) != 0) {
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (ssl->options.serverState == SERVER_HELLO_RETRY_REQUEST) {
|
||||
if ((ssl->error = SendTls13ServerHello(ssl,
|
||||
hello_retry_request)) != 0) {
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
#ifdef WOLFSSL_TLS13_MIDDLEBOX_COMPAT
|
||||
if ((ssl->error = SendChangeCipher(ssl)) != 0) {
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
ssl->options.sentChangeCipher = 1;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
ssl->options.acceptState = ACCEPT_HELLO_RETRY_REQUEST_DONE;
|
||||
WOLFSSL_MSG("accept state ACCEPT_HELLO_RETRY_REQUEST_DONE");
|
||||
FALL_THROUGH;
|
||||
|
||||
case ACCEPT_HELLO_RETRY_REQUEST_DONE :
|
||||
if (ssl->options.serverState == SERVER_HELLO_RETRY_REQUEST) {
|
||||
if ( (ssl->error = ProcessReply(ssl)) < 0) {
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
ssl->options.clientState = NULL_STATE;
|
||||
while (ssl->options.clientState < CLIENT_HELLO_COMPLETE) {
|
||||
if ((ssl->error = ProcessReply(ssl)) < 0) {
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
ssl->options.acceptState = ACCEPT_FIRST_REPLY_DONE;
|
||||
@ -7046,10 +7323,20 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
|
||||
FALL_THROUGH;
|
||||
|
||||
case ACCEPT_FIRST_REPLY_DONE :
|
||||
if ((ssl->error = SendTls13ServerHello(ssl)) != 0) {
|
||||
if ((ssl->error = SendTls13ServerHello(ssl, server_hello)) != 0) {
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
#if !defined(WOLFSSL_TLS13_DRAFT_18) && \
|
||||
defined(WOLFSSL_TLS13_MIDDLEBOX_COMPAT)
|
||||
if (!ssl->options.sentChangeCipher) {
|
||||
if ((ssl->error = SendChangeCipher(ssl)) != 0) {
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
ssl->options.sentChangeCipher = 1;
|
||||
}
|
||||
#endif
|
||||
ssl->options.acceptState = SERVER_HELLO_SENT;
|
||||
WOLFSSL_MSG("accept state SERVER_HELLO_SENT");
|
||||
FALL_THROUGH;
|
||||
|
@ -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 = 0x15, /* Minor version number of TLS draft */
|
||||
TLS_DRAFT_MINOR = 0x16, /* Minor version number of TLS draft */
|
||||
#endif
|
||||
OLD_HELLO_ID = 0x01, /* SSLv2 Client Hello Indicator */
|
||||
INVALID_BYTE = 0xff, /* Used to initialize cipher specs values */
|
||||
@ -2928,6 +2928,9 @@ typedef struct Options {
|
||||
#ifdef WOLFSSL_ALT_CERT_CHAINS
|
||||
word16 usingAltCertChain:1;/* Alternate cert chain was used */
|
||||
#endif
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_TLS13_MIDDLEBOX_COMPAT)
|
||||
word16 sentChangeCipher:1; /* Change Cipher Spec sent */
|
||||
#endif
|
||||
|
||||
/* need full byte values for this section */
|
||||
byte processReply; /* nonblocking resume */
|
||||
@ -2962,7 +2965,6 @@ typedef struct Options {
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
word32 maxEarlyDataSz;
|
||||
#endif
|
||||
|
||||
} Options;
|
||||
|
||||
typedef struct Arrays {
|
||||
@ -3178,7 +3180,7 @@ typedef struct DtlsMsg {
|
||||
typedef struct MsgsReceived {
|
||||
word16 got_hello_request:1;
|
||||
word16 got_client_hello:2;
|
||||
word16 got_server_hello:1;
|
||||
word16 got_server_hello:2;
|
||||
word16 got_hello_verify_request:1;
|
||||
word16 got_session_ticket:1;
|
||||
word16 got_end_of_early_data:1;
|
||||
@ -3664,7 +3666,11 @@ WOLFSSL_LOCAL int SendTicket(WOLFSSL*);
|
||||
WOLFSSL_LOCAL int DoClientTicket(WOLFSSL*, const byte*, word32);
|
||||
WOLFSSL_LOCAL int SendData(WOLFSSL*, const void*, int);
|
||||
#ifdef WOLFSSL_TLS13
|
||||
#ifdef WOLFSSL_TLS13_DRAFT_18
|
||||
WOLFSSL_LOCAL int SendTls13HelloRetryRequest(WOLFSSL*);
|
||||
#else
|
||||
WOLFSSL_LOCAL int SendTls13ServerHello(WOLFSSL*, byte);
|
||||
#endif
|
||||
#endif
|
||||
WOLFSSL_LOCAL int SendCertificate(WOLFSSL*);
|
||||
WOLFSSL_LOCAL int SendCertificateRequest(WOLFSSL*);
|
||||
|
Loading…
x
Reference in New Issue
Block a user