diff --git a/src/internal.c b/src/internal.c index 1afa361f9..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 @@ -24280,7 +24280,7 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list) } } - #ifdef OPENSSL_EXTRA + #if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) if (length > 1) { if (*current == '!') { allowing = 0; @@ -24293,7 +24293,42 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list) 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; @@ -24383,6 +24418,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/src/ssl.c b/src/ssl.c index 9a8a13987..a4559bc48 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -11775,6 +11775,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; diff --git a/tests/api.c b/tests/api.c index b1036481c..15877ab87 100644 --- a/tests/api.c +++ b/tests/api.c @@ -7166,6 +7166,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; @@ -7218,6 +7219,38 @@ 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")); + 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); #endif return res;