mirror of https://github.com/wolfSSL/wolfssl.git
Updates from code review
parent
decdf7ae8b
commit
08a0b98f52
46
configure.ac
46
configure.ac
|
@ -248,21 +248,55 @@ then
|
|||
fi
|
||||
|
||||
|
||||
# TLS v1.3 Draft 18
|
||||
AC_ARG_ENABLE([tls13-draft18],
|
||||
[AS_HELP_STRING([--enable-tls13-draft18],[Enable wolfSSL TLS v1.3 Draft 18 (default: disabled)])],
|
||||
[ ENABLED_TLS13_DRAFT18=$enableval ],
|
||||
[ ENABLED_TLS13_DRAFT18=no ]
|
||||
)
|
||||
if test "$ENABLED_TLS13_DRAFT18" = "yes"
|
||||
then
|
||||
AM_CFLAGS="-DWOLFSSL_TLS13_DRAFT18 $AM_CFLAGS"
|
||||
fi
|
||||
|
||||
|
||||
# TLS v1.3
|
||||
AC_ARG_ENABLE([tls13],
|
||||
[AS_HELP_STRING([--enable-tls13],[Enable wolfSSL TLS v1.3 (default: disabled)])],
|
||||
[ ENABLED_TLS13=$enableval ],
|
||||
[ ENABLED_TLS13=no ]
|
||||
)
|
||||
|
||||
if test "$ENABLED_TLS13_DRAFT18" = "yes"
|
||||
then
|
||||
ENABLED_TLS13="yes"
|
||||
fi
|
||||
|
||||
if test "$ENABLED_TLS13" = "yes"
|
||||
then
|
||||
AM_CFLAGS="-DWOLFSSL_TLS13 -DHAVE_TLS_EXTENSIONS -DHAVE_FFDHE_2048 $AM_CFLAGS"
|
||||
AM_CFLAGS="-DWOLFSSL_TLS13 -DHAVE_TLS_EXTENSIONS -DHAVE_FFDHE_2048 $AM_CFLAGS"
|
||||
fi
|
||||
|
||||
# check if TLS v1.3 was enabled for conditionally running tls13.test script
|
||||
AM_CONDITIONAL([BUILD_TLS13], [test "x$ENABLED_TLS13" = "xyes"])
|
||||
|
||||
|
||||
# Post-handshake Authentication
|
||||
AC_ARG_ENABLE([postauth],
|
||||
[AS_HELP_STRING([--enable-postauth],[Enable wolfSSL Post-handshake Authentication (default: disabled)])],
|
||||
[ ENABLED_TLS13_POST_AUTH=$enableval ],
|
||||
[ ENABLED_TLS13_POST_AUTH=no ]
|
||||
)
|
||||
if test "$ENABLED_TLS13_POST_AUTH" = "yes"
|
||||
then
|
||||
if test "x$ENABLED_TLS13" = "xno"
|
||||
then
|
||||
AC_MSG_ERROR([cannot enable postauth without enabling tls13.])
|
||||
fi
|
||||
AM_CFLAGS="-DWOLFSSL_POST_HANDSHAKE_AUTH $AM_CFLAGS"
|
||||
fi
|
||||
|
||||
|
||||
AC_ARG_ENABLE([rng],
|
||||
[AS_HELP_STRING([--enable-rng],[Enable compiling and using RNG (default: enabled)])],
|
||||
[ ENABLED_RNG=$enableval ],
|
||||
|
@ -2329,10 +2363,10 @@ fi
|
|||
# Early Data handshake in TLS v1.3 and above
|
||||
AC_ARG_ENABLE([earlydata],
|
||||
[AS_HELP_STRING([--enable-earlydata],[Enable Early Data handshake with wolfSSL TLS v1.3 (default: disabled)])],
|
||||
[ ENABLED_EARLY_DATA=$enableval ],
|
||||
[ ENABLED_EARLY_DATA=no ]
|
||||
[ ENABLED_TLS13_EARLY_DATA=$enableval ],
|
||||
[ ENABLED_TLS13_EARLY_DATA=no ]
|
||||
)
|
||||
if test "$ENABLED_EARLY_DATA" = "yes"
|
||||
if test "$ENABLED_TLS13_EARLY_DATA" = "yes"
|
||||
then
|
||||
if test "x$ENABLED_TLS13" = "xno"
|
||||
then
|
||||
|
@ -3760,7 +3794,9 @@ echo " * SCTP: $ENABLED_SCTP"
|
|||
echo " * Old TLS Versions: $ENABLED_OLD_TLS"
|
||||
echo " * SSL version 3.0: $ENABLED_SSLV3"
|
||||
echo " * TLS v1.3: $ENABLED_TLS13"
|
||||
echo " * Early Data: $ENABLED_EARLY_DATA"
|
||||
echo " * TLS v1.3 Draft 18: $ENABLED_TLS13_DRAFT18"
|
||||
echo " * Post-handshake Auth: $ENABLED_TLS13_POST_AUTH"
|
||||
echo " * Early Data: $ENABLED_TLS13_EARLY_DATA"
|
||||
echo " * OCSP: $ENABLED_OCSP"
|
||||
echo " * OCSP Stapling: $ENABLED_CERTIFICATE_STATUS_REQUEST"
|
||||
echo " * OCSP Stapling v2: $ENABLED_CERTIFICATE_STATUS_REQUEST_V2"
|
||||
|
|
|
@ -1941,7 +1941,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
|||
|
||||
ClientRead(ssl, reply, sizeof(reply)-1, 1);
|
||||
|
||||
#ifdef WOLFSSL_POST_HANDSHAKE_AUTH
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
|
||||
if (postHandAuth)
|
||||
ClientWrite(ssl, msg, msgSz);
|
||||
#endif
|
||||
|
|
189
src/tls13.c
189
src/tls13.c
|
@ -20,6 +20,22 @@
|
|||
*/
|
||||
|
||||
|
||||
/*
|
||||
* WOLFSSL_TLS13_DRAFT_18
|
||||
* Conform with Draft 18 of the TLS v1.3 specification.
|
||||
* WOLFSSL_EARLY_DATA
|
||||
* Allow 0-RTT Handshake using Early Data extensions and handshake message
|
||||
* WOLFSSL_POST_HANDSHAKE_AUTH
|
||||
* Allow TLS v1.3 code to perform post-handshake authentication of the
|
||||
* client.
|
||||
* WOLFSSL_TLS13_TICKET_BEFORE_FINISHED
|
||||
* Allow a NewSessionTicket message to be sent by server before Client's
|
||||
* Finished message.
|
||||
* See TLS v.13 specification, Section 4.6.1, Paragraph 4 (Note).
|
||||
* TLS13_SUPPORTS_EXPORTERS
|
||||
* Gaurd to compile out any code for exporter keys.
|
||||
* Feature not supported yet.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
|
@ -210,16 +226,16 @@ static int Tls13_HKDF_Extract(byte* prk, const byte* salt, int saltLen,
|
|||
}
|
||||
|
||||
#ifdef WOLFSSL_DEBUG_TLS
|
||||
WOLFSSL_MSG("Salt");
|
||||
WOLFSSL_MSG(" Salt");
|
||||
WOLFSSL_BUFFER(salt, saltLen);
|
||||
WOLFSSL_MSG("IKM");
|
||||
WOLFSSL_MSG(" IKM");
|
||||
WOLFSSL_BUFFER(ikm, ikmLen);
|
||||
#endif
|
||||
|
||||
ret = wc_HKDF_Extract(hash, salt, saltLen, ikm, ikmLen, prk);
|
||||
|
||||
#ifdef WOLFSSL_DEBUG_TLS
|
||||
WOLFSSL_MSG("PRK");
|
||||
WOLFSSL_MSG(" PRK");
|
||||
WOLFSSL_BUFFER(prk, len);
|
||||
#endif
|
||||
|
||||
|
@ -268,16 +284,16 @@ static int HKDF_Expand_Label(byte* okm, word32 okmLen,
|
|||
idx += infoLen;
|
||||
|
||||
#ifdef WOLFSSL_DEBUG_TLS
|
||||
WOLFSSL_MSG("PRK");
|
||||
WOLFSSL_MSG(" PRK");
|
||||
WOLFSSL_BUFFER(prk, prkLen);
|
||||
WOLFSSL_MSG("Info");
|
||||
WOLFSSL_MSG(" Info");
|
||||
WOLFSSL_BUFFER(data, idx);
|
||||
#endif
|
||||
|
||||
ret = wc_HKDF_Expand(digest, prk, prkLen, data, idx, okm, okmLen);
|
||||
|
||||
#ifdef WOLFSSL_DEBUG_TLS
|
||||
WOLFSSL_MSG("OKM");
|
||||
WOLFSSL_MSG(" OKM");
|
||||
WOLFSSL_BUFFER(okm, okmLen);
|
||||
#endif
|
||||
|
||||
|
@ -548,7 +564,7 @@ static int DeriveEarlyTrafficSecret(WOLFSSL* ssl, byte* key)
|
|||
ssl->specs.mac_algorithm, 1);
|
||||
}
|
||||
|
||||
#ifdef TLS13_SUPPORTS_EXPORTERS
|
||||
#ifdef TLS13_SUPPORTS_EXPORTERS
|
||||
#ifdef WOLFSSL_TLS13_DRAFT_18
|
||||
/* The length of the early exporter label. */
|
||||
#define EARLY_EXPORTER_LABEL_SZ 28
|
||||
|
@ -575,7 +591,7 @@ static int DeriveEarlyExporterSecret(WOLFSSL* ssl, byte* key)
|
|||
earlyExporterLabel, EARLY_EXPORTER_LABEL_SZ,
|
||||
ssl->specs.mac_algorithm, 1);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_TLS13_DRAFT_18
|
||||
|
@ -1399,7 +1415,7 @@ static int RestartHandshakeHash(WOLFSSL* ssl)
|
|||
ret = HashOutputRaw(ssl, header, sizeof(header));
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
return HashOutputRaw(ssl, hash, header[3]);
|
||||
return HashOutputRaw(ssl, hash, header[MSG_HASH_LEN_OFFSET]);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2678,9 +2694,9 @@ static int DoTls13CertificateRequest(WOLFSSL* ssl, const byte* input,
|
|||
int ret = 0;
|
||||
#ifndef WOLFSSL_TLS13_DRAFT_18
|
||||
Suites peerSuites;
|
||||
#endif
|
||||
#ifdef WOLFSSL_POST_HANDSHAKE_AUTH
|
||||
CertReqCtx* certReqCtx;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
WOLFSSL_ENTER("DoTls13CertificateRequest");
|
||||
|
@ -2700,9 +2716,23 @@ static int DoTls13CertificateRequest(WOLFSSL* ssl, const byte* input,
|
|||
if (ssl->options.connectState < FINISHED_DONE && len > 0)
|
||||
return BUFFER_ERROR;
|
||||
|
||||
#ifdef WOLFSSL_TLS13_DRAFT_18
|
||||
#ifdef WOLFSSL_POST_HANDSHAKE_AUTH
|
||||
/* CertReqCtx has one byte at end for context value.
|
||||
* Increase size to handle other implementations sending more than one byte.
|
||||
* That is, allocate extra space, over one byte, to hold the context value.
|
||||
*/
|
||||
certReqCtx = (CertReqCtx*)XMALLOC(sizeof(CertReqCtx) + len - 1, ssl->heap,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (certReqCtx == NULL)
|
||||
return MEMORY_E;
|
||||
certReqCtx->next = ssl->certReqCtx;
|
||||
certReqCtx->len = len;
|
||||
XMEMCPY(&certReqCtx->ctx, input + *inOutIdx, len);
|
||||
ssl->certReqCtx = certReqCtx;
|
||||
#endif
|
||||
*inOutIdx += len;
|
||||
|
||||
#ifdef WOLFSSL_TLS13_DRAFT_18
|
||||
/* Signature and hash algorithms. */
|
||||
if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
|
||||
return BUFFER_ERROR;
|
||||
|
@ -2747,18 +2777,6 @@ static int DoTls13CertificateRequest(WOLFSSL* ssl, const byte* input,
|
|||
return BUFFER_ERROR;
|
||||
*inOutIdx += len;
|
||||
#else
|
||||
#ifdef WOLFSSL_POST_HANDSHAKE_AUTH
|
||||
certReqCtx = (CertReqCtx*)XMALLOC(sizeof(CertReqCtx) + len - 1, ssl->heap,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (certReqCtx == NULL)
|
||||
return MEMORY_E;
|
||||
certReqCtx->next = ssl->certReqCtx;
|
||||
certReqCtx->len = len;
|
||||
XMEMCPY(&certReqCtx->ctx, input + *inOutIdx, len);
|
||||
ssl->certReqCtx = certReqCtx;
|
||||
#endif
|
||||
*inOutIdx += len;
|
||||
|
||||
/* TODO: Add support for more extensions:
|
||||
* signed_certificate_timestamp, certificate_authorities, oid_filters.
|
||||
*/
|
||||
|
@ -3486,8 +3504,6 @@ static int SendTls13CertificateRequest(WOLFSSL* ssl, byte* reqCtx,
|
|||
WOLFSSL_ENTER("SendTls13CertificateRequest");
|
||||
|
||||
#ifdef WOLFSSL_TLS13_DRAFT_18
|
||||
(void)reqCtx;
|
||||
|
||||
i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
|
||||
reqSz = OPAQUE8_LEN + reqCtxLen + REQ_HEADER_SZ + REQ_HEADER_SZ;
|
||||
reqSz += LENGTH_SZ + ssl->suites->hashSigAlgoSz;
|
||||
|
@ -3509,6 +3525,10 @@ static int SendTls13CertificateRequest(WOLFSSL* ssl, byte* reqCtx,
|
|||
|
||||
/* Certificate request context. */
|
||||
output[i++] = reqCtxLen;
|
||||
if (reqCtxLen != 0) {
|
||||
XMEMCPY(output + i, reqCtx, reqCtxLen);
|
||||
i += reqCtxLen;
|
||||
}
|
||||
|
||||
/* supported hash/sig */
|
||||
c16toa(ssl->suites->hashSigAlgoSz, &output[i]);
|
||||
|
@ -5525,6 +5545,101 @@ static int DoTls13NewSessionTicket(WOLFSSL* ssl, const byte* input,
|
|||
|
||||
#ifndef NO_WOLFSSL_SERVER
|
||||
#ifdef HAVE_SESSION_TICKET
|
||||
|
||||
#ifdef WOLFSSL_TLS13_TICKET_BEFORE_FINISHED
|
||||
/* Offset of the MAC size in the finished message. */
|
||||
#define FINISHED_MSG_SIZE_OFFSET 3
|
||||
|
||||
/* Calculate the resumption secret which includes the unseen client finished
|
||||
* message.
|
||||
*
|
||||
* ssl The SSL/TLS object.
|
||||
* retuns 0 on success, otherwise failure.
|
||||
*/
|
||||
static int ExpectedResumptionSecret(WOLFSSL* ssl)
|
||||
{
|
||||
int ret;
|
||||
word32 finishedSz = 0;
|
||||
byte mac[MAX_DIGEST_SIZE];
|
||||
Digest digest;
|
||||
static byte header[] = { 0x14, 0x00, 0x00, 0x00 };
|
||||
|
||||
/* Copy the running hash so we cna restore it after. */
|
||||
switch (ssl->specs.mac_algorithm) {
|
||||
#ifndef NO_SHA256
|
||||
case sha256_mac:
|
||||
ret = wc_Sha256Copy(&ssl->hsHashes->hashSha256, &digest.sha256);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
case sha384_mac:
|
||||
ret = wc_Sha384Copy(&ssl->hsHashes->hashSha384, &digest.sha384);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
case sha512_mac:
|
||||
ret = wc_Sha512Copy(&ssl->hsHashes->hashSha512, &digest.sha512);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Generate the Client's Finished message and hash it. */
|
||||
ret = BuildTls13HandshakeHmac(ssl, ssl->keys.client_write_MAC_secret, mac,
|
||||
&finishedSz);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
header[FINISHED_MSG_SIZE_OFFSET] = finishedSz;
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
if (ssl->earlyData) {
|
||||
static byte endOfEarlyData[] = { 0x05, 0x00, 0x00, 0x00 };
|
||||
ret = HashInputRaw(ssl, endOfEarlyData, sizeof(endOfEarlyData));
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
if ((ret = HashInputRaw(ssl, header, sizeof(header))) != 0)
|
||||
return ret;
|
||||
if ((ret = HashInputRaw(ssl, mac, finishedSz)) != 0)
|
||||
return ret;
|
||||
|
||||
if ((ret = DeriveResumptionSecret(ssl, ssl->session.masterSecret)) != 0)
|
||||
return ret;
|
||||
|
||||
/* Restore the hash inline with currently seen messages. */
|
||||
switch (ssl->specs.mac_algorithm) {
|
||||
#ifndef NO_SHA256
|
||||
case sha256_mac:
|
||||
ret = wc_Sha256Copy(&digest.sha256, &ssl->hsHashes->hashSha256);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
case sha384_mac:
|
||||
ret = wc_Sha384Copy(&digest.sha384, &ssl->hsHashes->hashSha384);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
case sha512_mac:
|
||||
ret = wc_Sha512Copy(&digest.sha512, &ssl->hsHashes->hashSha384);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Send New Session Ticket handshake message.
|
||||
* Message contains the information required to perform resumption.
|
||||
*
|
||||
|
@ -5542,6 +5657,13 @@ static int SendTls13NewSessionTicket(WOLFSSL* ssl)
|
|||
|
||||
WOLFSSL_ENTER("SendTls13NewSessionTicket");
|
||||
|
||||
#ifdef WOLFSSL_TLS13_TICKET_BEFORE_FINISHED
|
||||
if (!ssl->msgsReceived.got_finished) {
|
||||
if ((ret = ExpectedResumptionSecret(ssl)) != 0)
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!ssl->options.noTicketTls13) {
|
||||
if ((ret = CreateTicket(ssl)) != 0)
|
||||
return ret;
|
||||
|
@ -5994,8 +6116,11 @@ int DoTls13HandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
|||
}
|
||||
|
||||
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
||||
if (type == finished && ssl->options.side == WOLFSSL_SERVER_END)
|
||||
DeriveResumptionSecret(ssl, ssl->session.masterSecret);
|
||||
if (type == finished && ssl->options.side == WOLFSSL_SERVER_END) {
|
||||
ret = DeriveResumptionSecret(ssl, ssl->session.masterSecret);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -6477,7 +6602,6 @@ int wolfSSL_allow_post_handshake_auth(WOLFSSL* ssl)
|
|||
{
|
||||
if (ssl == NULL || !IsAtLeastTLSv1_3(ssl->version))
|
||||
return BAD_FUNC_ARG;
|
||||
return BAD_FUNC_ARG;
|
||||
if (ssl->options.side == WOLFSSL_SERVER_END)
|
||||
return SIDE_ERROR;
|
||||
|
||||
|
@ -6719,8 +6843,7 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
|
|||
|
||||
case ACCEPT_FINISHED_DONE :
|
||||
#ifdef HAVE_SESSION_TICKET
|
||||
#ifdef RESUMPTION_SECRET_CALCULATED_WITHOUT_CLIENT_FINISHED
|
||||
/* TODO: [TLS13] Section 4.6.1 Note. */
|
||||
#ifdef WOLFSSL_TLS13_TICKET_BEFORE_FINISHED
|
||||
if (!ssl->options.resuming && !ssl->options.verifyPeer &&
|
||||
!ssl->options.noTicketTls13 && ssl->ctx->ticketEncCb != NULL) {
|
||||
if ((ssl->error = SendTls13NewSessionTicket(ssl)) != 0) {
|
||||
|
@ -6728,7 +6851,7 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
|
|||
return SSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif /* HAVE_SESSION_TICKET */
|
||||
ssl->options.acceptState = TICKET_SENT;
|
||||
WOLFSSL_MSG("accept state TICKET_SENT");
|
||||
|
@ -6747,11 +6870,11 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
|
|||
|
||||
case ACCEPT_SECOND_REPLY_DONE :
|
||||
#ifdef HAVE_SESSION_TICKET
|
||||
#ifdef RESUMPTION_SECRET_CALCULATED_WITHOUT_CLIENT_FINISHED
|
||||
#ifdef WOLFSSL_TLS13_TICKET_BEFORE_FINISHED
|
||||
if (!ssl->options.verifyPeer) {
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#endif
|
||||
if (!ssl->options.resuming &&
|
||||
!ssl->options.noTicketTls13 && ssl->ctx->ticketEncCb != NULL) {
|
||||
if ((ssl->error = SendTls13NewSessionTicket(ssl)) != 0) {
|
||||
|
|
Loading…
Reference in New Issue