diff --git a/src/ssl.c b/src/ssl.c index 149594eb0..945ac32e5 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -134,6 +134,34 @@ #endif /* !WOLFCRYPT_ONLY || OPENSSL_EXTRA */ #ifndef WOLFCRYPT_ONLY +#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) +const WOLF_EC_NIST_NAME kNistCurves[] = { + {STR_SIZEOF("P-192"), "P-192", NID_X9_62_prime192v1}, + {STR_SIZEOF("P-256"), "P-256", NID_X9_62_prime256v1}, + {STR_SIZEOF("P-112"), "P-112", NID_secp112r1}, + {STR_SIZEOF("P-112-2"), "P-112-2", NID_secp112r2}, + {STR_SIZEOF("P-128"), "P-128", NID_secp128r1}, + {STR_SIZEOF("P-128-2"), "P-128-2", NID_secp128r2}, + {STR_SIZEOF("P-160"), "P-160", NID_secp160r1}, + {STR_SIZEOF("P-160-2"), "P-160-2", NID_secp160r2}, + {STR_SIZEOF("P-224"), "P-224", NID_secp224r1}, + {STR_SIZEOF("P-384"), "P-384", NID_secp384r1}, + {STR_SIZEOF("P-521"), "P-521", NID_secp521r1}, + {STR_SIZEOF("K-160"), "K-160", NID_secp160k1}, + {STR_SIZEOF("K-192"), "K-192", NID_secp192k1}, + {STR_SIZEOF("K-224"), "K-224", NID_secp224k1}, + {STR_SIZEOF("K-256"), "K-256", NID_secp256k1}, + {STR_SIZEOF("B-160"), "B-160", NID_brainpoolP160r1}, + {STR_SIZEOF("B-192"), "B-192", NID_brainpoolP192r1}, + {STR_SIZEOF("B-224"), "B-224", NID_brainpoolP224r1}, + {STR_SIZEOF("B-256"), "B-256", NID_brainpoolP256r1}, + {STR_SIZEOF("B-320"), "B-320", NID_brainpoolP320r1}, + {STR_SIZEOF("B-384"), "B-384", NID_brainpoolP384r1}, + {STR_SIZEOF("B-512"), "B-512", NID_brainpoolP512r1}, + {0, NULL, 0}, +}; +#endif + #if defined(WOLFSSL_RENESAS_TSIP_TLS) /* for root ca verification */ int tsip_tls_RootCertVerify(const byte *cert, word32 cert_len, @@ -33095,45 +33123,95 @@ int wolfSSL_EVP_PKEY_set1_EC_KEY(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_EC_KEY *key) } #endif /* WOLFSSL_QT || OPENSSL_ALL */ -typedef struct { - const char *name; - int nid; -} WOLF_EC_NIST_NAME; -static const WOLF_EC_NIST_NAME kNistCurves[] = { - {"P-192", NID_X9_62_prime192v1}, - {"P-256", NID_X9_62_prime256v1}, - {"P-112", NID_secp112r1}, - {"P-112-2", NID_secp112r2}, - {"P-128", NID_secp128r1}, - {"P-128-2", NID_secp128r2}, - {"P-160", NID_secp160r1}, - {"P-160-2", NID_secp160r2}, - {"P-224", NID_secp224r1}, - {"P-384", NID_secp384r1}, - {"P-521", NID_secp521r1}, - {"K-160", NID_secp160k1}, - {"K-192", NID_secp192k1}, - {"K-224", NID_secp224k1}, - {"K-256", NID_secp256k1}, - {"B-160", NID_brainpoolP160r1}, - {"B-192", NID_brainpoolP192r1}, - {"B-224", NID_brainpoolP224r1}, - {"B-256", NID_brainpoolP256r1}, - {"B-320", NID_brainpoolP320r1}, - {"B-384", NID_brainpoolP384r1}, - {"B-512", NID_brainpoolP512r1}, -}; const char* wolfSSL_EC_curve_nid2nist(int nid) { - int i; - for (i = 0; i < (int)(sizeof(kNistCurves)/sizeof(WOLF_EC_NIST_NAME)); i++) { - if (kNistCurves[i].nid == nid) { - return kNistCurves[i].name; + const WOLF_EC_NIST_NAME* nist_name; + for (nist_name = kNistCurves; nist_name->name != NULL; nist_name++) { + if (nist_name->nid == nid) { + return kNistCurves->name; } } return NULL; } +#ifdef WOLFSSL_TLS13 +static int populate_groups(int* groups, int max_count, char *list) +{ + char *end; + size_t len; + int count = 0; + const WOLF_EC_NIST_NAME* nist_name; + + if (!groups || !list) { + return -1; + } + + for (end = list; ; list = ++end) { + if (count > max_count) { + WOLFSSL_MSG("Too many curves in list"); + return -1; + } + while (*end != ':' && *end != '\0') end++; + len = end - list; /* end points to char after end + * of curve name so no need for -1 */ + if ((len < kNistCurves_MIN_NAME_LEN) || + (len > kNistCurves_MAX_NAME_LEN)) { + WOLFSSL_MSG("Unrecognized curve name in list"); + return -1; + } + for (nist_name = kNistCurves; nist_name->name != NULL; nist_name++) { + if (XSTRNCMP(list, nist_name->name, nist_name->name_len) == 0) { + break; + } + } + if (!nist_name->name) { + WOLFSSL_MSG("Unrecognized curve name in list"); + return -1; + } + groups[count++] = nist_name->nid; + if (*end == '\0') break; + } + + return count; +} + +int wolfSSL_CTX_set1_groups_list(WOLFSSL_CTX *ctx, char *list) +{ + int groups[WOLFSSL_MAX_GROUP_COUNT]; + int count; + + if (!ctx || !list) { + return WOLFSSL_FAILURE; + } + + if ((count = populate_groups(groups, + WOLFSSL_MAX_GROUP_COUNT, list)) == -1) { + return WOLFSSL_FAILURE; + } + + return wolfSSL_CTX_set_groups(ctx, groups, count) == WOLFSSL_SUCCESS ? + WOLFSSL_SUCCESS : WOLFSSL_FAILURE; +} + +int wolfSSL_set1_groups_list(WOLFSSL *ssl, char *list) +{ + int groups[WOLFSSL_MAX_GROUP_COUNT]; + int count; + + if (!ssl || !list) { + return WOLFSSL_FAILURE; + } + + if ((count = populate_groups(groups, + WOLFSSL_MAX_GROUP_COUNT, list)) == -1) { + return WOLFSSL_FAILURE; + } + + return wolfSSL_set_groups(ssl, groups, count) == WOLFSSL_SUCCESS ? + WOLFSSL_SUCCESS : WOLFSSL_FAILURE; +} +#endif /* WOLFSSL_TLS13 */ + #endif /* HAVE_ECC */ #endif /* OPENSSL_EXTRA */ diff --git a/tests/api.c b/tests/api.c index 846724350..4ade806c7 100644 --- a/tests/api.c +++ b/tests/api.c @@ -28248,6 +28248,9 @@ static int test_tls13_apis(void) #endif int groups[1] = { WOLFSSL_ECC_X25519 }; int numGroups = 1; +#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) + char groupList[] = "P-521:P-384:P-256"; +#endif /* defined(OPENSSL_EXTRA) && defined(HAVE_ECC) */ #ifndef WOLFSSL_NO_TLS12 #ifndef NO_WOLFSSL_CLIENT @@ -28491,6 +28494,44 @@ static int test_tls13_apis(void) WOLFSSL_SUCCESS); #endif +#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) + AssertIntEQ(wolfSSL_CTX_set1_groups_list(NULL, NULL), WOLFSSL_FAILURE); +#ifndef NO_WOLFSSL_CLIENT + AssertIntEQ(wolfSSL_CTX_set1_groups_list(clientCtx, NULL), WOLFSSL_FAILURE); +#endif + AssertIntEQ(wolfSSL_CTX_set1_groups_list(NULL, groupList), WOLFSSL_FAILURE); +#ifndef NO_WOLFSSL_CLIENT +#ifndef WOLFSSL_NO_TLS12 + AssertIntEQ(wolfSSL_CTX_set1_groups_list(clientTls12Ctx, groupList), + WOLFSSL_FAILURE); +#endif + AssertIntEQ(wolfSSL_CTX_set1_groups_list(clientCtx, groupList), + WOLFSSL_SUCCESS); +#endif +#ifndef NO_WOLFSSL_SERVER + AssertIntEQ(wolfSSL_CTX_set1_groups_list(serverCtx, groupList), + WOLFSSL_SUCCESS); +#endif + + AssertIntEQ(wolfSSL_set1_groups_list(NULL, NULL), WOLFSSL_FAILURE); +#ifndef NO_WOLFSSL_CLIENT + AssertIntEQ(wolfSSL_set1_groups_list(clientSsl, NULL), WOLFSSL_FAILURE); +#endif + AssertIntEQ(wolfSSL_set1_groups_list(NULL, groupList), WOLFSSL_FAILURE); +#ifndef NO_WOLFSSL_CLIENT +#ifndef WOLFSSL_NO_TLS12 + AssertIntEQ(wolfSSL_set1_groups_list(clientTls12Ssl, groupList), + WOLFSSL_FAILURE); +#endif + AssertIntEQ(wolfSSL_set1_groups_list(clientSsl, groupList), + WOLFSSL_SUCCESS); +#endif +#ifndef NO_WOLFSSL_SERVER + AssertIntEQ(wolfSSL_set1_groups_list(serverSsl, groupList), + WOLFSSL_SUCCESS); +#endif +#endif /* defined(OPENSSL_EXTRA) && defined(HAVE_ECC) */ + #ifdef WOLFSSL_EARLY_DATA AssertIntEQ(wolfSSL_CTX_set_max_early_data(NULL, 0), BAD_FUNC_ARG); #ifndef NO_WOLFSSL_CLIENT diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 15701bb4a..a586184d7 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -4235,6 +4235,19 @@ static const byte server[SIZEOF_SENDER] = { 0x53, 0x52, 0x56, 0x52 }; static const byte tls_client[FINISHED_LABEL_SZ + 1] = "client finished"; static const byte tls_server[FINISHED_LABEL_SZ + 1] = "server finished"; +#define STR_SIZEOF(x) (sizeof(x) - 1) /* -1 to not count the null char */ + +#ifdef OPENSSL_EXTRA +typedef struct { + int name_len; + const char *name; + int nid; +} WOLF_EC_NIST_NAME; +extern const WOLF_EC_NIST_NAME kNistCurves[]; +/* This is the longest and shortest curve name in the kNistCurves list */ +#define kNistCurves_MIN_NAME_LEN 5 +#define kNistCurves_MAX_NAME_LEN 7 +#endif /* internal functions */ WOLFSSL_LOCAL int SendChangeCipher(WOLFSSL*); diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index b5d016117..a1e01a126 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -293,6 +293,9 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; /* wolfSSL does not support expoting keying material */ #define SSL_export_keying_material(...) 0 +#define SSL_CTX_set1_groups_list wolfSSL_CTX_set1_groups_list +#define SSL_set1_groups_list wolfSSL_set1_groups_list + #define SSL_set_ex_data wolfSSL_set_ex_data #define SSL_get_shutdown wolfSSL_get_shutdown #define SSL_set_rfd wolfSSL_set_rfd diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 9dc3e0224..246734917 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -859,6 +859,9 @@ WOLFSSL_API int wolfSSL_CTX_allow_post_handshake_auth(WOLFSSL_CTX* ctx); WOLFSSL_API int wolfSSL_allow_post_handshake_auth(WOLFSSL* ssl); WOLFSSL_API int wolfSSL_request_certificate(WOLFSSL* ssl); +WOLFSSL_API int wolfSSL_CTX_set1_groups_list(WOLFSSL_CTX *ctx, char *list); +WOLFSSL_API int wolfSSL_set1_groups_list(WOLFSSL *ssl, char *list); + WOLFSSL_API int wolfSSL_preferred_group(WOLFSSL* ssl); WOLFSSL_API int wolfSSL_CTX_set_groups(WOLFSSL_CTX* ctx, int* groups, int count);