Fix group tuple handling in DEFAULT expansion
Also fine-tune docs and add tests. Fixes: #30109 Fixes: CVE-2026-2673 Reviewed-by: Tim Hudson <tjh@openssl.org> Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> MergeDate: Wed Feb 25 11:08:03 2026 (Merged from https://github.com/openssl/openssl/pull/30113)
This commit is contained in:
parent
2af8d3b640
commit
9efd7e9e98
3 changed files with 231 additions and 120 deletions
|
|
@ -40,13 +40,13 @@ SSL_get1_curves, SSL_get_shared_curve, SSL_CTX_get0_implemented_groups
|
|||
|
||||
For all of the functions below that set the supported groups there must be at
|
||||
least one group in the list. A number of these functions identify groups via a
|
||||
unique integer NID value. However, support for some groups may be added by
|
||||
external providers. In this case there will be no NID assigned for the group.
|
||||
unique integer B<NID> value. However, support for some groups may be added by
|
||||
external providers. In this case there will be no B<NID> assigned for the group.
|
||||
When setting such groups applications should use the "list" form of these
|
||||
functions (i.e. SSL_CTX_set1_groups_list() and SSL_set1_groups_list()).
|
||||
|
||||
SSL_CTX_set1_groups() sets the supported groups for B<ctx> to B<glistlen>
|
||||
groups in the array B<glist>. The array consist of all NIDs of supported groups.
|
||||
groups in the array B<glist>. The array consist of all B<NIDs> of supported groups.
|
||||
The supported groups for B<TLSv1.3> include:
|
||||
B<NID_X9_62_prime256v1>,
|
||||
B<NID_secp384r1>,
|
||||
|
|
@ -73,20 +73,27 @@ B<SSL_OP_SERVER_PREFERENCE> is set, the order of the elements in the
|
|||
array determines the selected group. Otherwise, the order is ignored and the
|
||||
client's order determines the selection.
|
||||
|
||||
For a TLS 1.3 server, the groups determine the selected group, but
|
||||
selection is more complex. A TLS 1.3 client sends both a group list as well as a
|
||||
predicted subset of groups. Choosing a group outside the predicted subset incurs
|
||||
an extra roundtrip. However, in some situations, the most preferred group may
|
||||
not be predicted. OpenSSL considers all supported groups in I<clist> to be comparable
|
||||
in security and prioritizes avoiding roundtrips above either client or server
|
||||
preference order. If an application uses an external provider to extend OpenSSL
|
||||
with, e.g., a post-quantum algorithm, this behavior may allow a network attacker
|
||||
to downgrade connections to a weaker algorithm. It is therefore recommended
|
||||
to use SSL_CTX_set1_groups_list() with the ability to specify group tuples.
|
||||
For a TLS 1.3 server, the groups determine the selected group, but selection is
|
||||
more complex.
|
||||
A TLS 1.3 client sends both a group list and predicted keyshares for a subset
|
||||
of groups.
|
||||
A server choosing a group outside the client's predicted subset incurs an extra
|
||||
roundtrip.
|
||||
However, in some situations, the most preferred group may not be predicted.
|
||||
|
||||
When groups are specified via SSL_CTX_set1_groups() as a list of B<NID>
|
||||
values, OpenSSL considers all supported groups in I<clist> to be comparable in
|
||||
security and prioritises avoiding roundtrips above either client or server
|
||||
preference order.
|
||||
If an application uses an external provider to extend OpenSSL with, e.g., a
|
||||
post-quantum algorithm, this behavior may allow a network attacker to downgrade
|
||||
connections to a weaker algorithm.
|
||||
It is therefore recommended to use SSL_CTX_set1_groups_list() instead, making
|
||||
it possible to specify group tuples as described below.
|
||||
|
||||
SSL_CTX_set1_groups_list() sets the supported groups for B<ctx> to
|
||||
string I<list>. In contrast to SSL_CTX_set1_groups(), the names of the
|
||||
groups, rather than their NIDs, are used.
|
||||
groups, rather than their B<NIDs>, are used.
|
||||
|
||||
The commands below list the available groups for TLS 1.2 and TLS 1.3,
|
||||
respectively:
|
||||
|
|
@ -102,30 +109,72 @@ The preferred group names are those defined by
|
|||
L<IANA|https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8>.
|
||||
|
||||
The I<list> can be used to define several group tuples of comparable security
|
||||
levels, and can specify which key shares should be sent by a client.
|
||||
The specified list elements can optionally be ignored, if not implemented
|
||||
levels, and can specify which predicted key shares should be sent by a client.
|
||||
Group tuples are used by OpenSSL TLS servers to decide whether to request a
|
||||
stronger keyshare than those predicted by sending a Hello Retry Request
|
||||
(B<HRR>) even if some of the predicted groups are supported.
|
||||
OpenSSL clients ignore tuple boundaries, and pay attenion only to the overall
|
||||
order of I<list> elements and which groups are selected as predicted keyshares
|
||||
as described below.
|
||||
|
||||
The specified list elements can optionally be ignored if not implemented
|
||||
(listing unknown groups otherwise results in error).
|
||||
It is also possible to specify the built-in default set of groups, and to explicitly
|
||||
remove a group from that list.
|
||||
It is also possible to specify the built-in default set of groups, and to
|
||||
explicitly remove a group from that list.
|
||||
|
||||
In its simplest form, the string I<list> is just a colon separated list
|
||||
of group names, for example "P-521:P-384:P-256:X25519:ffdhe2048". The first
|
||||
group listed will also be used for the B<key_share> sent by a client in a
|
||||
TLSv1.3 B<ClientHello>. For servers note the discussion above. The list should
|
||||
be in order of preference with the most preferred group first.
|
||||
In its simplest legacy form, the string I<list> is just a colon separated list
|
||||
of group names, for example "P-521:P-384:P-256:X25519:ffdhe2048".
|
||||
The first group listed will in this case be used as the sole predicted
|
||||
B<key_share> sent by a client in a TLSv1.3 B<ClientHello>.
|
||||
The list should be in order of preference with the most preferred group first.
|
||||
|
||||
Group tuples of comparable security are defined by separating them from each
|
||||
other by a tuple separator C</>. Keyshares to be sent by a client are specified
|
||||
by prepending a C<*> to the group name, while any C<*> will be ignored by a
|
||||
server. The following string I<list> for example defines three tuples when
|
||||
used on the server-side, and triggers the generation of three key shares
|
||||
when used on the client-side: P-521:*P-256/*P-384/*X25519:P-384:ffdhe2048.
|
||||
A more expressive syntax supports definition of group tuples of comparable
|
||||
security by separating them from each other with C</> characters.
|
||||
|
||||
If a group name is preceded with the C<?> character, it will be ignored if an
|
||||
implementation is missing. If a group name is preceded with the C<-> character, it
|
||||
will be removed from the list of groups if present (including not sending a
|
||||
key share for this group), ignored otherwise. The pseudo group name
|
||||
C<DEFAULT> can be used to select the OpenSSL built-in default list of groups.
|
||||
The predicted keyshares to be sent by clients can be explicitly specified by
|
||||
adding a C<*> prefix to the associated group name.
|
||||
These C<*> prefixes are ignored by servers.
|
||||
|
||||
If a group name is prefixed with the C<?> character, it will be ignored if an
|
||||
implementation is missing.
|
||||
Otherwise, listing an unknown group name will cause a failure to parse the
|
||||
I<list>.
|
||||
Note that whether a group is known or not may depend on the OpenSSL version,
|
||||
how OpenSSL was compiled and/or which providers are loaded.
|
||||
Make sure you have the correct spelling of the group name and when in doubt
|
||||
prefix it with a C<?> to handle configurations in which it might nevertheless
|
||||
be unknown.
|
||||
|
||||
If a group name is prefixed with the C<-> character, it will be removed from
|
||||
the list of groups specified up to that point.
|
||||
It can be added again if specified later.
|
||||
Removal of groups that have not been included earlier in the list is silently
|
||||
ignored.
|
||||
|
||||
The pseudo group name C<DEFAULT> can be used to select the OpenSSL built-in
|
||||
default list of groups.
|
||||
Prepending one or more groups to C<DEFAULT> using only C<:> separators prepends those
|
||||
groups to the built-in default list's first tuple.
|
||||
Additional tuples can be prepended by use of the C</> separator.
|
||||
Appending a set of groups to C<DEFAULT> using only C<:> separators appends those
|
||||
groups to the built-in default list's last tuple.
|
||||
Additional tuples can be appended by use of the C</> separator.
|
||||
|
||||
The B<DEFAULT> list selects B<X25519MLKEM768> as one of the predicted keyshares.
|
||||
In rare cases this can lead to failures or timeouts because the resulting
|
||||
larger TLS Client Hello message may no longer fit in a single TCP segment and
|
||||
firewall software may erroneously disrupt the TLS handshake.
|
||||
If this is an issue or concern, prepending C<?X25519MLKEM768:> without a C<*>
|
||||
prefix leads to its occurrence in the default list to be ignored as a duplicate,
|
||||
and along with that also the keyshare prediction.
|
||||
The group will then only be selected by servers that specifically expect it,
|
||||
after a Hello Retry Request (HRR).
|
||||
Servers that specifically prefer B<X25519MLKEM768>, are much less likely to be
|
||||
found behind problematic firewalls.
|
||||
|
||||
The following string I<list> for example defines three tuples when used on the
|
||||
server-side, and triggers the generation of three key shares when used on the
|
||||
client-side: P-521:*P-256/*P-384/*X25519:P-384:ffdhe2048.
|
||||
|
||||
For a TLS 1.3 client, all the groups in the string I<list> are added to the
|
||||
supported groups extension of a C<ClientHello>, in the order in which they are listed,
|
||||
|
|
|
|||
169
ssl/t1_lib.c
169
ssl/t1_lib.c
|
|
@ -225,7 +225,7 @@ static const uint16_t suiteb_curves[] = {
|
|||
|
||||
/* Group list string of the built-in pseudo group DEFAULT_SUITE_B */
|
||||
#define SUITE_B_GROUP_NAME "DEFAULT_SUITE_B"
|
||||
#define SUITE_B_GROUP_LIST "secp256r1:secp384r1",
|
||||
#define SUITE_B_GROUP_LIST "?secp256r1:?secp384r1",
|
||||
|
||||
struct provider_ctx_data_st {
|
||||
SSL_CTX *ctx;
|
||||
|
|
@ -1274,8 +1274,8 @@ typedef struct {
|
|||
size_t ksidcnt; /* Number of key shares */
|
||||
uint16_t *ksid_arr; /* The IDs of the key share groups (flat list) */
|
||||
/* Variable to keep state between execution of callback or helper functions */
|
||||
size_t tuple_mode; /* Keeps track whether tuple_cb called from 'the top' or from gid_cb */
|
||||
int ignore_unknown_default; /* Flag such that unknown groups for DEFAULT[_XYZ] are ignored */
|
||||
int inner; /* Are we expanding a DEFAULT list */
|
||||
int first; /* First tuple of possibly nested expansion? */
|
||||
} gid_cb_st;
|
||||
|
||||
/* Forward declaration of tuple callback function */
|
||||
|
|
@ -1350,16 +1350,16 @@ static int gid_cb(const char *elem, int len, void *arg)
|
|||
for (i = 0; i < OSSL_NELEM(default_group_strings); i++) {
|
||||
if ((size_t)len == (strlen(default_group_strings[i].list_name))
|
||||
&& OPENSSL_strncasecmp(default_group_strings[i].list_name, elem, len) == 0) {
|
||||
int saved_first;
|
||||
|
||||
/*
|
||||
* We're asked to insert an entire list of groups from a
|
||||
* DEFAULT[_XYZ] 'pseudo group' which we do by
|
||||
* recursively calling this function (indirectly via
|
||||
* CONF_parse_list and tuple_cb); essentially, we treat a DEFAULT
|
||||
* group string like a tuple which is appended to the current tuple
|
||||
* rather then starting a new tuple. Variable tuple_mode is the flag which
|
||||
* controls append tuple vs start new tuple.
|
||||
* rather then starting a new tuple.
|
||||
*/
|
||||
|
||||
if (ignore_unknown || remove_group)
|
||||
return -1; /* removal or ignore not allowed here -> syntax error */
|
||||
|
||||
|
|
@ -1380,15 +1380,17 @@ static int gid_cb(const char *elem, int len, void *arg)
|
|||
default_group_strings[i].group_string,
|
||||
strlen(default_group_strings[i].group_string));
|
||||
restored_default_group_string[strlen(default_group_strings[i].group_string) + restored_prefix_index] = '\0';
|
||||
/* We execute the recursive call */
|
||||
garg->ignore_unknown_default = 1; /* We ignore unknown groups for DEFAULT_XYZ */
|
||||
/* we enforce group mode (= append tuple) for DEFAULT_XYZ group lists */
|
||||
garg->tuple_mode = 0;
|
||||
/* We use the tuple_cb callback to process the pseudo group tuple */
|
||||
/*
|
||||
* Append first tuple of result to current tuple, and don't
|
||||
* terminate the last tuple until we return to a top-level
|
||||
* tuple_cb.
|
||||
*/
|
||||
saved_first = garg->first;
|
||||
garg->inner = garg->first = 1;
|
||||
retval = CONF_parse_list(restored_default_group_string,
|
||||
TUPLE_DELIMITER_CHARACTER, 1, tuple_cb, garg);
|
||||
garg->tuple_mode = 1; /* next call to tuple_cb will again start new tuple */
|
||||
garg->ignore_unknown_default = 0; /* reset to original value */
|
||||
garg->inner = 0;
|
||||
garg->first = saved_first;
|
||||
/* We don't need the \0-terminated string anymore */
|
||||
OPENSSL_free(restored_default_group_string);
|
||||
|
||||
|
|
@ -1408,9 +1410,6 @@ static int gid_cb(const char *elem, int len, void *arg)
|
|||
if (len == 0)
|
||||
return -1; /* Seems we have prefxes without a group name -> syntax error */
|
||||
|
||||
if (garg->ignore_unknown_default == 1) /* Always ignore unknown groups for DEFAULT[_XYZ] */
|
||||
ignore_unknown = 1;
|
||||
|
||||
/* Memory management in case more groups are present compared to initial allocation */
|
||||
if (garg->gidcnt == garg->gidmax) {
|
||||
uint16_t *tmp = OPENSSL_realloc_array(garg->gid_arr,
|
||||
|
|
@ -1486,51 +1485,48 @@ static int gid_cb(const char *elem, int len, void *arg)
|
|||
}
|
||||
/* Remove group (and keyshare) from anywhere in the list if present, ignore if not present */
|
||||
if (remove_group) {
|
||||
/* Is the current group specified anywhere in the entire list so far? */
|
||||
found_group = 0;
|
||||
for (i = 0; i < garg->gidcnt; i++)
|
||||
if (garg->gid_arr[i] == gid) {
|
||||
found_group = 1;
|
||||
size_t n; /* tuple size */
|
||||
|
||||
j = 0; /* tuple index */
|
||||
k = 0; /* keyshare index */
|
||||
n = garg->tuplcnt_arr[j];
|
||||
|
||||
for (i = 0; i < garg->gidcnt; ++i) {
|
||||
if (garg->gid_arr[i] == gid)
|
||||
break;
|
||||
}
|
||||
/* The group to remove is at position i in the list of (zero indexed) groups */
|
||||
if (found_group) {
|
||||
/* We remove that group from its position (which is at i)... */
|
||||
for (j = i; j < (garg->gidcnt - 1); j++)
|
||||
garg->gid_arr[j] = garg->gid_arr[j + 1]; /* ...shift remaining groups left ... */
|
||||
garg->gidcnt--; /* ..and update the book keeping for the number of groups */
|
||||
/* Skip keyshare slots associated with groups prior to that removed */
|
||||
if (k < garg->ksidcnt && garg->gid_arr[i] == garg->ksid_arr[k])
|
||||
++k;
|
||||
/* Skip to next tuple? */
|
||||
if (j < garg->tplcnt && --n == 0)
|
||||
n = garg->tuplcnt_arr[++j];
|
||||
}
|
||||
|
||||
/*
|
||||
* We also must update the number of groups either in a previous tuple (which we
|
||||
* must identify and check whether it becomes empty due to the deletion) or in
|
||||
* the current tuple, pending where the deleted group resides
|
||||
*/
|
||||
k = 0;
|
||||
for (j = 0; j < garg->tplcnt; j++) {
|
||||
k += garg->tuplcnt_arr[j];
|
||||
/* Remark: i is zero-indexed, k is one-indexed */
|
||||
if (k > i) { /* remove from one of the previous tuples */
|
||||
garg->tuplcnt_arr[j]--;
|
||||
break; /* We took care not to have group duplicates, hence we can stop here */
|
||||
}
|
||||
}
|
||||
if (k <= i) /* remove from current tuple */
|
||||
garg->tuplcnt_arr[j]--;
|
||||
/* Nothing to remove? */
|
||||
if (i >= garg->gidcnt)
|
||||
goto done;
|
||||
|
||||
/* We also remove the group from the list of keyshares (if present) */
|
||||
found_group = 0;
|
||||
for (i = 0; i < garg->ksidcnt; i++)
|
||||
if (garg->ksid_arr[i] == gid) {
|
||||
found_group = 1;
|
||||
break;
|
||||
}
|
||||
if (found_group) {
|
||||
/* Found, hence we remove that keyshare from its position (which is at i)... */
|
||||
for (j = i; j < (garg->ksidcnt - 1); j++)
|
||||
garg->ksid_arr[j] = garg->ksid_arr[j + 1]; /* shift remaining key shares */
|
||||
/* ... and update the book keeping */
|
||||
garg->ksidcnt--;
|
||||
}
|
||||
garg->gidcnt--;
|
||||
garg->tuplcnt_arr[j]--;
|
||||
memmove(garg->gid_arr + i, garg->gid_arr + i + 1,
|
||||
(garg->gidcnt - i) * sizeof(gid));
|
||||
|
||||
/* Handle keyshare removal */
|
||||
if (k < garg->ksidcnt && garg->ksid_arr[k] == gid) {
|
||||
garg->ksidcnt--;
|
||||
memmove(garg->ksid_arr + k, garg->ksid_arr + k + 1,
|
||||
(garg->ksidcnt - k) * sizeof(gid));
|
||||
}
|
||||
|
||||
/*
|
||||
* Adjust closed or current tuple's group count, if a closed tuple
|
||||
* count reaches zero excise the resulting empty tuple. The current
|
||||
* (not yet closed) tuple at the end of the list stays even if empty.
|
||||
*/
|
||||
if (garg->tuplcnt_arr[j] == 0 && j < garg->tplcnt) {
|
||||
garg->tplcnt--;
|
||||
memmove(garg->tuplcnt_arr + j, garg->tuplcnt_arr + j + 1,
|
||||
(garg->tplcnt - j) * sizeof(size_t));
|
||||
}
|
||||
} else { /* Processing addition of a single new group */
|
||||
|
||||
|
|
@ -1546,7 +1542,7 @@ static int gid_cb(const char *elem, int len, void *arg)
|
|||
/* and update the book keeping for the number of groups in current tuple */
|
||||
garg->tuplcnt_arr[garg->tplcnt]++;
|
||||
|
||||
/* We memorize if needed that we want to add a key share for the current group */
|
||||
/* We want to add a key share for the current group */
|
||||
if (add_keyshare)
|
||||
garg->ksid_arr[garg->ksidcnt++] = gid;
|
||||
}
|
||||
|
|
@ -1555,6 +1551,34 @@ done:
|
|||
return retval;
|
||||
}
|
||||
|
||||
static int grow_tuples(gid_cb_st *garg)
|
||||
{
|
||||
if (garg->tplcnt == garg->tplmax) {
|
||||
size_t *tmp = OPENSSL_realloc_array(garg->tuplcnt_arr,
|
||||
garg->tplmax + GROUPLIST_INCREMENT,
|
||||
sizeof(*garg->tuplcnt_arr));
|
||||
|
||||
if (tmp == NULL)
|
||||
return 0;
|
||||
garg->tplmax += GROUPLIST_INCREMENT;
|
||||
garg->tuplcnt_arr = tmp;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int close_tuple(gid_cb_st *garg)
|
||||
{
|
||||
size_t gidcnt = garg->tuplcnt_arr[garg->tplcnt];
|
||||
|
||||
if (gidcnt == 0)
|
||||
return 1;
|
||||
if (!grow_tuples(garg))
|
||||
return 0;
|
||||
|
||||
garg->tuplcnt_arr[++garg->tplcnt] = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Extract and process a tuple of groups */
|
||||
static int tuple_cb(const char *tuple, int len, void *arg)
|
||||
{
|
||||
|
|
@ -1568,17 +1592,9 @@ static int tuple_cb(const char *tuple, int len, void *arg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Memory management for tuples */
|
||||
if (garg->tplcnt == garg->tplmax) {
|
||||
size_t *tmp = OPENSSL_realloc_array(garg->tuplcnt_arr,
|
||||
garg->tplmax + GROUPLIST_INCREMENT,
|
||||
sizeof(*garg->tuplcnt_arr));
|
||||
|
||||
if (tmp == NULL)
|
||||
return 0;
|
||||
garg->tplmax += GROUPLIST_INCREMENT;
|
||||
garg->tuplcnt_arr = tmp;
|
||||
}
|
||||
if (garg->inner && !garg->first && !close_tuple(garg))
|
||||
return 0;
|
||||
garg->first = 0;
|
||||
|
||||
/* Convert to \0-terminated string */
|
||||
restored_tuple_string = OPENSSL_malloc(len + 1 /* \0 */);
|
||||
|
|
@ -1593,15 +1609,8 @@ static int tuple_cb(const char *tuple, int len, void *arg)
|
|||
/* We don't need the \o-terminated string anymore */
|
||||
OPENSSL_free(restored_tuple_string);
|
||||
|
||||
if (garg->tuplcnt_arr[garg->tplcnt] > 0) { /* Some valid groups are present in current tuple... */
|
||||
if (garg->tuple_mode) {
|
||||
/* We 'close' the tuple */
|
||||
garg->tplcnt++;
|
||||
garg->tuplcnt_arr[garg->tplcnt] = 0; /* Next tuple is initialized to be empty */
|
||||
garg->tuple_mode = 1; /* next call will start a tuple (unless overridden in gid_cb) */
|
||||
}
|
||||
}
|
||||
|
||||
if (!garg->inner && !close_tuple(garg))
|
||||
return 0;
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -1632,8 +1641,6 @@ int tls1_set_groups_list(SSL_CTX *ctx,
|
|||
}
|
||||
|
||||
memset(&gcb, 0, sizeof(gcb));
|
||||
gcb.tuple_mode = 1; /* We prepare to collect the first tuple */
|
||||
gcb.ignore_unknown_default = 0;
|
||||
gcb.gidmax = GROUPLIST_INCREMENT;
|
||||
gcb.tplmax = GROUPLIST_INCREMENT;
|
||||
gcb.ksidmax = GROUPLIST_INCREMENT;
|
||||
|
|
|
|||
|
|
@ -40,6 +40,12 @@ typedef enum SERVER_RESPONSE {
|
|||
SH = 2
|
||||
} SERVER_RESPONSE;
|
||||
|
||||
static const char *response_desc[] = {
|
||||
"HRR",
|
||||
"INIT",
|
||||
"SH",
|
||||
};
|
||||
|
||||
static char *cert = NULL;
|
||||
static char *privkey = NULL;
|
||||
|
||||
|
|
@ -51,6 +57,17 @@ struct tls13groupselection_test_st {
|
|||
const enum SERVER_RESPONSE expected_server_response;
|
||||
};
|
||||
|
||||
/*
|
||||
* Tests that probe robust handling of group removal depend on detailed
|
||||
* knowledge of the default group list. A stable list is needed that does not
|
||||
* depend on future changes in the actual built-in default.
|
||||
*/
|
||||
#define TEST_DEFLT \
|
||||
"?*X25519MLKEM768 / " \
|
||||
"?*X25519 : ?secp256r1 / " \
|
||||
"?X448 : ?secp384r1 : ?secp521r1 / " \
|
||||
"?ffdhe2048:?ffdhe3072"
|
||||
|
||||
static const struct tls13groupselection_test_st tls13groupselection_tests[] = {
|
||||
|
||||
/*
|
||||
|
|
@ -313,7 +330,40 @@ static const struct tls13groupselection_test_st tls13groupselection_tests[] = {
|
|||
{ "*brainpoolP256r1:X25519", /* test 43 */
|
||||
"X25519",
|
||||
SERVER_PREFERENCE,
|
||||
NEGOTIATION_FAILURE, INIT }
|
||||
NEGOTIATION_FAILURE, INIT },
|
||||
|
||||
/* DEFAULT retains tuple structure */
|
||||
{ "*X25519:secp256r1",
|
||||
"secp256r1:DEFAULT", /* test 44 */
|
||||
SERVER_PREFERENCE,
|
||||
"secp256r1", HRR },
|
||||
#ifndef OPENSSL_NO_DH
|
||||
{ "*ffdhe2048:secp256r1",
|
||||
"DEFAULT:ffdhe4096", /* test 45 */
|
||||
CLIENT_PREFERENCE,
|
||||
"secp256r1", HRR },
|
||||
{ "x25519:ffdhe2048:*ffdhe4096",
|
||||
"DEFAULT:ffdhe4096", /* test 46 */
|
||||
SERVER_PREFERENCE,
|
||||
"x25519", HRR },
|
||||
/*
|
||||
* The server's second tuple becomes empty after removal
|
||||
* of "secp256r1", the subsequent removal of X448 is
|
||||
* then from the third tuple.
|
||||
*/
|
||||
{ "*ffdhe2048:secp384r1", /* test 47 */
|
||||
"*X25519:" TEST_DEFLT ":-secp256r1:-X448",
|
||||
SERVER_PREFERENCE,
|
||||
"secp384r1", HRR },
|
||||
/*
|
||||
* The server's last tuple becomes empty after removals,
|
||||
* and then continues to fill.
|
||||
*/
|
||||
{ "*ffdhe2048:ffdhe4096", /* test 48 */
|
||||
"*X25519:" TEST_DEFLT ":-ffdhe2048:-ffdhe3072:ffdhe4096",
|
||||
SERVER_PREFERENCE,
|
||||
"ffdhe4096", HRR },
|
||||
#endif
|
||||
};
|
||||
|
||||
static void server_response_check_cb(int write_p, int version,
|
||||
|
|
@ -324,10 +374,12 @@ static void server_response_check_cb(int write_p, int version,
|
|||
enum SERVER_RESPONSE *server_response = (enum SERVER_RESPONSE *)arg;
|
||||
/* Prepare check for HRR */
|
||||
const uint8_t *incoming_random = (const uint8_t *)buf + 6;
|
||||
const uint8_t magic_HRR_random[32] = { 0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11,
|
||||
const uint8_t magic_HRR_random[32] = {
|
||||
0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11,
|
||||
0xBE, 0x1D, 0x8C, 0x02, 0x1E, 0x65, 0xB8, 0x91,
|
||||
0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, 0x8C, 0x5E,
|
||||
0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C };
|
||||
0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C
|
||||
};
|
||||
|
||||
/* Did a server hello arrive? */
|
||||
if (write_p == 0 && /* Incoming data... */
|
||||
|
|
@ -456,13 +508,16 @@ static int test_groupnegotiation(const struct tls13groupselection_test_st *curre
|
|||
group_name_client = SSL_group_to_name(clientssl, negotiated_group_client);
|
||||
if (!TEST_int_eq(negotiated_group_client, negotiated_group_server))
|
||||
goto end;
|
||||
if (!TEST_int_eq((int)current_test_vector->expected_server_response, (int)server_response))
|
||||
if (!TEST_str_eq(response_desc[current_test_vector->expected_server_response],
|
||||
response_desc[server_response]))
|
||||
goto end;
|
||||
if (TEST_str_eq(group_name_client, current_test_vector->expected_group))
|
||||
ok = 1;
|
||||
} else {
|
||||
TEST_false_or_end(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE));
|
||||
if (test_type == TEST_NEGOTIATION_FAILURE && !TEST_int_eq((int)current_test_vector->expected_server_response, (int)server_response))
|
||||
if (test_type == TEST_NEGOTIATION_FAILURE
|
||||
&& !TEST_str_eq(response_desc[current_test_vector->expected_server_response],
|
||||
response_desc[server_response]))
|
||||
goto end;
|
||||
ok = 1;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue