diff --git a/src/internal.c b/src/internal.c index 1b93022d6..ffeff4415 100644 --- a/src/internal.c +++ b/src/internal.c @@ -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; } diff --git a/src/ssl.c b/src/ssl.c index 0e7290e7d..d2e45894f 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -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; diff --git a/src/tls.c b/src/tls.c index 2db3c6ff7..82587f032 100644 --- a/src/tls.c +++ b/src/tls.c @@ -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 diff --git a/src/tls13.c b/src/tls13.c index 1522b3fb5..94abe2186 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -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. diff --git a/tests/api.c b/tests/api.c index 0829866ca..0e5ecc2eb 100644 --- a/tests/api.c +++ b/tests/api.c @@ -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), diff --git a/wolfssl/internal.h b/wolfssl/internal.h index c2b289fad..a7780768b 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -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); diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index e7c8832f0..b571ec810 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -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);