add messages received framework, disallow duplicates
This commit is contained in:
parent
de388bf37f
commit
5318b243ba
@ -124,6 +124,7 @@ enum CyaSSL_ErrorCodes {
|
|||||||
SCR_DIFFERENT_CERT_E = -391, /* SCR Different cert error */
|
SCR_DIFFERENT_CERT_E = -391, /* SCR Different cert error */
|
||||||
SESSION_SECRET_CB_E = -392, /* Session secret Cb fcn failure */
|
SESSION_SECRET_CB_E = -392, /* Session secret Cb fcn failure */
|
||||||
NO_CHANGE_CIPHER_E = -393, /* Finished before change cipher */
|
NO_CHANGE_CIPHER_E = -393, /* Finished before change cipher */
|
||||||
|
SANITY_MSG_E = -394, /* Sanity check on msg order error */
|
||||||
|
|
||||||
/* add strings to SetErrorString !!!!! */
|
/* add strings to SetErrorString !!!!! */
|
||||||
|
|
||||||
|
@ -1956,6 +1956,24 @@ typedef struct DtlsMsg {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Handshake messages recevied from peer (plus change cipher */
|
||||||
|
typedef struct MsgsReceived {
|
||||||
|
word16 got_hello_request:1;
|
||||||
|
word16 got_client_hello:1;
|
||||||
|
word16 got_server_hello:1;
|
||||||
|
word16 got_hello_verify_request:1;
|
||||||
|
word16 got_session_ticket:1;
|
||||||
|
word16 got_certificate:1;
|
||||||
|
word16 got_server_key_exchange:1;
|
||||||
|
word16 got_certificate_request:1;
|
||||||
|
word16 got_server_hello_done:1;
|
||||||
|
word16 got_certificate_verify:1;
|
||||||
|
word16 got_client_key_exchange:1;
|
||||||
|
word16 got_finished:1;
|
||||||
|
word16 got_change_cipher:1;
|
||||||
|
} MsgsReceived;
|
||||||
|
|
||||||
|
|
||||||
/* CyaSSL ssl type */
|
/* CyaSSL ssl type */
|
||||||
struct CYASSL {
|
struct CYASSL {
|
||||||
CYASSL_CTX* ctx;
|
CYASSL_CTX* ctx;
|
||||||
@ -1970,6 +1988,7 @@ struct CYASSL {
|
|||||||
#endif
|
#endif
|
||||||
CipherSpecs specs;
|
CipherSpecs specs;
|
||||||
Keys keys;
|
Keys keys;
|
||||||
|
MsgsReceived msgsReceived; /* peer messages received */
|
||||||
int rfd; /* read file descriptor */
|
int rfd; /* read file descriptor */
|
||||||
int wfd; /* write file descriptor */
|
int wfd; /* write file descriptor */
|
||||||
int rflags; /* user read flags */
|
int rflags; /* user read flags */
|
||||||
|
181
src/internal.c
181
src/internal.c
@ -1580,29 +1580,8 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
|
|||||||
ssl->keys.dtls_state.nextSeq = 0;
|
ssl->keys.dtls_state.nextSeq = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef NO_OLD_TLS
|
XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
|
||||||
#ifndef NO_MD5
|
|
||||||
InitMd5(&ssl->hashMd5);
|
|
||||||
#endif
|
|
||||||
#ifndef NO_SHA
|
|
||||||
ret = InitSha(&ssl->hashSha);
|
|
||||||
if (ret != 0) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#ifndef NO_SHA256
|
|
||||||
ret = InitSha256(&ssl->hashSha256);
|
|
||||||
if (ret != 0) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef CYASSL_SHA384
|
|
||||||
ret = InitSha384(&ssl->hashSha384);
|
|
||||||
if (ret != 0) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifndef NO_RSA
|
#ifndef NO_RSA
|
||||||
ssl->peerRsaKey = NULL;
|
ssl->peerRsaKey = NULL;
|
||||||
ssl->peerRsaKeyPresent = 0;
|
ssl->peerRsaKeyPresent = 0;
|
||||||
@ -1800,6 +1779,30 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
|
|||||||
|
|
||||||
/* all done with init, now can return errors, call other stuff */
|
/* all done with init, now can return errors, call other stuff */
|
||||||
|
|
||||||
|
#ifndef NO_OLD_TLS
|
||||||
|
#ifndef NO_MD5
|
||||||
|
InitMd5(&ssl->hashMd5);
|
||||||
|
#endif
|
||||||
|
#ifndef NO_SHA
|
||||||
|
ret = InitSha(&ssl->hashSha);
|
||||||
|
if (ret != 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifndef NO_SHA256
|
||||||
|
ret = InitSha256(&ssl->hashSha256);
|
||||||
|
if (ret != 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef CYASSL_SHA384
|
||||||
|
ret = InitSha384(&ssl->hashSha384);
|
||||||
|
if (ret != 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* increment CTX reference count */
|
/* increment CTX reference count */
|
||||||
if (LockMutex(&ctx->countMutex) != 0) {
|
if (LockMutex(&ctx->countMutex) != 0) {
|
||||||
CYASSL_MSG("Couldn't lock CTX count mutex");
|
CYASSL_MSG("Couldn't lock CTX count mutex");
|
||||||
@ -4686,6 +4689,129 @@ int DoFinished(CYASSL* ssl, const byte* input, word32* inOutIdx, word32 size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Make sure no duplicates, no fast forward, or other problems; 0 on success */
|
||||||
|
static int SanityCheckMsgReceived(CYASSL* ssl, byte type)
|
||||||
|
{
|
||||||
|
/* verify not a duplicate, mark received, check state */
|
||||||
|
switch (type) {
|
||||||
|
|
||||||
|
case hello_request:
|
||||||
|
if (ssl->msgsReceived.got_hello_request) {
|
||||||
|
CYASSL_MSG("Duplicate HelloRequest received");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ssl->msgsReceived.got_hello_request = 1;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case client_hello:
|
||||||
|
if (ssl->msgsReceived.got_client_hello) {
|
||||||
|
CYASSL_MSG("Duplicate ClientHello received");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ssl->msgsReceived.got_client_hello = 1;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case server_hello:
|
||||||
|
if (ssl->msgsReceived.got_server_hello) {
|
||||||
|
CYASSL_MSG("Duplicate ServerHello received");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ssl->msgsReceived.got_server_hello = 1;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case hello_verify_request:
|
||||||
|
if (ssl->msgsReceived.got_hello_verify_request) {
|
||||||
|
CYASSL_MSG("Duplicate HelloVerifyRequest received");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ssl->msgsReceived.got_hello_verify_request = 1;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case session_ticket:
|
||||||
|
if (ssl->msgsReceived.got_session_ticket) {
|
||||||
|
CYASSL_MSG("Duplicate SessionTicket received");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ssl->msgsReceived.got_session_ticket = 1;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case certificate:
|
||||||
|
if (ssl->msgsReceived.got_certificate) {
|
||||||
|
CYASSL_MSG("Duplicate Certificate received");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ssl->msgsReceived.got_certificate = 1;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case server_key_exchange:
|
||||||
|
if (ssl->msgsReceived.got_server_key_exchange) {
|
||||||
|
CYASSL_MSG("Duplicate ServerKeyExchange received");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ssl->msgsReceived.got_server_key_exchange = 1;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case certificate_request:
|
||||||
|
if (ssl->msgsReceived.got_certificate_request) {
|
||||||
|
CYASSL_MSG("Duplicate CertificateRequest received");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ssl->msgsReceived.got_certificate_request = 1;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case server_hello_done:
|
||||||
|
if (ssl->msgsReceived.got_server_hello_done) {
|
||||||
|
CYASSL_MSG("Duplicate ServerHelloDone received");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ssl->msgsReceived.got_server_hello_done = 1;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case certificate_verify:
|
||||||
|
if (ssl->msgsReceived.got_certificate_verify) {
|
||||||
|
CYASSL_MSG("Duplicate CertificateVerify received");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ssl->msgsReceived.got_certificate_verify = 1;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case client_key_exchange:
|
||||||
|
if (ssl->msgsReceived.got_client_key_exchange) {
|
||||||
|
CYASSL_MSG("Duplicate ClientKeyExchange received");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ssl->msgsReceived.got_client_key_exchange = 1;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case finished:
|
||||||
|
if (ssl->msgsReceived.got_finished) {
|
||||||
|
CYASSL_MSG("Duplicate Finished received");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ssl->msgsReceived.got_finished = 1;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
CYASSL_MSG("Unknown message type");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int DoHandShakeMsgType(CYASSL* ssl, byte* input, word32* inOutIdx,
|
static int DoHandShakeMsgType(CYASSL* ssl, byte* input, word32* inOutIdx,
|
||||||
byte type, word32 size, word32 totalSz)
|
byte type, word32 size, word32 totalSz)
|
||||||
{
|
{
|
||||||
@ -4698,6 +4824,12 @@ static int DoHandShakeMsgType(CYASSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
if (*inOutIdx + size > totalSz)
|
if (*inOutIdx + size > totalSz)
|
||||||
return INCOMPLETE_DATA;
|
return INCOMPLETE_DATA;
|
||||||
|
|
||||||
|
/* sanity check msg received */
|
||||||
|
if (SanityCheckMsgReceived(ssl, type) != 0) {
|
||||||
|
CYASSL_MSG("Sanity Check on handshake message type received failed");
|
||||||
|
return SANITY_MSG_E;
|
||||||
|
}
|
||||||
|
|
||||||
/* hello_request not hashed */
|
/* hello_request not hashed */
|
||||||
if (type != hello_request) {
|
if (type != hello_request) {
|
||||||
ret = HashInput(ssl, input + *inOutIdx, size);
|
ret = HashInput(ssl, input + *inOutIdx, size);
|
||||||
@ -7898,6 +8030,9 @@ const char* CyaSSL_ERR_reason_error_string(unsigned long e)
|
|||||||
case NO_CHANGE_CIPHER_E:
|
case NO_CHANGE_CIPHER_E:
|
||||||
return "Finished received from peer before Change Cipher Error";
|
return "Finished received from peer before Change Cipher Error";
|
||||||
|
|
||||||
|
case SANITY_MSG_E:
|
||||||
|
return "Sanity Check on message order Error";
|
||||||
|
|
||||||
default :
|
default :
|
||||||
return "unknown error number";
|
return "unknown error number";
|
||||||
}
|
}
|
||||||
|
@ -779,6 +779,8 @@ int CyaSSL_Rehandshake(CYASSL* ssl)
|
|||||||
ssl->options.processReply = 0; /* TODO, move states in internal.h */
|
ssl->options.processReply = 0; /* TODO, move states in internal.h */
|
||||||
ssl->options.gotChangeCipher = 0;
|
ssl->options.gotChangeCipher = 0;
|
||||||
|
|
||||||
|
XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
|
||||||
|
|
||||||
ssl->secure_renegotiation->cache_status = SCR_CACHE_NEEDED;
|
ssl->secure_renegotiation->cache_status = SCR_CACHE_NEEDED;
|
||||||
|
|
||||||
#ifndef NO_OLD_TLS
|
#ifndef NO_OLD_TLS
|
||||||
@ -5313,6 +5315,8 @@ int CyaSSL_dtls_got_timeout(CYASSL* ssl)
|
|||||||
#ifdef CYASSL_DTLS
|
#ifdef CYASSL_DTLS
|
||||||
if (ssl->options.dtls) {
|
if (ssl->options.dtls) {
|
||||||
ssl->options.clientState = NULL_STATE; /* get again */
|
ssl->options.clientState = NULL_STATE; /* get again */
|
||||||
|
/* reset messages received */
|
||||||
|
XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
|
||||||
/* re-init hashes, exclude first hello and verify request */
|
/* re-init hashes, exclude first hello and verify request */
|
||||||
#ifndef NO_OLD_TLS
|
#ifndef NO_OLD_TLS
|
||||||
InitMd5(&ssl->hashMd5);
|
InitMd5(&ssl->hashMd5);
|
||||||
|
Loading…
Reference in New Issue
Block a user