Expose *_set_groups for TLS < 1.3

- Add test to make sure we fail on curve mismatch
This commit is contained in:
Juliusz Sosinowicz
2024-04-04 18:43:28 +02:00
parent 020bcd0043
commit 6b47ebd66a
7 changed files with 233 additions and 111 deletions

View File

@ -517,6 +517,22 @@ int IsTLS(const WOLFSSL* ssl)
{
if (ssl->version.major == SSLv3_MAJOR && ssl->version.minor >=TLSv1_MINOR)
return 1;
#ifdef WOLFSSL_DTLS
if (ssl->version.major == DTLS_MAJOR)
return 1;
#endif
return 0;
}
int IsTLS_ex(const ProtocolVersion pv)
{
if (pv.major == SSLv3_MAJOR && pv.minor >=TLSv1_MINOR)
return 1;
#ifdef WOLFSSL_DTLS
if (pv.major == DTLS_MAJOR)
return 1;
#endif
return 0;
}

View File

@ -2692,6 +2692,7 @@ int wolfSSL_GetOutputSize(WOLFSSL* ssl, int inSz)
#ifdef HAVE_ECC
int wolfSSL_CTX_SetMinEccKey_Sz(WOLFSSL_CTX* ctx, short keySz)
{
WOLFSSL_ENTER("wolfSSL_CTX_SetMinEccKey_Sz");
if (ctx == NULL || keySz < 0 || keySz % 8 != 0) {
WOLFSSL_MSG("Key size must be divisible by 8 or ctx was null");
return BAD_FUNC_ARG;
@ -2707,6 +2708,7 @@ int wolfSSL_CTX_SetMinEccKey_Sz(WOLFSSL_CTX* ctx, short keySz)
int wolfSSL_SetMinEccKey_Sz(WOLFSSL* ssl, short keySz)
{
WOLFSSL_ENTER("wolfSSL_SetMinEccKey_Sz");
if (ssl == NULL || keySz < 0 || keySz % 8 != 0) {
WOLFSSL_MSG("Key size must be divisible by 8 or ssl was null");
return BAD_FUNC_ARG;
@ -3349,7 +3351,7 @@ int wolfSSL_CTX_UseSupportedCurve(WOLFSSL_CTX* ctx, word16 name)
#endif /* NO_TLS */
}
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_TLS13)
#if defined(OPENSSL_EXTRA)
int wolfSSL_CTX_set1_groups(WOLFSSL_CTX* ctx, int* groups,
int count)
{
@ -3420,7 +3422,7 @@ int wolfSSL_set1_groups(WOLFSSL* ssl, int* groups, int count)
return wolfSSL_set_groups(ssl, _groups, count) == WOLFSSL_SUCCESS ?
WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
}
#endif /* OPENSSL_EXTRA && WOLFSSL_TLS13 */
#endif /* OPENSSL_EXTRA */
#endif /* HAVE_SUPPORTED_CURVES */
/* Application-Layer Protocol Negotiation */
@ -7877,6 +7879,8 @@ WOLFSSL_API int wolfSSL_get_negotiated_server_cert_type(WOLFSSL* ssl, int* tp)
/* Set Temp CTX EC-DHE size in octets, can be 14 - 66 (112 - 521 bit) */
int wolfSSL_CTX_SetTmpEC_DHE_Sz(WOLFSSL_CTX* ctx, word16 sz)
{
WOLFSSL_ENTER("wolfSSL_CTX_SetTmpEC_DHE_Sz");
if (ctx == NULL)
return BAD_FUNC_ARG;
@ -7911,6 +7915,8 @@ int wolfSSL_CTX_SetTmpEC_DHE_Sz(WOLFSSL_CTX* ctx, word16 sz)
/* Set Temp SSL EC-DHE size in octets, can be 14 - 66 (112 - 521 bit) */
int wolfSSL_SetTmpEC_DHE_Sz(WOLFSSL* ssl, word16 sz)
{
WOLFSSL_ENTER("wolfSSL_SetTmpEC_DHE_Sz");
if (ssl == NULL)
return BAD_FUNC_ARG;
@ -15819,7 +15825,6 @@ long wolfSSL_set_options(WOLFSSL* ssl, long op)
}
ssl->suites->hashSigAlgoSz = out;
}
}
return ssl->options.mask;
@ -21356,20 +21361,29 @@ void wolfSSL_get0_next_proto_negotiated(const WOLFSSL *s,
#if defined(OPENSSL_EXTRA) || defined(HAVE_CURL)
int wolfSSL_curve_is_disabled(const WOLFSSL* ssl, word16 curve_id)
{
if (curve_id >= WOLFSSL_FFDHE_START) {
/* DH parameters are never disabled. */
return 0;
int ret = 0;
WOLFSSL_ENTER("wolfSSL_curve_is_disabled");
WOLFSSL_MSG_EX("wolfSSL_curve_is_disabled checking for %d", curve_id);
/* (curve_id >= WOLFSSL_FFDHE_START) - DH parameters are never disabled. */
if (curve_id < WOLFSSL_FFDHE_START) {
if (curve_id > WOLFSSL_ECC_MAX_AVAIL) {
WOLFSSL_MSG("Curve id out of supported range");
/* Disabled if not in valid range. */
ret = 1;
}
else if (curve_id >= 32) {
/* 0 is for invalid and 1-14 aren't used otherwise. */
ret = (ssl->disabledCurves & (1U << (curve_id - 32))) != 0;
}
else {
ret = (ssl->disabledCurves & (1U << curve_id)) != 0;
}
}
if (curve_id > WOLFSSL_ECC_MAX_AVAIL) {
WOLFSSL_MSG("Curve id out of supported range");
/* Disabled if not in valid range. */
return 1;
}
if (curve_id >= 32) {
/* 0 is for invalid and 1-14 aren't used otherwise. */
return (ssl->disabledCurves & (1U << (curve_id - 32))) != 0;
}
return (ssl->disabledCurves & (1U << curve_id)) != 0;
WOLFSSL_LEAVE("wolfSSL_curve_is_disabled", ret);
return ret;
}
#if (defined(HAVE_ECC) || \
@ -21504,7 +21518,7 @@ static int set_curves_list(WOLFSSL* ssl, WOLFSSL_CTX *ctx, const char* names)
disabled &= ~(1U << curve);
}
#ifdef HAVE_SUPPORTED_CURVES
#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_OLD_SET_CURVES_LIST)
#if !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
@ -21545,6 +21559,7 @@ leave:
int wolfSSL_CTX_set1_curves_list(WOLFSSL_CTX* ctx, const char* names)
{
WOLFSSL_ENTER("wolfSSL_CTX_set1_curves_list");
if (ctx == NULL || names == NULL) {
WOLFSSL_MSG("ctx or names was NULL");
return WOLFSSL_FAILURE;
@ -21554,6 +21569,7 @@ int wolfSSL_CTX_set1_curves_list(WOLFSSL_CTX* ctx, const char* names)
int wolfSSL_set1_curves_list(WOLFSSL* ssl, const char* names)
{
WOLFSSL_ENTER("wolfSSL_set1_curves_list");
if (ssl == NULL || names == NULL) {
WOLFSSL_MSG("ssl or names was NULL");
return WOLFSSL_FAILURE;

View File

@ -300,6 +300,86 @@ ProtocolVersion MakeTLSv1_3(void)
}
#endif
#if defined(HAVE_SUPPORTED_CURVES)
/* Sets the key exchange groups in rank order on a context.
*
* ctx SSL/TLS context object.
* groups Array of groups.
* count Number of groups in array.
* returns BAD_FUNC_ARG when ctx or groups is NULL, not using TLS v1.3 or
* count is greater than WOLFSSL_MAX_GROUP_COUNT and WOLFSSL_SUCCESS on success.
*/
int wolfSSL_CTX_set_groups(WOLFSSL_CTX* ctx, int* groups, int count)
{
int ret, i;
WOLFSSL_ENTER("wolfSSL_CTX_set_groups");
if (ctx == NULL || groups == NULL || count > WOLFSSL_MAX_GROUP_COUNT)
return BAD_FUNC_ARG;
if (!IsTLS_ex(ctx->method->version))
return BAD_FUNC_ARG;
ctx->numGroups = 0;
#if !defined(NO_TLS)
TLSX_Remove(&ctx->extensions, TLSX_SUPPORTED_GROUPS, ctx->heap);
#endif /* !NO_TLS */
for (i = 0; i < count; i++) {
/* Call to wolfSSL_CTX_UseSupportedCurve also checks if input groups
* are valid */
if ((ret = wolfSSL_CTX_UseSupportedCurve(ctx, (word16)groups[i]))
!= WOLFSSL_SUCCESS) {
#if !defined(NO_TLS)
TLSX_Remove(&ctx->extensions, TLSX_SUPPORTED_GROUPS, ctx->heap);
#endif /* !NO_TLS */
return ret;
}
ctx->group[i] = (word16)groups[i];
}
ctx->numGroups = (byte)count;
return WOLFSSL_SUCCESS;
}
/* Sets the key exchange groups in rank order.
*
* ssl SSL/TLS object.
* groups Array of groups.
* count Number of groups in array.
* returns BAD_FUNC_ARG when ssl or groups is NULL, not using TLS v1.3 or
* count is greater than WOLFSSL_MAX_GROUP_COUNT and WOLFSSL_SUCCESS on success.
*/
int wolfSSL_set_groups(WOLFSSL* ssl, int* groups, int count)
{
int ret, i;
WOLFSSL_ENTER("wolfSSL_set_groups");
if (ssl == NULL || groups == NULL || count > WOLFSSL_MAX_GROUP_COUNT)
return BAD_FUNC_ARG;
if (!IsTLS_ex(ssl->version))
return BAD_FUNC_ARG;
ssl->numGroups = 0;
#if !defined(NO_TLS)
TLSX_Remove(&ssl->extensions, TLSX_SUPPORTED_GROUPS, ssl->heap);
#endif /* !NO_TLS */
for (i = 0; i < count; i++) {
/* Call to wolfSSL_UseSupportedCurve also checks if input groups
* are valid */
if ((ret = wolfSSL_UseSupportedCurve(ssl, (word16)groups[i]))
!= WOLFSSL_SUCCESS) {
#if !defined(NO_TLS)
TLSX_Remove(&ssl->extensions, TLSX_SUPPORTED_GROUPS, ssl->heap);
#endif /* !NO_TLS */
return ret;
}
ssl->group[i] = (word16)groups[i];
}
ssl->numGroups = (byte)count;
return WOLFSSL_SUCCESS;
}
#endif /* HAVE_SUPPORTED_CURVES */
#ifndef WOLFSSL_NO_TLS12
#ifdef HAVE_EXTENDED_MASTER
@ -4675,6 +4755,7 @@ int TLSX_ValidateSupportedCurves(const WOLFSSL* ssl, byte first, byte second,
int ephmSuite = 0;
word16 octets = 0; /* according to 'ecc_set_type ecc_sets[];' */
int key = 0; /* validate key */
int foundCurve = 0; /* Found at least one supported curve */
(void)oid;
@ -4836,6 +4917,8 @@ int TLSX_ValidateSupportedCurves(const WOLFSSL* ssl, byte first, byte second,
default: continue; /* unsupported curve */
}
foundCurve = 1;
#ifdef HAVE_ECC
/* Set default Oid */
if (defOid == 0 && ssl->eccTempKeySz <= octets && defSz > octets) {
@ -4980,6 +5063,10 @@ int TLSX_ValidateSupportedCurves(const WOLFSSL* ssl, byte first, byte second,
}
}
/* Check we found at least one supported curve */
if (!foundCurve)
return 0;
*ecdhCurveOID = ssl->ecdhCurveOID;
/* Choose the default if it is at the required strength. */
#ifdef HAVE_ECC

View File

@ -13687,86 +13687,6 @@ int wolfSSL_preferred_group(WOLFSSL* ssl)
}
#endif
#if defined(HAVE_SUPPORTED_CURVES)
/* Sets the key exchange groups in rank order on a context.
*
* ctx SSL/TLS context object.
* groups Array of groups.
* count Number of groups in array.
* returns BAD_FUNC_ARG when ctx or groups is NULL, not using TLS v1.3 or
* count is greater than WOLFSSL_MAX_GROUP_COUNT and WOLFSSL_SUCCESS on success.
*/
int wolfSSL_CTX_set_groups(WOLFSSL_CTX* ctx, int* groups, int count)
{
int ret, i;
WOLFSSL_ENTER("wolfSSL_CTX_set_groups");
if (ctx == NULL || groups == NULL || count > WOLFSSL_MAX_GROUP_COUNT)
return BAD_FUNC_ARG;
if (!IsAtLeastTLSv1_3(ctx->method->version))
return BAD_FUNC_ARG;
ctx->numGroups = 0;
#if !defined(NO_TLS)
TLSX_Remove(&ctx->extensions, TLSX_SUPPORTED_GROUPS, ctx->heap);
#endif /* !NO_TLS */
for (i = 0; i < count; i++) {
/* Call to wolfSSL_CTX_UseSupportedCurve also checks if input groups
* are valid */
if ((ret = wolfSSL_CTX_UseSupportedCurve(ctx, (word16)groups[i]))
!= WOLFSSL_SUCCESS) {
#if !defined(NO_TLS)
TLSX_Remove(&ctx->extensions, TLSX_SUPPORTED_GROUPS, ctx->heap);
#endif /* !NO_TLS */
return ret;
}
ctx->group[i] = (word16)groups[i];
}
ctx->numGroups = (byte)count;
return WOLFSSL_SUCCESS;
}
/* Sets the key exchange groups in rank order.
*
* ssl SSL/TLS object.
* groups Array of groups.
* count Number of groups in array.
* returns BAD_FUNC_ARG when ssl or groups is NULL, not using TLS v1.3 or
* count is greater than WOLFSSL_MAX_GROUP_COUNT and WOLFSSL_SUCCESS on success.
*/
int wolfSSL_set_groups(WOLFSSL* ssl, int* groups, int count)
{
int ret, i;
WOLFSSL_ENTER("wolfSSL_set_groups");
if (ssl == NULL || groups == NULL || count > WOLFSSL_MAX_GROUP_COUNT)
return BAD_FUNC_ARG;
if (!IsAtLeastTLSv1_3(ssl->version))
return BAD_FUNC_ARG;
ssl->numGroups = 0;
#if !defined(NO_TLS)
TLSX_Remove(&ssl->extensions, TLSX_SUPPORTED_GROUPS, ssl->heap);
#endif /* !NO_TLS */
for (i = 0; i < count; i++) {
/* Call to wolfSSL_UseSupportedCurve also checks if input groups
* are valid */
if ((ret = wolfSSL_UseSupportedCurve(ssl, (word16)groups[i]))
!= WOLFSSL_SUCCESS) {
#if !defined(NO_TLS)
TLSX_Remove(&ssl->extensions, TLSX_SUPPORTED_GROUPS, ssl->heap);
#endif /* !NO_TLS */
return ret;
}
ssl->group[i] = (word16)groups[i];
}
ssl->numGroups = (byte)count;
return WOLFSSL_SUCCESS;
}
#endif /* HAVE_SUPPORTED_CURVES */
#ifndef NO_PSK
/* Set the PSK callback, that is passed the cipher suite, for a client to use
* against context object.

View File

@ -40475,6 +40475,86 @@ static int test_wolfSSL_set1_curves_list(void)
return EXPECT_RESULT();
}
#if defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
static int test_wolfSSL_curves_mismatch_ctx_ready(WOLFSSL_CTX* ctx)
{
static int counter = 0;
EXPECT_DECLS;
if (counter % 2) {
ExpectIntEQ(wolfSSL_CTX_set1_curves_list(ctx, "P-256"),
WOLFSSL_SUCCESS);
}
else {
ExpectIntEQ(wolfSSL_CTX_set1_curves_list(ctx, "P-384"),
WOLFSSL_SUCCESS);
}
/* Ciphersuites that require curves */
wolfSSL_CTX_set_cipher_list(ctx, "TLS13-AES256-GCM-SHA384:"
"TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES128-GCM-SHA256:"
"ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:"
"ECDHE-ECDSA-AES128-GCM-SHA256:"
"ECDHE-RSA-AES128-GCM-SHA256");
counter++;
return EXPECT_RESULT();
}
#endif
static int test_wolfSSL_curves_mismatch(void)
{
EXPECT_DECLS;
#if defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
test_ssl_cbf func_cb_client;
test_ssl_cbf func_cb_server;
size_t i;
struct {
method_provider client_meth;
method_provider server_meth;
const char* desc;
int client_last_err;
int server_last_err;
} test_params[] = {
#ifdef WOLFSSL_TLS13
{wolfTLSv1_3_client_method, wolfTLSv1_3_server_method, "TLS 1.3",
FATAL_ERROR, BAD_KEY_SHARE_DATA},
#endif
#ifndef WOLFSSL_NO_TLS12
{wolfTLSv1_2_client_method, wolfTLSv1_2_server_method, "TLS 1.2",
FATAL_ERROR, MATCH_SUITE_ERROR},
#endif
#ifndef NO_OLD_TLS
{wolfTLSv1_1_client_method, wolfTLSv1_1_server_method, "TLS 1.1",
FATAL_ERROR, MATCH_SUITE_ERROR},
#endif
};
for (i = 0; i < XELEM_CNT(test_params) && !EXPECT_FAIL(); i++) {
XMEMSET(&func_cb_client, 0, sizeof(func_cb_client));
XMEMSET(&func_cb_server, 0, sizeof(func_cb_server));
printf("\tTesting with %s...\n", test_params[i].desc);
func_cb_client.ctx_ready = &test_wolfSSL_curves_mismatch_ctx_ready;
func_cb_server.ctx_ready = &test_wolfSSL_curves_mismatch_ctx_ready;
func_cb_client.method = test_params[i].client_meth;
func_cb_server.method = test_params[i].server_meth;
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client,
&func_cb_server, NULL), TEST_FAIL);
ExpectIntEQ(func_cb_client.last_err, test_params[i].client_last_err);
ExpectIntEQ(func_cb_server.last_err, test_params[i].server_last_err);
if (!EXPECT_SUCCESS())
break;
printf("\t%s passed\n", test_params[i].desc);
}
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_set1_sigalgs_list(void)
{
EXPECT_DECLS;
@ -72292,6 +72372,7 @@ TEST_CASE testCases[] = {
TEST_DECL(test_wolfSSL_configure_args),
TEST_DECL(test_wolfSSL_sk_SSL_CIPHER),
TEST_DECL(test_wolfSSL_set1_curves_list),
TEST_DECL(test_wolfSSL_curves_mismatch),
TEST_DECL(test_wolfSSL_set1_sigalgs_list),
TEST_DECL(test_wolfSSL_OtherName),

View File

@ -6186,6 +6186,7 @@ WOLFSSL_LOCAL int DeriveKeys(WOLFSSL* ssl);
WOLFSSL_LOCAL int StoreKeys(WOLFSSL* ssl, const byte* keyData, int side);
WOLFSSL_LOCAL int IsTLS(const WOLFSSL* ssl);
WOLFSSL_LOCAL int IsTLS_ex(const ProtocolVersion pv);
WOLFSSL_LOCAL int IsAtLeastTLSv1_2(const WOLFSSL* ssl);
WOLFSSL_LOCAL int IsAtLeastTLSv1_3(ProtocolVersion pv);
WOLFSSL_LOCAL int IsEncryptionOn(const WOLFSSL* ssl, int isSend);

View File

@ -1181,6 +1181,21 @@ WOLFSSL_API int wolfSSL_peek(WOLFSSL* ssl, void* data, int sz);
WOLFSSL_ABI WOLFSSL_API int wolfSSL_accept(WOLFSSL* ssl);
WOLFSSL_API int wolfSSL_CTX_mutual_auth(WOLFSSL_CTX* ctx, int req);
WOLFSSL_API int wolfSSL_mutual_auth(WOLFSSL* ssl, int req);
WOLFSSL_API int wolfSSL_CTX_set_groups(WOLFSSL_CTX* ctx, int* groups,
int count);
WOLFSSL_API int wolfSSL_set_groups(WOLFSSL* ssl, int* groups, int count);
#if defined(OPENSSL_EXTRA) && defined(HAVE_SUPPORTED_CURVES)
WOLFSSL_API int wolfSSL_CTX_set1_groups(WOLFSSL_CTX* ctx, int* groups,
int count);
WOLFSSL_API int wolfSSL_set1_groups(WOLFSSL* ssl, int* groups, int count);
#ifdef HAVE_ECC
WOLFSSL_API int wolfSSL_CTX_set1_groups_list(WOLFSSL_CTX *ctx, const char *list);
WOLFSSL_API int wolfSSL_set1_groups_list(WOLFSSL *ssl, const char *list);
#endif
#endif
#ifdef WOLFSSL_TLS13
WOLFSSL_API int wolfSSL_send_hrr_cookie(WOLFSSL* ssl,
const unsigned char* secret, unsigned int secretSz);
@ -1198,20 +1213,6 @@ WOLFSSL_API int wolfSSL_allow_post_handshake_auth(WOLFSSL* ssl);
WOLFSSL_API int wolfSSL_request_certificate(WOLFSSL* ssl);
WOLFSSL_API int wolfSSL_preferred_group(WOLFSSL* ssl);
WOLFSSL_API int wolfSSL_CTX_set_groups(WOLFSSL_CTX* ctx, int* groups,
int count);
WOLFSSL_API int wolfSSL_set_groups(WOLFSSL* ssl, int* groups, int count);
#if defined(OPENSSL_EXTRA) && defined(HAVE_SUPPORTED_CURVES)
WOLFSSL_API int wolfSSL_CTX_set1_groups(WOLFSSL_CTX* ctx, int* groups,
int count);
WOLFSSL_API int wolfSSL_set1_groups(WOLFSSL* ssl, int* groups, int count);
#ifdef HAVE_ECC
WOLFSSL_API int wolfSSL_CTX_set1_groups_list(WOLFSSL_CTX *ctx, const char *list);
WOLFSSL_API int wolfSSL_set1_groups_list(WOLFSSL *ssl, const char *list);
#endif
#endif
WOLFSSL_API int wolfSSL_connect_TLSv13(WOLFSSL* ssl);
WOLFSSL_API int wolfSSL_accept_TLSv13(WOLFSSL* ssl);