Skip to content

Commit 761f0f1

Browse files
committed
Simplify TLSX_SupportedCurve_Parse
Server only uses curves that are supported by both the client and the server. If no common groups are found, the connection will fail in TLS 1.2 and below. In TLS 1.3, HRR may still be used to resolve the group mismatch.
1 parent a160ba1 commit 761f0f1

3 files changed

Lines changed: 63 additions & 63 deletions

File tree

src/tls.c

Lines changed: 56 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -5042,12 +5042,14 @@ static word16 TLSX_PointFormat_Write(PointFormat* list, byte* output)
50425042

50435043
#if !defined(NO_WOLFSSL_SERVER) || (defined(WOLFSSL_TLS13) && \
50445044
!defined(WOLFSSL_NO_SERVER_GROUPS_EXT))
5045+
50455046
int TLSX_SupportedCurve_Parse(const WOLFSSL* ssl, const byte* input,
50465047
word16 length, byte isRequest, TLSX** extensions)
50475048
{
50485049
word16 offset;
50495050
word16 name;
50505051
int ret;
5052+
TLSX* extension;
50515053

50525054
if(!isRequest && !IsAtLeastTLSv1_3(ssl->version)) {
50535055
#ifdef WOLFSSL_ALLOW_SERVER_SC_EXT
@@ -5066,74 +5068,47 @@ int TLSX_SupportedCurve_Parse(const WOLFSSL* ssl, const byte* input,
50665068
if (offset == length)
50675069
return 0;
50685070

5069-
#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_SERVER_GROUPS_EXT)
5070-
if (!isRequest) {
5071-
TLSX* extension;
5072-
SupportedCurve* curve;
5073-
extension = TLSX_Find(*extensions, TLSX_SUPPORTED_GROUPS);
5074-
if (extension != NULL) {
5075-
/* Replace client list with server list of supported groups. */
5076-
curve = (SupportedCurve*)extension->data;
5077-
extension->data = NULL;
5078-
TLSX_SupportedCurve_FreeAll(curve, ssl->heap);
5079-
ato16(input + offset, &name);
5080-
offset += OPAQUE16_LEN;
5081-
ret = TLSX_SupportedCurve_New(&curve, name, ssl->heap);
5082-
if (ret != 0)
5083-
return ret; /* throw error */
5084-
extension->data = (void*)curve;
5085-
}
5086-
}
5087-
#endif
5088-
if(!IsAtLeastTLSv1_3(ssl->version)) {
5089-
TLSX* existingExt;
5090-
TLSX* newExt = NULL;
5091-
SupportedCurve* intersectionCurve;
5092-
5093-
existingExt = TLSX_Find(*extensions, TLSX_SUPPORTED_GROUPS);
5071+
extension = TLSX_Find(*extensions, TLSX_SUPPORTED_GROUPS);
5072+
if (extension == NULL) {
5073+
/* Just accept what the peer wants to use */
50945074
for (; offset < length; offset += OPAQUE16_LEN) {
50955075
ato16(input + offset, &name);
5096-
if (existingExt != NULL) {
5097-
/* Check if this curve exists in our current list */
5098-
intersectionCurve = (SupportedCurve*)existingExt->data;
5099-
while (intersectionCurve != NULL) {
5100-
if (intersectionCurve->name == name) {
5101-
ret = TLSX_UseSupportedCurve(&newExt, name, ssl->heap);
5102-
if (ret != WOLFSSL_SUCCESS && ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
5103-
return ret;
5104-
break;
5105-
}
5106-
intersectionCurve = intersectionCurve->next;
5107-
}
5108-
}
5109-
else {
5110-
ret = TLSX_UseSupportedCurve(extensions, name, ssl->heap);
5111-
if (ret != WOLFSSL_SUCCESS && ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
5112-
return ret;
5113-
}
5076+
5077+
ret = TLSX_UseSupportedCurve(extensions, name, ssl->heap);
51145078
/* If it is BAD_FUNC_ARG then it is a group we do not support, but
51155079
* that is fine. */
5116-
}
5117-
if (existingExt != NULL) {
5118-
if (newExt == NULL){
5119-
return ECC_CURVE_ERROR;
5080+
if (ret != WOLFSSL_SUCCESS &&
5081+
ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) {
5082+
return ret;
51205083
}
5121-
/* Replace existing extension data with intersection */
5122-
intersectionCurve = (SupportedCurve*)existingExt->data;
5123-
TLSX_SupportedCurve_FreeAll(intersectionCurve, ssl->heap);
5124-
existingExt->data = newExt->data;
51255084
}
5126-
}else{
5085+
}
5086+
else {
5087+
/* Find the intersection with what the user has set */
5088+
SupportedCurve* commonCurves = NULL;
51275089
for (; offset < length; offset += OPAQUE16_LEN) {
5090+
SupportedCurve* foundCurve = (SupportedCurve*)extension->data;
51285091
ato16(input + offset, &name);
51295092

5130-
ret = TLSX_UseSupportedCurve(extensions, name, ssl->heap);
5131-
/* If it is BAD_FUNC_ARG then it is a group we do not support, but
5132-
* that is fine. */
5133-
if (ret != WOLFSSL_SUCCESS && ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) {
5134-
return ret;
5093+
while (foundCurve != NULL && foundCurve->name != name)
5094+
foundCurve = foundCurve->next;
5095+
5096+
if (foundCurve != NULL) {
5097+
ret = commonCurves == NULL ?
5098+
TLSX_SupportedCurve_New(&commonCurves, name, ssl->heap) :
5099+
TLSX_SupportedCurve_Append(commonCurves, name, ssl->heap);
5100+
if (ret != 0)
5101+
return ret;
51355102
}
51365103
}
5104+
/* If no common curves return error. In TLS 1.3 we can still try to save
5105+
* this by using HRR. */
5106+
if (commonCurves == NULL && !IsAtLeastTLSv1_3(ssl->version))
5107+
return ECC_CURVE_ERROR;
5108+
/* Now swap out the curves in the extension */
5109+
TLSX_SupportedCurve_FreeAll((SupportedCurve*)extension->data,
5110+
ssl->heap);
5111+
extension->data = commonCurves;
51375112
}
51385113

51395114
return 0;
@@ -10828,15 +10803,17 @@ int TLSX_KeyShare_SetSupported(const WOLFSSL* ssl, TLSX** extensions)
1082810803
TLSX* extension;
1082910804
SupportedCurve* curve = NULL;
1083010805
SupportedCurve* preferredCurve = NULL;
10806+
word16 name = WOLFSSL_NAMED_GROUP_INVALID;
1083110807
KeyShareEntry* kse = NULL;
1083210808
int preferredRank = WOLFSSL_MAX_GROUP_COUNT;
1083310809
int rank;
1083410810

1083510811
extension = TLSX_Find(*extensions, TLSX_SUPPORTED_GROUPS);
1083610812
if (extension != NULL)
1083710813
curve = (SupportedCurve*)extension->data;
10838-
/* Use server's preference order. */
1083910814
for (; curve != NULL; curve = curve->next) {
10815+
/* Use server's preference order. Common group was found but key share
10816+
* was missing */
1084010817
if (!TLSX_IsGroupSupported(curve->name))
1084110818
continue;
1084210819
if (wolfSSL_curve_is_disabled(ssl, curve->name))
@@ -10853,8 +10830,26 @@ int TLSX_KeyShare_SetSupported(const WOLFSSL* ssl, TLSX** extensions)
1085310830
curve = preferredCurve;
1085410831

1085510832
if (curve == NULL) {
10856-
WOLFSSL_ERROR_VERBOSE(BAD_KEY_SHARE_DATA);
10857-
return BAD_KEY_SHARE_DATA;
10833+
byte i;
10834+
/* Fallback to user selected group */
10835+
preferredRank = WOLFSSL_MAX_GROUP_COUNT;
10836+
for (i = 0; i < ssl->numGroups; i++) {
10837+
rank = TLSX_KeyShare_GroupRank(ssl, ssl->group[i]);
10838+
if (rank == -1)
10839+
continue;
10840+
if (rank < preferredRank) {
10841+
name = ssl->group[i];
10842+
preferredRank = rank;
10843+
}
10844+
}
10845+
if (name == WOLFSSL_NAMED_GROUP_INVALID) {
10846+
/* No group selected or specified by the server */
10847+
WOLFSSL_ERROR_VERBOSE(BAD_KEY_SHARE_DATA);
10848+
return BAD_KEY_SHARE_DATA;
10849+
}
10850+
}
10851+
else {
10852+
name = curve->name;
1085810853
}
1085910854

1086010855
#ifdef WOLFSSL_ASYNC_CRYPT
@@ -10878,7 +10873,7 @@ int TLSX_KeyShare_SetSupported(const WOLFSSL* ssl, TLSX** extensions)
1087810873
/* Extension got pushed to head */
1087910874
extension = *extensions;
1088010875
/* Push the selected curve */
10881-
ret = TLSX_KeyShare_New((KeyShareEntry**)&extension->data, curve->name,
10876+
ret = TLSX_KeyShare_New((KeyShareEntry**)&extension->data, name,
1088210877
ssl->heap, &kse);
1088310878
if (ret != 0)
1088410879
return ret;

tests/api.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30634,11 +30634,16 @@ static int test_wolfSSL_curves_mismatch(void)
3063430634
} test_params[] = {
3063530635
#ifdef WOLFSSL_TLS13
3063630636
{wolfTLSv1_3_client_method, wolfTLSv1_3_server_method, "TLS 1.3",
30637-
WC_NO_ERR_TRACE(FATAL_ERROR), WC_NO_ERR_TRACE(BAD_KEY_SHARE_DATA)},
30637+
/* Client gets error because server will attempt HRR */
30638+
WC_NO_ERR_TRACE(BAD_KEY_SHARE_DATA),
30639+
WC_NO_ERR_TRACE(FATAL_ERROR)
30640+
},
3063830641
#endif
3063930642
#ifndef WOLFSSL_NO_TLS12
3064030643
{wolfTLSv1_2_client_method, wolfTLSv1_2_server_method, "TLS 1.2",
3064130644
WC_NO_ERR_TRACE(FATAL_ERROR),
30645+
/* Server gets error because <=1.2 doesn't have a mechanism
30646+
* to negotiate curves. */
3064230647
#ifdef OPENSSL_EXTRA
3064330648
WC_NO_ERR_TRACE(WOLFSSL_ERROR_SYSCALL)
3064430649
#else

tests/api/test_tls.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ int test_tls12_curve_intersection(void) {
188188
ret = wolfSSL_get_error(ssl_s, WOLFSSL_FATAL_ERROR);
189189

190190
// Fix: Use proper constant or define HANDSHAKE_FAILURE
191-
ExpectTrue(ret == ECC_CURVE_ERROR);
191+
ExpectTrue(ret == WC_NO_ERR_TRACE(ECC_CURVE_ERROR));
192192

193193
wolfSSL_free(ssl_c);
194194
wolfSSL_free(ssl_s);

0 commit comments

Comments
 (0)