Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix ClientHello key share ext no curveSM2 when enable TLS1.3 + SM strictly #525

Merged
merged 1 commit into from
Nov 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions ssl/statem/extensions_clnt.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,56 @@ EXT_RETURN tls_construct_ctos_supported_groups(SSL *s, WPACKET *pkt,
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return EXT_RETURN_FAIL;
}

#ifndef OPENSSL_NO_SM2
/*
* RFC 8998 requires that:
* For the key_share extension, a KeyShareEntry for the "curveSM2" group
* MUST be included. We re-order curveSM2 to the first supported group when
* enable_sm_tls13_strict so that the key_share extension will include a
* KeyShareEntry for the "curveSM2" group because only one KeyShareEntry is
* sent now.
*/
if (!SSL_IS_DTLS(s) && max_version >= TLS1_3_VERSION
&& s->enable_sm_tls13_strict == 1) {
int sm2_idx = -1;

for (i = 0; i < num_groups; i++) {
if (pgroups[i] == TLSEXT_curve_SM2) {
sm2_idx = i;
break;
}
}

if (sm2_idx > 0) {
int *groups = OPENSSL_malloc(sizeof(int) * num_groups);
if (groups == NULL) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return EXT_RETURN_FAIL;
}

for (i = 0; i < num_groups; i++)
groups[i] = tls1_group_id2nid(pgroups[i], 1);

for (i = sm2_idx; i > 0; i--)
groups[i] = groups[i - 1];

groups[0] = NID_sm2;

if (!tls1_set_groups(&s->ext.supportedgroups,
&s->ext.supportedgroups_len,
groups, num_groups)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
OPENSSL_free(groups);
return EXT_RETURN_FAIL;
}

OPENSSL_free(groups);
tls1_get_supported_groups(s, &pgroups, &num_groups);
}
}
#endif

/* Copy group ID if supported */
for (i = 0; i < num_groups; i++) {
uint16_t ctmp = pgroups[i];
Expand Down
19 changes: 6 additions & 13 deletions ssl/t1_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -677,13 +677,7 @@ int tls1_set_groups(uint16_t **pext, size_t *pextlen,
{
uint16_t *glist;
size_t i;
/*
* Bitmap of groups included to detect duplicates: two variables are added
* to detect duplicates as some values are more than 32.
*/
unsigned long *dup_list = NULL;
unsigned long dup_list_egrp = 0;
unsigned long dup_list_dhgrp = 0;
uint8_t bitmap[64] = { 0 };

if (ngroups == 0) {
ERR_raise(ERR_LIB_SSL, SSL_R_BAD_LENGTH);
Expand All @@ -694,20 +688,19 @@ int tls1_set_groups(uint16_t **pext, size_t *pextlen,
return 0;
}
for (i = 0; i < ngroups; i++) {
unsigned long idmask;
uint16_t id;
id = tls1_nid2group_id(groups[i]);
if (ngroups == 1) {
glist[i] = id;
break;
}
if ((id & 0x00FF) >= (sizeof(unsigned long) * 8))
if (id == 0 || id >= sizeof(bitmap) * 8)
goto err;
idmask = 1L << (id & 0x00FF);
dup_list = (id < 0x100) ? &dup_list_egrp : &dup_list_dhgrp;
if (!id || ((*dup_list) & idmask))

if (bitmap[id / 8] & (1 << (id % 8)))
goto err;
*dup_list |= idmask;

bitmap[id / 8] |= 1 << (id % 8);
glist[i] = id;
}
OPENSSL_free(*pext);
Expand Down
3 changes: 3 additions & 0 deletions test/helpers/handshake.c
Original file line number Diff line number Diff line change
Expand Up @@ -1716,6 +1716,9 @@ static HANDSHAKE_RESULT *do_handshake_internal(
SSL_get_peer_signature_type_nid(client.ssl, &ret->server_sign_type);
SSL_get_peer_signature_type_nid(server.ssl, &ret->client_sign_type);

if (SSL_IS_TLS13(client.ssl) && client.ssl->s3.did_kex)
ret->client_key_share = SSL_get_negotiated_group(client.ssl);

names = SSL_get0_peer_CA_list(client.ssl);
if (names == NULL)
ret->client_ca_names = NULL;
Expand Down
2 changes: 2 additions & 0 deletions test/helpers/handshake.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ typedef struct handshake_result {
int client_sign_hash;
/* client signature type */
int client_sign_type;
/* client key share */
int client_key_share;
/* Client CA names */
STACK_OF(X509_NAME) *client_ca_names;
/* Session id status */
Expand Down
25 changes: 25 additions & 0 deletions test/helpers/ssl_test_ctx.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <openssl/crypto.h>

#include "internal/nelem.h"
#include "../../ssl/ssl_local.h"
#include "ssl_test_ctx.h"
#include "../testutil.h"

Expand Down Expand Up @@ -636,6 +637,22 @@ __owur static int parse_expected_sign_hash(int *ptype, const char *value)
return 1;
}

__owur static int parse_expected_key_share(int *ptype, const char *value)
{
int nid;

if (value == NULL)
return 0;
nid = OBJ_sn2nid(value);
if (nid == NID_undef)
nid = OBJ_ln2nid(value);
if (nid == NID_undef)
return 0;

*ptype = nid;
return 1;
}

__owur static int parse_expected_server_sign_hash(SSL_TEST_CTX *test_ctx,
const char *value)
{
Expand All @@ -650,6 +667,13 @@ __owur static int parse_expected_client_sign_hash(SSL_TEST_CTX *test_ctx,
value);
}

__owur static int parse_expected_client_key_share(SSL_TEST_CTX *test_ctx,
const char *value)
{
return parse_expected_key_share(&test_ctx->expected_client_key_share,
value);
}

__owur static int parse_expected_ca_names(STACK_OF(X509_NAME) **pnames,
const char *value,
OSSL_LIB_CTX *libctx)
Expand Down Expand Up @@ -737,6 +761,7 @@ static const ssl_test_ctx_option ssl_test_ctx_options[] = {
{ "ExpectedClientSignHash", &parse_expected_client_sign_hash },
{ "ExpectedClientSignType", &parse_expected_client_sign_type },
{ "ExpectedClientCANames", &parse_expected_client_ca_names },
{ "ExpectedClientKeyShare", &parse_expected_client_key_share },
{ "UseSCTP", &parse_test_use_sctp },
{ "EnableClientSCTPLabelBug", &parse_test_enable_client_sctp_label_bug },
{ "EnableServerSCTPLabelBug", &parse_test_enable_server_sctp_label_bug },
Expand Down
2 changes: 2 additions & 0 deletions test/helpers/ssl_test_ctx.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,8 @@ typedef struct {
int expected_client_sign_type;
/* Expected CA names for client auth */
STACK_OF(X509_NAME) *expected_client_ca_names;
/* Expected client key share */
int expected_client_key_share;
/* Whether to use SCTP for the transport */
int use_sctp;
/* Enable SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG on client side */
Expand Down
Loading
Loading