diff --git a/src/internal.c b/src/internal.c index bc3016362..2001cb9c7 100644 --- a/src/internal.c +++ b/src/internal.c @@ -24086,6 +24086,114 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list) return ret; } + +int SetCipherListFromBytes(WOLFSSL_CTX* ctx, Suites* suites, const byte* list, + const int listSz) +{ + int ret = 0; + int idx = 0; + + int haveRSAsig = 0; + int haveECDSAsig = 0; + int haveFalconSig = 0; + int haveDilithiumSig = 0; + int haveAnon = 0; + + + if (suites == NULL || list == NULL) { + WOLFSSL_MSG("SetCipherListFromBytes parameter error"); + return 0; + } + + for (int i = 0; (i + 1) < listSz; i += 2) { + const byte firstByte = list[i]; + const byte secondByte = list[i + 1]; + const char* name = NULL; + + name = GetCipherNameInternal(firstByte, secondByte); + if (XSTRCMP(name, "None") == 0) { + /* bytes don't match any known cipher */ + continue; + } + + #ifdef WOLFSSL_DTLS + /* don't allow stream ciphers with DTLS */ + if (ctx->method->version.major == DTLS_MAJOR) { + if (XSTRSTR(name, "RC4")) { + WOLFSSL_MSG("Stream ciphers not supported with DTLS"); + continue; + } + } + #endif /* WOLFSSL_DTLS */ + + if (idx + 1 >= WOLFSSL_MAX_SUITE_SZ) { + WOLFSSL_MSG("WOLFSSL_MAX_SUITE_SZ set too low"); + return 0; /* suites buffer not large enough, error out */ + } + + suites->suites[idx++] = firstByte; + suites->suites[idx++] = secondByte; + + /* The suites are either ECDSA, RSA, PSK, or Anon. The RSA + * suites don't necessarily have RSA in the name. */ + #ifdef WOLFSSL_TLS13 + if (firstByte == TLS13_BYTE || (firstByte == ECC_BYTE && + (secondByte == TLS_SHA256_SHA256 || + secondByte == TLS_SHA384_SHA384))) { + #ifndef NO_RSA + haveRSAsig = 1; + #endif + #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) + haveECDSAsig = 1; + #endif + #if defined(HAVE_PQC) + #ifdef HAVE_FALCON + haveFalconSig = 1; + #endif /* HAVE_FALCON */ + #ifdef HAVE_DILITHIUM + haveDilithiumSig = 1; + #endif /* HAVE_DILITHIUM */ + #endif /* HAVE_PQC */ + } + else + #endif /* WOLFSSL_TLS13 */ + #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) + if ((haveECDSAsig == 0) && XSTRSTR(name, "ECDSA")) + haveECDSAsig = 1; + else + #endif + #ifdef HAVE_ANON + if (XSTRSTR(name, "ADH")) + haveAnon = 1; + else + #endif + if (haveRSAsig == 0 + #ifndef NO_PSK + && (XSTRSTR(name, "PSK") == NULL) + #endif + ) { + haveRSAsig = 1; + } + + ret = 1; /* found at least one */ + } + + if (ret) { + int keySz = 0; + #ifndef NO_CERTS + keySz = ctx->privateKeySz; + #endif + suites->suiteSz = (word16)idx; + InitSuitesHashSigAlgo(suites, haveECDSAsig, haveRSAsig, haveFalconSig, + haveDilithiumSig, haveAnon, 1, keySz); + suites->setSuites = 1; + } + + (void)ctx; + + return ret; +} + #ifdef OPENSSL_EXTRA struct mac_algs { diff --git a/src/ssl.c b/src/ssl.c index 934e03e0a..1a752403b 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -11660,6 +11660,31 @@ int wolfSSL_CTX_set_cipher_list(WOLFSSL_CTX* ctx, const char* list) } +int wolfSSL_CTX_set_cipher_list_bytes(WOLFSSL_CTX* ctx, const byte* list, + const int listSz) +{ + WOLFSSL_ENTER("wolfSSL_CTX_set_cipher_list_bytes"); + + if (ctx == NULL) + return WOLFSSL_FAILURE; + + /* alloc/init on demand only */ + if (ctx->suites == NULL) { + ctx->suites = (Suites*)XMALLOC(sizeof(Suites), ctx->heap, + DYNAMIC_TYPE_SUITES); + if (ctx->suites == NULL) { + WOLFSSL_MSG("Memory alloc for Suites failed"); + return WOLFSSL_FAILURE; + } + XMEMSET(ctx->suites, 0, sizeof(Suites)); + } + + return (SetCipherListFromBytes(ctx, ctx->suites, list, listSz)) + ? WOLFSSL_SUCCESS + : WOLFSSL_FAILURE; +} + + int wolfSSL_set_cipher_list(WOLFSSL* ssl, const char* list) { WOLFSSL_ENTER("wolfSSL_set_cipher_list"); @@ -11683,6 +11708,29 @@ int wolfSSL_set_cipher_list(WOLFSSL* ssl, const char* list) #endif } + +int wolfSSL_set_cipher_list_bytes(WOLFSSL* ssl, const byte* list, + const int listSz) +{ + WOLFSSL_ENTER("wolfSSL_set_cipher_list_bytes"); +#ifdef SINGLE_THREADED + if (ssl->ctx->suites == ssl->suites) { + ssl->suites = (Suites*)XMALLOC(sizeof(Suites), ssl->heap, + DYNAMIC_TYPE_SUITES); + if (ssl->suites == NULL) { + WOLFSSL_MSG("Suites Memory error"); + return MEMORY_E; + } + *ssl->suites = *ssl->ctx->suites; + ssl->options.ownSuites = 1; + } +#endif + + return (SetCipherListFromBytes(ssl->ctx, ssl->suites, list, listSz)) + ? WOLFSSL_SUCCESS + : WOLFSSL_FAILURE; +} + #ifdef HAVE_KEYING_MATERIAL #define TLS_PRF_LABEL_CLIENT_FINISHED "client finished" diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 7a09f901b..3f82b5a06 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2032,6 +2032,8 @@ WOLFSSL_LOCAL void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, WOLFSSL_LOCAL int MatchSuite(WOLFSSL* ssl, Suites* peerSuites); WOLFSSL_LOCAL int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list); +WOLFSSL_LOCAL int SetCipherListFromBytes(WOLFSSL_CTX* ctx, Suites* suites, + const byte* list, const int listSz); WOLFSSL_LOCAL int SetSuitesHashSigAlgo(Suites* suites, const char* list); #ifndef PSK_TYPES_DEFINED diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index dfc89c722..183cc0e7b 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1337,6 +1337,10 @@ WOLFSSL_API int wolfSSL_CTX_get_cert_cache_memsize(WOLFSSL_CTX* ctx); WOLFSSL_API int wolfSSL_CTX_set_cipher_list(WOLFSSL_CTX* ctx, const char* list); WOLFSSL_API int wolfSSL_set_cipher_list(WOLFSSL* ssl, const char* list); +/* supports 2 byte code from cipher_name[] */ +WOLFSSL_API int wolfSSL_CTX_set_cipher_list_bytes(WOLFSSL_CTX* ctx, const byte* list, const int listSz); +WOLFSSL_API int wolfSSL_set_cipher_list_bytes(WOLFSSL* ssl, const byte* list, const int listSz); + #ifdef HAVE_KEYING_MATERIAL /* Keying Material Exporter for TLS */ WOLFSSL_API int wolfSSL_export_keying_material(WOLFSSL *ssl,