diff --git a/cyassl/error-ssl.h b/cyassl/error-ssl.h index de87d6a4d..2a1f4d91e 100644 --- a/cyassl/error-ssl.h +++ b/cyassl/error-ssl.h @@ -125,6 +125,7 @@ enum CyaSSL_ErrorCodes { SESSION_SECRET_CB_E = -392, /* Session secret Cb fcn failure */ NO_CHANGE_CIPHER_E = -393, /* Finished before change cipher */ SANITY_MSG_E = -394, /* Sanity check on msg order error */ + DUPLICATE_MSG_E = -395, /* Duplicate message error */ /* add strings to SetErrorString !!!!! */ diff --git a/src/internal.c b/src/internal.c index 970246859..4808cff99 100644 --- a/src/internal.c +++ b/src/internal.c @@ -4689,109 +4689,160 @@ static int SanityCheckMsgReceived(CYASSL* ssl, byte type) /* verify not a duplicate, mark received, check state */ switch (type) { +#ifndef NO_CYASSL_CLIENT case hello_request: if (ssl->msgsReceived.got_hello_request) { CYASSL_MSG("Duplicate HelloRequest received"); - return -1; + return DUPLICATE_MSG_E; } ssl->msgsReceived.got_hello_request = 1; break; +#endif +#ifndef NO_CYASSL_SERVER case client_hello: if (ssl->msgsReceived.got_client_hello) { CYASSL_MSG("Duplicate ClientHello received"); - return -1; + return DUPLICATE_MSG_E; } ssl->msgsReceived.got_client_hello = 1; break; +#endif +#ifndef NO_CYASSL_CLIENT case server_hello: if (ssl->msgsReceived.got_server_hello) { CYASSL_MSG("Duplicate ServerHello received"); - return -1; + return DUPLICATE_MSG_E; } ssl->msgsReceived.got_server_hello = 1; break; +#endif +#ifndef NO_CYASSL_CLIENT case hello_verify_request: if (ssl->msgsReceived.got_hello_verify_request) { CYASSL_MSG("Duplicate HelloVerifyRequest received"); - return -1; + return DUPLICATE_MSG_E; } ssl->msgsReceived.got_hello_verify_request = 1; break; +#endif +#ifndef NO_CYASSL_CLIENT case session_ticket: if (ssl->msgsReceived.got_session_ticket) { CYASSL_MSG("Duplicate SessionTicket received"); - return -1; + return DUPLICATE_MSG_E; } ssl->msgsReceived.got_session_ticket = 1; break; +#endif case certificate: if (ssl->msgsReceived.got_certificate) { CYASSL_MSG("Duplicate Certificate received"); - return -1; + return DUPLICATE_MSG_E; } ssl->msgsReceived.got_certificate = 1; +#ifndef NO_CYASSL_CLIENT + if (ssl->options.side == CYASSL_CLIENT_END) { + if ( ssl->msgsReceived.got_server_hello == 0) { + CYASSL_MSG("No ServerHello before Cert"); + return OUT_OF_ORDER_E; + } + } +#endif break; +#ifndef NO_CYASSL_CLIENT case server_key_exchange: if (ssl->msgsReceived.got_server_key_exchange) { CYASSL_MSG("Duplicate ServerKeyExchange received"); - return -1; + return DUPLICATE_MSG_E; } ssl->msgsReceived.got_server_key_exchange = 1; - break; + if ( ssl->msgsReceived.got_server_hello == 0) { + CYASSL_MSG("No ServerHello before Cert"); + return OUT_OF_ORDER_E; + } + break; +#endif + +#ifndef NO_CYASSL_CLIENT case certificate_request: if (ssl->msgsReceived.got_certificate_request) { CYASSL_MSG("Duplicate CertificateRequest received"); - return -1; + return DUPLICATE_MSG_E; } ssl->msgsReceived.got_certificate_request = 1; break; +#endif +#ifndef NO_CYASSL_CLIENT case server_hello_done: if (ssl->msgsReceived.got_server_hello_done) { CYASSL_MSG("Duplicate ServerHelloDone received"); - return -1; + return DUPLICATE_MSG_E; } ssl->msgsReceived.got_server_hello_done = 1; + if (ssl->msgsReceived.got_certificate == 0) { + if (ssl->specs.kea == psk_kea) { + CYASSL_MSG("No Cert required"); + } else { + CYASSL_MSG("No Certificate before ServerHelloDone"); + return OUT_OF_ORDER_E; + } + } + if (ssl->msgsReceived.got_server_key_exchange == 0) { + if (ssl->specs.static_ecdh == 1 || + ssl->specs.kea == rsa_kea || + ssl->specs.kea == ntru_kea) { + CYASSL_MSG("No KeyExchange required"); + } else { + CYASSL_MSG("No ServerKeyExchange before ServerDone"); + return OUT_OF_ORDER_E; + } + } break; +#endif +#ifndef NO_CYASSL_SERVER case certificate_verify: if (ssl->msgsReceived.got_certificate_verify) { CYASSL_MSG("Duplicate CertificateVerify received"); - return -1; + return DUPLICATE_MSG_E; } ssl->msgsReceived.got_certificate_verify = 1; break; +#endif +#ifndef NO_CYASSL_SERVER case client_key_exchange: if (ssl->msgsReceived.got_client_key_exchange) { CYASSL_MSG("Duplicate ClientKeyExchange received"); - return -1; + return DUPLICATE_MSG_E; } ssl->msgsReceived.got_client_key_exchange = 1; break; +#endif case finished: if (ssl->msgsReceived.got_finished) { CYASSL_MSG("Duplicate Finished received"); - return -1; + return DUPLICATE_MSG_E; } ssl->msgsReceived.got_finished = 1; @@ -4805,15 +4856,25 @@ static int SanityCheckMsgReceived(CYASSL* ssl, byte type) case change_cipher_hs: if (ssl->msgsReceived.got_change_cipher) { CYASSL_MSG("Duplicate ChangeCipher received"); - return -1; + return DUPLICATE_MSG_E; } ssl->msgsReceived.got_change_cipher = 1; +#ifndef NO_CYASSL_CLIENT + if (ssl->options.side == CYASSL_CLIENT_END) { + if (!ssl->options.resuming && + ssl->msgsReceived.got_server_hello_done == 0) { + CYASSL_MSG("No ServerHelloDone before ChangeCipher "); + return OUT_OF_ORDER_E; + } + } +#endif + break; default: CYASSL_MSG("Unknown message type"); - return -1; + return SANITY_MSG_E; } return 0; @@ -4833,9 +4894,9 @@ static int DoHandShakeMsgType(CYASSL* ssl, byte* input, word32* inOutIdx, return INCOMPLETE_DATA; /* sanity check msg received */ - if (SanityCheckMsgReceived(ssl, type) != 0) { + if ( (ret = SanityCheckMsgReceived(ssl, type)) != 0) { CYASSL_MSG("Sanity Check on handshake message type received failed"); - return SANITY_MSG_E; + return ret; } /* hello_request not hashed */ @@ -8044,6 +8105,9 @@ const char* CyaSSL_ERR_reason_error_string(unsigned long e) case SANITY_MSG_E: return "Sanity Check on message order Error"; + case DUPLICATE_MSG_E: + return "Duplicate HandShake message Error"; + default : return "unknown error number"; }