disallow basic server fast forwards during handshake

This commit is contained in:
toddouska
2014-11-17 15:25:49 -08:00
parent 31858d2a34
commit 57522d217b
2 changed files with 82 additions and 17 deletions

View File

@@ -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 !!!!! */

View File

@@ -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";
}