Send more alerts as per TLS specification

Requires WOLFSSL_EXTRA_ALERTS or OPENSSL_EXTRA to enable
This commit is contained in:
Sean Parkinson
2019-07-01 17:01:06 +10:00
parent f51a8fffde
commit b7e00eea1a
3 changed files with 84 additions and 18 deletions

View File

@@ -538,7 +538,7 @@ fi
if test "$ENABLED_OPENSSLEXTRA" = "yes" && test "x$ENABLED_OPENSSLCOEXIST" = "xno" if test "$ENABLED_OPENSSLEXTRA" = "yes" && test "x$ENABLED_OPENSSLCOEXIST" = "xno"
then then
AM_CFLAGS="-DOPENSSL_EXTRA -DWOLFSSL_ALWAYS_VERIFY_CB $AM_CFLAGS" AM_CFLAGS="-DOPENSSL_EXTRA -DWOLFSSL_ALWAYS_VERIFY_CB $AM_CFLAGS"
AM_CFLAGS="-DWOLFSSL_VERIFY_CB_ALL_CERTS $AM_CFLAGS" AM_CFLAGS="-DWOLFSSL_VERIFY_CB_ALL_CERTS -DWOLFSSL_EXTRA_ALERTS $AM_CFLAGS"
fi fi
if test "$ENABLED_OPENSSLEXTRA" = "yes" && test "$ENABLED_SMALL" = "yes" if test "$ENABLED_OPENSSLEXTRA" = "yes" && test "$ENABLED_SMALL" = "yes"

View File

@@ -10179,6 +10179,10 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
#endif /* SESSION_CERTS */ #endif /* SESSION_CERTS */
ret = ProcessPeerCerts(ssl, input, inOutIdx, size); ret = ProcessPeerCerts(ssl, input, inOutIdx, size);
#ifdef WOLFSSL_EXTRA_ALERTS
if (ret == BUFFER_ERROR || ret == ASN_PARSE_E)
SendAlert(ssl, alert_fatal, decode_error);
#endif
#ifdef OPENSSL_EXTRA #ifdef OPENSSL_EXTRA
ssl->options.serverState = SERVER_CERT_COMPLETE; ssl->options.serverState = SERVER_CERT_COMPLETE;
@@ -10407,6 +10411,9 @@ int DoFinished(WOLFSSL* ssl, const byte* input, word32* inOutIdx, word32 size,
if (sniff == NO_SNIFF) { if (sniff == NO_SNIFF) {
if (XMEMCMP(input + *inOutIdx, &ssl->hsHashes->verifyHashes,size) != 0){ if (XMEMCMP(input + *inOutIdx, &ssl->hsHashes->verifyHashes,size) != 0){
WOLFSSL_MSG("Verify finished error on hashes"); WOLFSSL_MSG("Verify finished error on hashes");
#ifdef WOLFSSL_EXTRA_ALERTS
SendAlert(ssl, alert_fatal, decrypt_error);
#endif
return VERIFY_FINISHED_ERROR; return VERIFY_FINISHED_ERROR;
} }
} }
@@ -10488,6 +10495,9 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type)
case client_hello: case client_hello:
if (ssl->msgsReceived.got_client_hello) { if (ssl->msgsReceived.got_client_hello) {
WOLFSSL_MSG("Duplicate ClientHello received"); WOLFSSL_MSG("Duplicate ClientHello received");
#ifdef WOLFSSL_EXTRA_ALERTS
SendAlert(ssl, alert_fatal, unexpected_message);
#endif
return DUPLICATE_MSG_E; return DUPLICATE_MSG_E;
} }
ssl->msgsReceived.got_client_hello = 1; ssl->msgsReceived.got_client_hello = 1;
@@ -10679,6 +10689,9 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type)
case client_key_exchange: case client_key_exchange:
if (ssl->msgsReceived.got_client_key_exchange) { if (ssl->msgsReceived.got_client_key_exchange) {
WOLFSSL_MSG("Duplicate ClientKeyExchange received"); WOLFSSL_MSG("Duplicate ClientKeyExchange received");
#ifdef WOLFSSL_EXTRA_ALERTS
SendAlert(ssl, alert_fatal, unexpected_message);
#endif
return DUPLICATE_MSG_E; return DUPLICATE_MSG_E;
} }
ssl->msgsReceived.got_client_key_exchange = 1; ssl->msgsReceived.got_client_key_exchange = 1;
@@ -10699,6 +10712,9 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type)
if (ssl->msgsReceived.got_change_cipher == 0) { if (ssl->msgsReceived.got_change_cipher == 0) {
WOLFSSL_MSG("Finished received before ChangeCipher"); WOLFSSL_MSG("Finished received before ChangeCipher");
#ifdef WOLFSSL_EXTRA_ALERTS
SendAlert(ssl, alert_fatal, unexpected_message);
#endif
return NO_CHANGE_CIPHER_E; return NO_CHANGE_CIPHER_E;
} }
break; break;
@@ -10706,6 +10722,9 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type)
case change_cipher_hs: case change_cipher_hs:
if (ssl->msgsReceived.got_change_cipher) { if (ssl->msgsReceived.got_change_cipher) {
WOLFSSL_MSG("Duplicate ChangeCipher received"); WOLFSSL_MSG("Duplicate ChangeCipher received");
#ifdef WOLFSSL_EXTRA_ALERTS
SendAlert(ssl, alert_fatal, unexpected_message);
#endif
return DUPLICATE_MSG_E; return DUPLICATE_MSG_E;
} }
/* DTLS is going to ignore the CCS message if the client key /* DTLS is going to ignore the CCS message if the client key
@@ -10744,6 +10763,9 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type)
if (!ssl->options.resuming && if (!ssl->options.resuming &&
ssl->msgsReceived.got_client_key_exchange == 0) { ssl->msgsReceived.got_client_key_exchange == 0) {
WOLFSSL_MSG("No ClientKeyExchange before ChangeCipher"); WOLFSSL_MSG("No ClientKeyExchange before ChangeCipher");
#ifdef WOLFSSL_EXTRA_ALERTS
SendAlert(ssl, alert_fatal, unexpected_message);
#endif
return OUT_OF_ORDER_E; return OUT_OF_ORDER_E;
} }
#ifndef NO_CERTS #ifndef NO_CERTS
@@ -12730,6 +12752,7 @@ int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx)
dataSz = msgSz - ivExtra - ssl->keys.padSz; dataSz = msgSz - ivExtra - ssl->keys.padSz;
if (dataSz < 0) { if (dataSz < 0) {
WOLFSSL_MSG("App data buffer error, malicious input?"); WOLFSSL_MSG("App data buffer error, malicious input?");
SendAlert(ssl, alert_fatal, unexpected_message);
return BUFFER_ERROR; return BUFFER_ERROR;
} }
#ifdef WOLFSSL_EARLY_DATA #ifdef WOLFSSL_EARLY_DATA
@@ -13150,9 +13173,15 @@ int ProcessReply(WOLFSSL* ssl)
/* get sz bytes or return error */ /* get sz bytes or return error */
if (!ssl->options.dtls) { if (!ssl->options.dtls) {
if ((ret = GetInputData(ssl, ssl->curSize)) < 0) if ((ret = GetInputData(ssl, ssl->curSize)) < 0) {
#ifdef WOLFSSL_EXTRA_ALERTS
if (ret != WANT_READ)
SendAlert(ssl, alert_fatal, bad_record_mac);
#endif
return ret; return ret;
} else { }
}
else {
#ifdef WOLFSSL_DTLS #ifdef WOLFSSL_DTLS
/* read ahead may already have */ /* read ahead may already have */
used = ssl->buffers.inputBuffer.length - used = ssl->buffers.inputBuffer.length -
@@ -13181,8 +13210,12 @@ int ProcessReply(WOLFSSL* ssl)
bufferStatic* in = &ssl->buffers.inputBuffer; bufferStatic* in = &ssl->buffers.inputBuffer;
ret = SanityCheckCipherText(ssl, ssl->curSize); ret = SanityCheckCipherText(ssl, ssl->curSize);
if (ret < 0) if (ret < 0) {
#ifdef WOLFSSL_EXTRA_ALERTS
SendAlert(ssl, alert_fatal, bad_record_mac);
#endif
return ret; return ret;
}
if (atomicUser) { if (atomicUser) {
#ifdef ATOMIC_USER #ifdef ATOMIC_USER
@@ -13315,6 +13348,10 @@ int ProcessReply(WOLFSSL* ssl)
#endif /* WOLFSSL_DTLS_DROP_STATS */ #endif /* WOLFSSL_DTLS_DROP_STATS */
} }
#endif /* WOLFSSL_DTLS */ #endif /* WOLFSSL_DTLS */
#ifdef WOLFSSL_EXTRA_ALERTS
if (!ssl->options.dtls)
SendAlert(ssl, alert_fatal, bad_record_mac);
#endif
return DECRYPT_ERROR; return DECRYPT_ERROR;
} }
} }
@@ -23272,7 +23309,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
/* & 0x1 equivalent % 2 */ /* & 0x1 equivalent % 2 */
if (peerSuites->suiteSz == 0 || peerSuites->suiteSz & 0x1) if (peerSuites->suiteSz == 0 || peerSuites->suiteSz & 0x1)
return MATCH_SUITE_ERROR; return BUFFER_ERROR;
if (ssl->suites == NULL) if (ssl->suites == NULL)
return SUITES_ERROR; return SUITES_ERROR;
@@ -23891,6 +23928,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
if (b == 0) { if (b == 0) {
WOLFSSL_MSG("No compression types in list"); WOLFSSL_MSG("No compression types in list");
#ifdef WOLFSSL_EXTRA_ALERTS
SendAlert(ssl, alert_fatal, decode_error);
#endif
return COMPRESSION_ERROR; return COMPRESSION_ERROR;
} }
@@ -23957,6 +23997,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
ssl->options.usingCompression = 0; /* turn off */ ssl->options.usingCompression = 0; /* turn off */
} else { } else {
WOLFSSL_MSG("Could not match compression"); WOLFSSL_MSG("Could not match compression");
#ifdef WOLFSSL_EXTRA_ALERTS
SendAlert(ssl, alert_fatal, illegal_parameter);
#endif
return COMPRESSION_ERROR; return COMPRESSION_ERROR;
} }
} }
@@ -24329,6 +24372,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
/* Check for error */ /* Check for error */
if (ret != 0) { if (ret != 0) {
ret = SIG_VERIFY_E;
goto exit_dcv; goto exit_dcv;
} }
@@ -24351,9 +24395,11 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
ssl->buffers.digest.length, ssl->buffers.digest.length,
args->output, args->sigSz, args->output, args->sigSz,
HashAlgoToType(args->hashAlgo)); HashAlgoToType(args->hashAlgo));
if (ret != 0) if (ret != 0) {
ret = SIG_VERIFY_E;
goto exit_dcv; goto exit_dcv;
} }
}
else else
#endif #endif
{ {
@@ -24372,7 +24418,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
#endif #endif
if (args->sigAlgo != rsa_sa_algo) { if (args->sigAlgo != rsa_sa_algo) {
WOLFSSL_MSG("Oops, peer sent RSA key but not in verify"); WOLFSSL_MSG("Oops, peer sent RSA key but not "
"in verify");
} }
SetDigest(ssl, args->hashAlgo); SetDigest(ssl, args->hashAlgo);
@@ -24446,10 +24493,11 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
return ret; return ret;
} }
#endif /* WOLFSSL_ASYNC_CRYPT */ #endif /* WOLFSSL_ASYNC_CRYPT */
#ifdef OPENSSL_EXTRA #ifdef WOLFSSL_EXTRA_ALERTS
if (ret != 0){ if (ret == SIG_VERIFY_E)
SendAlert(ssl, alert_fatal, decrypt_error);
else if (ret != 0)
SendAlert(ssl, alert_fatal, bad_certificate); SendAlert(ssl, alert_fatal, bad_certificate);
}
#endif #endif
/* Digest is not allocated, so do this to prevent free */ /* Digest is not allocated, so do this to prevent free */
ssl->buffers.digest.buffer = NULL; ssl->buffers.digest.buffer = NULL;
@@ -25193,6 +25241,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
if ((word32)check != args->length) { if ((word32)check != args->length) {
WOLFSSL_MSG("RSA explicit size doesn't match"); WOLFSSL_MSG("RSA explicit size doesn't match");
#ifdef WOLFSSL_EXTRA_ALERTS
SendAlert(ssl, alert_fatal, bad_record_mac);
#endif
ERROR_OUT(RSA_PRIVATE_ERROR, exit_dcke); ERROR_OUT(RSA_PRIVATE_ERROR, exit_dcke);
} }
} }
@@ -25326,12 +25377,18 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
/* import peer ECC key */ /* import peer ECC key */
if ((args->idx - args->begin) + OPAQUE8_LEN > size) { if ((args->idx - args->begin) + OPAQUE8_LEN > size) {
#ifdef WOLFSSL_EXTRA_ALERTS
SendAlert(ssl, alert_fatal, decode_error);
#endif
ERROR_OUT(BUFFER_ERROR, exit_dcke); ERROR_OUT(BUFFER_ERROR, exit_dcke);
} }
args->length = input[args->idx++]; args->length = input[args->idx++];
if ((args->idx - args->begin) + args->length > size) { if ((args->idx - args->begin) + args->length > size) {
#ifdef WOLFSSL_EXTRA_ALERTS
SendAlert(ssl, alert_fatal, decode_error);
#endif
ERROR_OUT(BUFFER_ERROR, exit_dcke); ERROR_OUT(BUFFER_ERROR, exit_dcke);
} }
@@ -25363,6 +25420,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
input + args->idx, args->length, input + args->idx, args->length,
ssl->peerX25519Key, ssl->peerX25519Key,
EC25519_LITTLE_ENDIAN)) { EC25519_LITTLE_ENDIAN)) {
#ifdef WOLFSSL_EXTRA_ALERTS
SendAlert(ssl, alert_fatal, illegal_parameter);
#endif
ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke); ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke);
} }
@@ -25429,6 +25489,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
args->idx += OPAQUE16_LEN; args->idx += OPAQUE16_LEN;
if ((args->idx - args->begin) + clientPubSz > size) { if ((args->idx - args->begin) + clientPubSz > size) {
#ifdef WOLFSSL_EXTRA_ALERTS
SendAlert(ssl, alert_fatal, decode_error);
#endif
ERROR_OUT(BUFFER_ERROR, exit_dcke); ERROR_OUT(BUFFER_ERROR, exit_dcke);
} }

View File

@@ -10391,6 +10391,9 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
if (IsAtLeastTLSv1_3(ssl->version)) if (IsAtLeastTLSv1_3(ssl->version))
break; break;
#endif #endif
if (size != 0)
return BUFFER_ERROR;
#ifndef NO_WOLFSSL_SERVER #ifndef NO_WOLFSSL_SERVER
if (isRequest) if (isRequest)
ssl->options.haveEMS = 1; ssl->options.haveEMS = 1;