Merge pull request #5585 from icing/groups-key-share
wolfSSL_set1_curves_list(), wolfSSL_CTX_set1_curves_list() improvements.
This commit is contained in:
commit
12ec2272d6
97
src/ssl.c
97
src/ssl.c
@ -33926,20 +33926,34 @@ int wolfSSL_curve_is_disabled(WOLFSSL* ssl, word16 curve_id)
|
||||
defined(HAVE_CURVE25519) || defined(HAVE_CURVE448))
|
||||
static int set_curves_list(WOLFSSL* ssl, WOLFSSL_CTX *ctx, const char* names)
|
||||
{
|
||||
int idx, start = 0, len;
|
||||
int idx, start = 0, len, i, ret = WOLFSSL_FAILURE;
|
||||
word16 curve;
|
||||
word32 disabled;
|
||||
char name[MAX_CURVE_NAME_SZ];
|
||||
byte groups_len = 0;
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
void *heap = ssl? ssl->heap : ctx->heap;
|
||||
int *groups;
|
||||
#else
|
||||
int groups[WOLFSSL_MAX_GROUP_COUNT];
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
groups = (int*)XMALLOC(sizeof(int)*WOLFSSL_MAX_GROUP_COUNT,
|
||||
heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (groups == NULL) {
|
||||
ret = MEMORY_E;
|
||||
goto leave;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Disable all curves so that only the ones the user wants are enabled. */
|
||||
disabled = 0xFFFFFFFFUL;
|
||||
for (idx = 1; names[idx-1] != '\0'; idx++) {
|
||||
if (names[idx] != ':' && names[idx] != '\0')
|
||||
continue;
|
||||
|
||||
len = idx - start;
|
||||
if (len > MAX_CURVE_NAME_SZ - 1)
|
||||
return WOLFSSL_FAILURE;
|
||||
goto leave;
|
||||
|
||||
XMEMCPY(name, names + start, len);
|
||||
name[len] = 0;
|
||||
@ -33974,25 +33988,25 @@ static int set_curves_list(WOLFSSL* ssl, WOLFSSL_CTX *ctx, const char* names)
|
||||
#endif
|
||||
else {
|
||||
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
|
||||
int ret;
|
||||
int nret;
|
||||
const ecc_set_type *eccSet;
|
||||
|
||||
ret = wc_ecc_get_curve_idx_from_name(name);
|
||||
if (ret < 0) {
|
||||
nret = wc_ecc_get_curve_idx_from_name(name);
|
||||
if (nret < 0) {
|
||||
WOLFSSL_MSG("Could not find name in set");
|
||||
return WOLFSSL_FAILURE;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
eccSet = wc_ecc_get_curve_params(ret);
|
||||
if (eccSet == NULL) {
|
||||
WOLFSSL_MSG("NULL set returned");
|
||||
return WOLFSSL_FAILURE;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
curve = GetCurveByOID(eccSet->oidSum);
|
||||
#else
|
||||
WOLFSSL_MSG("API not present to search farther using name");
|
||||
return WOLFSSL_FAILURE;
|
||||
goto leave;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -34000,32 +34014,71 @@ static int set_curves_list(WOLFSSL* ssl, WOLFSSL_CTX *ctx, const char* names)
|
||||
/* shift left more than size of ctx->disabledCurves causes static
|
||||
* analysis report */
|
||||
WOLFSSL_MSG("curve value is too large for upcoming shift");
|
||||
return WOLFSSL_FAILURE;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
#if defined(HAVE_SUPPORTED_CURVES) && !defined(NO_WOLFSSL_CLIENT)
|
||||
for (i = 0; i < groups_len; ++i) {
|
||||
if (groups[i] == curve) {
|
||||
/* silently drop duplicates */
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i >= groups_len) {
|
||||
if (groups_len >= WOLFSSL_MAX_GROUP_COUNT) {
|
||||
WOLFSSL_MSG_EX("setting %d or more supported "
|
||||
"curves is not permitted", groups_len);
|
||||
goto leave;
|
||||
}
|
||||
groups[groups_len++] = (int)curve;
|
||||
}
|
||||
|
||||
start = idx + 1;
|
||||
}
|
||||
|
||||
/* Disable all curves so that only the ones the user wants are enabled. */
|
||||
disabled = 0xFFFFFFFFUL;
|
||||
for (i = 0; i < groups_len; ++i) {
|
||||
/* Switch the bit to off and therefore is enabled. */
|
||||
curve = (word16)groups[i];
|
||||
disabled &= ~(1U << curve);
|
||||
#ifdef HAVE_SUPPORTED_CURVES
|
||||
#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_OLD_SET_CURVES_LIST)
|
||||
/* using the wolfSSL API to set the groups, this will populate
|
||||
* (ssl|ctx)->groups and reset any TLSX_SUPPORTED_GROUPS.
|
||||
* The order in (ssl|ctx)->groups will then be respected
|
||||
* when TLSX_KEY_SHARE needs to be established */
|
||||
if ((ssl && wolfSSL_set_groups(ssl, groups, groups_len)
|
||||
!= WOLFSSL_SUCCESS)
|
||||
|| (ctx && wolfSSL_CTX_set_groups(ctx, groups, groups_len)
|
||||
!= WOLFSSL_SUCCESS)) {
|
||||
WOLFSSL_MSG("Unable to set supported curve");
|
||||
goto leave;
|
||||
}
|
||||
#elif !defined(NO_WOLFSSL_CLIENT)
|
||||
/* set the supported curve so client TLS extension contains only the
|
||||
* desired curves */
|
||||
if ((ssl
|
||||
&& wolfSSL_UseSupportedCurve(ssl, curve) != WOLFSSL_SUCCESS)
|
||||
|| (ctx
|
||||
&& wolfSSL_CTX_UseSupportedCurve(ctx, curve) != WOLFSSL_SUCCESS)) {
|
||||
if ((ssl && wolfSSL_UseSupportedCurve(ssl, curve) != WOLFSSL_SUCCESS)
|
||||
|| (ctx && wolfSSL_CTX_UseSupportedCurve(ctx, curve)
|
||||
!= WOLFSSL_SUCCESS)) {
|
||||
WOLFSSL_MSG("Unable to set supported curve");
|
||||
return WOLFSSL_FAILURE;
|
||||
goto leave;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Switch the bit to off and therefore is enabled. */
|
||||
disabled &= ~(1U << curve);
|
||||
start = idx + 1;
|
||||
#endif /* HAVE_SUPPORTED_CURVES */
|
||||
}
|
||||
|
||||
if (ssl)
|
||||
ssl->disabledCurves = disabled;
|
||||
else
|
||||
ctx->disabledCurves = disabled;
|
||||
ret = WOLFSSL_SUCCESS;
|
||||
|
||||
return WOLFSSL_SUCCESS;
|
||||
leave:
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
if (groups)
|
||||
XFREE((void*)groups, heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wolfSSL_CTX_set1_curves_list(WOLFSSL_CTX* ctx, const char* names)
|
||||
|
86
tests/quic.c
86
tests/quic.c
@ -949,20 +949,26 @@ static int QuicConversation_start(QuicConversation *conv, const byte *data,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int QuicConversation_step(QuicConversation *conv)
|
||||
static int QuicConversation_step(QuicConversation *conv, int may_fail)
|
||||
{
|
||||
int n;
|
||||
|
||||
if (!conv->started) {
|
||||
AssertTrue(wolfSSL_connect(conv->client->ssl) != WOLFSSL_SUCCESS);
|
||||
AssertIntEQ(SSL_ERROR_WANT_READ, wolfSSL_get_error(conv->client->ssl, 0));
|
||||
n = wolfSSL_connect(conv->client->ssl);
|
||||
if (n != WOLFSSL_SUCCESS
|
||||
&& wolfSSL_get_error(conv->client->ssl, 0) != SSL_ERROR_WANT_READ) {
|
||||
if (may_fail) return 0;
|
||||
AssertIntEQ(SSL_ERROR_WANT_READ, wolfSSL_get_error(conv->client->ssl, 0));
|
||||
}
|
||||
conv->started = 1;
|
||||
}
|
||||
if (conv->server->output.len > 0) {
|
||||
QuicTestContext_forward(conv->server, conv->client, conv->rec_log, sizeof(conv->rec_log));
|
||||
n = wolfSSL_quic_read_write(conv->client->ssl);
|
||||
if (n != WOLFSSL_SUCCESS) {
|
||||
AssertIntEQ(wolfSSL_get_error(conv->client->ssl, 0), SSL_ERROR_WANT_READ);
|
||||
if (n != WOLFSSL_SUCCESS
|
||||
&& wolfSSL_get_error(conv->client->ssl, 0) != SSL_ERROR_WANT_READ) {
|
||||
if (may_fail) return 0;
|
||||
AssertIntEQ(SSL_ERROR_WANT_READ, wolfSSL_get_error(conv->client->ssl, 0));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -976,7 +982,10 @@ static int QuicConversation_step(QuicConversation *conv)
|
||||
(int)(sizeof(conv->early_data) - conv->early_data_len),
|
||||
&written);
|
||||
if (n < 0) {
|
||||
AssertIntEQ(wolfSSL_get_error(conv->server->ssl, 0), SSL_ERROR_WANT_READ);
|
||||
if (wolfSSL_get_error(conv->server->ssl, 0) != SSL_ERROR_WANT_READ) {
|
||||
if (may_fail) return 0;
|
||||
AssertIntEQ(wolfSSL_get_error(conv->server->ssl, 0), SSL_ERROR_WANT_READ);
|
||||
}
|
||||
}
|
||||
else if (n > 0) {
|
||||
conv->early_data_len += n;
|
||||
@ -988,7 +997,9 @@ static int QuicConversation_step(QuicConversation *conv)
|
||||
#endif /* WOLFSSL_EARLY_DATA */
|
||||
{
|
||||
n = wolfSSL_quic_read_write(conv->server->ssl);
|
||||
if (n != WOLFSSL_SUCCESS) {
|
||||
if (n != WOLFSSL_SUCCESS
|
||||
&& wolfSSL_get_error(conv->server->ssl, 0) != SSL_ERROR_WANT_READ) {
|
||||
if (may_fail) return 0;
|
||||
AssertIntEQ(wolfSSL_get_error(conv->server->ssl, 0), SSL_ERROR_WANT_READ);
|
||||
}
|
||||
}
|
||||
@ -1004,7 +1015,7 @@ static void QuicConversation_do(QuicConversation *conv)
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if (!QuicConversation_step(conv)) {
|
||||
if (!QuicConversation_step(conv, 0)) {
|
||||
int c_err = wolfSSL_get_error(conv->client->ssl, 0);
|
||||
int s_err = wolfSSL_get_error(conv->server->ssl, 0);
|
||||
if (c_err == 0 && s_err == 0) {
|
||||
@ -1018,6 +1029,22 @@ static void QuicConversation_do(QuicConversation *conv)
|
||||
}
|
||||
}
|
||||
|
||||
static void QuicConversation_fail(QuicConversation *conv)
|
||||
{
|
||||
if (!conv->started) {
|
||||
QuicConversation_start(conv, NULL, 0, NULL);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if (!QuicConversation_step(conv, 1)) {
|
||||
int c_err = wolfSSL_get_error(conv->client->ssl, 0);
|
||||
int s_err = wolfSSL_get_error(conv->server->ssl, 0);
|
||||
AssertTrue(c_err != 0 || s_err != 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int test_quic_client_hello(int verbose) {
|
||||
WOLFSSL_CTX *ctx;
|
||||
int ret = 0;
|
||||
@ -1089,14 +1116,14 @@ static int test_quic_server_hello(int verbose) {
|
||||
|
||||
/* connect */
|
||||
QuicConversation_init(&conv, &tclient, &tserver);
|
||||
QuicConversation_step(&conv);
|
||||
QuicConversation_step(&conv, 0);
|
||||
/* check established/missing secrets */
|
||||
check_secrets(&tserver, wolfssl_encryption_initial, 0, 0);
|
||||
check_secrets(&tserver, wolfssl_encryption_handshake, 32, 32);
|
||||
check_secrets(&tserver, wolfssl_encryption_application, 32, 32);
|
||||
check_secrets(&tclient, wolfssl_encryption_handshake, 0, 0);
|
||||
/* feed the server data to the client */
|
||||
QuicConversation_step(&conv);
|
||||
QuicConversation_step(&conv, 0);
|
||||
/* client has generated handshake secret */
|
||||
check_secrets(&tclient, wolfssl_encryption_handshake, 32, 32);
|
||||
/* continue the handshake till done */
|
||||
@ -1166,8 +1193,9 @@ static int test_quic_key_share(int verbose) {
|
||||
QuicTestContext_free(&tclient);
|
||||
QuicTestContext_free(&tserver);
|
||||
|
||||
/* setup & handshake, restricted groups, will trigger a
|
||||
* HelloRetryRequest(ServerHello) and a new ClientHello */
|
||||
/* setup & handshake, restricted groups. KEY_SHARE should use
|
||||
* the first configured group. */
|
||||
/*If that is supported by the server, expect a smooth handshake.*/
|
||||
QuicTestContext_init(&tclient, ctx_c, "client", verbose);
|
||||
QuicTestContext_init(&tserver, ctx_s, "server", verbose);
|
||||
AssertTrue(wolfSSL_set1_curves_list(tclient.ssl, "X25519:P-256")
|
||||
@ -1176,11 +1204,43 @@ static int test_quic_key_share(int verbose) {
|
||||
== WOLFSSL_SUCCESS);
|
||||
QuicConversation_init(&conv, &tclient, &tserver);
|
||||
QuicConversation_do(&conv);
|
||||
AssertStrEQ(conv.rec_log,
|
||||
"ClientHello:ServerHello:EncryptedExtension:"
|
||||
"Certificate:CertificateVerify:Finished:Finished:SessionTicket");
|
||||
QuicTestContext_free(&tclient);
|
||||
QuicTestContext_free(&tserver);
|
||||
printf(" test_quic_key_share: priority ok\n");
|
||||
|
||||
/* If group is not supported by server, expect HelloRetry */
|
||||
QuicTestContext_init(&tclient, ctx_c, "client", verbose);
|
||||
QuicTestContext_init(&tserver, ctx_s, "server", verbose);
|
||||
AssertTrue(wolfSSL_set1_curves_list(tclient.ssl, "X25519:P-256")
|
||||
== WOLFSSL_SUCCESS);
|
||||
AssertTrue(wolfSSL_set1_curves_list(tserver.ssl, "P-256")
|
||||
== WOLFSSL_SUCCESS);
|
||||
QuicConversation_init(&conv, &tclient, &tserver);
|
||||
QuicConversation_do(&conv);
|
||||
AssertStrEQ(conv.rec_log,
|
||||
"ClientHello:ServerHello:ClientHello:ServerHello:EncryptedExtension:"
|
||||
"Certificate:CertificateVerify:Finished:Finished:SessionTicket");
|
||||
QuicTestContext_free(&tclient);
|
||||
QuicTestContext_free(&tserver);
|
||||
printf(" test_quic_key_share: retry ok\n");
|
||||
|
||||
/* If no group overlap, expect failure */
|
||||
QuicTestContext_init(&tclient, ctx_c, "client", verbose);
|
||||
QuicTestContext_init(&tserver, ctx_s, "server", verbose);
|
||||
AssertTrue(wolfSSL_set1_curves_list(tclient.ssl, "P-256")
|
||||
== WOLFSSL_SUCCESS);
|
||||
AssertTrue(wolfSSL_set1_curves_list(tserver.ssl, "X25519")
|
||||
== WOLFSSL_SUCCESS);
|
||||
QuicConversation_init(&conv, &tclient, &tserver);
|
||||
QuicConversation_fail(&conv);
|
||||
AssertIntEQ(wolfSSL_get_error(tserver.ssl, 0), SSL_ERROR_WANT_READ);
|
||||
AssertIntEQ(wolfSSL_get_error(tclient.ssl, 0), BAD_KEY_SHARE_DATA);
|
||||
QuicTestContext_free(&tclient);
|
||||
QuicTestContext_free(&tserver);
|
||||
printf(" test_quic_key_share: no match ok\n");
|
||||
|
||||
wolfSSL_CTX_free(ctx_c);
|
||||
wolfSSL_CTX_free(ctx_s);
|
||||
@ -1476,7 +1536,7 @@ int QuicTest(void)
|
||||
if ((ret = test_quic_key_share(verbose)) != 0) goto leave;
|
||||
if ((ret = test_quic_resumption(verbose)) != 0) goto leave;
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
if ((ret = test_quic_early_data(verbose || 1)) != 0) goto leave;
|
||||
if ((ret = test_quic_early_data(verbose)) != 0) goto leave;
|
||||
#endif /* WOLFSSL_EARLY_DATA */
|
||||
if ((ret = test_quic_session_export(verbose)) != 0) goto leave;
|
||||
#endif /* HAVE_SESSION_TICKET */
|
||||
|
Loading…
x
Reference in New Issue
Block a user