mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-05 21:54:41 +02:00
Merge pull request #4863 from SparkiDev/tls13_auth
TLS 1.3: improved checks on received message type
This commit is contained in:
198
src/tls13.c
198
src/tls13.c
@@ -3370,15 +3370,20 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
|
|
||||||
/* Check if hello retry request */
|
/* Check if hello retry request */
|
||||||
if (XMEMCMP(input + args->idx, helloRetryRequestRandom, RAN_LEN) == 0) {
|
if (XMEMCMP(input + args->idx, helloRetryRequestRandom, RAN_LEN) == 0) {
|
||||||
|
WOLFSSL_MSG("HelloRetryRequest format");
|
||||||
*extMsgType = hello_retry_request;
|
*extMsgType = hello_retry_request;
|
||||||
|
|
||||||
/* A HelloRetryRequest comes in as an ServerHello for MiddleBox compat.
|
/* A HelloRetryRequest comes in as an ServerHello for MiddleBox compat.
|
||||||
* Found message to be a HelloRetryRequest.
|
* Found message to be a HelloRetryRequest.
|
||||||
* Don't allow more than one HelloRetryRequest or ServerHello.
|
* Don't allow more than one HelloRetryRequest or ServerHello.
|
||||||
*/
|
*/
|
||||||
if (ssl->msgsReceived.got_hello_retry_request == 1) {
|
if (ssl->msgsReceived.got_hello_retry_request) {
|
||||||
return DUPLICATE_MSG_E;
|
return DUPLICATE_MSG_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Update counts to reflect change of message type. */
|
||||||
|
ssl->msgsReceived.got_hello_retry_request = 1;
|
||||||
|
ssl->msgsReceived.got_server_hello--;
|
||||||
}
|
}
|
||||||
args->extMsgType = *extMsgType;
|
args->extMsgType = *extMsgType;
|
||||||
|
|
||||||
@@ -3499,11 +3504,6 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
args->idx += args->totalExtSz;
|
args->idx += args->totalExtSz;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*extMsgType == hello_retry_request) {
|
|
||||||
/* Update counts to reflect change of message type. */
|
|
||||||
ssl->msgsReceived.got_hello_retry_request = 1;
|
|
||||||
ssl->msgsReceived.got_server_hello--;
|
|
||||||
}
|
|
||||||
*inOutIdx = args->idx;
|
*inOutIdx = args->idx;
|
||||||
|
|
||||||
ssl->options.serverState = SERVER_HELLO_COMPLETE;
|
ssl->options.serverState = SERVER_HELLO_COMPLETE;
|
||||||
@@ -3618,8 +3618,12 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
ssl->arrays->psk_keySz = 0;
|
ssl->arrays->psk_keySz = 0;
|
||||||
XMEMSET(ssl->arrays->psk_key, 0, MAX_PSK_KEY_LEN);
|
XMEMSET(ssl->arrays->psk_key, 0, MAX_PSK_KEY_LEN);
|
||||||
}
|
}
|
||||||
else if ((ret = SetupPskKey(ssl, psk, 0)) != 0)
|
else {
|
||||||
return ret;
|
if ((ret = SetupPskKey(ssl, psk, 0)) != 0)
|
||||||
|
return ret;
|
||||||
|
ssl->options.pskNegotiated = 1;
|
||||||
|
ssl->options.peerAuthGood = 1;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ssl->keys.encryptionOn = 1;
|
ssl->keys.encryptionOn = 1;
|
||||||
@@ -4877,6 +4881,10 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
{
|
{
|
||||||
*inOutIdx = args->idx;
|
*inOutIdx = args->idx;
|
||||||
ssl->options.clientState = CLIENT_HELLO_COMPLETE;
|
ssl->options.clientState = CLIENT_HELLO_COMPLETE;
|
||||||
|
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
||||||
|
ssl->options.pskNegotiated = (args->usingPSK != 0);
|
||||||
|
ssl->options.peerAuthGood = ssl->options.pskNegotiated;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!args->usingPSK) {
|
if (!args->usingPSK) {
|
||||||
#ifndef NO_CERTS
|
#ifndef NO_CERTS
|
||||||
@@ -5832,7 +5840,7 @@ static int SendTls13Certificate(WOLFSSL* ssl)
|
|||||||
word32 i = RECORD_HEADER_SZ;
|
word32 i = RECORD_HEADER_SZ;
|
||||||
int sendSz = RECORD_HEADER_SZ;
|
int sendSz = RECORD_HEADER_SZ;
|
||||||
|
|
||||||
if (ssl->fragOffset == 0) {
|
if (ssl->fragOffset == 0) {
|
||||||
if (headerSz + certSz + extSz + certChainSz <=
|
if (headerSz + certSz + extSz + certChainSz <=
|
||||||
maxFragment - HANDSHAKE_HEADER_SZ) {
|
maxFragment - HANDSHAKE_HEADER_SZ) {
|
||||||
fragSz = headerSz + certSz + extSz + certChainSz;
|
fragSz = headerSz + certSz + extSz + certChainSz;
|
||||||
@@ -6816,6 +6824,7 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input,
|
|||||||
case TLS_ASYNC_FINALIZE:
|
case TLS_ASYNC_FINALIZE:
|
||||||
{
|
{
|
||||||
ssl->options.havePeerVerify = 1;
|
ssl->options.havePeerVerify = 1;
|
||||||
|
ssl->options.peerAuthGood = 1;
|
||||||
|
|
||||||
/* Set final index */
|
/* Set final index */
|
||||||
args->idx += args->sz;
|
args->idx += args->sz;
|
||||||
@@ -7752,19 +7761,30 @@ static int SanityCheckTls13MsgReceived(WOLFSSL* ssl, byte type)
|
|||||||
#ifndef NO_WOLFSSL_SERVER
|
#ifndef NO_WOLFSSL_SERVER
|
||||||
case client_hello:
|
case client_hello:
|
||||||
#ifndef NO_WOLFSSL_CLIENT
|
#ifndef NO_WOLFSSL_CLIENT
|
||||||
|
/* Only valid when received on SERVER side. */
|
||||||
if (ssl->options.side == WOLFSSL_CLIENT_END) {
|
if (ssl->options.side == WOLFSSL_CLIENT_END) {
|
||||||
WOLFSSL_MSG("ClientHello received by client");
|
WOLFSSL_MSG("ClientHello received by client");
|
||||||
return SIDE_ERROR;
|
return SIDE_ERROR;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
/* Check state. */
|
||||||
if (ssl->options.clientState >= CLIENT_HELLO_COMPLETE) {
|
if (ssl->options.clientState >= CLIENT_HELLO_COMPLETE) {
|
||||||
WOLFSSL_MSG("ClientHello received out of order");
|
WOLFSSL_MSG("ClientHello received out of order");
|
||||||
return OUT_OF_ORDER_E;
|
return OUT_OF_ORDER_E;
|
||||||
}
|
}
|
||||||
|
/* Check previously seen. */
|
||||||
|
/* Initial and after HelloRetryRequest - no more than 2. */
|
||||||
if (ssl->msgsReceived.got_client_hello == 2) {
|
if (ssl->msgsReceived.got_client_hello == 2) {
|
||||||
WOLFSSL_MSG("Too many ClientHello received");
|
WOLFSSL_MSG("Too many ClientHello received");
|
||||||
return DUPLICATE_MSG_E;
|
return DUPLICATE_MSG_E;
|
||||||
}
|
}
|
||||||
|
/* Second only after HelloRetryRequest seen. */
|
||||||
|
if (ssl->msgsReceived.got_client_hello == 1 &&
|
||||||
|
ssl->options.serverState !=
|
||||||
|
SERVER_HELLO_RETRY_REQUEST_COMPLETE) {
|
||||||
|
WOLFSSL_MSG("Duplicate ClientHello received");
|
||||||
|
return DUPLICATE_MSG_E;
|
||||||
|
}
|
||||||
ssl->msgsReceived.got_client_hello++;
|
ssl->msgsReceived.got_client_hello++;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -7773,16 +7793,27 @@ static int SanityCheckTls13MsgReceived(WOLFSSL* ssl, byte type)
|
|||||||
#ifndef NO_WOLFSSL_CLIENT
|
#ifndef NO_WOLFSSL_CLIENT
|
||||||
case server_hello:
|
case server_hello:
|
||||||
#ifndef NO_WOLFSSL_SERVER
|
#ifndef NO_WOLFSSL_SERVER
|
||||||
|
/* Only valid when received on CLIENT side. */
|
||||||
if (ssl->options.side == WOLFSSL_SERVER_END) {
|
if (ssl->options.side == WOLFSSL_SERVER_END) {
|
||||||
WOLFSSL_MSG("ServerHello received by server");
|
WOLFSSL_MSG("ServerHello received by server");
|
||||||
return SIDE_ERROR;
|
return SIDE_ERROR;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (ssl->msgsReceived.got_server_hello == 1) {
|
/* Check state. */
|
||||||
|
if (ssl->options.serverState >= SERVER_HELLO_COMPLETE) {
|
||||||
|
WOLFSSL_MSG("ServerHello received out of order");
|
||||||
|
return OUT_OF_ORDER_E;
|
||||||
|
}
|
||||||
|
/* Check previously seen. */
|
||||||
|
/* Only once after ClientHello.
|
||||||
|
* HelloRetryRequest has ServerHello type but count fixed up later
|
||||||
|
* - see DoTls13ServerHello().
|
||||||
|
*/
|
||||||
|
if (ssl->msgsReceived.got_server_hello) {
|
||||||
WOLFSSL_MSG("Duplicate ServerHello received");
|
WOLFSSL_MSG("Duplicate ServerHello received");
|
||||||
return DUPLICATE_MSG_E;
|
return DUPLICATE_MSG_E;
|
||||||
}
|
}
|
||||||
ssl->msgsReceived.got_server_hello++;
|
ssl->msgsReceived.got_server_hello = 1;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
@@ -7790,15 +7821,27 @@ static int SanityCheckTls13MsgReceived(WOLFSSL* ssl, byte type)
|
|||||||
#ifndef NO_WOLFSSL_CLIENT
|
#ifndef NO_WOLFSSL_CLIENT
|
||||||
case session_ticket:
|
case session_ticket:
|
||||||
#ifndef NO_WOLFSSL_SERVER
|
#ifndef NO_WOLFSSL_SERVER
|
||||||
|
/* Only valid when received on CLIENT side. */
|
||||||
if (ssl->options.side == WOLFSSL_SERVER_END) {
|
if (ssl->options.side == WOLFSSL_SERVER_END) {
|
||||||
WOLFSSL_MSG("NewSessionTicket received by server");
|
WOLFSSL_MSG("NewSessionTicket received by server");
|
||||||
return SIDE_ERROR;
|
return SIDE_ERROR;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
/* Check state. */
|
||||||
|
#ifdef WOLFSSL_TLS13_TICKET_BEFORE_FINISHED
|
||||||
|
/* Only allowed after server's Finished message. */
|
||||||
|
if (ssl->options.serverState < SERVER_FINISHED_COMPLETE) {
|
||||||
|
WOLFSSL_MSG("NewSessionTicket received out of order");
|
||||||
|
return OUT_OF_ORDER_E;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* Only allowed after client's Finished message. */
|
||||||
if (ssl->options.clientState < CLIENT_FINISHED_COMPLETE) {
|
if (ssl->options.clientState < CLIENT_FINISHED_COMPLETE) {
|
||||||
WOLFSSL_MSG("NewSessionTicket received out of order");
|
WOLFSSL_MSG("NewSessionTicket received out of order");
|
||||||
return OUT_OF_ORDER_E;
|
return OUT_OF_ORDER_E;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
/* Many SessionTickets can be sent. */
|
||||||
ssl->msgsReceived.got_session_ticket = 1;
|
ssl->msgsReceived.got_session_ticket = 1;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -7808,11 +7851,14 @@ static int SanityCheckTls13MsgReceived(WOLFSSL* ssl, byte type)
|
|||||||
#ifdef WOLFSSL_EARLY_DATA
|
#ifdef WOLFSSL_EARLY_DATA
|
||||||
case end_of_early_data:
|
case end_of_early_data:
|
||||||
#ifndef NO_WOLFSSL_CLIENT
|
#ifndef NO_WOLFSSL_CLIENT
|
||||||
|
/* Only valid when received on SERVER side. */
|
||||||
if (ssl->options.side == WOLFSSL_CLIENT_END) {
|
if (ssl->options.side == WOLFSSL_CLIENT_END) {
|
||||||
WOLFSSL_MSG("EndOfEarlyData received by client");
|
WOLFSSL_MSG("EndOfEarlyData received by client");
|
||||||
return SIDE_ERROR;
|
return SIDE_ERROR;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
/* Check state. */
|
||||||
|
/* Only after server's Finished and before client's Finished. */
|
||||||
if (ssl->options.serverState < SERVER_FINISHED_COMPLETE) {
|
if (ssl->options.serverState < SERVER_FINISHED_COMPLETE) {
|
||||||
WOLFSSL_MSG("EndOfEarlyData received out of order");
|
WOLFSSL_MSG("EndOfEarlyData received out of order");
|
||||||
return OUT_OF_ORDER_E;
|
return OUT_OF_ORDER_E;
|
||||||
@@ -7821,11 +7867,12 @@ static int SanityCheckTls13MsgReceived(WOLFSSL* ssl, byte type)
|
|||||||
WOLFSSL_MSG("EndOfEarlyData received out of order");
|
WOLFSSL_MSG("EndOfEarlyData received out of order");
|
||||||
return OUT_OF_ORDER_E;
|
return OUT_OF_ORDER_E;
|
||||||
}
|
}
|
||||||
if (ssl->msgsReceived.got_end_of_early_data == 1) {
|
/* Check previously seen. */
|
||||||
|
if (ssl->msgsReceived.got_end_of_early_data) {
|
||||||
WOLFSSL_MSG("Too many EndOfEarlyData received");
|
WOLFSSL_MSG("Too many EndOfEarlyData received");
|
||||||
return DUPLICATE_MSG_E;
|
return DUPLICATE_MSG_E;
|
||||||
}
|
}
|
||||||
ssl->msgsReceived.got_end_of_early_data++;
|
ssl->msgsReceived.got_end_of_early_data = 1;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
@@ -7834,15 +7881,22 @@ static int SanityCheckTls13MsgReceived(WOLFSSL* ssl, byte type)
|
|||||||
#ifndef NO_WOLFSSL_CLIENT
|
#ifndef NO_WOLFSSL_CLIENT
|
||||||
case encrypted_extensions:
|
case encrypted_extensions:
|
||||||
#ifndef NO_WOLFSSL_SERVER
|
#ifndef NO_WOLFSSL_SERVER
|
||||||
|
/* Only valid when received on CLIENT side. */
|
||||||
if (ssl->options.side == WOLFSSL_SERVER_END) {
|
if (ssl->options.side == WOLFSSL_SERVER_END) {
|
||||||
WOLFSSL_MSG("EncryptedExtensions received by server");
|
WOLFSSL_MSG("EncryptedExtensions received by server");
|
||||||
return SIDE_ERROR;
|
return SIDE_ERROR;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
/* Check state. */
|
||||||
|
/* Must be received directly after ServerHello.
|
||||||
|
* DoTls13EncryptedExtensions() changes state to:
|
||||||
|
* SERVER_ENCRYPTED_EXTENSIONS_COMPLETE.
|
||||||
|
*/
|
||||||
if (ssl->options.serverState != SERVER_HELLO_COMPLETE) {
|
if (ssl->options.serverState != SERVER_HELLO_COMPLETE) {
|
||||||
WOLFSSL_MSG("EncryptedExtensions received out of order");
|
WOLFSSL_MSG("EncryptedExtensions received out of order");
|
||||||
return OUT_OF_ORDER_E;
|
return OUT_OF_ORDER_E;
|
||||||
}
|
}
|
||||||
|
/* Check previously seen. */
|
||||||
if (ssl->msgsReceived.got_encrypted_extensions) {
|
if (ssl->msgsReceived.got_encrypted_extensions) {
|
||||||
WOLFSSL_MSG("Duplicate EncryptedExtensions received");
|
WOLFSSL_MSG("Duplicate EncryptedExtensions received");
|
||||||
return DUPLICATE_MSG_E;
|
return DUPLICATE_MSG_E;
|
||||||
@@ -7853,7 +7907,13 @@ static int SanityCheckTls13MsgReceived(WOLFSSL* ssl, byte type)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
case certificate:
|
case certificate:
|
||||||
|
/* Valid on both sides. */
|
||||||
#ifndef NO_WOLFSSL_CLIENT
|
#ifndef NO_WOLFSSL_CLIENT
|
||||||
|
/* Check state. */
|
||||||
|
/* On client, seen after EncryptedExtension and CertificateRequest
|
||||||
|
* (if sent) and before CertificateVerify and Finished.
|
||||||
|
* DoTls13Certificate() sets serverState to SERVER_CERT_COMPLETE.
|
||||||
|
*/
|
||||||
if (ssl->options.side == WOLFSSL_CLIENT_END &&
|
if (ssl->options.side == WOLFSSL_CLIENT_END &&
|
||||||
ssl->options.serverState !=
|
ssl->options.serverState !=
|
||||||
SERVER_ENCRYPTED_EXTENSIONS_COMPLETE) {
|
SERVER_ENCRYPTED_EXTENSIONS_COMPLETE) {
|
||||||
@@ -7864,42 +7924,58 @@ static int SanityCheckTls13MsgReceived(WOLFSSL* ssl, byte type)
|
|||||||
/* Server's authenticating with PSK must not send this. */
|
/* Server's authenticating with PSK must not send this. */
|
||||||
if (ssl->options.side == WOLFSSL_CLIENT_END &&
|
if (ssl->options.side == WOLFSSL_CLIENT_END &&
|
||||||
ssl->options.serverState == SERVER_CERT_COMPLETE &&
|
ssl->options.serverState == SERVER_CERT_COMPLETE &&
|
||||||
ssl->arrays->psk_keySz != 0) {
|
ssl->options.pskNegotiated) {
|
||||||
WOLFSSL_MSG("Certificate received while using PSK");
|
WOLFSSL_MSG("Certificate received while using PSK");
|
||||||
return SANITY_MSG_E;
|
return SANITY_MSG_E;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#ifndef NO_WOLFSSL_SERVER
|
#ifndef NO_WOLFSSL_SERVER
|
||||||
|
/* Check state. */
|
||||||
|
/* On Server, valid after ClientHello received and ServerFinished
|
||||||
|
* sent. */
|
||||||
if (ssl->options.side == WOLFSSL_SERVER_END &&
|
if (ssl->options.side == WOLFSSL_SERVER_END &&
|
||||||
|
ssl->options.clientState != CLIENT_HELLO_COMPLETE &&
|
||||||
ssl->options.serverState < SERVER_FINISHED_COMPLETE) {
|
ssl->options.serverState < SERVER_FINISHED_COMPLETE) {
|
||||||
WOLFSSL_MSG("Certificate received out of order - Server");
|
WOLFSSL_MSG("Certificate received out of order - Server");
|
||||||
return OUT_OF_ORDER_E;
|
return OUT_OF_ORDER_E;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
/* Check previously seen. */
|
||||||
if (ssl->msgsReceived.got_certificate) {
|
if (ssl->msgsReceived.got_certificate) {
|
||||||
WOLFSSL_MSG("Duplicate Certificate received");
|
WOLFSSL_MSG("Duplicate Certificate received");
|
||||||
return DUPLICATE_MSG_E;
|
return DUPLICATE_MSG_E;
|
||||||
}
|
}
|
||||||
ssl->msgsReceived.got_certificate = 1;
|
ssl->msgsReceived.got_certificate = 1;
|
||||||
|
if (ssl->options.side == WOLFSSL_SERVER_END &&
|
||||||
|
(!ssl->options.verifyPeer || !ssl->options.failNoCert)) {
|
||||||
|
ssl->options.peerAuthGood = 1;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifndef NO_WOLFSSL_CLIENT
|
#ifndef NO_WOLFSSL_CLIENT
|
||||||
case certificate_request:
|
case certificate_request:
|
||||||
#ifndef NO_WOLFSSL_SERVER
|
#ifndef NO_WOLFSSL_SERVER
|
||||||
|
/* Only valid when received on CLIENT side. */
|
||||||
if (ssl->options.side == WOLFSSL_SERVER_END) {
|
if (ssl->options.side == WOLFSSL_SERVER_END) {
|
||||||
WOLFSSL_MSG("CertificateRequest received by server");
|
WOLFSSL_MSG("CertificateRequest received by server");
|
||||||
return SIDE_ERROR;
|
return SIDE_ERROR;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
/* Check state. */
|
||||||
#ifndef WOLFSSL_POST_HANDSHAKE_AUTH
|
#ifndef WOLFSSL_POST_HANDSHAKE_AUTH
|
||||||
|
/* Only valid when sent after EncryptedExtensions and before
|
||||||
|
* Certificate. */
|
||||||
if (ssl->options.serverState !=
|
if (ssl->options.serverState !=
|
||||||
SERVER_ENCRYPTED_EXTENSIONS_COMPLETE) {
|
SERVER_ENCRYPTED_EXTENSIONS_COMPLETE) {
|
||||||
WOLFSSL_MSG("CertificateRequest received out of order");
|
WOLFSSL_MSG("CertificateRequest received out of order");
|
||||||
return OUT_OF_ORDER_E;
|
return OUT_OF_ORDER_E;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
/* Valid when sent after EncryptedExtensions and before Certificate
|
||||||
|
* and after both client and server have sent Finished (Post
|
||||||
|
* Handshake Authentication). */
|
||||||
if (ssl->options.serverState !=
|
if (ssl->options.serverState !=
|
||||||
SERVER_ENCRYPTED_EXTENSIONS_COMPLETE &&
|
SERVER_ENCRYPTED_EXTENSIONS_COMPLETE &&
|
||||||
(ssl->options.serverState != SERVER_FINISHED_COMPLETE ||
|
(ssl->options.serverState != SERVER_FINISHED_COMPLETE ||
|
||||||
@@ -7910,19 +7986,25 @@ static int SanityCheckTls13MsgReceived(WOLFSSL* ssl, byte type)
|
|||||||
#endif
|
#endif
|
||||||
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
||||||
/* Server's authenticating with PSK must not send this. */
|
/* Server's authenticating with PSK must not send this. */
|
||||||
if (ssl->options.serverState ==
|
if (ssl->options.pskNegotiated) {
|
||||||
SERVER_ENCRYPTED_EXTENSIONS_COMPLETE &&
|
|
||||||
ssl->arrays != NULL &&
|
|
||||||
ssl->arrays->psk_keySz != 0) {
|
|
||||||
WOLFSSL_MSG("CertificateRequest received while using PSK");
|
WOLFSSL_MSG("CertificateRequest received while using PSK");
|
||||||
return SANITY_MSG_E;
|
return SANITY_MSG_E;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
/* Check previously seen. */
|
||||||
#ifndef WOLFSSL_POST_HANDSHAKE_AUTH
|
#ifndef WOLFSSL_POST_HANDSHAKE_AUTH
|
||||||
|
/* Only once during handshake. */
|
||||||
if (ssl->msgsReceived.got_certificate_request) {
|
if (ssl->msgsReceived.got_certificate_request) {
|
||||||
WOLFSSL_MSG("Duplicate CertificateRequest received");
|
WOLFSSL_MSG("Duplicate CertificateRequest received");
|
||||||
return DUPLICATE_MSG_E;
|
return DUPLICATE_MSG_E;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
/* Only once during handshake. */
|
||||||
|
if (ssl->msgsReceived.got_certificate_request &&
|
||||||
|
ssl->options.clientState != CLIENT_FINISHED_COMPLETE) {
|
||||||
|
WOLFSSL_MSG("Duplicate CertificateRequest received");
|
||||||
|
return DUPLICATE_MSG_E;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
ssl->msgsReceived.got_certificate_request = 1;
|
ssl->msgsReceived.got_certificate_request = 1;
|
||||||
|
|
||||||
@@ -7930,7 +8012,10 @@ static int SanityCheckTls13MsgReceived(WOLFSSL* ssl, byte type)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
case certificate_verify:
|
case certificate_verify:
|
||||||
|
/* Valid on both sides. */
|
||||||
#ifndef NO_WOLFSSL_CLIENT
|
#ifndef NO_WOLFSSL_CLIENT
|
||||||
|
/* Check state on client.
|
||||||
|
* Valid only directly after a Certificate message. */
|
||||||
if (ssl->options.side == WOLFSSL_CLIENT_END) {
|
if (ssl->options.side == WOLFSSL_CLIENT_END) {
|
||||||
if (ssl->options.serverState != SERVER_CERT_COMPLETE) {
|
if (ssl->options.serverState != SERVER_CERT_COMPLETE) {
|
||||||
WOLFSSL_MSG("No Cert before CertVerify");
|
WOLFSSL_MSG("No Cert before CertVerify");
|
||||||
@@ -7938,9 +8023,7 @@ static int SanityCheckTls13MsgReceived(WOLFSSL* ssl, byte type)
|
|||||||
}
|
}
|
||||||
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
||||||
/* Server's authenticating with PSK must not send this. */
|
/* Server's authenticating with PSK must not send this. */
|
||||||
if (ssl->options.serverState == SERVER_CERT_COMPLETE &&
|
if (ssl->options.pskNegotiated) {
|
||||||
ssl->arrays != NULL &&
|
|
||||||
ssl->arrays->psk_keySz != 0) {
|
|
||||||
WOLFSSL_MSG("CertificateVerify received while using PSK");
|
WOLFSSL_MSG("CertificateVerify received while using PSK");
|
||||||
return SANITY_MSG_E;
|
return SANITY_MSG_E;
|
||||||
}
|
}
|
||||||
@@ -7948,11 +8031,14 @@ static int SanityCheckTls13MsgReceived(WOLFSSL* ssl, byte type)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifndef NO_WOLFSSL_SERVER
|
#ifndef NO_WOLFSSL_SERVER
|
||||||
|
/* Check state on server. */
|
||||||
if (ssl->options.side == WOLFSSL_SERVER_END) {
|
if (ssl->options.side == WOLFSSL_SERVER_END) {
|
||||||
|
/* Server must have sent Finished message. */
|
||||||
if (ssl->options.serverState < SERVER_FINISHED_COMPLETE) {
|
if (ssl->options.serverState < SERVER_FINISHED_COMPLETE) {
|
||||||
WOLFSSL_MSG("CertificateVerify received out of order");
|
WOLFSSL_MSG("CertificateVerify received out of order");
|
||||||
return OUT_OF_ORDER_E;
|
return OUT_OF_ORDER_E;
|
||||||
}
|
}
|
||||||
|
/* Valid only directly after a Certificate message. */
|
||||||
if (ssl->options.clientState < CLIENT_HELLO_COMPLETE) {
|
if (ssl->options.clientState < CLIENT_HELLO_COMPLETE) {
|
||||||
WOLFSSL_MSG("CertificateVerify before ClientHello done");
|
WOLFSSL_MSG("CertificateVerify before ClientHello done");
|
||||||
return OUT_OF_ORDER_E;
|
return OUT_OF_ORDER_E;
|
||||||
@@ -7963,6 +8049,7 @@ static int SanityCheckTls13MsgReceived(WOLFSSL* ssl, byte type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
/* Check previously seen. */
|
||||||
if (ssl->msgsReceived.got_certificate_verify) {
|
if (ssl->msgsReceived.got_certificate_verify) {
|
||||||
WOLFSSL_MSG("Duplicate CertificateVerify received");
|
WOLFSSL_MSG("Duplicate CertificateVerify received");
|
||||||
return DUPLICATE_MSG_E;
|
return DUPLICATE_MSG_E;
|
||||||
@@ -7972,38 +8059,42 @@ static int SanityCheckTls13MsgReceived(WOLFSSL* ssl, byte type)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case finished:
|
case finished:
|
||||||
|
/* Valid on both sides. */
|
||||||
#ifndef NO_WOLFSSL_CLIENT
|
#ifndef NO_WOLFSSL_CLIENT
|
||||||
|
/* Check state on client. */
|
||||||
if (ssl->options.side == WOLFSSL_CLIENT_END) {
|
if (ssl->options.side == WOLFSSL_CLIENT_END) {
|
||||||
|
/* After sending ClientHello */
|
||||||
if (ssl->options.clientState < CLIENT_HELLO_COMPLETE) {
|
if (ssl->options.clientState < CLIENT_HELLO_COMPLETE) {
|
||||||
WOLFSSL_MSG("Finished received out of order");
|
WOLFSSL_MSG("Finished received out of order - clientState");
|
||||||
return OUT_OF_ORDER_E;
|
return OUT_OF_ORDER_E;
|
||||||
}
|
}
|
||||||
/* Must have seen certificate and verify from server except when
|
/* Must have seen certificate and verify from server except when
|
||||||
* using PSK. */
|
* using PSK. */
|
||||||
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
||||||
if (ssl->arrays != NULL && ssl->arrays->psk_keySz != 0) {
|
if (ssl->options.pskNegotiated) {
|
||||||
if (ssl->options.serverState !=
|
if (ssl->options.serverState !=
|
||||||
SERVER_ENCRYPTED_EXTENSIONS_COMPLETE) {
|
SERVER_ENCRYPTED_EXTENSIONS_COMPLETE) {
|
||||||
WOLFSSL_MSG("Finished received out of order");
|
WOLFSSL_MSG("Finished received out of order - PSK");
|
||||||
return OUT_OF_ORDER_E;
|
return OUT_OF_ORDER_E;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
if (ssl->options.serverState != SERVER_CERT_VERIFY_COMPLETE) {
|
if (ssl->options.serverState != SERVER_CERT_VERIFY_COMPLETE) {
|
||||||
WOLFSSL_MSG("Finished received out of order");
|
WOLFSSL_MSG("Finished received out of order - serverState");
|
||||||
return OUT_OF_ORDER_E;
|
return OUT_OF_ORDER_E;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifndef NO_WOLFSSL_SERVER
|
#ifndef NO_WOLFSSL_SERVER
|
||||||
|
/* Check state on server. */
|
||||||
if (ssl->options.side == WOLFSSL_SERVER_END) {
|
if (ssl->options.side == WOLFSSL_SERVER_END) {
|
||||||
if (ssl->options.serverState != SERVER_FINISHED_COMPLETE) {
|
if (ssl->options.serverState != SERVER_FINISHED_COMPLETE) {
|
||||||
WOLFSSL_MSG("Finished received out of order");
|
WOLFSSL_MSG("Finished received out of order - serverState");
|
||||||
return OUT_OF_ORDER_E;
|
return OUT_OF_ORDER_E;
|
||||||
}
|
}
|
||||||
if (ssl->options.clientState < CLIENT_HELLO_COMPLETE) {
|
if (ssl->options.clientState < CLIENT_HELLO_COMPLETE) {
|
||||||
WOLFSSL_MSG("Finished received out of order");
|
WOLFSSL_MSG("Finished received out of order - clientState");
|
||||||
return OUT_OF_ORDER_E;
|
return OUT_OF_ORDER_E;
|
||||||
}
|
}
|
||||||
#ifdef WOLFSSL_EARLY_DATA
|
#ifdef WOLFSSL_EARLY_DATA
|
||||||
@@ -8013,6 +8104,42 @@ static int SanityCheckTls13MsgReceived(WOLFSSL* ssl, byte type)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
||||||
|
if (!ssl->options.pskNegotiated)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
/* Must have received a Certificate message from client if
|
||||||
|
* verifying the peer. Empty certificate message indicates
|
||||||
|
* no certificate available.
|
||||||
|
*/
|
||||||
|
if (ssl->options.verifyPeer &&
|
||||||
|
!ssl->msgsReceived.got_certificate) {
|
||||||
|
WOLFSSL_MSG("Finished received out of order - "
|
||||||
|
"missing Certificate message");
|
||||||
|
return OUT_OF_ORDER_E;
|
||||||
|
}
|
||||||
|
/* Mutual authentication on server requires a certificate from
|
||||||
|
* peer. Verify peer set on client side requires a certificate
|
||||||
|
* from peer as not doing PSK.
|
||||||
|
*/
|
||||||
|
if ((ssl->options.mutualAuth ||
|
||||||
|
(ssl->options.side == WOLFSSL_CLIENT_END &&
|
||||||
|
ssl->options.verifyPeer)) && !ssl->options.havePeerCert) {
|
||||||
|
WOLFSSL_MSG("Finished received out of order - "
|
||||||
|
"no valid certificate");
|
||||||
|
return OUT_OF_ORDER_E;
|
||||||
|
}
|
||||||
|
/* Must have received a valid CertificateVerify if verifying
|
||||||
|
* peer and got a peer certificate.
|
||||||
|
*/
|
||||||
|
if ((ssl->options.mutualAuth || ssl->options.verifyPeer) &&
|
||||||
|
ssl->options.havePeerCert && !ssl->options.havePeerVerify) {
|
||||||
|
WOLFSSL_MSG("Finished received out of order - "
|
||||||
|
"Certificate message but no CertificateVerify");
|
||||||
|
return OUT_OF_ORDER_E;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Check previously seen. */
|
||||||
if (ssl->msgsReceived.got_finished) {
|
if (ssl->msgsReceived.got_finished) {
|
||||||
WOLFSSL_MSG("Duplicate Finished received");
|
WOLFSSL_MSG("Duplicate Finished received");
|
||||||
return DUPLICATE_MSG_E;
|
return DUPLICATE_MSG_E;
|
||||||
@@ -8022,10 +8149,16 @@ static int SanityCheckTls13MsgReceived(WOLFSSL* ssl, byte type)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case key_update:
|
case key_update:
|
||||||
|
/* Valid on both sides. */
|
||||||
|
/* Check state.
|
||||||
|
* Client and server must have received finished message from other
|
||||||
|
* side.
|
||||||
|
*/
|
||||||
if (!ssl->msgsReceived.got_finished) {
|
if (!ssl->msgsReceived.got_finished) {
|
||||||
WOLFSSL_MSG("No KeyUpdate before Finished");
|
WOLFSSL_MSG("No KeyUpdate before Finished");
|
||||||
return OUT_OF_ORDER_E;
|
return OUT_OF_ORDER_E;
|
||||||
}
|
}
|
||||||
|
/* Multiple KeyUpdates can be sent. */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -8581,6 +8714,10 @@ int wolfSSL_connect_TLSv13(WOLFSSL* ssl)
|
|||||||
FALL_THROUGH;
|
FALL_THROUGH;
|
||||||
|
|
||||||
case FIRST_REPLY_SECOND:
|
case FIRST_REPLY_SECOND:
|
||||||
|
if (!ssl->options.peerAuthGood) {
|
||||||
|
WOLFSSL_MSG("Server authentication did not happen");
|
||||||
|
return WOLFSSL_FATAL_ERROR;
|
||||||
|
}
|
||||||
#ifndef NO_CERTS
|
#ifndef NO_CERTS
|
||||||
if (!ssl->options.resuming && ssl->options.sendVerify) {
|
if (!ssl->options.resuming && ssl->options.sendVerify) {
|
||||||
ssl->error = SendTls13Certificate(ssl);
|
ssl->error = SendTls13Certificate(ssl);
|
||||||
@@ -9527,6 +9664,9 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
|
|||||||
return WOLFSSL_FATAL_ERROR;
|
return WOLFSSL_FATAL_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
ssl->options.peerAuthGood = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
ssl->options.acceptState = TLS13_CERT_REQ_SENT;
|
ssl->options.acceptState = TLS13_CERT_REQ_SENT;
|
||||||
@@ -9605,6 +9745,10 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
|
|||||||
FALL_THROUGH;
|
FALL_THROUGH;
|
||||||
|
|
||||||
case TLS13_ACCEPT_FINISHED_DONE :
|
case TLS13_ACCEPT_FINISHED_DONE :
|
||||||
|
if (!ssl->options.peerAuthGood) {
|
||||||
|
WOLFSSL_MSG("Client authentication did not happen");
|
||||||
|
return WOLFSSL_FATAL_ERROR;
|
||||||
|
}
|
||||||
#ifdef HAVE_SESSION_TICKET
|
#ifdef HAVE_SESSION_TICKET
|
||||||
while (ssl->options.ticketsSent < ssl->options.maxTicketTls13) {
|
while (ssl->options.ticketsSent < ssl->options.maxTicketTls13) {
|
||||||
if (!ssl->options.noTicketTls13 && ssl->ctx->ticketEncCb
|
if (!ssl->options.noTicketTls13 && ssl->ctx->ticketEncCb
|
||||||
|
@@ -3663,6 +3663,10 @@ typedef struct Options {
|
|||||||
word16 keepResources:1; /* Keep resources after handshake */
|
word16 keepResources:1; /* Keep resources after handshake */
|
||||||
word16 useClientOrder:1; /* Use client's cipher order */
|
word16 useClientOrder:1; /* Use client's cipher order */
|
||||||
word16 mutualAuth:1; /* Mutual authentication is required */
|
word16 mutualAuth:1; /* Mutual authentication is required */
|
||||||
|
word16 peerAuthGood:1; /* Any required peer auth done */
|
||||||
|
#if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK))
|
||||||
|
word16 pskNegotiated:1; /* Session Ticket/PSK negotiated. */
|
||||||
|
#endif
|
||||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
|
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
|
||||||
word16 postHandshakeAuth:1;/* Client send post_handshake_auth
|
word16 postHandshakeAuth:1;/* Client send post_handshake_auth
|
||||||
* extension */
|
* extension */
|
||||||
@@ -4064,7 +4068,7 @@ typedef struct DtlsMsg {
|
|||||||
typedef struct MsgsReceived {
|
typedef struct MsgsReceived {
|
||||||
word16 got_hello_request:1;
|
word16 got_hello_request:1;
|
||||||
word16 got_client_hello:2;
|
word16 got_client_hello:2;
|
||||||
word16 got_server_hello:2;
|
word16 got_server_hello:1;
|
||||||
word16 got_hello_verify_request:1;
|
word16 got_hello_verify_request:1;
|
||||||
word16 got_session_ticket:1;
|
word16 got_session_ticket:1;
|
||||||
word16 got_end_of_early_data:1;
|
word16 got_end_of_early_data:1;
|
||||||
|
Reference in New Issue
Block a user