From a3e085f204079003b36e6328d23cd91c10c261bb Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Wed, 4 Jan 2023 10:49:18 -0800 Subject: [PATCH 1/3] very basic support for public key types in cipher list string with '+' --- src/internal.c | 32 +++++++++++++++++++++++++++++++- tests/api.c | 6 ++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/internal.c b/src/internal.c index 1afa361f9..c11a90fda 100644 --- a/src/internal.c +++ b/src/internal.c @@ -24280,13 +24280,33 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list) } } - #ifdef OPENSSL_EXTRA + #if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) if (length > 1) { + const char* substr = NULL; + if (*current == '!') { allowing = 0; current++; length--; } + + /* extract public key types from a string like ECDHE+AESGCM */ + substr = XSTRSTR(current, "+"); + if (substr != NULL) { + word32 currLen = (word32)(substr - current); + if (length > currLen) { + length = currLen; + } + + /* checking for the DH substring includes ECDH / ECDHE suites */ + if (XSTRSTR(substr, "DH") || XSTRSTR(substr, "RSA")) { + substr += 1; /* +1 to skip over '+' */ + current = substr; + } + else { + length = (word32)(substr - current); + } + } } #endif @@ -24383,6 +24403,16 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list) continue; } + if (XSTRCMP(name, "ECDHE") == 0) { + if (allowing) { + haveECC = 1; + haveECDSAsig = 1; + callInitSuites = 1; + ret = 1; + } + continue; + } + if (XSTRCMP(name, "kRSA") == 0 || XSTRCMP(name, "RSA") == 0) { haveStaticRSA = allowing; if (allowing) { diff --git a/tests/api.c b/tests/api.c index 95b010f5a..e8508bcc3 100644 --- a/tests/api.c +++ b/tests/api.c @@ -7113,6 +7113,12 @@ static int test_wolfSSL_CTX_set_cipher_list(void) AssertIntEQ(server_args.return_code, TEST_SUCCESS); FreeTcpReady(&ready); + + /* check with cipher string that has '+' */ + AssertNotNull((ctxClient = wolfSSL_CTX_new(wolfTLSv1_2_client_method()))); + AssertTrue(wolfSSL_CTX_set_cipher_list(ctxClient, "ECDHE+AESGCM")); + wolfSSL_CTX_free(ctxClient); + res = TEST_RES_CHECK(1); #endif return res; From ab33788cdb2e5ff66653ca0cf3f3ae797f958739 Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Thu, 5 Jan 2023 13:48:34 -0800 Subject: [PATCH 2/3] treat ECDHE,RSA cipher suite list as mixed TLS 1.3 and pre TLS 1.3 --- src/ssl.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/ssl.c b/src/ssl.c index 33d70b416..4227cb859 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -11765,6 +11765,28 @@ static int CheckcipherList(const char* list) break; } } + + #if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) + /* check if mixed due to names like RSA:ECDHE+AESGCM etc. */ + if (ret != 0) { + char* subStr = name; + char* subStrNext; + + do { + subStrNext = XSTRSTR(subStr, "+"); + + if ((XSTRCMP(subStr, "ECDHE") == 0) || + (XSTRCMP(subStr, "RSA") == 0)) { + return 0; + } + + if (subStrNext && (XSTRLEN(subStrNext) > 0)) { + subStr = subStrNext + 1; /* +1 to skip past '+' */ + } + } while (subStrNext != NULL); + } + #endif + if (findTLSv13Suites == 1 && findbeforeSuites == 1) { /* list has mixed suites */ return 0; From 99a489dec3933c9b76c1a7e2b1749e2ac5bfa572 Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Fri, 6 Jan 2023 09:53:51 -0800 Subject: [PATCH 3/3] improve test and handling of public key type cipher suite string --- src/internal.c | 59 +++++++++++++++++++++++++++++++------------------- tests/api.c | 27 +++++++++++++++++++++++ 2 files changed, 64 insertions(+), 22 deletions(-) diff --git a/src/internal.c b/src/internal.c index c11a90fda..95592d240 100644 --- a/src/internal.c +++ b/src/internal.c @@ -24267,7 +24267,7 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list) char name[MAX_SUITE_NAME + 1]; int i; word32 length; - #ifdef OPENSSL_EXTRA + #if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) int allowing = 1; #endif @@ -24282,38 +24282,53 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list) #if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) if (length > 1) { - const char* substr = NULL; - if (*current == '!') { allowing = 0; current++; length--; } - - /* extract public key types from a string like ECDHE+AESGCM */ - substr = XSTRSTR(current, "+"); - if (substr != NULL) { - word32 currLen = (word32)(substr - current); - if (length > currLen) { - length = currLen; - } - - /* checking for the DH substring includes ECDH / ECDHE suites */ - if (XSTRSTR(substr, "DH") || XSTRSTR(substr, "RSA")) { - substr += 1; /* +1 to skip over '+' */ - current = substr; - } - else { - length = (word32)(substr - current); - } - } } #endif XSTRNCPY(name, current, length); name[(length == sizeof(name)) ? length - 1 : length] = 0; - #ifdef OPENSSL_EXTRA + + #if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) + if (length > 1) { + char* substr = NULL; + char* substrCurrent = name; + + /* extract first public key type from a string like ECDHE+AESGCM */ + substr = XSTRSTR(substrCurrent, "+"); + if (substr != NULL) { + do { + if (substr) { + length = (word32)(substr - substrCurrent); + substrCurrent[length] = '\0'; + } + else { + length = (int)XSTRLEN(substrCurrent); + } + + /* check if is a public key type */ + if (XSTRCMP(substrCurrent, "ECDHE") == 0 || + XSTRCMP(substrCurrent, "RSA") == 0 || + XSTRCMP(substrCurrent, "DHE") == 0) { + XMEMCPY(name, substrCurrent, length); + name[length] = '\0'; + break; + } + + substrCurrent = substr; + if (substr) { + substrCurrent = substrCurrent + 1; /* +1 to skip over '+' */ + substr = XSTRSTR(substrCurrent, "+"); + } + } while (substrCurrent != NULL); + } + } + if (XSTRCMP(name, "DEFAULT") == 0 || XSTRCMP(name, "ALL") == 0) { if (XSTRCMP(name, "ALL") == 0) haveAnon = 1; diff --git a/tests/api.c b/tests/api.c index e8508bcc3..ee03ce64f 100644 --- a/tests/api.c +++ b/tests/api.c @@ -7061,6 +7061,7 @@ static int test_wolfSSL_CTX_set_cipher_list(void) && !defined(NO_SHA256) WOLFSSL_CTX* ctx; WOLFSSL_CTX* ctxClient; + WOLFSSL* sslClient; tcp_ready ready; func_args client_args; func_args server_args; @@ -7117,6 +7118,32 @@ static int test_wolfSSL_CTX_set_cipher_list(void) /* check with cipher string that has '+' */ AssertNotNull((ctxClient = wolfSSL_CTX_new(wolfTLSv1_2_client_method()))); AssertTrue(wolfSSL_CTX_set_cipher_list(ctxClient, "ECDHE+AESGCM")); + AssertNotNull((sslClient = wolfSSL_new(ctxClient))); + + /* check for the existance of an ECDHE ECDSA cipher suite */ + { + int i = 0; + int found = 0; + const char* suite; + + WOLF_STACK_OF(WOLFSSL_CIPHER)* sk; + WOLFSSL_CIPHER* current; + + AssertNotNull((sk = wolfSSL_get_ciphers_compat(sslClient))); + do { + current = wolfSSL_sk_SSL_CIPHER_value(sk, i++); + if (current) { + suite = wolfSSL_CIPHER_get_name(current); + if (suite && XSTRSTR(suite, "ECDSA")) { + found = 1; + break; + } + } + } while (current); + AssertIntEQ(found, 1); + } + + wolfSSL_free(sslClient); wolfSSL_CTX_free(ctxClient); res = TEST_RES_CHECK(1);