Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TLS EMS: Set haveEMS when we negotiate TLS 1.3 #8487

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2512,6 +2512,7 @@ if(WOLFSSL_EXAMPLES)
tests/api/test_ascon.c
tests/api/test_mlkem.c
tests/api/test_ocsp.c
tests/api/test_tls_ext.c
tests/hash.c
tests/srp.c
tests/suites.c
Expand Down
11 changes: 10 additions & 1 deletion src/ssl_sess.c
Original file line number Diff line number Diff line change
Expand Up @@ -3565,7 +3565,16 @@ void SetupSession(WOLFSSL* ssl)
session->side = (byte)ssl->options.side;
if (!IsAtLeastTLSv1_3(ssl->version) && ssl->arrays != NULL)
XMEMCPY(session->masterSecret, ssl->arrays->masterSecret, SECRET_LEN);
session->haveEMS = ssl->options.haveEMS;
/* RFC8446 Appendix D.
* implementations which support both TLS 1.3 and earlier versions SHOULD
* indicate the use of the Extended Master Secret extension in their APIs
* whenever TLS 1.3 is used.
* Set haveEMS so that we send the extension in subsequent connections that
* offer downgrades. */
if (IsAtLeastTLSv1_3(ssl->version))
session->haveEMS = 1;
else
session->haveEMS = ssl->options.haveEMS;
#ifdef WOLFSSL_SESSION_ID_CTX
/* If using compatibility layer then check for and copy over session context
* id. */
Expand Down
27 changes: 2 additions & 25 deletions tests/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@
#include <tests/api/test_mlkem.h>
#include <tests/api/test_dtls.h>
#include <tests/api/test_ocsp.h>
#include <tests/api/test_tls_ext.h>

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_TLS) && \
!defined(NO_RSA) && !defined(SINGLE_THREADED) && \
Expand Down Expand Up @@ -12520,31 +12521,6 @@ static int test_wolfSSL_set_alpn_protos(void)

#endif /* HAVE_ALPN_PROTOS_SUPPORT */

static int test_wolfSSL_DisableExtendedMasterSecret(void)
{
EXPECT_DECLS;
#if defined(HAVE_EXTENDED_MASTER) && !defined(NO_WOLFSSL_CLIENT) && \
!defined(NO_TLS)
WOLFSSL_CTX *ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
WOLFSSL *ssl = wolfSSL_new(ctx);

ExpectNotNull(ctx);
ExpectNotNull(ssl);

/* error cases */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_DisableExtendedMasterSecret(NULL));
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_DisableExtendedMasterSecret(NULL));

/* success cases */
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_DisableExtendedMasterSecret(ctx));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_DisableExtendedMasterSecret(ssl));

wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}

static int test_wolfSSL_wolfSSL_UseSecureRenegotiation(void)
{
EXPECT_DECLS;
Expand Down Expand Up @@ -95350,6 +95326,7 @@ TEST_CASE testCases[] = {
/* Uses Assert in handshake callback. */
TEST_DECL(test_wolfSSL_set_alpn_protos),
#endif
TEST_DECL(test_tls_ems_downgrade),
TEST_DECL(test_wolfSSL_DisableExtendedMasterSecret),
TEST_DECL(test_wolfSSL_wolfSSL_UseSecureRenegotiation),
TEST_DECL(test_wolfSSL_SCR_Reconnect),
Expand Down
2 changes: 2 additions & 0 deletions tests/api/include.am
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ tests_unit_test_SOURCES += tests/api/test_ascon.c
tests_unit_test_SOURCES += tests/api/test_mlkem.c
tests_unit_test_SOURCES += tests/api/test_dtls.c
tests_unit_test_SOURCES += tests/api/test_ocsp.c
tests_unit_test_SOURCES += tests/api/test_tls_ext.c
endif
EXTRA_DIST += tests/api/api.h
EXTRA_DIST += tests/api/test_md5.h
Expand All @@ -35,4 +36,5 @@ EXTRA_DIST += tests/api/test_dtls.h
EXTRA_DIST += tests/api/test_ocsp.h
EXTRA_DIST += tests/api/test_ocsp_test_blobs.h
EXTRA_DIST += tests/api/create_ocsp_test_blobs.py
EXTRA_DIST += tests/api/test_tls_ext.h

137 changes: 137 additions & 0 deletions tests/api/test_tls_ext.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/* test_tls_ems.c
*
* Copyright (C) 2006-2025 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#if !defined(WOLFSSL_USER_SETTINGS) && !defined(WOLFSSL_NO_OPTIONS_H)
#include <wolfssl/options.h>
#endif
#include <wolfssl/wolfcrypt/settings.h>

#ifdef NO_INLINE
#include <wolfssl/wolfcrypt/misc.h>
#else
#define WOLFSSL_MISC_INCLUDED
#include <wolfcrypt/src/misc.c>
#endif

#include <wolfssl/internal.h>
#include <tests/unit.h>
#include <tests/utils.h>
#include <tests/api/test_tls_ext.h>

int test_tls_ems_downgrade(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_TLS12) && \
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
defined(HAVE_SESSION_TICKET)
struct test_memio_ctx test_ctx;
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
WOLFSSL_SESSION* session = NULL;
/* TLS EMS extension in binary form */
const char ems_ext[] = { 0x00, 0x17, 0x00, 0x00 };
char data = 0;

XMEMSET(&test_ctx, 0, sizeof(test_ctx));

ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfTLS_client_method, wolfTLS_server_method), 0);

ExpectIntEQ(wolfSSL_connect(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);

/* Verify that the EMS extension is present in Client's message */
ExpectNotNull(mymemmem(test_ctx.s_buff, test_ctx.s_len,
ems_ext, sizeof(ems_ext)));

ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
ExpectIntEQ(wolfSSL_version(ssl_c), TLS1_3_VERSION);

/* Do a round of reads to exchange the ticket message */
ExpectIntEQ(wolfSSL_read(ssl_s, &data, sizeof(data)), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
ExpectIntEQ(wolfSSL_read(ssl_c, &data, sizeof(data)), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);

ExpectNotNull(session = wolfSSL_get1_session(ssl_c));
ExpectTrue(session->haveEMS);

wolfSSL_free(ssl_c);
ssl_c = NULL;
wolfSSL_free(ssl_s);
ssl_s = NULL;

ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfTLS_client_method, wolfTLS_server_method), 0);

/* Resuming the connection */
ExpectIntEQ(wolfSSL_set_session(ssl_c, session), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_connect(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);

/* Verify that the EMS extension is still present in the resumption CH
* even though we used TLS 1.3 */
ExpectNotNull(mymemmem(test_ctx.s_buff, test_ctx.s_len,
ems_ext, sizeof(ems_ext)));

ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
ExpectIntEQ(wolfSSL_version(ssl_c), TLS1_3_VERSION);

wolfSSL_SESSION_free(session);
wolfSSL_free(ssl_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_c);
wolfSSL_CTX_free(ctx_s);
#endif
return EXPECT_RESULT();
}


int test_wolfSSL_DisableExtendedMasterSecret(void)
{
EXPECT_DECLS;
#if defined(HAVE_EXTENDED_MASTER) && !defined(NO_WOLFSSL_CLIENT) && \
!defined(NO_TLS)
WOLFSSL_CTX *ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
WOLFSSL *ssl = wolfSSL_new(ctx);

ExpectNotNull(ctx);
ExpectNotNull(ssl);

/* error cases */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_DisableExtendedMasterSecret(NULL));
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_DisableExtendedMasterSecret(NULL));

/* success cases */
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_DisableExtendedMasterSecret(ctx));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_DisableExtendedMasterSecret(ssl));

wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
28 changes: 28 additions & 0 deletions tests/api/test_tls_ext.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* test_tls_ems.h
*
* Copyright (C) 2006-2025 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/

#ifndef TESTS_API_TEST_TLS_EMS_H
#define TESTS_API_TEST_TLS_EMS_H

int test_tls_ems_downgrade(void);
int test_wolfSSL_DisableExtendedMasterSecret(void);

#endif /* TESTS_API_TEST_TLS_EMS_H */
Loading