mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-08 08:40:49 +02:00
F-5810: require renegotiation_info on renegotiation ClientHello
The server validated client_verify_data only inside TLSX_SecureRenegotiation_Parse, which never runs when the renegotiation_info extension is absent, so a renegotiation ClientHello that omitted it was never checked. Track a per-handshake renegInfoSeen flag and, after parsing the renegotiation ClientHello extensions, abort with handshake_failure if the extension was absent (RFC 5746 3.7). Also reject an SCSV received during renegotiation (RFC 5746 3.5).
This commit is contained in:
@@ -18811,6 +18811,8 @@ int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
ssl->options.acceptState = ACCEPT_FIRST_REPLY_DONE;
|
||||
ssl->options.handShakeState = NULL_STATE;
|
||||
ssl->secure_renegotiation->cache_status = SCR_CACHE_NEEDED;
|
||||
/* Reset for the renegotiation_info presence check below. */
|
||||
ssl->secure_renegotiation->renegInfoSeen = 0;
|
||||
|
||||
ret = InitHandshakeHashes(ssl);
|
||||
if (ret != 0)
|
||||
@@ -38745,6 +38747,17 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
|
||||
0) {
|
||||
TLSX* extension;
|
||||
|
||||
#ifdef HAVE_SECURE_RENEGOTIATION
|
||||
/* SCSV not allowed on a renegotiation ClientHello (RFC 5746 3.5). */
|
||||
if (ssl->secure_renegotiation &&
|
||||
ssl->secure_renegotiation->enabled &&
|
||||
ssl->secure_renegotiation->verifySet) {
|
||||
WOLFSSL_MSG("SCSV received on renegotiation ClientHello");
|
||||
SendAlert(ssl, alert_fatal, handshake_failure);
|
||||
ret = SECURE_RENEGOTIATION_E;
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
/* check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV suite */
|
||||
ret = TLSX_AddEmptyRenegotiationInfo(&ssl->extensions, ssl->heap);
|
||||
if (ret != WOLFSSL_SUCCESS) {
|
||||
@@ -38989,6 +39002,19 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
|
||||
*inOutIdx = begin + helloSz; /* skip extensions */
|
||||
}
|
||||
|
||||
#ifdef HAVE_SECURE_RENEGOTIATION
|
||||
/* renegotiation_info MUST be present on a renegotiation (RFC 5746 3.7). */
|
||||
if (ssl->secure_renegotiation &&
|
||||
ssl->secure_renegotiation->enabled &&
|
||||
ssl->secure_renegotiation->verifySet &&
|
||||
!ssl->secure_renegotiation->renegInfoSeen) {
|
||||
WOLFSSL_MSG("Renegotiation ClientHello missing renegotiation_info");
|
||||
SendAlert(ssl, alert_fatal, handshake_failure);
|
||||
ret = SECURE_RENEGOTIATION_E;
|
||||
goto out;
|
||||
}
|
||||
#endif /* HAVE_SECURE_RENEGOTIATION */
|
||||
|
||||
#ifdef WOLFSSL_DTLS_CID
|
||||
if (ssl->options.useDtlsCID)
|
||||
DtlsCIDOnExtensionsParsed(ssl);
|
||||
|
||||
@@ -6234,6 +6234,9 @@ static int TLSX_SecureRenegotiation_Parse(WOLFSSL* ssl, const byte* input,
|
||||
if (ret == WOLFSSL_SUCCESS)
|
||||
ret = 0;
|
||||
}
|
||||
/* renegotiation_info seen (checked by DoClientHello, RFC 5746 3.7) */
|
||||
if (ssl->secure_renegotiation != NULL)
|
||||
ssl->secure_renegotiation->renegInfoSeen = 1;
|
||||
if (ret != 0 && ret != WC_NO_ERR_TRACE(SECURE_RENEGOTIATION_E)) {
|
||||
}
|
||||
else if (ssl->secure_renegotiation == NULL) {
|
||||
|
||||
+7
-4
@@ -3498,13 +3498,16 @@ enum key_cache_state {
|
||||
|
||||
/* Additional Connection State according to rfc5746 section 3.1 */
|
||||
typedef struct SecureRenegotiation {
|
||||
byte enabled; /* secure_renegotiation flag in rfc */
|
||||
byte verifySet;
|
||||
byte startScr; /* server requested client to start scr */
|
||||
/* Single-bit flags grouped together so they pack into one storage unit. */
|
||||
WC_BITFIELD enabled:1; /* secure_renegotiation flag in rfc */
|
||||
WC_BITFIELD verifySet:1;
|
||||
WC_BITFIELD startScr:1; /* server requested client to start scr */
|
||||
WC_BITFIELD renegInfoSeen:1; /* renegotiation_info ext seen this
|
||||
* handshake (RFC 5746 3.7) */
|
||||
WC_BITFIELD subject_hash_set:1; /* if peer cert hash is set */
|
||||
enum key_cache_state cache_status; /* track key cache state */
|
||||
byte client_verify_data[TLS_FINISHED_SZ]; /* cached */
|
||||
byte server_verify_data[TLS_FINISHED_SZ]; /* cached */
|
||||
byte subject_hash_set; /* if peer cert hash is set */
|
||||
byte subject_hash[KEYID_SIZE]; /* peer cert hash */
|
||||
Keys tmp_keys; /* can't overwrite real keys yet */
|
||||
} SecureRenegotiation;
|
||||
|
||||
Reference in New Issue
Block a user