Skip to content

Commit 94d1bb7

Browse files
committed
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).
1 parent a8696d0 commit 94d1bb7

3 files changed

Lines changed: 36 additions & 4 deletions

File tree

src/internal.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18769,6 +18769,8 @@ int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1876918769
ssl->options.acceptState = ACCEPT_FIRST_REPLY_DONE;
1877018770
ssl->options.handShakeState = NULL_STATE;
1877118771
ssl->secure_renegotiation->cache_status = SCR_CACHE_NEEDED;
18772+
/* Reset for the renegotiation_info presence check below. */
18773+
ssl->secure_renegotiation->renegInfoSeen = 0;
1877218774

1877318775
ret = InitHandshakeHashes(ssl);
1877418776
if (ret != 0)
@@ -38658,6 +38660,17 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
3865838660
0) {
3865938661
TLSX* extension;
3866038662

38663+
#ifdef HAVE_SECURE_RENEGOTIATION
38664+
/* SCSV not allowed on a renegotiation ClientHello (RFC 5746 3.5). */
38665+
if (ssl->secure_renegotiation &&
38666+
ssl->secure_renegotiation->enabled &&
38667+
ssl->secure_renegotiation->verifySet) {
38668+
WOLFSSL_MSG("SCSV received on renegotiation ClientHello");
38669+
SendAlert(ssl, alert_fatal, handshake_failure);
38670+
ret = SECURE_RENEGOTIATION_E;
38671+
goto out;
38672+
}
38673+
#endif
3866138674
/* check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV suite */
3866238675
ret = TLSX_AddEmptyRenegotiationInfo(&ssl->extensions, ssl->heap);
3866338676
if (ret != WOLFSSL_SUCCESS) {
@@ -38888,6 +38901,19 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
3888838901
*inOutIdx = begin + helloSz; /* skip extensions */
3888938902
}
3889038903

38904+
#ifdef HAVE_SECURE_RENEGOTIATION
38905+
/* renegotiation_info MUST be present on a renegotiation (RFC 5746 3.7). */
38906+
if (ssl->secure_renegotiation &&
38907+
ssl->secure_renegotiation->enabled &&
38908+
ssl->secure_renegotiation->verifySet &&
38909+
!ssl->secure_renegotiation->renegInfoSeen) {
38910+
WOLFSSL_MSG("Renegotiation ClientHello missing renegotiation_info");
38911+
SendAlert(ssl, alert_fatal, handshake_failure);
38912+
ret = SECURE_RENEGOTIATION_E;
38913+
goto out;
38914+
}
38915+
#endif /* HAVE_SECURE_RENEGOTIATION */
38916+
3889138917
#ifdef WOLFSSL_DTLS_CID
3889238918
if (ssl->options.useDtlsCID)
3889338919
DtlsCIDOnExtensionsParsed(ssl);

src/tls.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6142,6 +6142,9 @@ static int TLSX_SecureRenegotiation_Parse(WOLFSSL* ssl, const byte* input,
61426142
if (ret == WOLFSSL_SUCCESS)
61436143
ret = 0;
61446144
}
6145+
/* renegotiation_info seen (checked by DoClientHello, RFC 5746 3.7) */
6146+
if (ssl->secure_renegotiation != NULL)
6147+
ssl->secure_renegotiation->renegInfoSeen = 1;
61456148
if (ret != 0 && ret != WC_NO_ERR_TRACE(SECURE_RENEGOTIATION_E)) {
61466149
}
61476150
else if (ssl->secure_renegotiation == NULL) {

wolfssl/internal.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3493,13 +3493,16 @@ enum key_cache_state {
34933493

34943494
/* Additional Connection State according to rfc5746 section 3.1 */
34953495
typedef struct SecureRenegotiation {
3496-
byte enabled; /* secure_renegotiation flag in rfc */
3497-
byte verifySet;
3498-
byte startScr; /* server requested client to start scr */
3496+
/* Single-bit flags grouped together so they pack into one storage unit. */
3497+
WC_BITFIELD enabled:1; /* secure_renegotiation flag in rfc */
3498+
WC_BITFIELD verifySet:1;
3499+
WC_BITFIELD startScr:1; /* server requested client to start scr */
3500+
WC_BITFIELD renegInfoSeen:1; /* renegotiation_info ext seen this
3501+
* handshake (RFC 5746 3.7) */
3502+
WC_BITFIELD subject_hash_set:1; /* if peer cert hash is set */
34993503
enum key_cache_state cache_status; /* track key cache state */
35003504
byte client_verify_data[TLS_FINISHED_SZ]; /* cached */
35013505
byte server_verify_data[TLS_FINISHED_SZ]; /* cached */
3502-
byte subject_hash_set; /* if peer cert hash is set */
35033506
byte subject_hash[KEYID_SIZE]; /* peer cert hash */
35043507
Keys tmp_keys; /* can't overwrite real keys yet */
35053508
} SecureRenegotiation;

0 commit comments

Comments
 (0)