pull/980/head
Sean Parkinson 2017-06-21 16:56:51 +10:00
parent 1549a60aa5
commit decdf7ae8b
5 changed files with 315 additions and 262 deletions

View File

@ -1941,6 +1941,10 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
ClientRead(ssl, reply, sizeof(reply)-1, 1); ClientRead(ssl, reply, sizeof(reply)-1, 1);
#ifdef WOLFSSL_POST_HANDSHAKE_AUTH
if (postHandAuth)
ClientWrite(ssl, msg, msgSz);
#endif
if (sendGET) { /* get html */ if (sendGET) { /* get html */
ClientRead(ssl, reply, sizeof(reply)-1, 0); ClientRead(ssl, reply, sizeof(reply)-1, 0);
} }

View File

@ -95,6 +95,22 @@ if [ $RESULT -ne 0 ]; then
fi fi
echo "" echo ""
# Use HelloRetryRequest with TLS v1.3 server / TLS v1.3 client - SHA384.
echo -e "\n\nTLS v1.3 HelloRetryRequest - SHA384"
port=0
./examples/server/server -v 4 -l TLS13-AES256-GCM-SHA384 -R $ready_file -p $port &
server_pid=$!
create_port
./examples/client/client -v 4 -J -p $port
RESULT=$?
remove_ready_file
if [ $RESULT -ne 0 ]; then
echo -e "\n\nTLS v1.3 HelloRetryRequest with SHA384 not working"
do_cleanup
exit 1
fi
echo ""
# Resumption TLS v1.3 server / TLS v1.3 client. # Resumption TLS v1.3 server / TLS v1.3 client.
echo -e "\n\nTLS v1.3 resumption" echo -e "\n\nTLS v1.3 resumption"
port=0 port=0
@ -111,6 +127,22 @@ if [ $RESULT -ne 0 ]; then
fi fi
echo "" echo ""
# Resumption TLS v1.3 server / TLS v1.3 client - SHA384
echo -e "\n\nTLS v1.3 resumption - SHA384"
port=0
./examples/server/server -v 4 -l TLS13-AES256-GCM-SHA384 -r -R $ready_file -p $port &
server_pid=$!
create_port
./examples/client/client -v 4 -l TLS13-AES256-GCM-SHA384 -r -p $port
RESULT=$?
remove_ready_file
if [ $RESULT -ne 0 ]; then
echo -e "\n\nTLS v1.3 resumption with SHA384 not working"
do_cleanup
exit 1
fi
echo ""
# Usual TLS v1.3 server / TLS v1.3 client and ECC certificates. # Usual TLS v1.3 server / TLS v1.3 client and ECC certificates.
echo -e "\n\nTLS v1.3 server with TLS v1.3 client - ECC certificates" echo -e "\n\nTLS v1.3 server with TLS v1.3 client - ECC certificates"
port=0 port=0
@ -127,6 +159,22 @@ if [ $RESULT -ne 0 ]; then
fi fi
echo "" echo ""
# Usual TLS v1.3 server / TLS v1.3 client and no client certificate.
echo -e "\n\nTLS v1.3 server with TLS v1.3 client - no client cretificate"
port=0
./examples/server/server -v 4 -R $ready_file -p $port &
server_pid=$!
create_port
./examples/client/client -v 4 -x -p $port
RESULT=$?
remove_ready_file
if [ $RESULT -ne 0 ]; then
echo -e "\n\nTLS v1.3 and no client certificate not working"
do_cleanup
exit 1
fi
echo ""
# Usual TLS v1.3 server / TLS v1.3 client and DH Key. # Usual TLS v1.3 server / TLS v1.3 client and DH Key.
echo -e "\n\nTLS v1.3 server with TLS v1.3 client - DH Key Exchange" echo -e "\n\nTLS v1.3 server with TLS v1.3 client - DH Key Exchange"
port=0 port=0
@ -306,6 +354,38 @@ if [ $RESULT -ne 0 ]; then
fi fi
echo "" echo ""
# TLS 1.3 server / TLS 1.3 client don't use (EC)DHE with PSK.
echo -e "\n\nTLS v1.3 KeyUpdate"
port=0
./examples/server/server -v 4 -r -R $ready_file -p $port &
server_pid=$!
create_port
./examples/client/client -v 4 -r -K -p $port
RESULT=$?
remove_ready_file
if [ $RESULT -ne 0 ]; then
echo -e "\n\nIssue with TLS v1.3 KeyUpdate"
do_cleanup
exit 1
fi
echo ""
# TLS 1.3 server / TLS 1.3 client and Post-Handshake Authentication.
echo -e "\n\nTLS v1.3 Post-Handshake Authentication"
port=0
./examples/server/server -v 4 -Q -R $ready_file -p $port &
server_pid=$!
create_port
./examples/client/client -v 4 -Q -p $port
RESULT=$?
remove_ready_file
if [ $RESULT -ne 0 ]; then
echo -e "\n\nIssue with TLS v1.3 Post-Handshake Auth"
do_cleanup
exit 1
fi
echo ""
echo -e "\nALL Tests Passed" echo -e "\nALL Tests Passed"
exit 0 exit 0

View File

@ -7480,7 +7480,8 @@ static void FreeProcPeerCertArgs(WOLFSSL* ssl, void* pArgs)
} }
} }
int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, word32 totalSz) int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
word32 totalSz)
{ {
int ret = 0; int ret = 0;
#ifdef WOLFSSL_ASYNC_CRYPT #ifdef WOLFSSL_ASYNC_CRYPT
@ -13067,7 +13068,7 @@ int SendCertificateStatus(WOLFSSL* ssl)
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), ssl->heap, cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), ssl->heap,
DYNAMIC_TYPE_TMP_DCERT); DYNAMIC_TYPE_DCERT);
if (cert == NULL) if (cert == NULL)
return MEMORY_E; return MEMORY_E;
#endif #endif

View File

@ -365,9 +365,6 @@ static int DeriveKeyMsg(WOLFSSL* ssl, byte* output, int outputLen,
digestAlg = SHA512; digestAlg = SHA512;
break; break;
#endif #endif
default:
return BAD_FUNC_ARG;
} }
if (ret != 0) if (ret != 0)
@ -992,16 +989,9 @@ static int DeriveTls13Keys(WOLFSSL* ssl, int secret, int side, int store)
switch (secret) { switch (secret) {
#ifdef WOLFSSL_EARLY_DATA #ifdef WOLFSSL_EARLY_DATA
case early_data_key: case early_data_key:
if (provision & PROVISION_CLIENT) { ret = DeriveEarlyTrafficSecret(ssl, ssl->arrays->clientSecret);
ret = DeriveEarlyTrafficSecret(ssl, ssl->arrays->clientSecret); if (ret != 0)
if (ret != 0) goto end;
goto end;
}
if (provision & PROVISION_SERVER) {
ret = DeriveEarlyTrafficSecret(ssl, ssl->arrays->serverSecret);
if (ret != 0)
goto end;
}
break; break;
#endif #endif
@ -1360,6 +1350,10 @@ static int HashInputRaw(WOLFSSL* ssl, const byte* input, int sz)
} }
#endif #endif
#ifndef WOLFSSL_TLS13_DRAFT_18
/* The offset into MessageHash of the low byte of the length field. */
#define MSG_HASH_LEN_OFFSET 3
/* Restart the Hanshake hash with a hash of the previous messages. /* Restart the Hanshake hash with a hash of the previous messages.
* *
* ssl The SSL/TLS object. * ssl The SSL/TLS object.
@ -1381,19 +1375,19 @@ static int RestartHandshakeHash(WOLFSSL* ssl)
switch (ssl->specs.mac_algorithm) { switch (ssl->specs.mac_algorithm) {
#ifndef NO_SHA256 #ifndef NO_SHA256
case sha256_mac: case sha256_mac:
header[3] = SHA256_DIGEST_SIZE; header[MSG_HASH_LEN_OFFSET] = SHA256_DIGEST_SIZE;
hash = hashes.sha256; hash = hashes.sha256;
break; break;
#endif #endif
#ifdef WOLFSSL_SHA384 #ifdef WOLFSSL_SHA384
case sha384_mac: case sha384_mac:
header[3] = SHA384_DIGEST_SIZE; header[MSG_HASH_LEN_OFFSET] = SHA384_DIGEST_SIZE;
hash = hashes.sha384; hash = hashes.sha384;
break; break;
#endif #endif
#ifdef WOLFSSL_SHA512 #ifdef WOLFSSL_SHA512
case sha512_mac: case sha512_mac:
header[3] = SHA512_DIGEST_SIZE; header[MSG_HASH_LEN_OFFSET] = SHA512_DIGEST_SIZE;
hash = hashes.sha512; hash = hashes.sha512;
break; break;
#endif #endif
@ -1407,6 +1401,7 @@ static int RestartHandshakeHash(WOLFSSL* ssl)
return ret; return ret;
return HashOutputRaw(ssl, hash, header[3]); return HashOutputRaw(ssl, hash, header[3]);
} }
#endif
/* Extract the handshake header information. /* Extract the handshake header information.
@ -1968,7 +1963,7 @@ int DecryptTls13(WOLFSSL* ssl, byte* output, const byte* input, word16 sz)
return ret; return ret;
} }
/* Persistable BuildMessage arguments */ /* Persistable BuildTls13Message arguments */
typedef struct BuildMsg13Args { typedef struct BuildMsg13Args {
word32 sz; word32 sz;
word32 idx; word32 idx;
@ -2014,10 +2009,6 @@ int BuildTls13Message(WOLFSSL* ssl, byte* output, int outSz, const byte* input,
WOLFSSL_ENTER("BuildTls13Message"); WOLFSSL_ENTER("BuildTls13Message");
if (ssl == NULL) {
return BAD_FUNC_ARG;
}
ret = WC_NOT_PENDING_E; ret = WC_NOT_PENDING_E;
#ifdef WOLFSSL_ASYNC_CRYPT #ifdef WOLFSSL_ASYNC_CRYPT
if (asyncOkay) { if (asyncOkay) {
@ -2051,11 +2042,12 @@ int BuildTls13Message(WOLFSSL* ssl, byte* output, int outSz, const byte* input,
switch (ssl->options.buildMsgState) { switch (ssl->options.buildMsgState) {
case BUILD_MSG_BEGIN: case BUILD_MSG_BEGIN:
{ {
if (!sizeOnly && (output == NULL || input == NULL)) if (output == NULL || input == NULL)
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
/* catch mistaken sizeOnly parameter */ /* catch mistaken sizeOnly parameter */
if (sizeOnly && (output || input)) { if (sizeOnly && (output || input)) {
WOLFSSL_MSG("BuildMessage with sizeOnly doesn't need input or output"); WOLFSSL_MSG("BuildTls13Message with sizeOnly doesn't need "
"input or output");
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
} }
@ -2149,33 +2141,52 @@ exit_buildmsg:
} }
#ifndef NO_WOLFSSL_CLIENT #ifndef NO_WOLFSSL_CLIENT
#ifdef HAVE_SESSION_TICKET #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
/* Get the size of the message hash. /* Setup pre-shared key based on the details in the extension data.
* *
* ssl The SSL/TLS object. * ssl SSL/TLS object.
* returns the length of the hash. * psk Pre-shared key extension data.
* returns 0 on success, PSK_KEY_ERROR when the client PSK callback fails and
* other negative value on failure.
*/ */
static int GetMsgHashSize(WOLFSSL* ssl) static int SetupPskKey(WOLFSSL* ssl, PreSharedKey* psk)
{ {
switch (ssl->specs.mac_algorithm) { int ret;
#ifndef NO_SHA256
case sha256_mac: ssl->options.cipherSuite0 = psk->cipherSuite0;
return SHA256_DIGEST_SIZE; ssl->options.cipherSuite = psk->cipherSuite;
#endif /* !NO_SHA256 */ if ((ret = SetCipherSpecs(ssl)) != 0)
#ifdef WOLFSSL_SHA384 return ret;
case sha384_mac:
return SHA384_DIGEST_SIZE; #ifdef HAVE_SESSION_TICKET
#endif /* WOLFSSL_SHA384 */ if (psk->resumption) {
#ifdef WOLFSSL_SHA512 #ifdef WOLFSSL_EARLY_DATA
case sha512_mac: if (ssl->session.maxEarlyDataSz == 0)
return SHA512_DIGEST_SIZE; ssl->earlyData = 0;
#endif /* WOLFSSL_SHA512 */ #endif
/* Resumption PSK is master secret. */
ssl->arrays->psk_keySz = ssl->specs.hash_size;
XMEMCPY(ssl->arrays->psk_key, ssl->session.masterSecret,
ssl->arrays->psk_keySz);
}
#endif
#ifndef NO_PSK
if (!psk->resumption) {
/* Get the pre-shared key. */
ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl,
(char *)psk->identity, ssl->arrays->client_identity,
MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
if (ssl->arrays->psk_keySz == 0 ||
ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
return PSK_KEY_ERROR;
}
} }
return 0;
}
#endif #endif
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) /* Derive the early secret using the PSK. */
return DeriveEarlySecret(ssl);
}
/* Derive and write the binders into the ClientHello in space left when /* Derive and write the binders into the ClientHello in space left when
* writing the Pre-Shared Key extension. * writing the Pre-Shared Key extension.
* *
@ -2191,13 +2202,6 @@ static int WritePSKBinders(WOLFSSL* ssl, byte* output, word32 idx)
PreSharedKey* current; PreSharedKey* current;
byte binderKey[MAX_DIGEST_SIZE]; byte binderKey[MAX_DIGEST_SIZE];
word16 len; word16 len;
#ifdef WOLFSSL_EARLY_DATA
byte pskKey[MAX_DIGEST_SIZE];
int pskKeySz = 0;
int seenPsk = 0;
byte cipherSuite0 = 0;
byte cipherSuite = 0;
#endif
ext = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY); ext = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY);
if (ext == NULL) if (ext == NULL)
@ -2216,69 +2220,19 @@ static int WritePSKBinders(WOLFSSL* ssl, byte* output, word32 idx)
/* Calculate the binder for each identity based on previous handshake data. /* Calculate the binder for each identity based on previous handshake data.
*/ */
while (current != NULL) { while (current != NULL) {
#ifdef HAVE_SESSION_TICKET if ((ret = SetupPskKey(ssl, current)) != 0)
if (current->resumption) { return ret;
ssl->specs.mac_algorithm = current->hmac;
#ifdef WOLFSSL_EARLY_DATA #ifdef HAVE_SESSION_TICKET
if (ssl->session.maxEarlyDataSz == 0) if (current->resumption)
ssl->earlyData = 0;
#endif
/* Resumption PSK is master secret. */
ssl->arrays->psk_keySz = GetMsgHashSize(ssl);
XMEMCPY(ssl->arrays->psk_key, ssl->session.masterSecret,
ssl->arrays->psk_keySz);
ssl->options.cipherSuite0 = current->cipherSuite0;
ssl->options.cipherSuite = current->cipherSuite;
ret = SetCipherSpecs(ssl);
if (ret != 0)
return ret;
/* Derive the early secret using the PSK. */
ret = DeriveEarlySecret(ssl);
if (ret != 0)
return ret;
ret = DeriveBinderKeyResume(ssl, binderKey); ret = DeriveBinderKeyResume(ssl, binderKey);
if (ret != 0)
return ret;
}
else
#endif #endif
#ifndef NO_PSK #ifndef NO_PSK
if (!current->resumption) { if (!current->resumption)
/* Get the pre-shared key. */
ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl,
(char *)current->identity, ssl->arrays->client_identity,
MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
/* TODO: Callback should be able to change ciphersuite. */
ssl->options.cipherSuite0 = current->cipherSuite0;
ssl->options.cipherSuite = current->cipherSuite;
ret = SetCipherSpecs(ssl);
if (ret != 0)
return ret;
/* Derive the early secret using the PSK. */
ret = DeriveEarlySecret(ssl);
if (ret != 0)
return ret;
ret = DeriveBinderKey(ssl, binderKey); ret = DeriveBinderKey(ssl, binderKey);
if (ret != 0)
return ret;
}
else
#endif
{
current = current->next;
continue;
}
#ifdef WOLFSSL_EARLY_DATA
if (ssl->earlyData && !seenPsk) {
pskKeySz = ssl->arrays->psk_keySz;
XMEMCPY(pskKey, ssl->arrays->psk_key, pskKeySz);
cipherSuite0 = ssl->options.cipherSuite0;
cipherSuite = ssl->options.cipherSuite;
seenPsk = 1;
}
#endif #endif
if (ret != 0)
return ret;
/* Derive the Finished message secret. */ /* Derive the Finished message secret. */
ret = DeriveFinishedSecret(ssl, binderKey, ret = DeriveFinishedSecret(ssl, binderKey,
@ -2305,20 +2259,10 @@ static int WritePSKBinders(WOLFSSL* ssl, byte* output, word32 idx)
return ret; return ret;
#ifdef WOLFSSL_EARLY_DATA #ifdef WOLFSSL_EARLY_DATA
if (ssl->earlyData && seenPsk) { if (ssl->earlyData) {
XMEMCPY(ssl->arrays->psk_key, pskKey, pskKeySz); if ((ret = SetupPskKey(ssl, (PreSharedKey*)ext->data)) != 0)
ssl->arrays->psk_keySz = pskKeySz;
ssl->options.cipherSuite0 = cipherSuite0;
ssl->options.cipherSuite = cipherSuite;
ret = SetCipherSpecs(ssl);
if (ret != 0)
return ret; return ret;
/* Derive the early secret using the PSK. */
ret = DeriveEarlySecret(ssl);
if (ret != 0)
return ret;
/* Derive early data encryption key. */ /* Derive early data encryption key. */
ret = DeriveTls13Keys(ssl, early_data_key, ENCRYPT_SIDE_ONLY, 1); ret = DeriveTls13Keys(ssl, early_data_key, ENCRYPT_SIDE_ONLY, 1);
if (ret != 0) if (ret != 0)
@ -2353,6 +2297,8 @@ int SendTls13ClientHello(WOLFSSL* ssl)
if (ssl->options.resuming && if (ssl->options.resuming &&
(ssl->session.version.major != ssl->version.major || (ssl->session.version.major != ssl->version.major ||
ssl->session.version.minor != ssl->version.minor)) { ssl->session.version.minor != ssl->version.minor)) {
/* Cannot resume with a different protocol version - new handshake. */
ssl->options.resuming = 0;
ssl->version.major = ssl->session.version.major; ssl->version.major = ssl->session.version.major;
ssl->version.minor = ssl->session.version.minor; ssl->version.minor = ssl->session.version.minor;
return SendClientHello(ssl); return SendClientHello(ssl);
@ -2452,9 +2398,10 @@ int SendTls13ClientHello(WOLFSSL* ssl)
#ifdef WOLFSSL_CALLBACKS #ifdef WOLFSSL_CALLBACKS
if (ssl->hsInfoOn) AddPacketName("ClientHello", &ssl->handShakeInfo); if (ssl->hsInfoOn) AddPacketName("ClientHello", &ssl->handShakeInfo);
if (ssl->toInfoOn) if (ssl->toInfoOn) {
AddPacketInfo("ClientHello", &ssl->timeoutInfo, output, sendSz, AddPacketInfo("ClientHello", &ssl->timeoutInfo, output, sendSz,
ssl->heap); ssl->heap);
}
#endif #endif
ssl->buffers.outputBuffer.length += sendSz; ssl->buffers.outputBuffer.length += sendSz;
@ -2524,7 +2471,7 @@ static int DoTls13HelloRetryRequest(WOLFSSL* ssl, const byte* input,
if (i - begin + totalExtSz > totalSz) if (i - begin + totalExtSz > totalSz)
return BUFFER_ERROR; return BUFFER_ERROR;
if ((ret = TLSX_Parse(ssl, (byte *)(input + i), totalExtSz, if ((ret = TLSX_Parse(ssl, (byte *)(input + i), totalExtSz,
hello_retry_request, NULL))) hello_retry_request, NULL)) != 0)
return ret; return ret;
/* The KeyShare extension parsing fails when not valid. */ /* The KeyShare extension parsing fails when not valid. */
@ -2534,7 +2481,13 @@ static int DoTls13HelloRetryRequest(WOLFSSL* ssl, const byte* input,
ssl->options.tls1_3 = 1; ssl->options.tls1_3 = 1;
ssl->options.serverState = SERVER_HELLO_RETRY_REQUEST; ssl->options.serverState = SERVER_HELLO_RETRY_REQUEST;
return RestartHandshakeHash(ssl); #ifndef WOLFSSL_TLS13_DRAFT_18
ret = RestartHandshakeHash(ssl);
#endif
WOLFSSL_LEAVE("DoTls13HelloRetryRequest", ret);
return ret;
} }
/* Handle the ServerHello message from the server. /* Handle the ServerHello message from the server.
@ -2555,6 +2508,10 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
word32 begin = i; word32 begin = i;
int ret; int ret;
word16 totalExtSz; word16 totalExtSz;
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
TLSX* ext;
PreSharedKey* psk = NULL;
#endif
WOLFSSL_ENTER("DoTls13ServerHello"); WOLFSSL_ENTER("DoTls13ServerHello");
@ -2621,44 +2578,24 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
return ret; return ret;
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
if (ssl->options.resuming) { ext = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY);
PreSharedKey* psk = NULL; if (ext != NULL)
TLSX* ext = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY); psk = (PreSharedKey*)ext->data;
if (ext != NULL) while (psk != NULL && !psk->chosen)
psk = (PreSharedKey*)ext->data; psk = psk->next;
while (psk != NULL && !psk->chosen) if (psk == NULL) {
psk = psk->next; ssl->options.resuming = 0;
if (psk == NULL) { ssl->arrays->psk_keySz = 0;
ssl->options.resuming = 0; XMEMSET(ssl->arrays->psk_key, 0, MAX_PSK_KEY_LEN);
ssl->arrays->psk_keySz = ssl->specs.hash_size;
XMEMSET(ssl->arrays->psk_key, 0, ssl->arrays->psk_keySz);
}
#ifdef HAVE_SESSION_TICKET
else if (psk->resumption) {
ssl->arrays->psk_keySz = ssl->specs.hash_size;
XMEMCPY(ssl->arrays->psk_key, ssl->session.masterSecret,
ssl->specs.hash_size);
}
#endif
#ifndef NO_PSK
else if (!psk->resumption) {
/* Get the pre-shared key. */
ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl,
(char *)psk->identity, ssl->arrays->client_identity,
MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
/* TODO: Callback should be able to change ciphersuite. */
ssl->options.cipherSuite0 = psk->cipherSuite0;
ssl->options.cipherSuite = psk->cipherSuite;
ret = SetCipherSpecs(ssl);
if (ret != 0)
return ret;
}
#endif
} }
else if ((ret = SetupPskKey(ssl, psk)) != 0)
return ret;
#endif #endif
ssl->keys.encryptionOn = 1; ssl->keys.encryptionOn = 1;
WOLFSSL_LEAVE("DoTls13ServerHello", ret);
return ret; return ret;
} }
@ -2717,6 +2654,8 @@ static int DoTls13EncryptedExtensions(WOLFSSL* ssl, const byte* input,
} }
#endif #endif
WOLFSSL_LEAVE("DoTls13EncryptedExtensions", ret);
return ret; return ret;
} }
@ -2807,10 +2746,6 @@ static int DoTls13CertificateRequest(WOLFSSL* ssl, const byte* input,
if ((*inOutIdx - begin) + len > size) if ((*inOutIdx - begin) + len > size)
return BUFFER_ERROR; return BUFFER_ERROR;
*inOutIdx += len; *inOutIdx += len;
ssl->options.sendVerify = SEND_CERT;
/* This message is always encrypted so add encryption padding. */
*inOutIdx += ssl->keys.padSz;
#else #else
#ifdef WOLFSSL_POST_HANDSHAKE_AUTH #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
certReqCtx = (CertReqCtx*)XMALLOC(sizeof(CertReqCtx) + len - 1, ssl->heap, certReqCtx = (CertReqCtx*)XMALLOC(sizeof(CertReqCtx) + len - 1, ssl->heap,
@ -2842,6 +2777,7 @@ static int DoTls13CertificateRequest(WOLFSSL* ssl, const byte* input,
*inOutIdx += len; *inOutIdx += len;
PickHashSigAlgo(ssl, peerSuites.hashSigAlgo, peerSuites.hashSigAlgoSz); PickHashSigAlgo(ssl, peerSuites.hashSigAlgo, peerSuites.hashSigAlgoSz);
#endif
if (ssl->buffers.certificate && ssl->buffers.certificate->buffer && if (ssl->buffers.certificate && ssl->buffers.certificate->buffer &&
ssl->buffers.key && ssl->buffers.key->buffer) ssl->buffers.key && ssl->buffers.key->buffer)
@ -2851,7 +2787,6 @@ static int DoTls13CertificateRequest(WOLFSSL* ssl, const byte* input,
/* This message is always encrypted so add encryption padding. */ /* This message is always encrypted so add encryption padding. */
*inOutIdx += ssl->keys.padSz; *inOutIdx += ssl->keys.padSz;
#endif
#if !defined(NO_WOLFSSL_CLIENT) && defined(WOLFSSL_POST_HANDSHAKE_AUTH) #if !defined(NO_WOLFSSL_CLIENT) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
if (ssl->options.side == WOLFSSL_CLIENT_END && if (ssl->options.side == WOLFSSL_CLIENT_END &&
@ -2863,6 +2798,8 @@ static int DoTls13CertificateRequest(WOLFSSL* ssl, const byte* input,
} }
#endif #endif
WOLFSSL_LEAVE("DoTls13CertificateRequest", ret);
return ret; return ret;
} }
@ -2937,11 +2874,14 @@ static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz,
#ifdef HAVE_SESSION_TICKET #ifdef HAVE_SESSION_TICKET
/* Decode the identity. */ /* Decode the identity. */
if ((ret = DoClientTicket(ssl, current->identity, current->identityLen)) == WOLFSSL_TICKET_RET_OK) { if ((ret = DoClientTicket(ssl, current->identity, current->identityLen))
== WOLFSSL_TICKET_RET_OK) {
word32 now; word32 now;
int diff; int diff;
now = TimeNowInMilliseconds(); now = TimeNowInMilliseconds();
if (now == (word32)GETTIME_ERROR)
return now;
diff = now - ssl->session.ticketSeen; diff = now - ssl->session.ticketSeen;
diff -= current->ticketAge - ssl->session.ticketAdd; diff -= current->ticketAge - ssl->session.ticketAdd;
/* Check session and ticket age timeout. /* Check session and ticket age timeout.
@ -2968,6 +2908,7 @@ static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz,
ssl->arrays->psk_keySz = ssl->specs.hash_size; ssl->arrays->psk_keySz = ssl->specs.hash_size;
XMEMCPY(ssl->arrays->psk_key, ssl->session.masterSecret, XMEMCPY(ssl->arrays->psk_key, ssl->session.masterSecret,
ssl->specs.hash_size); ssl->specs.hash_size);
/* Derive the early secret using the PSK. */ /* Derive the early secret using the PSK. */
ret = DeriveEarlySecret(ssl); ret = DeriveEarlySecret(ssl);
if (ret != 0) if (ret != 0)
@ -2995,8 +2936,8 @@ static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz,
/* TODO: Callback should be able to change ciphersuite. */ /* TODO: Callback should be able to change ciphersuite. */
/* Default to ciphersuite if cb doesn't specify. */ /* Default to ciphersuite if cb doesn't specify. */
ssl->options.cipherSuite0 = TLS13_BYTE; ssl->options.cipherSuite0 = TLS13_BYTE;
ssl->options.cipherSuite = WOLFSSL_DEF_PSK_CIPHER; ssl->options.cipherSuite = WOLFSSL_DEF_PSK_CIPHER;
ret = SetCipherSpecs(ssl); ret = SetCipherSpecs(ssl);
if (ret != 0) if (ret != 0)
return ret; return ret;
@ -3074,8 +3015,8 @@ static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz,
ext = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE); ext = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
/* Use (EC)DHE for forward-security if possible. */ /* Use (EC)DHE for forward-security if possible. */
if (ext != NULL && (modes & (1 << PSK_DHE_KE)) != 0 && if ((modes & (1 << PSK_DHE_KE)) != 0 && !ssl->options.noPskDheKe &&
!ssl->options.noPskDheKe) { ext != NULL) {
/* Only use named group used in last session. */ /* Only use named group used in last session. */
ssl->namedGroup = ssl->session.namedGroup; ssl->namedGroup = ssl->session.namedGroup;
@ -3083,18 +3024,13 @@ static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz,
ret = TLSX_KeyShare_Establish(ssl); ret = TLSX_KeyShare_Establish(ssl);
if (ret == KEY_SHARE_ERROR) if (ret == KEY_SHARE_ERROR)
return PSK_KEY_ERROR; return PSK_KEY_ERROR;
else if (ret > 0) else if (ret < 0)
ret = 0; return ret;
/* Send new public key to client. */ /* Send new public key to client. */
ext->resp = 1; ext->resp = 1;
} }
else if ((modes & (1 << PSK_KE)) != 0) { else if ((modes & (1 << PSK_KE)) == 0)
/* Don't send a key share extension back. */
if (ext != NULL)
ext->resp = 0;
}
else
return PSK_KEY_ERROR; return PSK_KEY_ERROR;
*usingPSK = 1; *usingPSK = 1;
@ -3215,7 +3151,7 @@ static int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
/* Parse extensions */ /* Parse extensions */
if ((ret = TLSX_Parse(ssl, (byte*)input + i, totalExtSz, client_hello, if ((ret = TLSX_Parse(ssl, (byte*)input + i, totalExtSz, client_hello,
&clSuites))) { &clSuites))) {
return ret; return ret;
} }
@ -3237,8 +3173,7 @@ static int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
#endif #endif
if (!usingPSK) { if (!usingPSK) {
ret = MatchSuite(ssl, &clSuites); if ((ret = MatchSuite(ssl, &clSuites)) < 0) {
if (ret < 0) {
WOLFSSL_MSG("Unsupported cipher suite, ClientHello"); WOLFSSL_MSG("Unsupported cipher suite, ClientHello");
return ret; return ret;
} }
@ -3248,14 +3183,12 @@ static int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
ssl->options.resuming = 0; ssl->options.resuming = 0;
XMEMSET(ssl->arrays->psk_key, 0, ssl->specs.hash_size); XMEMSET(ssl->arrays->psk_key, 0, ssl->specs.hash_size);
/* May or may not have done any hashing. */ /* May or may not have done any hashing. */
ret = InitHandshakeHashes(ssl); if ((ret = InitHandshakeHashes(ssl)) != 0)
if (ret != 0)
return ret; return ret;
} }
#endif #endif
ret = HashInput(ssl, input + begin, helloSz); if ((ret = HashInput(ssl, input + begin, helloSz)) != 0)
if (ret != 0)
return ret; return ret;
/* Derive early secret for handshake secret. */ /* Derive early secret for handshake secret. */
@ -3268,6 +3201,8 @@ static int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
ssl->options.clientState = CLIENT_HELLO_COMPLETE; ssl->options.clientState = CLIENT_HELLO_COMPLETE;
WOLFSSL_LEAVE("DoTls13ClientHello", ret);
return ret; return ret;
} }
@ -3300,8 +3235,7 @@ int SendTls13HelloRetryRequest(WOLFSSL* ssl)
sendSz = idx + length; sendSz = idx + length;
/* Check buffers are big enough and grow if needed. */ /* Check buffers are big enough and grow if needed. */
ret = CheckAvailableSize(ssl, sendSz); if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
if (ret != 0)
return ret; return ret;
/* Get position in output buffer to write new message to. */ /* Get position in output buffer to write new message to. */
@ -3332,25 +3266,28 @@ int SendTls13HelloRetryRequest(WOLFSSL* ssl)
#ifdef WOLFSSL_CALLBACKS #ifdef WOLFSSL_CALLBACKS
if (ssl->hsInfoOn) if (ssl->hsInfoOn)
AddPacketName("HelloRetryRequest", &ssl->handShakeInfo); AddPacketName("HelloRetryRequest", &ssl->handShakeInfo);
if (ssl->toInfoOn) if (ssl->toInfoOn) {
AddPacketInfo("HelloRetryRequest", &ssl->timeoutInfo, output, sendSz, AddPacketInfo("HelloRetryRequest", &ssl->timeoutInfo, output, sendSz,
ssl->heap); ssl->heap);
}
#endif #endif
ret = RestartHandshakeHash(ssl); #ifndef WOLFSSL_TLS13_DRAFT_18
if (ret < 0) if ((ret = RestartHandshakeHash(ssl)) < 0)
return ret; return ret;
#endif
ret = HashOutput(ssl, output, idx, 0); if ((ret = HashOutput(ssl, output, idx, 0)) != 0)
if (ret != 0)
return ret; return ret;
ssl->buffers.outputBuffer.length += sendSz; ssl->buffers.outputBuffer.length += sendSz;
if (ssl->options.groupMessages) if (!ssl->options.groupMessages)
return 0; ret = SendBuffered(ssl);
else
return SendBuffered(ssl); WOLFSSL_LEAVE("SendTls13HelloRetryRequest", ret);
return ret;
} }
/* Send TLS v1.3 ServerHello message to client. /* Send TLS v1.3 ServerHello message to client.
@ -3359,7 +3296,7 @@ int SendTls13HelloRetryRequest(WOLFSSL* ssl)
* ssl The SSL/TLS object. * ssl The SSL/TLS object.
* returns 0 on success, otherwise failure. * returns 0 on success, otherwise failure.
*/ */
int SendTls13ServerHello(WOLFSSL* ssl) static int SendTls13ServerHello(WOLFSSL* ssl)
{ {
byte* output; byte* output;
word32 length; word32 length;
@ -3397,8 +3334,7 @@ int SendTls13ServerHello(WOLFSSL* ssl)
output[idx++] = TLS_DRAFT_MINOR; output[idx++] = TLS_DRAFT_MINOR;
/* Generate server random. */ /* Generate server random. */
ret = wc_RNG_GenerateBlock(ssl->rng, output + idx, RAN_LEN); if ((ret = wc_RNG_GenerateBlock(ssl->rng, output + idx, RAN_LEN)) != 0)
if (ret != 0)
return ret; return ret;
/* Store in SSL for debugging. */ /* Store in SSL for debugging. */
XMEMCPY(ssl->arrays->serverRandom, output + idx, RAN_LEN); XMEMCPY(ssl->arrays->serverRandom, output + idx, RAN_LEN);
@ -3418,24 +3354,26 @@ int SendTls13ServerHello(WOLFSSL* ssl)
ssl->buffers.outputBuffer.length += sendSz; ssl->buffers.outputBuffer.length += sendSz;
ret = HashOutput(ssl, output, sendSz, 0); if ((ret = HashOutput(ssl, output, sendSz, 0)) != 0)
if (ret != 0)
return ret; return ret;
#ifdef WOLFSSL_CALLBACKS #ifdef WOLFSSL_CALLBACKS
if (ssl->hsInfoOn) if (ssl->hsInfoOn)
AddPacketName("ServerHello", &ssl->handShakeInfo); AddPacketName("ServerHello", &ssl->handShakeInfo);
if (ssl->toInfoOn) if (ssl->toInfoOn) {
AddPacketInfo("ServerHello", &ssl->timeoutInfo, output, sendSz, AddPacketInfo("ServerHello", &ssl->timeoutInfo, output, sendSz,
ssl->heap); ssl->heap);
}
#endif #endif
ssl->options.serverState = SERVER_HELLO_COMPLETE; ssl->options.serverState = SERVER_HELLO_COMPLETE;
if (ssl->options.groupMessages) if (!ssl->options.groupMessages)
return 0; ret = SendBuffered(ssl);
else
return SendBuffered(ssl); WOLFSSL_LEAVE("SendTls13ServerHello", ret);
return ret;
} }
/* Send the rest of the extensions encrypted under the handshake key. /* Send the rest of the extensions encrypted under the handshake key.
@ -3445,7 +3383,7 @@ int SendTls13ServerHello(WOLFSSL* ssl)
* ssl The SSL/TLS object. * ssl The SSL/TLS object.
* returns 0 on success, otherwise failure. * returns 0 on success, otherwise failure.
*/ */
int SendTls13EncryptedExtensions(WOLFSSL* ssl) static int SendTls13EncryptedExtensions(WOLFSSL* ssl)
{ {
int ret; int ret;
byte* output; byte* output;
@ -3502,9 +3440,10 @@ int SendTls13EncryptedExtensions(WOLFSSL* ssl)
#ifdef WOLFSSL_CALLBACKS #ifdef WOLFSSL_CALLBACKS
if (ssl->hsInfoOn) if (ssl->hsInfoOn)
AddPacketName("EncryptedExtensions", &ssl->handShakeInfo); AddPacketName("EncryptedExtensions", &ssl->handShakeInfo);
if (ssl->toInfoOn) if (ssl->toInfoOn) {
AddPacketInfo("EncryptedExtensions", &ssl->timeoutInfo, output, AddPacketInfo("EncryptedExtensions", &ssl->timeoutInfo, output,
sendSz, ssl->heap); sendSz, ssl->heap);
}
#endif #endif
/* This handshake message is always encrypted. */ /* This handshake message is always encrypted. */
@ -3517,10 +3456,12 @@ int SendTls13EncryptedExtensions(WOLFSSL* ssl)
ssl->options.serverState = SERVER_ENCRYPTED_EXTENSIONS_COMPLETE; ssl->options.serverState = SERVER_ENCRYPTED_EXTENSIONS_COMPLETE;
if (ssl->options.groupMessages) if (!ssl->options.groupMessages)
return 0; ret = SendBuffered(ssl);
else
return SendBuffered(ssl); WOLFSSL_LEAVE("SendTls13EncryptedExtensions", ret);
return ret;
} }
#ifndef NO_CERTS #ifndef NO_CERTS
@ -3533,7 +3474,8 @@ int SendTls13EncryptedExtensions(WOLFSSL* ssl)
* reqCtxLen Length of context. 0 when sending as part of handshake. * reqCtxLen Length of context. 0 when sending as part of handshake.
* returns 0 on success, otherwise failure. * returns 0 on success, otherwise failure.
*/ */
int SendTls13CertificateRequest(WOLFSSL* ssl, byte* reqCtx, int reqCtxLen) static int SendTls13CertificateRequest(WOLFSSL* ssl, byte* reqCtx,
int reqCtxLen)
{ {
byte* output; byte* output;
int ret; int ret;
@ -3543,9 +3485,6 @@ int SendTls13CertificateRequest(WOLFSSL* ssl, byte* reqCtx, int reqCtxLen)
WOLFSSL_ENTER("SendTls13CertificateRequest"); WOLFSSL_ENTER("SendTls13CertificateRequest");
if (ssl->options.usingPSK_cipher || ssl->options.usingAnon_cipher)
return 0; /* not needed */
#ifdef WOLFSSL_TLS13_DRAFT_18 #ifdef WOLFSSL_TLS13_DRAFT_18
(void)reqCtx; (void)reqCtx;
@ -3625,15 +3564,19 @@ int SendTls13CertificateRequest(WOLFSSL* ssl, byte* reqCtx, int reqCtxLen)
#ifdef WOLFSSL_CALLBACKS #ifdef WOLFSSL_CALLBACKS
if (ssl->hsInfoOn) if (ssl->hsInfoOn)
AddPacketName("CertificateRequest", &ssl->handShakeInfo); AddPacketName("CertificateRequest", &ssl->handShakeInfo);
if (ssl->toInfoOn) if (ssl->toInfoOn) {
AddPacketInfo("CertificateRequest", &ssl->timeoutInfo, output, AddPacketInfo("CertificateRequest", &ssl->timeoutInfo, output,
sendSz, ssl->heap); sendSz, ssl->heap);
}
#endif #endif
ssl->buffers.outputBuffer.length += sendSz; ssl->buffers.outputBuffer.length += sendSz;
if (!ssl->options.groupMessages) if (!ssl->options.groupMessages)
return SendBuffered(ssl); ret = SendBuffered(ssl);
return 0;
WOLFSSL_LEAVE("SendTls13CertificateRequest", ret);
return ret;
} }
#endif /* NO_CERTS */ #endif /* NO_CERTS */
#endif /* NO_WOLFSSL_SERVER */ #endif /* NO_WOLFSSL_SERVER */
@ -4095,7 +4038,7 @@ static word32 AddCertExt(byte* cert, word32 len, word32 idx, word32 fragSz,
* ssl The SSL/TLS object. * ssl The SSL/TLS object.
* returns 0 on success, otherwise failure. * returns 0 on success, otherwise failure.
*/ */
int SendTls13Certificate(WOLFSSL* ssl) static int SendTls13Certificate(WOLFSSL* ssl)
{ {
int ret = 0; int ret = 0;
word32 certSz, certChainSz, headerSz, listSz, payloadSz; word32 certSz, certChainSz, headerSz, listSz, payloadSz;
@ -4119,8 +4062,8 @@ int SendTls13Certificate(WOLFSSL* ssl)
if (ssl->options.sendVerify == SEND_BLANK_CERT) { if (ssl->options.sendVerify == SEND_BLANK_CERT) {
certSz = 0; certSz = 0;
certChainSz = 0; certChainSz = 0;
headerSz = CERT_HEADER_SZ; headerSz = OPAQUE8_LEN + certReqCtxLen + CERT_HEADER_SZ;
length = CERT_HEADER_SZ; length = headerSz;
listSz = 0; listSz = 0;
} }
else { else {
@ -4274,9 +4217,10 @@ int SendTls13Certificate(WOLFSSL* ssl)
#ifdef WOLFSSL_CALLBACKS #ifdef WOLFSSL_CALLBACKS
if (ssl->hsInfoOn) if (ssl->hsInfoOn)
AddPacketName("Certificate", &ssl->handShakeInfo); AddPacketName("Certificate", &ssl->handShakeInfo);
if (ssl->toInfoOn) if (ssl->toInfoOn) {
AddPacketInfo("Certificate", &ssl->timeoutInfo, output, sendSz, AddPacketInfo("Certificate", &ssl->timeoutInfo, output, sendSz,
ssl->heap); ssl->heap);
}
#endif #endif
ssl->buffers.outputBuffer.length += sendSz; ssl->buffers.outputBuffer.length += sendSz;
@ -4299,6 +4243,8 @@ int SendTls13Certificate(WOLFSSL* ssl)
} }
#endif #endif
WOLFSSL_LEAVE("SendTls13Certificate", ret);
return ret; return ret;
} }
@ -4345,7 +4291,7 @@ static void FreeScv13Args(WOLFSSL* ssl, void* pArgs)
* ssl The SSL/TLS object. * ssl The SSL/TLS object.
* returns 0 on success, otherwise failure. * returns 0 on success, otherwise failure.
*/ */
int SendTls13CertificateVerify(WOLFSSL* ssl) static int SendTls13CertificateVerify(WOLFSSL* ssl)
{ {
int ret = 0; int ret = 0;
buffer* sig = &ssl->buffers.sig; buffer* sig = &ssl->buffers.sig;
@ -4425,8 +4371,10 @@ int SendTls13CertificateVerify(WOLFSSL* ssl)
} }
else if (ssl->hsType == DYNAMIC_TYPE_ECC) else if (ssl->hsType == DYNAMIC_TYPE_ECC)
args->sigAlgo = ecc_dsa_sa_algo; args->sigAlgo = ecc_dsa_sa_algo;
#ifdef HAVE_ED25519
else if (ssl->hsType == DYNAMIC_TYPE_ED25519) else if (ssl->hsType == DYNAMIC_TYPE_ED25519)
args->sigAlgo = ed25519_sa_algo; args->sigAlgo = ed25519_sa_algo;
#endif
EncodeSigAlg(ssl->suites->hashAlgo, args->sigAlgo, args->verify); EncodeSigAlg(ssl->suites->hashAlgo, args->sigAlgo, args->verify);
/* Create the data to be signed. */ /* Create the data to be signed. */
@ -4614,9 +4562,10 @@ int SendTls13CertificateVerify(WOLFSSL* ssl)
#ifdef WOLFSSL_CALLBACKS #ifdef WOLFSSL_CALLBACKS
if (ssl->hsInfoOn) if (ssl->hsInfoOn)
AddPacketName("CertificateVerify", &ssl->handShakeInfo); AddPacketName("CertificateVerify", &ssl->handShakeInfo);
if (ssl->toInfoOn) if (ssl->toInfoOn) {
AddPacketInfo("CertificateVerify", &ssl->timeoutInfo, AddPacketInfo("CertificateVerify", &ssl->timeoutInfo,
args->output, args->sendSz, ssl->heap); args->output, args->sendSz, ssl->heap);
}
#endif #endif
ssl->buffers.outputBuffer.length += args->sendSz; ssl->buffers.outputBuffer.length += args->sendSz;
@ -4662,12 +4611,12 @@ static int DoTls13Certificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
{ {
int ret; int ret;
WOLFSSL_ENTER("DoTls13Certificate");
ret = ProcessPeerCerts(ssl, input, inOutIdx, totalSz); ret = ProcessPeerCerts(ssl, input, inOutIdx, totalSz);
if (ret != 0)
return ret;
#if !defined(NO_WOLFSSL_SERVER) && defined(WOLFSSL_POST_HANDSHAKE_AUTH) #if !defined(NO_WOLFSSL_SERVER) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
if (ssl->options.side == WOLFSSL_SERVER_END && if (ret == 0 && ssl->options.side == WOLFSSL_SERVER_END &&
ssl->options.handShakeState == HANDSHAKE_DONE) { ssl->options.handShakeState == HANDSHAKE_DONE) {
/* reset handshake states */ /* reset handshake states */
ssl->options.serverState = SERVER_FINISHED_COMPLETE; ssl->options.serverState = SERVER_FINISHED_COMPLETE;
@ -4676,7 +4625,9 @@ static int DoTls13Certificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
} }
#endif #endif
return 0; WOLFSSL_LEAVE("DoTls13Certificate", ret);
return ret;
} }
#if !defined(NO_RSA) || defined(HAVE_ECC) #if !defined(NO_RSA) || defined(HAVE_ECC)
@ -5094,7 +5045,7 @@ static int DoTls13Finished(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
* ssl The SSL/TLS object. * ssl The SSL/TLS object.
* returns 0 on success, otherwise failure. * returns 0 on success, otherwise failure.
*/ */
int SendTls13Finished(WOLFSSL* ssl) static int SendTls13Finished(WOLFSSL* ssl)
{ {
int sendSz; int sendSz;
int finishedSz = ssl->specs.hash_size; int finishedSz = ssl->specs.hash_size;
@ -5156,15 +5107,15 @@ int SendTls13Finished(WOLFSSL* ssl)
#ifdef WOLFSSL_CALLBACKS #ifdef WOLFSSL_CALLBACKS
if (ssl->hsInfoOn) AddPacketName("Finished", &ssl->handShakeInfo); if (ssl->hsInfoOn) AddPacketName("Finished", &ssl->handShakeInfo);
if (ssl->toInfoOn) if (ssl->toInfoOn) {
AddPacketInfo("Finished", &ssl->timeoutInfo, output, sendSz, AddPacketInfo("Finished", &ssl->timeoutInfo, output, sendSz,
ssl->heap); ssl->heap);
}
#endif #endif
ssl->buffers.outputBuffer.length += sendSz; ssl->buffers.outputBuffer.length += sendSz;
ret = SendBuffered(ssl); if ((ret = SendBuffered(ssl)) != 0)
if (ret != 0)
return ret; return ret;
if (ssl->options.side == WOLFSSL_SERVER_END) { if (ssl->options.side == WOLFSSL_SERVER_END) {
@ -5276,9 +5227,10 @@ static int SendTls13KeyUpdate(WOLFSSL* ssl)
#ifdef WOLFSSL_CALLBACKS #ifdef WOLFSSL_CALLBACKS
if (ssl->hsInfoOn) AddPacketName("KeyUpdate", &ssl->handShakeInfo); if (ssl->hsInfoOn) AddPacketName("KeyUpdate", &ssl->handShakeInfo);
if (ssl->toInfoOn) if (ssl->toInfoOn) {
AddPacketInfo("KeyUpdate", &ssl->timeoutInfo, output, sendSz, AddPacketInfo("KeyUpdate", &ssl->timeoutInfo, output, sendSz,
ssl->heap); ssl->heap);
}
#endif #endif
ssl->buffers.outputBuffer.length += sendSz; ssl->buffers.outputBuffer.length += sendSz;
@ -5373,6 +5325,8 @@ static int SendTls13EndOfEarlyData(WOLFSSL* ssl)
word32 length; word32 length;
word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ; word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
WOLFSSL_ENTER("SendTls13EndOfEarlyData");
length = 0; length = 0;
sendSz = idx + length + MAX_MSG_EXTRA; sendSz = idx + length + MAX_MSG_EXTRA;
@ -5398,7 +5352,12 @@ static int SendTls13EndOfEarlyData(WOLFSSL* ssl)
if ((ret = SetKeysSide(ssl, ENCRYPT_SIDE_ONLY)) != 0) if ((ret = SetKeysSide(ssl, ENCRYPT_SIDE_ONLY)) != 0)
return ret; return ret;
return SendBuffered(ssl); if (!ssl->options.groupMessages)
ret = SendBuffered(ssl);
WOLFSSL_LEAVE("SendTls13EndOfEarlyData", ret);
return ret;
} }
#endif /* !NO_WOLFSSL_CLIENT */ #endif /* !NO_WOLFSSL_CLIENT */
@ -5413,18 +5372,24 @@ static int SendTls13EndOfEarlyData(WOLFSSL* ssl)
static int DoTls13EndOfEarlyData(WOLFSSL* ssl, const byte* input, static int DoTls13EndOfEarlyData(WOLFSSL* ssl, const byte* input,
word32* inOutIdx, word32 size) word32* inOutIdx, word32 size)
{ {
word32 begin = *inOutIdx; int ret;
word32 begin = *inOutIdx;
(void)input; (void)input;
WOLFSSL_ENTER("DoTls13EndOfEarlyData");
if ((*inOutIdx - begin) != size) if ((*inOutIdx - begin) != size)
return BUFFER_ERROR; return BUFFER_ERROR;
/* Always encrypted. */ /* Always encrypted. */
*inOutIdx += ssl->keys.padSz; *inOutIdx += ssl->keys.padSz;
return SetKeysSide(ssl, DECRYPT_SIDE_ONLY); ret = SetKeysSide(ssl, DECRYPT_SIDE_ONLY);
WOLFSSL_LEAVE("SendTls13EndOfEarlyData", ret);
return ret;
} }
#endif /* !NO_WOLFSSL_SERVER */ #endif /* !NO_WOLFSSL_SERVER */
#endif /* WOLFSSL_EARLY_DATA */ #endif /* WOLFSSL_EARLY_DATA */
@ -5445,12 +5410,15 @@ static int DoTls13NewSessionTicket(WOLFSSL* ssl, const byte* input,
{ {
#ifdef HAVE_SESSION_TICKET #ifdef HAVE_SESSION_TICKET
#ifdef WOLFSSL_EARLY_DATA #ifdef WOLFSSL_EARLY_DATA
int ret; int ret;
#endif #endif
word32 begin = *inOutIdx; word32 begin = *inOutIdx;
word32 lifetime; word32 lifetime;
word32 ageAdd; word32 ageAdd;
word16 length; word16 length;
word32 now;
WOLFSSL_ENTER("DoTls13NewSessionTicket");
/* Lifetime hint. */ /* Lifetime hint. */
if ((*inOutIdx - begin) + SESSION_HINT_SZ > size) if ((*inOutIdx - begin) + SESSION_HINT_SZ > size)
@ -5491,12 +5459,15 @@ static int DoTls13NewSessionTicket(WOLFSSL* ssl, const byte* input,
ssl->session.isDynamic = 1; ssl->session.isDynamic = 1;
} }
now = TimeNowInMilliseconds();
if (now == (word32)GETTIME_ERROR)
return now;
/* Copy in ticket data (server identity). */ /* Copy in ticket data (server identity). */
ssl->timeout = lifetime; ssl->timeout = lifetime;
ssl->session.timeout = lifetime; ssl->session.timeout = lifetime;
ssl->session.cipherSuite0 = ssl->options.cipherSuite0; ssl->session.cipherSuite0 = ssl->options.cipherSuite0;
ssl->session.cipherSuite = ssl->options.cipherSuite; ssl->session.cipherSuite = ssl->options.cipherSuite;
ssl->session.ticketSeen = TimeNowInMilliseconds(); ssl->session.ticketSeen = now;
ssl->session.ticketAdd = ageAdd; ssl->session.ticketAdd = ageAdd;
#ifdef WOLFSSL_EARLY_DATA #ifdef WOLFSSL_EARLY_DATA
ssl->session.maxEarlyDataSz = ssl->options.maxEarlyDataSz; ssl->session.maxEarlyDataSz = ssl->options.maxEarlyDataSz;
@ -5540,9 +5511,14 @@ static int DoTls13NewSessionTicket(WOLFSSL* ssl, const byte* input,
#else #else
(void)ssl; (void)ssl;
(void)input; (void)input;
WOLFSSL_ENTER("DoTls13NewSessionTicket");
*inOutIdx += size + ssl->keys.padSz; *inOutIdx += size + ssl->keys.padSz;
#endif /* HAVE_SESSION_TICKET */ #endif /* HAVE_SESSION_TICKET */
WOLFSSL_LEAVE("DoTls13NewSessionTicket", 0);
return 0; return 0;
} }
#endif /* NO_WOLFSSL_CLIENT */ #endif /* NO_WOLFSSL_CLIENT */
@ -5555,7 +5531,7 @@ static int DoTls13NewSessionTicket(WOLFSSL* ssl, const byte* input,
* ssl The SSL/TLS object. * ssl The SSL/TLS object.
* retuns 0 on success, otherwise failure. * retuns 0 on success, otherwise failure.
*/ */
int SendTls13NewSessionTicket(WOLFSSL* ssl) static int SendTls13NewSessionTicket(WOLFSSL* ssl)
{ {
byte* output; byte* output;
int ret; int ret;
@ -5564,9 +5540,11 @@ int SendTls13NewSessionTicket(WOLFSSL* ssl)
word32 length; word32 length;
word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ; word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
WOLFSSL_ENTER("SendTls13NewSessionTicket");
if (!ssl->options.noTicketTls13) { if (!ssl->options.noTicketTls13) {
ret = CreateTicket(ssl); if ((ret = CreateTicket(ssl)) != 0)
if (ret != 0) return ret; return ret;
} }
#ifdef WOLFSSL_EARLY_DATA #ifdef WOLFSSL_EARLY_DATA
@ -5630,7 +5608,12 @@ int SendTls13NewSessionTicket(WOLFSSL* ssl)
ssl->buffers.outputBuffer.length += sendSz; ssl->buffers.outputBuffer.length += sendSz;
return SendBuffered(ssl); if (!ssl->options.groupMessages)
ret = SendBuffered(ssl);
WOLFSSL_LEAVE("SendTls13NewSessionTicket", 0);
return ret;
} }
#endif /* HAVE_SESSION_TICKET */ #endif /* HAVE_SESSION_TICKET */
#endif /* NO_WOLFSSL_SERVER */ #endif /* NO_WOLFSSL_SERVER */
@ -5680,6 +5663,7 @@ static int SanityCheckTls13MsgReceived(WOLFSSL* ssl, byte type)
#endif #endif
#ifndef NO_WOLFSSL_SERVER #ifndef NO_WOLFSSL_SERVER
#ifdef WOLFSSL_EARLY_DATA
case end_of_early_data: case end_of_early_data:
if (ssl->msgsReceived.got_end_of_early_data == 1) { if (ssl->msgsReceived.got_end_of_early_data == 1) {
WOLFSSL_MSG("Too many EndOfEarlyData received"); WOLFSSL_MSG("Too many EndOfEarlyData received");
@ -5688,6 +5672,7 @@ static int SanityCheckTls13MsgReceived(WOLFSSL* ssl, byte type)
ssl->msgsReceived.got_end_of_early_data++; ssl->msgsReceived.got_end_of_early_data++;
break; break;
#endif
#endif #endif
#ifndef NO_WOLFSSL_CLIENT #ifndef NO_WOLFSSL_CLIENT

View File

@ -3503,26 +3503,14 @@ WOLFSSL_LOCAL int DoClientTicket(WOLFSSL*, const byte*, word32);
WOLFSSL_LOCAL int SendData(WOLFSSL*, const void*, int); WOLFSSL_LOCAL int SendData(WOLFSSL*, const void*, int);
#ifdef WOLFSSL_TLS13 #ifdef WOLFSSL_TLS13
WOLFSSL_LOCAL int SendTls13HelloRetryRequest(WOLFSSL*); WOLFSSL_LOCAL int SendTls13HelloRetryRequest(WOLFSSL*);
WOLFSSL_LOCAL int SendTls13EncryptedExtensions(WOLFSSL*);
#endif #endif
WOLFSSL_LOCAL int SendCertificate(WOLFSSL*); WOLFSSL_LOCAL int SendCertificate(WOLFSSL*);
#ifdef WOLFSSL_TLS13
WOLFSSL_LOCAL int SendTls13Certificate(WOLFSSL*);
#endif
WOLFSSL_LOCAL int SendCertificateRequest(WOLFSSL*); WOLFSSL_LOCAL int SendCertificateRequest(WOLFSSL*);
#ifdef WOLFSSL_TLS13
WOLFSSL_LOCAL int SendTls13CertificateRequest(WOLFSSL* ssl, byte* reqCtx,
int reqCtxLen);
#endif
WOLFSSL_LOCAL int SendCertificateStatus(WOLFSSL*); WOLFSSL_LOCAL int SendCertificateStatus(WOLFSSL*);
WOLFSSL_LOCAL int SendServerKeyExchange(WOLFSSL*); WOLFSSL_LOCAL int SendServerKeyExchange(WOLFSSL*);
WOLFSSL_LOCAL int SendBuffered(WOLFSSL*); WOLFSSL_LOCAL int SendBuffered(WOLFSSL*);
WOLFSSL_LOCAL int ReceiveData(WOLFSSL*, byte*, int, int); WOLFSSL_LOCAL int ReceiveData(WOLFSSL*, byte*, int, int);
WOLFSSL_LOCAL int SendFinished(WOLFSSL*); WOLFSSL_LOCAL int SendFinished(WOLFSSL*);
#ifdef WOLFSSL_TLS13
WOLFSSL_LOCAL int SendTls13Finished(WOLFSSL*);
WOLFSSL_LOCAL int SendTls13NewSessionTicket(WOLFSSL*);
#endif
WOLFSSL_LOCAL int SendAlert(WOLFSSL*, int, int); WOLFSSL_LOCAL int SendAlert(WOLFSSL*, int, int);
WOLFSSL_LOCAL int ProcessReply(WOLFSSL*); WOLFSSL_LOCAL int ProcessReply(WOLFSSL*);
@ -3628,13 +3616,8 @@ WOLFSSL_LOCAL int GrowInputBuffer(WOLFSSL* ssl, int size, int usedLength);
WOLFSSL_LOCAL int SendCertificateVerify(WOLFSSL*); WOLFSSL_LOCAL int SendCertificateVerify(WOLFSSL*);
#endif /* NO_WOLFSSL_CLIENT */ #endif /* NO_WOLFSSL_CLIENT */
WOLFSSL_LOCAL int SendTls13CertificateVerify(WOLFSSL*);
#ifndef NO_WOLFSSL_SERVER #ifndef NO_WOLFSSL_SERVER
WOLFSSL_LOCAL int SendServerHello(WOLFSSL*); WOLFSSL_LOCAL int SendServerHello(WOLFSSL*);
#ifdef WOLFSSL_TLS13
WOLFSSL_LOCAL int SendTls13ServerHello(WOLFSSL*);
#endif
WOLFSSL_LOCAL int SendServerHelloDone(WOLFSSL*); WOLFSSL_LOCAL int SendServerHelloDone(WOLFSSL*);
#endif /* NO_WOLFSSL_SERVER */ #endif /* NO_WOLFSSL_SERVER */