forked from wolfSSL/wolfssl
Send secure renegotiation extension by default
- Add test for terminating the connection - Add ProcessReplyEx(ssl, 1) to wolfSSL_accept
This commit is contained in:
@ -195,6 +195,7 @@ then
|
||||
else
|
||||
AC_MSG_ERROR([Invalid value for --enable-harden-tls])
|
||||
fi
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_EXTRA_ALERTS -DWOLFSSL_CHECK_ALERT_ON_ERR"
|
||||
fi
|
||||
|
||||
# Support for forcing 32-bit mode
|
||||
|
@ -7127,11 +7127,13 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SECURE_RENEGOTIATION
|
||||
#if defined(HAVE_SECURE_RENEGOTIATION) || \
|
||||
defined(HAVE_SERVER_RENEGOTIATION_INFO)
|
||||
if (ssl->options.side == WOLFSSL_CLIENT_END) {
|
||||
int useSecureReneg = ssl->ctx->useSecureReneg;
|
||||
/* use secure renegotiation by default (not recommend) */
|
||||
#ifdef WOLFSSL_SECURE_RENEGOTIATION_ON_BY_DEFAULT
|
||||
#if defined(WOLFSSL_SECURE_RENEGOTIATION_ON_BY_DEFAULT) || \
|
||||
(defined(WOLFSSL_HARDEN_TLS) && !defined(WOLFSSL_NO_TLS12))
|
||||
useSecureReneg = 1;
|
||||
#endif
|
||||
if (useSecureReneg) {
|
||||
@ -26988,6 +26990,18 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_HARDEN_TLS
|
||||
if (ssl->secure_renegotiation == NULL ||
|
||||
!ssl->secure_renegotiation->enabled) {
|
||||
/* If the server does not acknowledge the extension, the client
|
||||
* MUST generate a fatal handshake_failure alert prior to
|
||||
* terminating the connection.
|
||||
* https://www.rfc-editor.org/rfc/rfc9325#name-renegotiation-in-tls-12 */
|
||||
WOLFSSL_MSG("ServerHello did not contain SCR extension");
|
||||
return SECURE_RENEGOTIATION_E;
|
||||
}
|
||||
#endif
|
||||
|
||||
ssl->options.serverState = SERVER_HELLO_COMPLETE;
|
||||
|
||||
if (IsEncryptionOn(ssl, 0)) {
|
||||
|
27
src/ssl.c
27
src/ssl.c
@ -13959,6 +13959,9 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
||||
|
||||
case ACCEPT_FIRST_REPLY_DONE :
|
||||
if ( (ssl->error = SendServerHello(ssl)) != 0) {
|
||||
#ifdef WOLFSSL_CHECK_ALERT_ON_ERR
|
||||
ProcessReplyEx(ssl, 1); /* See if an alert was sent. */
|
||||
#endif
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
@ -13975,6 +13978,9 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
||||
#ifndef NO_CERTS
|
||||
if (!ssl->options.resuming)
|
||||
if ( (ssl->error = SendCertificate(ssl)) != 0) {
|
||||
#ifdef WOLFSSL_CHECK_ALERT_ON_ERR
|
||||
ProcessReplyEx(ssl, 1); /* See if an alert was sent. */
|
||||
#endif
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
@ -13987,6 +13993,9 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
||||
#ifndef NO_CERTS
|
||||
if (!ssl->options.resuming)
|
||||
if ( (ssl->error = SendCertificateStatus(ssl)) != 0) {
|
||||
#ifdef WOLFSSL_CHECK_ALERT_ON_ERR
|
||||
ProcessReplyEx(ssl, 1); /* See if an alert was sent. */
|
||||
#endif
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
@ -14003,6 +14012,9 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
||||
#endif
|
||||
if (!ssl->options.resuming)
|
||||
if ( (ssl->error = SendServerKeyExchange(ssl)) != 0) {
|
||||
#ifdef WOLFSSL_CHECK_ALERT_ON_ERR
|
||||
ProcessReplyEx(ssl, 1); /* See if an alert was sent. */
|
||||
#endif
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
@ -14015,6 +14027,9 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
||||
if (!ssl->options.resuming) {
|
||||
if (ssl->options.verifyPeer) {
|
||||
if ( (ssl->error = SendCertificateRequest(ssl)) != 0) {
|
||||
#ifdef WOLFSSL_CHECK_ALERT_ON_ERR
|
||||
ProcessReplyEx(ssl, 1); /* See if an alert was sent. */
|
||||
#endif
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
@ -14032,6 +14047,9 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
||||
case CERT_REQ_SENT :
|
||||
if (!ssl->options.resuming)
|
||||
if ( (ssl->error = SendServerHelloDone(ssl)) != 0) {
|
||||
#ifdef WOLFSSL_CHECK_ALERT_ON_ERR
|
||||
ProcessReplyEx(ssl, 1); /* See if an alert was sent. */
|
||||
#endif
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
@ -14070,6 +14088,9 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
||||
#ifdef HAVE_SESSION_TICKET
|
||||
if (ssl->options.createTicket && !ssl->options.noTicketTls12) {
|
||||
if ( (ssl->error = SendTicket(ssl)) != 0) {
|
||||
#ifdef WOLFSSL_CHECK_ALERT_ON_ERR
|
||||
ProcessReplyEx(ssl, 1); /* See if an alert was sent. */
|
||||
#endif
|
||||
WOLFSSL_MSG("Thought we need ticket but failed");
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
@ -14088,6 +14109,9 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
||||
}
|
||||
|
||||
if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
|
||||
#ifdef WOLFSSL_CHECK_ALERT_ON_ERR
|
||||
ProcessReplyEx(ssl, 1); /* See if an alert was sent. */
|
||||
#endif
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
@ -14097,6 +14121,9 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
||||
|
||||
case CHANGE_CIPHER_SENT :
|
||||
if ( (ssl->error = SendFinished(ssl)) != 0) {
|
||||
#ifdef WOLFSSL_CHECK_ALERT_ON_ERR
|
||||
ProcessReplyEx(ssl, 1); /* See if an alert was sent. */
|
||||
#endif
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
|
72
tests/api.c
72
tests/api.c
@ -63519,6 +63519,77 @@ static int test_extra_alerts_bad_psk(void)
|
||||
return TEST_SKIPPED;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_HARDEN_TLS) && !defined(WOLFSSL_NO_TLS12) && \
|
||||
defined(HAVE_IO_TESTS_DEPENDENCIES)
|
||||
static int test_harden_no_secure_renegotiation_io_cb(WOLFSSL *ssl, char *buf,
|
||||
int sz, void *ctx)
|
||||
{
|
||||
static int sentServerHello = FALSE;
|
||||
|
||||
if (!sentServerHello) {
|
||||
byte renegExt[] = { 0xFF, 0x01, 0x00, 0x01, 0x00 };
|
||||
size_t i;
|
||||
|
||||
if (sz < (int)sizeof(renegExt))
|
||||
return WOLFSSL_CBIO_ERR_GENERAL;
|
||||
|
||||
/* Remove SCR from ServerHello */
|
||||
for (i = 0; i < sz - sizeof(renegExt); i++) {
|
||||
if (XMEMCMP(buf + i, renegExt, sizeof(renegExt)) == 0) {
|
||||
/* Found the extension. Change it to something unrecognized. */
|
||||
buf[i+1] = 0x11;
|
||||
break;
|
||||
}
|
||||
}
|
||||
sentServerHello = TRUE;
|
||||
}
|
||||
|
||||
return EmbedSend(ssl, buf, sz, ctx);
|
||||
}
|
||||
|
||||
static void test_harden_no_secure_renegotiation_ssl_ready(WOLFSSL* ssl)
|
||||
{
|
||||
wolfSSL_SSLSetIOSend(ssl, test_harden_no_secure_renegotiation_io_cb);
|
||||
}
|
||||
|
||||
static void test_harden_no_secure_renegotiation_on_cleanup(WOLFSSL* ssl)
|
||||
{
|
||||
WOLFSSL_ALERT_HISTORY h;
|
||||
AssertIntEQ(wolfSSL_get_alert_history(ssl, &h), WOLFSSL_SUCCESS);
|
||||
AssertIntEQ(h.last_rx.code, handshake_failure);
|
||||
AssertIntEQ(h.last_rx.level, alert_fatal);
|
||||
}
|
||||
|
||||
static int test_harden_no_secure_renegotiation(void)
|
||||
{
|
||||
callback_functions client_cbs, server_cbs;
|
||||
|
||||
XMEMSET(&client_cbs, 0, sizeof(client_cbs));
|
||||
XMEMSET(&server_cbs, 0, sizeof(server_cbs));
|
||||
|
||||
client_cbs.method = wolfTLSv1_2_client_method;
|
||||
server_cbs.method = wolfTLSv1_2_server_method;
|
||||
|
||||
server_cbs.ssl_ready = test_harden_no_secure_renegotiation_ssl_ready;
|
||||
server_cbs.on_cleanup = test_harden_no_secure_renegotiation_on_cleanup;
|
||||
test_wolfSSL_client_server_nofail(&client_cbs, &server_cbs);
|
||||
|
||||
AssertIntEQ(client_cbs.return_code, TEST_FAIL);
|
||||
AssertIntEQ(client_cbs.last_err, SECURE_RENEGOTIATION_E);
|
||||
AssertIntEQ(server_cbs.return_code, TEST_FAIL);
|
||||
AssertIntEQ(server_cbs.last_err, SOCKET_ERROR_E);
|
||||
|
||||
return TEST_RES_CHECK(1);
|
||||
}
|
||||
#else
|
||||
static int test_harden_no_secure_renegotiation(void)
|
||||
{
|
||||
return TEST_SKIPPED;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
| Main
|
||||
*----------------------------------------------------------------------------*/
|
||||
@ -64539,6 +64610,7 @@ TEST_CASE testCases[] = {
|
||||
TEST_DECL(test_extra_alerts_wrong_cs),
|
||||
TEST_DECL(test_extra_alerts_skip_hs),
|
||||
TEST_DECL(test_extra_alerts_bad_psk),
|
||||
TEST_DECL(test_harden_no_secure_renegotiation),
|
||||
/* If at some point a stub get implemented this test should fail indicating
|
||||
* a need to implement a new test case
|
||||
*/
|
||||
|
@ -2995,6 +2995,13 @@ extern void uITRON4_free(void *p) ;
|
||||
#ifndef NO_OLD_TLS
|
||||
#error "TLS < 1.2 protocol versions not allowed https://www.rfc-editor.org/rfc/rfc9325#section-3.1.1"
|
||||
#endif
|
||||
#if !defined(WOLFSSL_NO_TLS12) && !defined(HAVE_SECURE_RENEGOTIATION) && \
|
||||
!defined(HAVE_SERVER_RENEGOTIATION_INFO)
|
||||
#error "TLS 1.2 requires at least HAVE_SERVER_RENEGOTIATION_INFO to send the secure renegotiation extension https://www.rfc-editor.org/rfc/rfc9325#section-3.5"
|
||||
#endif
|
||||
#if !defined(WOLFSSL_EXTRA_ALERTS) || !defined(WOLFSSL_CHECK_ALERT_ON_ERR)
|
||||
#error "RFC9325 requires some additional alerts to be sent"
|
||||
#endif
|
||||
/* Ciphersuite check done in internal.h */
|
||||
#endif
|
||||
|
||||
|
Reference in New Issue
Block a user