Skip to content
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
8 changes: 6 additions & 2 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -8166,6 +8166,8 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)

#ifdef HAVE_EXTENDED_MASTER
ssl->options.haveEMS = ctx->haveEMS;
ssl->options.disableEMS = ctx->disableEMS;
ssl->options.requireEMS = ctx->requireEMS;
#endif
ssl->options.useClientOrder = ctx->useClientOrder;
ssl->options.mutualAuth = ctx->mutualAuth;
Expand Down Expand Up @@ -28857,7 +28859,7 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e)
return "Initialize ctx mutex error";

case EXT_MASTER_SECRET_NEEDED_E:
return "Extended Master Secret must be enabled to resume EMS session";
return "Extended Master Secret required but not negotiated with peer";

case DTLS_POOL_SZ_E:
return "Maximum DTLS pool size exceeded";
Expand Down Expand Up @@ -40095,7 +40097,9 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
i += hashSigAlgoSz;
}
#ifdef HAVE_EXTENDED_MASTER
else if (extId == HELLO_EXT_EXTMS)
/* Honor a user request to disable EMS on the server by
* ignoring the peer's extension. */
else if (extId == HELLO_EXT_EXTMS && !ssl->options.disableEMS)
ssl->options.haveEMS = 1;
#endif
else
Expand Down
119 changes: 117 additions & 2 deletions src/ssl_api_ext.c
Original file line number Diff line number Diff line change
Expand Up @@ -1276,9 +1276,12 @@ int wolfSSL_set_SessionTicket_cb(WOLFSSL* ssl,


#ifdef HAVE_EXTENDED_MASTER
#ifndef NO_WOLFSSL_CLIENT

/* Disable the Extended Master Secret extension on the context.
*
* For a client this stops the extension being advertised. For a server this
* causes the peer's Extended Master Secret request to be ignored so that a
* standard master secret is negotiated.
*
* @param [in] ctx SSL/TLS context object.
* @return WOLFSSL_SUCCESS on success.
Expand All @@ -1290,12 +1293,19 @@ int wolfSSL_CTX_DisableExtendedMasterSecret(WOLFSSL_CTX* ctx)
return BAD_FUNC_ARG;

ctx->haveEMS = 0;
ctx->disableEMS = 1;
/* Disabling EMS is mutually exclusive with requiring it. */
ctx->requireEMS = 0;

return WOLFSSL_SUCCESS;
}


/* Disable the Extended Master Secret extension on the object.
*
* For a client this stops the extension being advertised. For a server this
* causes the peer's Extended Master Secret request to be ignored so that a
* standard master secret is negotiated.
*
* @param [in] ssl SSL/TLS object.
* @return WOLFSSL_SUCCESS on success.
Expand All @@ -1307,11 +1317,116 @@ int wolfSSL_DisableExtendedMasterSecret(WOLFSSL* ssl)
return BAD_FUNC_ARG;

ssl->options.haveEMS = 0;
ssl->options.disableEMS = 1;
/* Disabling EMS is mutually exclusive with requiring it. */
ssl->options.requireEMS = 0;

return WOLFSSL_SUCCESS;
}


/* Disable the standard (non-extended) master secret on the context.
*
* The Extended Master Secret extension (RFC 7627) becomes mandatory: if it is
* not negotiated with the peer the connection is aborted with
* EXT_MASTER_SECRET_NEEDED_E rather than falling back to a standard master
* secret. This only applies to TLS 1.2 and earlier; TLS 1.3 always uses a
* secure key schedule and is unaffected.
*
* @param [in] ctx SSL/TLS context object.
* @return WOLFSSL_SUCCESS on success.
* @return BAD_FUNC_ARG when ctx is NULL.
*/
int wolfSSL_CTX_DisableNormalMasterSecret(WOLFSSL_CTX* ctx)
{
if (ctx == NULL)
return BAD_FUNC_ARG;

ctx->requireEMS = 1;
/* Requiring EMS is mutually exclusive with disabling it. */
ctx->disableEMS = 0;
/* A client must advertise the extension for it to be negotiated. Undo any
* previous disable so the extension is offered. A server keeps its EMS
* state driven by the incoming ClientHello. */
if (ctx->method != NULL && ctx->method->side == WOLFSSL_CLIENT_END)
ctx->haveEMS = 1;

return WOLFSSL_SUCCESS;
}


/* Disable the standard (non-extended) master secret on the object.
*
* The Extended Master Secret extension (RFC 7627) becomes mandatory: if it is
* not negotiated with the peer the connection is aborted with
* EXT_MASTER_SECRET_NEEDED_E rather than falling back to a standard master
* secret. This only applies to TLS 1.2 and earlier; TLS 1.3 always uses a
* secure key schedule and is unaffected.
*
* @param [in] ssl SSL/TLS object.
* @return WOLFSSL_SUCCESS on success.
* @return BAD_FUNC_ARG when ssl is NULL.
*/
int wolfSSL_DisableNormalMasterSecret(WOLFSSL* ssl)
{
if (ssl == NULL)
return BAD_FUNC_ARG;

ssl->options.requireEMS = 1;
/* Requiring EMS is mutually exclusive with disabling it. */
ssl->options.disableEMS = 0;
/* A client must advertise the extension for it to be negotiated. Undo any
* previous disable so the extension is offered. A server keeps its EMS
* state driven by the incoming ClientHello. */
if (ssl->options.side == WOLFSSL_CLIENT_END)
ssl->options.haveEMS = 1;

return WOLFSSL_SUCCESS;
}


/* Re-enable the standard (non-extended) master secret on the context.
*
* Undoes wolfSSL_CTX_DisableNormalMasterSecret so that a standard master
* secret is once again acceptable when the Extended Master Secret extension
* (RFC 7627) is not negotiated. Extended Master Secret support itself is left
* unchanged.
*
* @param [in] ctx SSL/TLS context object.
* @return WOLFSSL_SUCCESS on success.
* @return BAD_FUNC_ARG when ctx is NULL.
*/
int wolfSSL_CTX_EnableNormalMasterSecret(WOLFSSL_CTX* ctx)
{
if (ctx == NULL)
return BAD_FUNC_ARG;

ctx->requireEMS = 0;

return WOLFSSL_SUCCESS;
}


/* Re-enable the standard (non-extended) master secret on the object.
*
* Undoes wolfSSL_DisableNormalMasterSecret so that a standard master secret is
* once again acceptable when the Extended Master Secret extension (RFC 7627)
* is not negotiated. Extended Master Secret support itself is left unchanged.
*
* @param [in] ssl SSL/TLS object.
* @return WOLFSSL_SUCCESS on success.
* @return BAD_FUNC_ARG when ssl is NULL.
*/
int wolfSSL_EnableNormalMasterSecret(WOLFSSL* ssl)
{
if (ssl == NULL)
return BAD_FUNC_ARG;

ssl->options.requireEMS = 0;

return WOLFSSL_SUCCESS;
}

#endif
#endif

#endif /* !NO_TLS */
Expand Down
23 changes: 20 additions & 3 deletions src/tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,19 @@ int MakeTlsMasterSecret(WOLFSSL* ssl)
{
int ret;

#ifdef HAVE_EXTENDED_MASTER
/* The user disabled the standard master secret and requires the Extended
* Master Secret extension (RFC 7627). If it was not negotiated with the
* peer, abort rather than derive a standard master secret. Only reachable
* for TLS 1.2 and earlier; TLS 1.3 uses a separate key schedule. */
if (ssl->options.requireEMS && !ssl->options.haveEMS) {
WOLFSSL_MSG("EMS required but not negotiated with peer");
SendAlert(ssl, alert_fatal, handshake_failure);
WOLFSSL_ERROR_VERBOSE(EXT_MASTER_SECRET_NEEDED_E);
return EXT_MASTER_SECRET_NEEDED_E;
}
#endif

#if defined(WOLFSSL_SNIFFER) && defined(WOLFSSL_SNIFFER_KEYLOGFILE)
/* If this is called from a sniffer session with keylog file support, obtain
* the master secret from the callback */
Expand Down Expand Up @@ -18285,11 +18298,15 @@ WOLFSSL_TEST_VIS int TLSX_Parse(WOLFSSL* ssl, const byte* input, word16 length,
if (size != 0)
return BUFFER_ERROR;

/* Honor a user request to disable EMS by ignoring the peer's
* extension rather than enabling it. */
if (!ssl->options.disableEMS) {
#ifndef NO_WOLFSSL_SERVER
if (isRequest)
ssl->options.haveEMS = 1;
if (isRequest)
ssl->options.haveEMS = 1;
#endif
pendingEMS = 1;
pendingEMS = 1;
}
break;
#endif

Expand Down
3 changes: 3 additions & 0 deletions tests/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -38104,6 +38104,8 @@ TEST_CASE testCases[] = {
TEST_DECL(test_tls_ems_downgrade),
TEST_DECL(test_tls_ems_resumption_downgrade),
TEST_DECL(test_tls_ems_resumption_server_downgrade),
TEST_DECL(test_tls_ems_server_disable),
TEST_DECL(test_tls_require_ems),
TEST_DECL(test_tls12_chacha20_poly1305_bad_tag),
TEST_DECL(test_tls13_null_cipher_bad_hmac),
TEST_DECL(test_scr_verify_data_mismatch),
Expand All @@ -38112,6 +38114,7 @@ TEST_CASE testCases[] = {
TEST_DECL(test_tls13_hrr_cipher_suite_mismatch),
TEST_DECL(test_tls13_ticket_age_out_of_window),
TEST_DECL(test_wolfSSL_DisableExtendedMasterSecret),
TEST_DECL(test_wolfSSL_DisableNormalMasterSecret),
TEST_DECL(test_certificate_authorities_certificate_request),
TEST_DECL(test_certificate_authorities_client_hello),
TEST_DECL(test_TLSX_TCA_Find),
Expand Down
Loading
Loading