diff --git a/configure.ac b/configure.ac index d67f1ba4d..f9a7b472e 100644 --- a/configure.ac +++ b/configure.ac @@ -538,7 +538,7 @@ fi if test "$ENABLED_OPENSSLEXTRA" = "yes" && test "x$ENABLED_OPENSSLCOEXIST" = "xno" then 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 if test "$ENABLED_OPENSSLEXTRA" = "yes" && test "$ENABLED_SMALL" = "yes" diff --git a/src/internal.c b/src/internal.c index ea1b2e816..674d36b98 100644 --- a/src/internal.c +++ b/src/internal.c @@ -10179,6 +10179,10 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, #endif /* SESSION_CERTS */ 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 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 (XMEMCMP(input + *inOutIdx, &ssl->hsHashes->verifyHashes,size) != 0){ WOLFSSL_MSG("Verify finished error on hashes"); + #ifdef WOLFSSL_EXTRA_ALERTS + SendAlert(ssl, alert_fatal, decrypt_error); + #endif return VERIFY_FINISHED_ERROR; } } @@ -10488,6 +10495,9 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type) case client_hello: if (ssl->msgsReceived.got_client_hello) { WOLFSSL_MSG("Duplicate ClientHello received"); + #ifdef WOLFSSL_EXTRA_ALERTS + SendAlert(ssl, alert_fatal, unexpected_message); + #endif return DUPLICATE_MSG_E; } ssl->msgsReceived.got_client_hello = 1; @@ -10679,6 +10689,9 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type) case client_key_exchange: if (ssl->msgsReceived.got_client_key_exchange) { WOLFSSL_MSG("Duplicate ClientKeyExchange received"); + #ifdef WOLFSSL_EXTRA_ALERTS + SendAlert(ssl, alert_fatal, unexpected_message); + #endif return DUPLICATE_MSG_E; } 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) { WOLFSSL_MSG("Finished received before ChangeCipher"); + #ifdef WOLFSSL_EXTRA_ALERTS + SendAlert(ssl, alert_fatal, unexpected_message); + #endif return NO_CHANGE_CIPHER_E; } break; @@ -10706,6 +10722,9 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type) case change_cipher_hs: if (ssl->msgsReceived.got_change_cipher) { WOLFSSL_MSG("Duplicate ChangeCipher received"); + #ifdef WOLFSSL_EXTRA_ALERTS + SendAlert(ssl, alert_fatal, unexpected_message); + #endif return DUPLICATE_MSG_E; } /* 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 && ssl->msgsReceived.got_client_key_exchange == 0) { WOLFSSL_MSG("No ClientKeyExchange before ChangeCipher"); + #ifdef WOLFSSL_EXTRA_ALERTS + SendAlert(ssl, alert_fatal, unexpected_message); + #endif return OUT_OF_ORDER_E; } #ifndef NO_CERTS @@ -12730,6 +12752,7 @@ int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx) dataSz = msgSz - ivExtra - ssl->keys.padSz; if (dataSz < 0) { WOLFSSL_MSG("App data buffer error, malicious input?"); + SendAlert(ssl, alert_fatal, unexpected_message); return BUFFER_ERROR; } #ifdef WOLFSSL_EARLY_DATA @@ -13150,9 +13173,15 @@ int ProcessReply(WOLFSSL* ssl) /* get sz bytes or return error */ 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; - } else { + } + } + else { #ifdef WOLFSSL_DTLS /* read ahead may already have */ used = ssl->buffers.inputBuffer.length - @@ -13181,8 +13210,12 @@ int ProcessReply(WOLFSSL* ssl) bufferStatic* in = &ssl->buffers.inputBuffer; 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; + } if (atomicUser) { #ifdef ATOMIC_USER @@ -13303,7 +13336,7 @@ int ProcessReply(WOLFSSL* ssl) if (ret < 0) { WOLFSSL_MSG("VerifyMac failed"); WOLFSSL_ERROR(ret); - #ifdef WOLFSSL_DTLS + #ifdef WOLFSSL_DTLS /* If in DTLS mode, if the decrypt fails for any * reason, pretend the datagram never happened. */ if (ssl->options.dtls) { @@ -13314,7 +13347,11 @@ int ProcessReply(WOLFSSL* ssl) ssl->macDropCount++; #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; } } @@ -23272,7 +23309,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, /* & 0x1 equivalent % 2 */ if (peerSuites->suiteSz == 0 || peerSuites->suiteSz & 0x1) - return MATCH_SUITE_ERROR; + return BUFFER_ERROR; if (ssl->suites == NULL) return SUITES_ERROR; @@ -23891,6 +23928,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if (b == 0) { WOLFSSL_MSG("No compression types in list"); +#ifdef WOLFSSL_EXTRA_ALERTS + SendAlert(ssl, alert_fatal, decode_error); +#endif return COMPRESSION_ERROR; } @@ -23957,6 +23997,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ssl->options.usingCompression = 0; /* turn off */ } else { WOLFSSL_MSG("Could not match compression"); +#ifdef WOLFSSL_EXTRA_ALERTS + SendAlert(ssl, alert_fatal, illegal_parameter); +#endif return COMPRESSION_ERROR; } } @@ -24329,6 +24372,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, /* Check for error */ if (ret != 0) { + ret = SIG_VERIFY_E; goto exit_dcv; } @@ -24347,12 +24391,14 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, SetDigest(ssl, args->hashAlgo); ret = wc_RsaPSS_CheckPadding( - ssl->buffers.digest.buffer, - ssl->buffers.digest.length, - args->output, args->sigSz, - HashAlgoToType(args->hashAlgo)); - if (ret != 0) + ssl->buffers.digest.buffer, + ssl->buffers.digest.length, + args->output, args->sigSz, + HashAlgoToType(args->hashAlgo)); + if (ret != 0) { + ret = SIG_VERIFY_E; goto exit_dcv; + } } else #endif @@ -24365,14 +24411,15 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #ifdef WOLFSSL_SMALL_STACK encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, - ssl->heap, DYNAMIC_TYPE_SIGNATURE); + ssl->heap, DYNAMIC_TYPE_SIGNATURE); if (encodedSig == NULL) { ERROR_OUT(MEMORY_E, exit_dcv); } #endif 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); @@ -24446,10 +24493,11 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, return ret; } #endif /* WOLFSSL_ASYNC_CRYPT */ - #ifdef OPENSSL_EXTRA - if (ret != 0){ - SendAlert(ssl, alert_fatal, bad_certificate); - } + #ifdef WOLFSSL_EXTRA_ALERTS + if (ret == SIG_VERIFY_E) + SendAlert(ssl, alert_fatal, decrypt_error); + else if (ret != 0) + SendAlert(ssl, alert_fatal, bad_certificate); #endif /* Digest is not allocated, so do this to prevent free */ ssl->buffers.digest.buffer = NULL; @@ -25193,6 +25241,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if ((word32)check != args->length) { 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); } } @@ -25326,12 +25377,18 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, /* import peer ECC key */ 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); } args->length = input[args->idx++]; 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); } @@ -25363,6 +25420,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, input + args->idx, args->length, ssl->peerX25519Key, EC25519_LITTLE_ENDIAN)) { + #ifdef WOLFSSL_EXTRA_ALERTS + SendAlert(ssl, alert_fatal, illegal_parameter); + #endif 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; if ((args->idx - args->begin) + clientPubSz > size) { + #ifdef WOLFSSL_EXTRA_ALERTS + SendAlert(ssl, alert_fatal, decode_error); + #endif ERROR_OUT(BUFFER_ERROR, exit_dcke); } diff --git a/src/tls.c b/src/tls.c index d6b90114b..46eadfd17 100644 --- a/src/tls.c +++ b/src/tls.c @@ -10391,6 +10391,9 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType, if (IsAtLeastTLSv1_3(ssl->version)) break; #endif + if (size != 0) + return BUFFER_ERROR; + #ifndef NO_WOLFSSL_SERVER if (isRequest) ssl->options.haveEMS = 1;