diff --git a/src/internal.c b/src/internal.c index 553bf96c8..094ae66f0 100644 --- a/src/internal.c +++ b/src/internal.c @@ -24347,13 +24347,25 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, return ret; } } - ret = MatchSuite(ssl, &clSuites); -#if defined(HAVE_FFDHE) && defined(HAVE_SUPPORTED_CURVES) - if (ret == 0 && (ssl->specs.kea == diffie_hellman_kea || - ssl->specs.kea == dhe_psk_kea)) { +#ifdef HAVE_TLS_EXTENSIONS + #if defined(HAVE_FFDHE) && defined(HAVE_SUPPORTED_CURVES) + if (TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS) != NULL) { + /* Set FFDHE parameters or clear DHE parameters if FFDH parameters + * present and no matches in the server's list. */ ret = TLSX_SupportedFFDHE_Set(ssl); + if (ret != 0) + return ret; } + #endif +#endif + + ret = MatchSuite(ssl, &clSuites); +#ifdef WOLFSSL_EXTRA_ALERTS + if (ret == BUFFER_ERROR) + SendAlert(ssl, alert_fatal, decode_error); + else if (ret < 0) + SendAlert(ssl, alert_fatal, handshake_failure); #endif #ifdef HAVE_SECURE_RENEGOTIATION diff --git a/src/tls.c b/src/tls.c index 918ea3801..9722baea9 100644 --- a/src/tls.c +++ b/src/tls.c @@ -4005,12 +4005,35 @@ int TLSX_SupportedFFDHE_Set(WOLFSSL* ssl) SupportedCurve* clientGroup; SupportedCurve* group; const DhParams* params; + int found = 0; extension = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS); /* May be doing PSK with no key exchange. */ if (extension == NULL) return 0; clientGroup = (SupportedCurve*)extension->data; + for (group = clientGroup; group != NULL; group = group->next) { + if (group->name >= MIN_FFHDE_GROUP && group->name <= MAX_FFHDE_GROUP) { + found = 1; + break; + } + } + if (!found) + return 0; + + if (ssl->buffers.serverDH_P.buffer && ssl->buffers.weOwnDH) { + XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, + DYNAMIC_TYPE_PUBLIC_KEY); + } + if (ssl->buffers.serverDH_G.buffer && ssl->buffers.weOwnDH) { + XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap, + DYNAMIC_TYPE_PUBLIC_KEY); + } + ssl->buffers.serverDH_P.buffer = NULL; + ssl->buffers.serverDH_G.buffer = NULL; + ssl->buffers.weOwnDH = 0; + ssl->options.haveDH = 0; + if ((ret = TLSX_PopulateSupportedGroups(ssl, &priority)) != WOLFSSL_SUCCESS) return ret; @@ -4019,68 +4042,54 @@ int TLSX_SupportedFFDHE_Set(WOLFSSL* ssl) ext = TLSX_Find(priority, TLSX_SUPPORTED_GROUPS); serverGroup = (SupportedCurve*)ext->data; - while (serverGroup != NULL) { - if ((serverGroup->name & NAMED_DH_MASK) == NAMED_DH_MASK) { - group = clientGroup; - while (group != NULL) { - if (serverGroup->name == group->name) { - switch (serverGroup->name) { - #ifdef HAVE_FFDHE_2048 - case WOLFSSL_FFDHE_2048: - params = wc_Dh_ffdhe2048_Get(); - break; - #endif - #ifdef HAVE_FFDHE_3072 - case WOLFSSL_FFDHE_3072: - params = wc_Dh_ffdhe3072_Get(); - break; - #endif - #ifdef HAVE_FFDHE_4096 - case WOLFSSL_FFDHE_4096: - params = wc_Dh_ffdhe4096_Get(); - break; - #endif - #ifdef HAVE_FFDHE_6144 - case WOLFSSL_FFDHE_6144: - params = wc_Dh_ffdhe6144_Get(); - break; - #endif - #ifdef HAVE_FFDHE_8192 - case WOLFSSL_FFDHE_8192: - params = wc_Dh_ffdhe8192_Get(); - break; - #endif - default: - return BAD_FUNC_ARG; - } - if (params->p_len >= ssl->options.minDhKeySz && - params->p_len <= ssl->options.maxDhKeySz) { - break; - } - } + for (; serverGroup != NULL; serverGroup = serverGroup->next) { + if ((serverGroup->name & NAMED_DH_MASK) != NAMED_DH_MASK) + continue; - group = group->next; + for (group = clientGroup; group != NULL; group = group->next) { + if (serverGroup->name != group->name) + continue; + + switch (serverGroup->name) { + #ifdef HAVE_FFDHE_2048 + case WOLFSSL_FFDHE_2048: + params = wc_Dh_ffdhe2048_Get(); + break; + #endif + #ifdef HAVE_FFDHE_3072 + case WOLFSSL_FFDHE_3072: + params = wc_Dh_ffdhe3072_Get(); + break; + #endif + #ifdef HAVE_FFDHE_4096 + case WOLFSSL_FFDHE_4096: + params = wc_Dh_ffdhe4096_Get(); + break; + #endif + #ifdef HAVE_FFDHE_6144 + case WOLFSSL_FFDHE_6144: + params = wc_Dh_ffdhe6144_Get(); + break; + #endif + #ifdef HAVE_FFDHE_8192 + case WOLFSSL_FFDHE_8192: + params = wc_Dh_ffdhe8192_Get(); + break; + #endif + default: + return BAD_FUNC_ARG; } - if (group != NULL && serverGroup->name == group->name) + if (params->p_len >= ssl->options.minDhKeySz && + params->p_len <= ssl->options.maxDhKeySz) { break; + } } - serverGroup = serverGroup->next; + + if (group != NULL && serverGroup->name == group->name) + break; } if (serverGroup) { - - if (ssl->buffers.serverDH_P.buffer && ssl->buffers.weOwnDH) { - XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, - DYNAMIC_TYPE_PUBLIC_KEY); - ssl->buffers.serverDH_P.buffer = NULL; - } - if (ssl->buffers.serverDH_G.buffer && ssl->buffers.weOwnDH) { - XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap, - DYNAMIC_TYPE_PUBLIC_KEY); - ssl->buffers.serverDH_G.buffer = NULL; - } - - ssl->buffers.weOwnDH = 0; ssl->buffers.serverDH_P.buffer = (unsigned char *)params->p; ssl->buffers.serverDH_P.length = params->p_len; ssl->buffers.serverDH_G.buffer = (unsigned char *)params->g; @@ -4090,6 +4099,7 @@ int TLSX_SupportedFFDHE_Set(WOLFSSL* ssl) !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) ssl->options.dhDoKeyTest = 0; #endif + ssl->options.haveDH = 1; } TLSX_FreeAll(priority, ssl->heap); diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 8bd0d561a..49330e865 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1228,6 +1228,8 @@ enum Misc { MAX_DH_SIZE = MAX_DHKEY_SZ+1, /* Max size plus possible leading 0 */ NAMED_DH_MASK = 0x100, /* Named group mask for DH parameters */ + MIN_FFHDE_GROUP = 0x100, /* Named group minimum for FFDHE parameters */ + MAX_FFHDE_GROUP = 0x1FF, /* Named group maximum for FFDHE parameters */ SESSION_HINT_SZ = 4, /* session timeout hint */ SESSION_ADD_SZ = 4, /* session age add */ TICKET_NONCE_LEN_SZ = 1, /* Ticket nonce length size */