@@ -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+
50455046int 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;
0 commit comments