From 8bc9faf798d366534385fd80d9791f75f62bd988 Mon Sep 17 00:00:00 2001 From: jordan Date: Tue, 26 Nov 2024 16:12:24 -0600 Subject: [PATCH] fedora crypto-policies: initial support. --- configure.ac | 19 + examples/client/client.c | 33 +- examples/crypto_policies/default/wolfssl.txt | 1 + examples/crypto_policies/future/wolfssl.txt | 1 + examples/crypto_policies/legacy/wolfssl.txt | 1 + examples/server/server.c | 31 +- src/internal.c | 467 ++++++++++--- src/ssl.c | 467 ++++++++++++- src/ssl_load.c | 16 +- src/tls13.c | 9 +- tests/api.c | 692 +++++++++++++++++++ wolfssl/error-ssl.h | 6 +- wolfssl/internal.h | 30 +- wolfssl/ssl.h | 17 +- wolfssl/wolfcrypt/settings.h | 6 + 15 files changed, 1650 insertions(+), 146 deletions(-) create mode 100644 examples/crypto_policies/default/wolfssl.txt create mode 100644 examples/crypto_policies/future/wolfssl.txt create mode 100644 examples/crypto_policies/legacy/wolfssl.txt diff --git a/configure.ac b/configure.ac index ff9b61de20..4bb0e94e29 100644 --- a/configure.ac +++ b/configure.ac @@ -8910,6 +8910,25 @@ AC_ARG_WITH([libsuffix], ) AC_SUBST(LIBSUFFIX) +# Support system wide crypto-policy file: +# - Pass path to your wolfssl.config system crypto-policy file. +# - Pass no argument to use default. +AC_ARG_WITH([sys-crypto-policy], + [AS_HELP_STRING([--with-sys-crypto-policy=PATH],[Support for system-wide crypto-policy file. (default: disabled)])], + [ SYS_CRYPTO_POLICY=$withval], + [ SYS_CRYPTO_POLICY=no ] + ) + +if test "$SYS_CRYPTO_POLICY" != "no"; then + if test "$SYS_CRYPTO_POLICY" = "yes"; then + # Default to the wolfssl fedora crypto-policy file. + SYS_CRYPTO_POLICY="/etc/crypto-policies/back-ends/wolfssl.config" + fi + + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SYS_CRYPTO_POLICY" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CRYPTO_POLICY_FILE=\"$SYS_CRYPTO_POLICY\"" +fi + AC_ARG_ENABLE([context-extra-user-data], [AS_HELP_STRING([--enable-context-extra-user-data],[Enables option for storing user-defined data in TLS API contexts, with optional argument the number of slots to allocate (default: disabled)])], [ ENABLED_EX_DATA=$enableval ], diff --git a/examples/client/client.c b/examples/client/client.c index 13f26e20fb..1bdda7f144 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -1167,7 +1167,7 @@ static int ClientWriteRead(WOLFSSL* ssl, const char* msg, int msgSz, /* 4. add the same message into Japanese section */ /* (will be translated later) */ /* 5. add printf() into suitable position of Usage() */ -static const char* client_usage_msg[][77] = { +static const char* client_usage_msg[][78] = { /* English */ { " NOTE: All files relative to wolfSSL home dir\n", /* 0 */ @@ -1403,9 +1403,12 @@ static const char* client_usage_msg[][77] = { "--rpk Use RPK for the defined certificates\n", /* 74 */ #endif "--files-are-der Specified files are in DER, not PEM format\n", /* 75 */ +#ifdef WOLFSSL_SYS_CRYPTO_POLICY + "--crypto-policy \n", /* 76 */ +#endif "\n" "For simpler wolfSSL TLS client examples, visit\n" - "https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 76 */ + "https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 77 */ NULL, }, #ifndef NO_MULTIBYTE_PRINT @@ -1648,10 +1651,13 @@ static const char* client_usage_msg[][77] = { "--rpk Use RPK for the defined certificates\n", /* 74 */ #endif "--files-are-der Specified files are in DER, not PEM format\n", /* 75 */ +#ifdef WOLFSSL_SYS_CRYPTO_POLICY + "--crypto-policy \n", /* 76 */ +#endif "\n" "より簡単なwolfSSL TLS クライアントの例については" "下記にアクセスしてください\n" - "https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 76 */ + "https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 77 */ NULL, }, #endif @@ -2068,6 +2074,9 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) { "rpk", 0, 267 }, #endif /* HAVE_RPK */ { "files-are-der", 0, 268 }, +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) + { "crypto-policy", 1, 269 }, +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ { 0, 0, 0 } }; #endif @@ -2212,6 +2221,10 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) int useRPK = 0; #endif /* HAVE_RPK */ int fileFormat = WOLFSSL_FILETYPE_PEM; +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) + const char * policy = NULL; +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ + char buffer[WOLFSSL_MAX_ERROR_SZ]; @@ -2931,6 +2944,12 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) case 268: fileFormat = WOLFSSL_FILETYPE_ASN1; break; + case 269: +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) + policy = myoptarg; +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ + break; + default: Usage(); XEXIT_T(MY_EX_USAGE); @@ -3158,6 +3177,13 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) if (method == NULL) err_sys("unable to get method"); +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) + if (policy != NULL) { + if (wolfSSL_crypto_policy_enable(policy) != WOLFSSL_SUCCESS) { + err_sys("wolfSSL_crypto_policy_enable failed"); + } + } +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ #ifdef WOLFSSL_STATIC_MEMORY #if defined(DEBUG_WOLFSSL) && !defined(WOLFSSL_STATIC_MEMORY_LEAN) @@ -4820,7 +4846,6 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) { func_args args; - StartTCP(); #if defined(WOLFSSL_SRTP) && defined(WOLFSSL_COND) diff --git a/examples/crypto_policies/default/wolfssl.txt b/examples/crypto_policies/default/wolfssl.txt new file mode 100644 index 0000000000..ffecfdc324 --- /dev/null +++ b/examples/crypto_policies/default/wolfssl.txt @@ -0,0 +1 @@ +@SECLEVEL=2:EECDH:kRSA:EDH:PSK:DHEPSK:ECDHEPSK:RSAPSK:!RC4:!eNULL:!aNULL diff --git a/examples/crypto_policies/future/wolfssl.txt b/examples/crypto_policies/future/wolfssl.txt new file mode 100644 index 0000000000..a8f4a60660 --- /dev/null +++ b/examples/crypto_policies/future/wolfssl.txt @@ -0,0 +1 @@ +@SECLEVEL=3:EECDH:EDH:PSK:DHEPSK:ECDHEPSK:!RSAPSK:!kRSA:!AES128:!RC4:!eNULL:!aNULL:!SHA1 diff --git a/examples/crypto_policies/legacy/wolfssl.txt b/examples/crypto_policies/legacy/wolfssl.txt new file mode 100644 index 0000000000..75781383fa --- /dev/null +++ b/examples/crypto_policies/legacy/wolfssl.txt @@ -0,0 +1 @@ +@SECLEVEL=1:EECDH:kRSA:EDH:PSK:DHEPSK:ECDHEPSK:RSAPSK:!eNULL:!aNULL diff --git a/examples/server/server.c b/examples/server/server.c index de1b56318b..2ade217fc7 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -873,7 +873,7 @@ static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519, /* 4. add the same message into Japanese section */ /* (will be translated later) */ /* 5. add printf() into suitable position of Usage() */ -static const char* server_usage_msg[][65] = { +static const char* server_usage_msg[][66] = { /* English */ { " NOTE: All files relative to wolfSSL home dir\n", /* 0 */ @@ -1056,11 +1056,14 @@ static const char* server_usage_msg[][65] = { #ifdef WOLFSSL_DUAL_ALG_CERTS "--altPrivKey Generate alternative signature with this key.\n", /* 65 */ +#endif +#ifdef WOLFSSL_SYS_CRYPTO_POLICY + "--crypto-policy \n", /* 66 */ #endif "\n" "For simpler wolfSSL TLS server examples, visit\n" "https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", - /* 66 */ + /* 67 */ NULL, }, #ifndef NO_MULTIBYTE_PRINT @@ -1261,12 +1264,15 @@ static const char* server_usage_msg[][65] = { #ifdef WOLFSSL_DUAL_ALG_CERTS "--altPrivKey Generate alternative signature with this key.\n", /* 65 */ +#endif +#ifdef WOLFSSL_SYS_CRYPTO_POLICY + "--crypto-policy \n", /* 66 */ #endif "\n" "より簡単なwolfSSL TSL クライアントの例については" "下記にアクセスしてください\n" "https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", - /* 66 */ + /* 67 */ NULL, }, #endif @@ -1545,6 +1551,9 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) #ifdef WOLFSSL_DUAL_ALG_CERTS { "altPrivKey", 1, 267}, #endif +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) + { "crypto-policy", 1, 268 }, +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ { 0, 0, 0 } }; #endif @@ -1669,6 +1678,9 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) #if defined(HAVE_CRL) && !defined(NO_FILESYSTEM) char* crlDir = NULL; #endif +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) + const char * policy = NULL; +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ #ifdef WOLFSSL_STATIC_MEMORY /* Note: Actual memory used is much less, this is the entire buffer buckets, @@ -2438,6 +2450,11 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) altPrivKey = myoptarg; break; #endif + case 268: +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) + policy = myoptarg; +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ + break; case -1: default: @@ -2592,6 +2609,14 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) if (method == NULL) err_sys_ex(runWithErrors, "unable to get method"); +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) + if (policy != NULL) { + if (wolfSSL_crypto_policy_enable(policy) != WOLFSSL_SUCCESS) { + err_sys("wolfSSL_crypto_policy_enable failed"); + } + } +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ + #ifdef WOLFSSL_STATIC_MEMORY #if defined(DEBUG_WOLFSSL) && !defined(WOLFSSL_STATIC_MEMORY_LEAN) /* print off helper buffer sizes for use with static memory diff --git a/src/internal.c b/src/internal.c index 756f2812fc..8e4af56554 100644 --- a/src/internal.c +++ b/src/internal.c @@ -2270,6 +2270,225 @@ int InitSSL_Side(WOLFSSL* ssl, word16 side) } #endif /* OPENSSL_EXTRA || WOLFSSL_EITHER_SIDE */ +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) +/* Check the wolfssl method meets minimum requirements for + * the given security level. + * + * Returns 0 if method meets security level. + * Returns CRYPTO_POLICY_FORBIDDEN otherwise. + * */ +static int wolfSSL_crypto_policy_method_allowed(WOLFSSL_METHOD * method, + int level) +{ + if (level == 0) { + /* permissive, no restrictions. */ + return 0; + } + + #ifdef WOLFSSL_DTLS + if (method->version.major == DTLS_MAJOR) { + if (method->version.minor == DTLS_MINOR) { + /* sec level must be 1 or lower. */ + if (level > 1) { + return CRYPTO_POLICY_FORBIDDEN; + } + } + } + else + #endif /* WOLFSSL_DTLS */ + { + if (method->version.minor == SSLv3_MINOR) { + /* sec level must be 0. */ + if (level > 0) { + return CRYPTO_POLICY_FORBIDDEN; + } + } + else if (method->version.minor == TLSv1_MINOR || + method->version.minor == TLSv1_1_MINOR) { + /* sec level must be 1 or lower. */ + if (level > 1) { + return CRYPTO_POLICY_FORBIDDEN; + } + } + } + + /* nothing else to check, all other combinations ok. */ + + return 0; +} + +/* Configure the CTX to conform to the security policy. + * + * Also, check the WOLFSSL_METHOD against the supplied security + * level. + * + * Returns CRYPTO_POLICY_FORBIDDEN if not allowed per policy. + * Returns BAD_FUNC_ARG on null args. + * Returns 0 if ok. + * */ +int wolfSSL_crypto_policy_init_ctx(WOLFSSL_CTX * ctx, + WOLFSSL_METHOD * method) +{ + byte minDowngrade = 0x00; + #ifdef WOLFSSL_DTLS + int dtls = 0; + #endif /* WOLFSSL_DTLS */ + int level = 0; + #if !defined(NO_DH) || !defined(NO_RSA) + word16 minKeySz = 0; /* minimum DH or RSA key size */ + #endif /* !NO_DH || !NO_RSA*/ + #ifdef HAVE_ECC + short minEccKeySz = 0; /* minimum allowed ECC key size */ + #endif /* HAVE_ECC */ + + + if (ctx == NULL || method == NULL) { + return BAD_FUNC_ARG; + } + + #ifdef WOLFSSL_DTLS + dtls = (method->version.major == DTLS_MAJOR); + #endif /* WOLFSSL_DTLS */ + + /* get the crypto policy security level. */ + level = wolfSSL_crypto_policy_get_level(); + + if (level < 0 || level > 5) { + WOLFSSL_MSG_EX("crypto_policy_init_ctx: invalid level: %d", level); + return BAD_FUNC_ARG; + } + + /* Check requested method per security level. */ + if (wolfSSL_crypto_policy_method_allowed(method, level) != 0) { + WOLFSSL_MSG_EX("crypto_policy_init_ctx: " + "method=%d, SECLEVEL=%d combination not allowed", + method->version.minor, level); + return CRYPTO_POLICY_FORBIDDEN; + } + + /* Set appropriate min downgrade per security level. */ + #ifdef WOLFSSL_DTLS + if (dtls) { + switch (level) { + case 1: + minDowngrade = DTLS_MINOR; + break; + case 2: + case 3: + case 4: + case 5: + minDowngrade = DTLSv1_2_MINOR; + break; + case 0: + default: + /* Permissive, no restrictions. Allow defaults. */ + minDowngrade = WOLFSSL_MIN_DTLS_DOWNGRADE; + break; + } + } + else + #endif /* WOLFSSL_DTLS */ + { + switch (level) { + case 1: + /* prohibit SSLv3 and lower. */ + minDowngrade = TLSv1_MINOR; + break; + case 2: + case 3: + case 4: + case 5: + /* prohibit TLSv1_1 and lower. */ + minDowngrade = TLSv1_2_MINOR; + break; + case 0: + default: + ctx->minDowngrade = WOLFSSL_MIN_DOWNGRADE; + break; + } + } + + /* Set min RSA and DH key size. */ + #if !defined(NO_DH) || !defined(NO_RSA) + switch (level) { + case 1: + minKeySz = 128; /* 1024 bits / 8 */ + break; + case 2: + minKeySz = 256; /* 2048 bits / 8 */ + break; + case 3: + minKeySz = 384; /* 3072 bits / 8 */ + break; + case 4: + minKeySz = 960; /* 7680 bits / 8 */ + break; + case 5: + minKeySz = 1920; /* 15360 bits / 8 */ + break; + case 0: + default: + break; + } + #endif /* !NO_DH || !NO_RSA*/ + + /* Set min ECC key size. */ + #ifdef HAVE_ECC + switch (level) { + case 1: + minEccKeySz = 20; /* 160 bits / 8 */ + break; + case 2: + minEccKeySz = 28; /* 224 bits / 8 */ + break; + case 3: + minEccKeySz = 32; /* 256 bits / 8 */ + break; + case 4: + minEccKeySz = 48; /* 384 bits / 8 */ + break; + case 5: + minEccKeySz = 64; /* 512 bits / 8 */ + break; + default: + case 0: + break; + } + #endif /* HAVE_ECC */ + + /* Finally set the ctx values. */ + ctx->minDowngrade = minDowngrade; + ctx->secLevel = level; + ctx->method = method; + + #if !defined(NO_DH) || !defined(NO_RSA) + if (minKeySz > 0) { + #ifndef NO_DH + if (minKeySz > MAX_DHKEY_SZ) { + WOLFSSL_MSG_EX("crypto_policy_init_ctx: minKeySz=%d, " + "but MAX_DHKEY_SZ=%d", + minKeySz, MAX_DHKEY_SZ); + return CRYPTO_POLICY_FORBIDDEN; + } + ctx->minDhKeySz = minKeySz; + ctx->maxDhKeySz = MAX_DHKEY_SZ; + #endif /* NO_DH */ + #ifndef NO_RSA + ctx->minRsaKeySz = minKeySz; + #endif /* NO_RSA */ + } + #endif /* !NO_DH || !NO_RSA*/ + + #ifdef HAVE_ECC + if (minEccKeySz > 0) { + ctx->minEccKeySz = minEccKeySz; + } + #endif /* HAVE_ECC */ + + return 0; +} +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ + /* Initialize SSL context, return 0 on success */ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) { @@ -2323,6 +2542,7 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) #ifndef NO_RSA ctx->minRsaKeySz = MIN_RSAKEY_SZ; #endif + #ifdef HAVE_ECC ctx->minEccKeySz = MIN_ECCKEY_SZ; ctx->eccTempKeySz = ECDHE_SIZE; @@ -2547,6 +2767,14 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) ctx->doAppleNativeCertValidationFlag = 0; #endif /* defined(__APPLE__) && defined(WOLFSSL_SYS_CA_CERTS) */ +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) + ret = wolfSSL_crypto_policy_init_ctx(ctx, method); + if (ret != 0) { + WOLFSSL_MSG_EX("crypto_policy_init_ctx returned %d", ret); + return ret; + } +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ + return ret; } @@ -3224,8 +3452,8 @@ int AllocateSuites(WOLFSSL* ssl) void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, word16 havePSK, word16 haveDH, word16 haveECDSAsig, word16 haveECC, word16 haveStaticRSA, word16 haveStaticECC, - word16 haveFalconSig, word16 haveDilithiumSig, word16 haveAnon, - word16 haveNull, int side) + word16 haveAnon, word16 haveNull, word16 haveAES128, + word16 haveSHA1, word16 haveRC4, int side) { word16 idx = 0; int tls = pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_MINOR; @@ -3261,8 +3489,9 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, (void)haveRSAsig; /* non ecc builds won't read */ (void)haveAnon; /* anon ciphers optional */ (void)haveNull; - (void)haveFalconSig; - (void)haveDilithiumSig; + (void)haveAES128; + (void)haveSHA1; + (void)haveRC4; if (suites == NULL) { WOLFSSL_MSG("InitSuites pointer error"); @@ -3281,7 +3510,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #endif #ifdef BUILD_TLS_AES_128_GCM_SHA256 - if (tls1_3) { + if (tls1_3 && haveAES128) { suites->suites[idx++] = TLS13_BYTE; suites->suites[idx++] = TLS_AES_128_GCM_SHA256; } @@ -3295,14 +3524,14 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #endif #ifdef BUILD_TLS_AES_128_CCM_SHA256 - if (tls1_3) { + if (tls1_3 && haveAES128) { suites->suites[idx++] = TLS13_BYTE; suites->suites[idx++] = TLS_AES_128_CCM_SHA256; } #endif #ifdef BUILD_TLS_AES_128_CCM_8_SHA256 - if (tls1_3) { + if (tls1_3 && haveAES128) { suites->suites[idx++] = TLS13_BYTE; suites->suites[idx++] = TLS_AES_128_CCM_8_SHA256; } @@ -3369,7 +3598,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #endif #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - if (tls1_2 && haveECC) { + if (tls1_2 && haveECC && haveAES128) { suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256; } @@ -3389,9 +3618,10 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 #ifdef OPENSSL_EXTRA - if ((tls1_2 && haveRSA) || (tls1_2 && haveECDSAsig)) { + if ((tls1_2 && haveRSA && haveAES128) || + (tls1_2 && haveECDSAsig && haveAES128)) { #else - if (tls1_2 && haveRSA) { + if (tls1_2 && haveRSA && haveAES128) { #endif suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256; @@ -3406,7 +3636,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #endif #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 - if (tls1_2 && haveDH && haveRSA) { + if (tls1_2 && haveDH && haveRSA && haveAES128) { suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_GCM_SHA256; } @@ -3420,7 +3650,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #endif #ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256 - if (tls1_2 && haveRSA && haveStaticRSA) { + if (tls1_2 && haveRSA && haveStaticRSA && haveAES128) { suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = TLS_RSA_WITH_AES_128_GCM_SHA256; } @@ -3434,7 +3664,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #endif #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 - if (tls1_2 && haveECC && haveStaticECC) { + if (tls1_2 && haveECC && haveStaticECC && haveAES128) { suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256; } @@ -3448,7 +3678,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #endif #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 - if (tls1_2 && haveRSAsig && haveStaticECC) { + if (tls1_2 && haveRSAsig && haveStaticECC && haveAES128) { suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256; } @@ -3462,7 +3692,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #endif #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 - if (tls1_2 && haveECC) { + if (tls1_2 && haveECC && haveAES128) { suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256; } @@ -3476,7 +3706,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #endif #ifdef BUILD_TLS_DH_anon_WITH_AES_128_CBC_SHA - if (tls1_2 && haveDH && haveAnon) { + if (tls1_2 && haveDH && haveAnon && haveAES128 && haveSHA1) { suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = TLS_DH_anon_WITH_AES_128_CBC_SHA; } @@ -3490,7 +3720,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #endif #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 - if (tls1_2 && haveDH && havePSK) { + if (tls1_2 && haveDH && havePSK && haveAES128) { suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_128_GCM_SHA256; } @@ -3504,7 +3734,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #endif #ifdef BUILD_TLS_PSK_WITH_AES_128_GCM_SHA256 - if (tls1_2 && havePSK) { + if (tls1_2 && havePSK && haveAES128) { suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = TLS_PSK_WITH_AES_128_GCM_SHA256; } @@ -3538,7 +3768,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, /* Place as higher priority for MYSQL */ #if defined(WOLFSSL_MYSQL_COMPATIBLE) #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA - if (tls && haveDH && haveRSA) { + if (tls && haveDH && haveRSA && haveSHA1) { suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA; } @@ -3547,9 +3777,10 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 #ifdef OPENSSL_EXTRA - if ((tls1_2 && haveRSA) || (tls1_2 && haveECDSAsig)) { + if ((tls1_2 && haveRSA && haveAES128) || + (tls1_2 && haveECDSAsig && haveAES128)) { #else - if (tls1_2 && haveRSA) { + if (tls1_2 && haveRSA && haveAES128) { #endif suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256; @@ -3557,21 +3788,21 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #endif #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 - if (tls1_2 && haveECC) { + if (tls1_2 && haveECC && haveAES128) { suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256; } #endif #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 - if (tls1_2 && haveRSAsig && haveStaticECC) { + if (tls1_2 && haveRSAsig && haveStaticECC && haveAES128) { suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256; } #endif #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 - if (tls1_2 && haveECC && haveStaticECC) { + if (tls1_2 && haveECC && haveStaticECC && haveAES128) { suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256; } @@ -3610,56 +3841,56 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #endif #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA - if (tls && haveECC) { + if (tls && haveECC && haveSHA1) { suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA; } #endif #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA - if (tls && haveECC && haveStaticECC) { + if (tls && haveECC && haveStaticECC && haveSHA1) { suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA; } #endif #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA - if (tls && haveECC) { + if (tls && haveECC && haveAES128 && haveSHA1) { suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA; } #endif #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA - if (tls && haveECC && haveStaticECC) { + if (tls && haveECC && haveStaticECC && haveAES128 && haveSHA1) { suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA; } #endif #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA - if (!dtls && tls && haveECC) { + if (!dtls && tls && haveECC && haveSHA1 && haveRC4) { suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_RC4_128_SHA; } #endif #ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA - if (!dtls && tls && haveECC && haveStaticECC) { + if (!dtls && tls && haveECC && haveStaticECC && haveSHA1 && haveRC4) { suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_RC4_128_SHA; } #endif #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA - if (tls && haveECC) { + if (tls && haveECC && haveSHA1) { suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA; } #endif #ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA - if (tls && haveECC && haveStaticECC) { + if (tls && haveECC && haveStaticECC && haveSHA1) { suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA; } @@ -3667,9 +3898,9 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA #ifdef OPENSSL_EXTRA - if ((tls && haveRSA) || (tls && haveECDSAsig)) { + if ((tls && haveRSA && haveSHA1) || (tls && haveECDSAsig && haveSHA1)) { #else - if (tls && haveRSA) { + if (tls && haveRSA && haveSHA1) { #endif suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA; @@ -3677,7 +3908,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #endif #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA - if (tls && haveRSAsig && haveStaticECC) { + if (tls && haveRSAsig && haveStaticECC && haveSHA1) { suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_CBC_SHA; } @@ -3685,9 +3916,10 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA #ifdef OPENSSL_EXTRA - if ((tls && haveRSA) || (tls && haveECDSAsig)) { + if ((tls && haveRSA && haveAES128 && haveSHA1) || + (tls && haveECDSAsig && haveAES128 && haveSHA1)) { #else - if (tls && haveRSA) { + if (tls && haveRSA && haveAES128 && haveSHA1) { #endif suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA; @@ -3695,21 +3927,21 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #endif #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA - if (tls && haveRSAsig && haveStaticECC) { + if (tls && haveRSAsig && haveStaticECC && haveAES128 && haveSHA1) { suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_CBC_SHA; } #endif #ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA - if (!dtls && tls && haveRSA) { + if (!dtls && tls && haveRSA && haveSHA1 && haveRC4) { suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDHE_RSA_WITH_RC4_128_SHA; } #endif #ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA - if (!dtls && tls && haveRSAsig && haveStaticECC) { + if (!dtls && tls && haveRSAsig && haveStaticECC && haveSHA1 && haveRC4) { suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDH_RSA_WITH_RC4_128_SHA; } @@ -3717,9 +3949,9 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA #ifdef OPENSSL_EXTRA - if ((tls && haveRSA) || (tls && haveECDSAsig)) { + if ((tls && haveRSA && haveSHA1) || (tls && haveECDSAsig && haveSHA1)) { #else - if (tls && haveRSA) { + if (tls && haveRSA && haveSHA1) { #endif suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA; @@ -3727,21 +3959,21 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #endif #ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA - if (tls && haveRSAsig && haveStaticECC) { + if (tls && haveRSAsig && haveStaticECC && haveSHA1) { suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA; } #endif #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM - if (tls1_2 && haveECC) { + if (tls1_2 && haveECC && haveAES128) { suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CCM; } #endif #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 - if (tls1_2 && haveECC) { + if (tls1_2 && haveECC && haveAES128) { suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8; } @@ -3755,7 +3987,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #endif #ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8 - if (tls1_2 && haveRSA && haveStaticRSA) { + if (tls1_2 && haveRSA && haveStaticRSA && haveAES128) { suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_RSA_WITH_AES_128_CCM_8; } @@ -3782,9 +4014,9 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 #ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES - if (tls1_2 && haveDH && haveRSA) + if (tls1_2 && haveDH && haveRSA && haveAES128) #else - if (tls && haveDH && haveRSA) + if (tls && haveDH && haveRSA && haveAES128) #endif { suites->suites[idx++] = CIPHER_BYTE; @@ -3795,7 +4027,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, /* Place as higher priority for MYSQL testing */ #if !defined(WOLFSSL_MYSQL_COMPATIBLE) #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA - if (tls && haveDH && haveRSA) { + if (tls && haveDH && haveRSA && haveSHA1) { suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA; } @@ -3803,14 +4035,14 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #endif #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA - if (tls && haveDH && haveRSA) { + if (tls && haveDH && haveRSA && haveAES128 && haveSHA1) { suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA; } #endif #ifdef BUILD_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA - if (tls && haveDH && haveRSA) { + if (tls && haveDH && haveRSA && haveSHA1) { suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA; } @@ -3830,9 +4062,9 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256 #ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES - if (tls1_2 && haveRSA && haveStaticRSA) + if (tls1_2 && haveRSA && haveStaticRSA && haveAES128) #else - if (tls && haveRSA && haveStaticRSA) + if (tls && haveRSA && haveStaticRSA && haveAES128) #endif { suites->suites[idx++] = CIPHER_BYTE; @@ -3841,14 +4073,14 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #endif #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA - if (tls && haveRSA && haveStaticRSA) { + if (tls && haveRSA && haveStaticRSA && haveSHA1) { suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = TLS_RSA_WITH_AES_256_CBC_SHA; } #endif #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA - if (tls && haveRSA && haveStaticRSA) { + if (tls && haveRSA && haveStaticRSA && haveAES128 && haveSHA1) { suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = TLS_RSA_WITH_AES_128_CBC_SHA; } @@ -3885,7 +4117,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #endif #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_NULL_SHA - if (tls && haveECC && haveNull) { + if (tls && haveECC && haveNull && haveSHA1) { suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_NULL_SHA; } @@ -3899,7 +4131,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #endif #ifdef BUILD_TLS_RSA_WITH_NULL_SHA - if (tls && haveRSA && haveNull && haveStaticRSA) { + if (tls && haveRSA && haveNull && haveStaticRSA && haveSHA1) { suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = TLS_RSA_WITH_NULL_SHA; } @@ -3918,7 +4150,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #endif #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA - if (tls && havePSK) { + if (tls && havePSK && haveSHA1) { suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = TLS_PSK_WITH_AES_256_CBC_SHA; } @@ -3950,9 +4182,9 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 #ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES - if (tls1_2 && haveDH && havePSK) + if (tls1_2 && haveDH && havePSK && haveAES128) #else - if (tls && haveDH && havePSK) + if (tls && haveDH && havePSK && haveAES128) #endif { suites->suites[idx++] = CIPHER_BYTE; @@ -3962,9 +4194,9 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256 #ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES - if (tls1_2 && havePSK) + if (tls1_2 && havePSK && haveAES128) #else - if (tls1 && havePSK) + if (tls1 && havePSK && haveAES128) #endif { suites->suites[idx++] = CIPHER_BYTE; @@ -3973,14 +4205,14 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #endif #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA - if (tls && havePSK) { + if (tls && havePSK && haveAES128 && haveSHA1) { suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = TLS_PSK_WITH_AES_128_CBC_SHA; } #endif #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CCM - if (tls && haveDH && havePSK) { + if (tls && haveDH && havePSK && haveAES128) { suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_128_CCM; } @@ -4031,9 +4263,9 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #ifdef BUILD_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 #ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES - if (tls1_2 && havePSK) + if (tls1_2 && havePSK && haveAES128) #else - if (tls && havePSK) + if (tls && havePSK && haveAES128) #endif { suites->suites[idx++] = ECC_BYTE; @@ -4043,9 +4275,9 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #ifdef BUILD_TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256 #ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES - if (tls1_2 && havePSK) + if (tls1_2 && havePSK && haveAES128) #else - if (tls && havePSK) + if (tls && havePSK && haveAES128) #endif { suites->suites[idx++] = ECDHE_PSK_BYTE; @@ -4054,7 +4286,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #endif #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM - if (tls && havePSK) { + if (tls && havePSK && haveAES128) { suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_PSK_WITH_AES_128_CCM; } @@ -4068,7 +4300,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #endif #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM_8 - if (tls && havePSK) { + if (tls && havePSK && haveAES128) { suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_PSK_WITH_AES_128_CCM_8; } @@ -4149,49 +4381,49 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #endif #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA - if (!dtls && haveRSA && haveStaticRSA) { + if (!dtls && haveRSA && haveStaticRSA && haveSHA1 && haveRC4) { suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = SSL_RSA_WITH_RC4_128_SHA; } #endif #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5 - if (!dtls && haveRSA && haveStaticRSA) { + if (!dtls && haveRSA && haveStaticRSA && haveRC4) { suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = SSL_RSA_WITH_RC4_128_MD5; } #endif #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA - if (haveRSA && haveStaticRSA) { + if (haveRSA && haveStaticRSA && haveSHA1) { suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = SSL_RSA_WITH_3DES_EDE_CBC_SHA; } #endif #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA - if (tls && haveRSA && haveStaticRSA) { + if (tls && haveRSA && haveStaticRSA && haveSHA1) { suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_128_CBC_SHA; } #endif #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA - if (tls && haveDH && haveRSA && haveStaticRSA) { + if (tls && haveDH && haveRSA && haveStaticRSA && haveSHA1) { suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA; } #endif #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA - if (tls && haveRSA && haveStaticRSA) { + if (tls && haveRSA && haveStaticRSA && haveSHA1) { suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_256_CBC_SHA; } #endif #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA - if (tls && haveDH && haveRSA && haveStaticRSA) { + if (tls && haveDH && haveRSA && haveStaticRSA && haveSHA1) { suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA; } @@ -4288,8 +4520,6 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, (void)haveRSAsig; /* non ecc builds won't read */ (void)haveAnon; /* anon ciphers optional */ (void)haveNull; - (void)haveFalconSig; - (void)haveDilithiumSig; } #if !defined(NO_WOLFSSL_SERVER) || !defined(NO_CERTS) || \ @@ -6397,19 +6627,19 @@ int wolfSSL_CTX_IsPrivatePkSet(WOLFSSL_CTX* ctx) static void InitSuites_EitherSide(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, word16 havePSK, word16 haveDH, word16 haveECDSAsig, word16 haveECC, word16 haveStaticECC, - word16 haveFalconSig, word16 haveDilithiumSig, word16 haveAnon, + word16 haveAnon, int side) { /* make sure server has DH params, and add PSK if there */ if (side == WOLFSSL_SERVER_END) { InitSuites(suites, pv, keySz, haveRSA, havePSK, haveDH, haveECDSAsig, - haveECC, TRUE, haveStaticECC, haveFalconSig, - haveDilithiumSig, haveAnon, TRUE, side); + haveECC, TRUE, haveStaticECC, + haveAnon, TRUE, TRUE, TRUE, TRUE, side); } else { InitSuites(suites, pv, keySz, haveRSA, havePSK, TRUE, haveECDSAsig, - haveECC, TRUE, haveStaticECC, haveFalconSig, - haveDilithiumSig, haveAnon, TRUE, side); + haveECC, TRUE, haveStaticECC, + haveAnon, TRUE, TRUE, TRUE, TRUE, side); } } @@ -6433,7 +6663,7 @@ void InitSSL_CTX_Suites(WOLFSSL_CTX* ctx) #endif InitSuites_EitherSide(ctx->suites, ctx->method->version, keySz, haveRSA, havePSK, ctx->haveDH, ctx->haveECDSAsig, ctx->haveECC, - ctx->haveStaticECC, ctx->haveFalconSig, ctx->haveDilithiumSig, + ctx->haveStaticECC, haveAnon, ctx->method->side); } @@ -6488,7 +6718,6 @@ int InitSSL_Suites(WOLFSSL* ssl) InitSuites_EitherSide(ssl->suites, ssl->version, keySz, haveRSA, havePSK, ssl->options.haveDH, ssl->options.haveECDSAsig, ssl->options.haveECC, ssl->options.haveStaticECC, - ssl->options.haveFalconSig, ssl->options.haveDilithiumSig, ssl->options.useAnon, ssl->options.side); } @@ -7729,6 +7958,9 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) ssl->response_idx = 0; #endif #endif +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) + ssl->secLevel = ctx->secLevel; +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ /* Returns 0 on success, not WOLFSSL_SUCCESS (1) */ WOLFSSL_MSG_EX("InitSSL done. return 0 (success)"); return 0; @@ -25869,6 +26101,9 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e) case CRL_MISSING: return "CRL missing, not loaded"; + case CRYPTO_POLICY_FORBIDDEN: + return "Operation forbidden by system crypto-policy"; + case MONITOR_SETUP_E: return "CRL monitor setup error"; @@ -27296,6 +27531,9 @@ static int ParseCipherList(Suites* suites, word16 haveNull = 1; /* allowed by default if compiled in */ int callInitSuites = 0; word16 havePSK = 0; + word16 haveAES128 = 1; /* allowed by default if compiled in */ + word16 haveSHA1 = 1; /* allowed by default if compiled in */ + word16 haveRC4 = 1; /* allowed by default if compiled in */ #endif const int suiteSz = GetCipherNamesSize(); const char* next = list; @@ -27320,8 +27558,8 @@ static int ParseCipherList(Suites* suites, #else 0, #endif - haveRSA, 1, 1, !haveRSA, 1, haveRSA, !haveRSA, 1, 1, 0, 0, - side + haveRSA, 1, 1, !haveRSA, 1, haveRSA, !haveRSA, 0, 0, 1, + 1, 1, side ); return 1; /* wolfSSL default */ } @@ -27522,6 +27760,29 @@ static int ParseCipherList(Suites* suites, continue; } + #if defined(WOLFSSL_SYS_CRYPTO_POLICY) + if (XSTRCMP(name, "AES128") == 0) { + haveAES128 = allowing; + callInitSuites = 1; + ret = 1; + continue; + } + + if (XSTRCMP(name, "SHA1") == 0) { + haveSHA1 = allowing; + callInitSuites = 1; + ret = 1; + continue; + } + + if (XSTRCMP(name, "RC4") == 0) { + haveRC4 = allowing; + callInitSuites = 1; + ret = 1; + continue; + } + #endif /* WOLFSSL_SYS_CRYPTO_POLICY */ + if (XSTRCMP(name, "LOW") == 0 || XSTRCMP(name, "MEDIUM") == 0) { /* No way to limit or allow low bit sizes */ if (allowing) { @@ -27543,6 +27804,14 @@ static int ParseCipherList(Suites* suites, /* wolfSSL doesn't support "export" ciphers. We can skip this */ continue; } + + #if defined(WOLFSSL_SYS_CRYPTO_POLICY) + if (XSTRNCMP(name, WOLFSSL_SECLEVEL_STR, + strlen(WOLFSSL_SECLEVEL_STR)) == 0) { + /* Skip the "@SECLEVEL=N" string, we'll process it elsewhere. */ + continue; + } + #endif /* WOLFSSL_SYS_CRYPTO_POLICY */ #endif /* OPENSSL_EXTRA */ for (i = 0; i < suiteSz; i++) { @@ -27682,10 +27951,9 @@ static int ParseCipherList(Suites* suites, (word16)((haveSig & SIG_ECDSA) != 0), (word16)haveECC, (word16)haveStaticRSA, (word16)haveStaticECC, - (word16)((haveSig & SIG_FALCON) != 0), - (word16)((haveSig & SIG_DILITHIUM) != 0), (word16)((haveSig & SIG_ANON) != 0), - (word16)haveNull, side); + (word16)haveNull, (word16)haveAES128, + (word16)haveSHA1, (word16)haveRC4, side); /* Restore user ciphers ahead of defaults */ XMEMMOVE(suites->suites + idx, suites->suites, min(suites->suiteSz, WOLFSSL_MAX_SUITE_SZ-idx)); @@ -27696,7 +27964,7 @@ static int ParseCipherList(Suites* suites, { suites->suiteSz = (word16)idx; InitSuitesHashSigAlgo(suites->hashSigAlgo, haveSig, 1, keySz, - &suites->hashSigAlgoSz); + &suites->hashSigAlgoSz); } #ifdef HAVE_RENEGOTIATION_INDICATION @@ -36845,9 +37113,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK, ssl->options.haveDH, ssl->options.haveECDSAsig, ssl->options.haveECC, TRUE, ssl->options.haveStaticECC, - ssl->options.haveFalconSig, - ssl->options.haveDilithiumSig, ssl->options.useAnon, - TRUE, ssl->options.side); + ssl->options.useAnon, + TRUE, TRUE, TRUE, TRUE, ssl->options.side); } /* suite size */ @@ -37277,9 +37544,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK, ssl->options.haveDH, ssl->options.haveECDSAsig, ssl->options.haveECC, TRUE, ssl->options.haveStaticECC, - ssl->options.haveFalconSig, - ssl->options.haveDilithiumSig, ssl->options.useAnon, - TRUE, ssl->options.side); + ssl->options.useAnon, + TRUE, TRUE, TRUE, TRUE, ssl->options.side); } /* check if option is set to not allow the current version @@ -37355,9 +37621,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK, ssl->options.haveDH, ssl->options.haveECDSAsig, ssl->options.haveECC, TRUE, ssl->options.haveStaticECC, - ssl->options.haveFalconSig, - ssl->options.haveDilithiumSig, ssl->options.useAnon, - TRUE, ssl->options.side); + ssl->options.useAnon, + TRUE, TRUE, TRUE, TRUE, ssl->options.side); } } diff --git a/src/ssl.c b/src/ssl.c index b11ed59a7e..834b857a11 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -281,6 +281,18 @@ int wc_OBJ_sn2nid(const char *sn) #ifndef WOLFCRYPT_ONLY + +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) +/* Whether a system level crypto-policy is in effect. + * When enabled, user setting of ciphers will fail with + * error CRYPTO_POLICY_FORBIDDEN. + * + * The user must call wolfSSL_crypto_policy_disable to + * override. + * */ +static struct SystemCryptoPolicy crypto_policy; +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ + #if !defined(NO_RSA) || !defined(NO_DH) || defined(HAVE_ECC) || \ (defined(OPENSSL_EXTRA) && defined(WOLFSSL_KEY_GEN) && !defined(NO_DSA)) @@ -1026,6 +1038,11 @@ int GetEchConfigsEx(WOLFSSL_EchConfig* configs, byte* output, word32* outputLen) } #endif /* WOLFSSL_TLS13 && HAVE_ECH */ +#ifdef OPENSSL_EXTRA +static int wolfSSL_parse_cipher_list(WOLFSSL_CTX* ctx, WOLFSSL* ssl, + Suites* suites, const char* list); +#endif + #if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_FSPSM_TLS) #include @@ -1116,6 +1133,30 @@ WOLFSSL_CTX* wolfSSL_CTX_new_ex(WOLFSSL_METHOD* method, void* heap) } #endif +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) + /* Load the crypto-policy ciphers if configured. */ + if (ctx && wolfSSL_crypto_policy_is_enabled()) { + const char * list = wolfSSL_crypto_policy_get_ciphers(); + int ret = 0; + + if (list != NULL && *list != '\0') { + if (AllocateCtxSuites(ctx) != 0) { + WOLFSSL_MSG("allocate ctx suites failed"); + wolfSSL_CTX_free(ctx); + ctx = NULL; + } + else { + ret = wolfSSL_parse_cipher_list(ctx, NULL, ctx->suites, list); + if (ret != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("parse cipher list failed"); + wolfSSL_CTX_free(ctx); + ctx = NULL; + } + } + } + } +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ + WOLFSSL_LEAVE("wolfSSL_CTX_new_ex", 0); return ctx; } @@ -2686,6 +2727,14 @@ int wolfSSL_CTX_SetMinEccKey_Sz(WOLFSSL_CTX* ctx, short keySz) return BAD_FUNC_ARG; } +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) + if (crypto_policy.enabled) { + if (ctx->minEccKeySz > (keySz / 8)) { + return CRYPTO_POLICY_FORBIDDEN; + } + } +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ + ctx->minEccKeySz = keySz / 8; #ifndef NO_CERTS ctx->cm->minEccKeySz = keySz / 8; @@ -2702,6 +2751,14 @@ int wolfSSL_SetMinEccKey_Sz(WOLFSSL* ssl, short keySz) return BAD_FUNC_ARG; } +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) + if (crypto_policy.enabled) { + if (ssl->options.minEccKeySz > (keySz / 8)) { + return CRYPTO_POLICY_FORBIDDEN; + } + } +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ + ssl->options.minEccKeySz = keySz / 8; return WOLFSSL_SUCCESS; } @@ -2716,6 +2773,14 @@ int wolfSSL_CTX_SetMinRsaKey_Sz(WOLFSSL_CTX* ctx, short keySz) return BAD_FUNC_ARG; } +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) + if (crypto_policy.enabled) { + if (ctx->minRsaKeySz > (keySz / 8)) { + return CRYPTO_POLICY_FORBIDDEN; + } + } +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ + ctx->minRsaKeySz = keySz / 8; ctx->cm->minRsaKeySz = keySz / 8; return WOLFSSL_SUCCESS; @@ -2729,6 +2794,14 @@ int wolfSSL_SetMinRsaKey_Sz(WOLFSSL* ssl, short keySz) return BAD_FUNC_ARG; } +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) + if (crypto_policy.enabled) { + if (ssl->options.minRsaKeySz > (keySz / 8)) { + return CRYPTO_POLICY_FORBIDDEN; + } + } +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ + ssl->options.minRsaKeySz = keySz / 8; return WOLFSSL_SUCCESS; } @@ -2761,6 +2834,14 @@ int wolfSSL_CTX_SetMinDhKey_Sz(WOLFSSL_CTX* ctx, word16 keySz_bits) if (ctx == NULL || keySz_bits > 16000 || keySz_bits % 8 != 0) return BAD_FUNC_ARG; +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) + if (crypto_policy.enabled) { + if (ctx->minDhKeySz > (keySz_bits / 8)) { + return CRYPTO_POLICY_FORBIDDEN; + } + } +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ + ctx->minDhKeySz = keySz_bits / 8; return WOLFSSL_SUCCESS; } @@ -2771,6 +2852,14 @@ int wolfSSL_SetMinDhKey_Sz(WOLFSSL* ssl, word16 keySz_bits) if (ssl == NULL || keySz_bits > 16000 || keySz_bits % 8 != 0) return BAD_FUNC_ARG; +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) + if (crypto_policy.enabled) { + if (ssl->options.minDhKeySz > (keySz_bits / 8)) { + return CRYPTO_POLICY_FORBIDDEN; + } + } +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ + ssl->options.minDhKeySz = keySz_bits / 8; return WOLFSSL_SUCCESS; } @@ -2781,6 +2870,14 @@ int wolfSSL_CTX_SetMaxDhKey_Sz(WOLFSSL_CTX* ctx, word16 keySz_bits) if (ctx == NULL || keySz_bits > 16000 || keySz_bits % 8 != 0) return BAD_FUNC_ARG; +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) + if (crypto_policy.enabled) { + if (ctx->minDhKeySz > (keySz_bits / 8)) { + return CRYPTO_POLICY_FORBIDDEN; + } + } +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ + ctx->maxDhKeySz = keySz_bits / 8; return WOLFSSL_SUCCESS; } @@ -2791,6 +2888,14 @@ int wolfSSL_SetMaxDhKey_Sz(WOLFSSL* ssl, word16 keySz_bits) if (ssl == NULL || keySz_bits > 16000 || keySz_bits % 8 != 0) return BAD_FUNC_ARG; +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) + if (crypto_policy.enabled) { + if (ssl->options.minDhKeySz > (keySz_bits / 8)) { + return CRYPTO_POLICY_FORBIDDEN; + } + } +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ + ssl->options.maxDhKeySz = keySz_bits / 8; return WOLFSSL_SUCCESS; } @@ -4838,6 +4943,12 @@ int wolfSSL_CTX_SetMinVersion(WOLFSSL_CTX* ctx, int version) return BAD_FUNC_ARG; } +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) + if (crypto_policy.enabled) { + return CRYPTO_POLICY_FORBIDDEN; + } +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ + return SetMinVersionHelper(&ctx->minDowngrade, version); } @@ -4852,6 +4963,12 @@ int wolfSSL_SetMinVersion(WOLFSSL* ssl, int version) return BAD_FUNC_ARG; } +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) + if (crypto_policy.enabled) { + return CRYPTO_POLICY_FORBIDDEN; + } +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ + return SetMinVersionHelper(&ssl->options.minDowngrade, version); } @@ -4961,8 +5078,7 @@ int wolfSSL_SetVersion(WOLFSSL* ssl, int version) InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK, ssl->options.haveDH, ssl->options.haveECDSAsig, ssl->options.haveECC, TRUE, ssl->options.haveStaticECC, - ssl->options.haveFalconSig, ssl->options.haveDilithiumSig, - ssl->options.useAnon, TRUE, ssl->options.side); + ssl->options.useAnon, TRUE, TRUE, TRUE, TRUE, ssl->options.side); return WOLFSSL_SUCCESS; } #endif /* !leanpsk */ @@ -5844,6 +5960,13 @@ int wolfSSL_Init(void) #endif } +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) + /* System wide crypto policy disabled by default. */ + if (ret == WOLFSSL_SUCCESS) { + XMEMSET(&crypto_policy, 0, sizeof(crypto_policy)); + } +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ + if (ret == WOLFSSL_SUCCESS) { initRefCount++; } @@ -5860,6 +5983,304 @@ int wolfSSL_Init(void) return ret; } +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) +/* Helper function for wolfSSL_crypto_policy_enable and + * wolfSSL_crypto_policy_enable_buffer. + * + * Parses the crypto policy string, verifies values, + * and sets in global crypto policy struct. Not thread + * safe. String length has already been verified. + * + * Returns WOLFSSL_SUCCESS on success. + * Returns CRYPTO_POLICY_FORBIDDEN if already enabled. + * Returns < 0 on misc error. + * */ +static int crypto_policy_parse(void) +{ + const char * hdr = WOLFSSL_CRYPTO_POLICY_HDR; + int sec_level = 0; + size_t i = 0; + + /* All policies should begin with "@SECLEVEL=" (N={0..5}) followed + * by bulk cipher list. */ + if (XMEMCMP(crypto_policy.str, hdr, strlen(hdr)) != 0) { + WOLFSSL_MSG("error: crypto policy: invalid header"); + return WOLFSSL_BAD_FILE; + } + + { + /* Extract the security level. */ + char * policy_mem = crypto_policy.str; + policy_mem += strlen(hdr); + sec_level = (int) (*policy_mem - '0'); + } + + if (sec_level < MIN_WOLFSSL_SEC_LEVEL || + sec_level > MAX_WOLFSSL_SEC_LEVEL) { + WOLFSSL_MSG_EX("error: invalid SECLEVEL: %d", sec_level); + return WOLFSSL_BAD_FILE; + } + + /* Remove trailing '\r' or '\n'. */ + for (i = 0; i < MAX_WOLFSSL_CRYPTO_POLICY_SIZE; ++i) { + if (crypto_policy.str[i] == '\0') { + break; + } + + if (crypto_policy.str[i] == '\r' || crypto_policy.str[i] == '\n') { + crypto_policy.str[i] = '\0'; + break; + } + } + + #if defined(DEBUG_WOLFSSL_VERBOSE) + WOLFSSL_MSG_EX("info: SECLEVEL=%d", sec_level); + WOLFSSL_MSG_EX("info: using crypto-policy file: %s, %ld", policy_file, sz); + #endif /* DEBUG_WOLFSSL_VERBOSE */ + + crypto_policy.secLevel = sec_level; + crypto_policy.enabled = 1; + + return WOLFSSL_SUCCESS; +} + +/* Enables wolfSSL system wide crypto-policy, using the given policy + * file arg. If NULL is passed, then the default system crypto-policy + * file that was set at configure time will be used instead. + * + * While enabled: + * - TLS methods, min key sizes, and cipher lists are all configured + * automatically by the policy. + * - Attempting to use lesser strength parameters will fail with + * error CRYPTO_POLICY_FORBIDDEN. + * - API such as wolfSSL_CTX_SetMinVersion, and wolfSSL_CTX_set_cipher_list + * will fail with CRYPTO_POLICY_FORBIDDEN. + * + * Disable with wolfSSL_crypto_policy_disable. + * + * Note: the wolfSSL_crypto_policy_X API are not thread safe, and should + * only be called at program init time. + * + * Returns WOLFSSL_SUCCESS on success. + * Returns CRYPTO_POLICY_FORBIDDEN if already enabled. + * Returns < 0 on misc error. + * */ +int wolfSSL_crypto_policy_enable(const char * policy_file) +{ + XFILE file; + long sz = 0; + size_t n_read = 0; + + WOLFSSL_ENTER("wolfSSL_crypto_policy_enable"); + + if (wolfSSL_crypto_policy_is_enabled()) { + WOLFSSL_MSG_EX("error: crypto policy already enabled: %s", + policy_file); + return CRYPTO_POLICY_FORBIDDEN; + } + + if (policy_file == NULL) { + /* Use the configure-time default if NULL passed. */ + policy_file = WC_STRINGIFY(WOLFSSL_CRYPTO_POLICY_FILE); + } + + if (policy_file == NULL || *policy_file == '\0') { + WOLFSSL_MSG("error: crypto policy empty file"); + return BAD_FUNC_ARG; + } + + XMEMSET(&crypto_policy, 0, sizeof(crypto_policy)); + + file = XFOPEN(policy_file, "rb"); + + if (file == XBADFILE) { + WOLFSSL_MSG_EX("error: crypto policy file open failed: %s", + policy_file); + return WOLFSSL_BAD_FILE; + } + + if (XFSEEK(file, 0, XSEEK_END) != 0) { + WOLFSSL_MSG_EX("error: crypto policy file seek end failed: %s", + policy_file); + XFCLOSE(file); + return WOLFSSL_BAD_FILE; + } + + sz = XFTELL(file); + + if (XFSEEK(file, 0, XSEEK_SET) != 0) { + WOLFSSL_MSG_EX("error: crypto policy file seek failed: %s", + policy_file); + XFCLOSE(file); + return WOLFSSL_BAD_FILE; + } + + if (sz <= 0 || sz > MAX_WOLFSSL_CRYPTO_POLICY_SIZE) { + WOLFSSL_MSG_EX("error: crypto policy file %s, invalid size: %ld", + policy_file, sz); + XFCLOSE(file); + return WOLFSSL_BAD_FILE; + } + + n_read = XFREAD(crypto_policy.str, 1, sz, file); + XFCLOSE(file); + + if (n_read != (size_t) sz) { + WOLFSSL_MSG_EX("error: crypto policy file %s: read %zu, " + "expected %ld", policy_file, n_read, sz); + return WOLFSSL_BAD_FILE; + } + + crypto_policy.str[n_read] = '\0'; + + return crypto_policy_parse(); +} + +/* Same behavior as wolfSSL_crypto_policy_enable, but loads + * via memory buf instead of file. + * + * Returns WOLFSSL_SUCCESS on success. + * Returns CRYPTO_POLICY_FORBIDDEN if already enabled. + * Returns < 0 on misc error. + * */ +int wolfSSL_crypto_policy_enable_buffer(const char * buf) +{ + size_t sz = 0; + + WOLFSSL_ENTER("wolfSSL_crypto_policy_enable_buffer"); + + if (wolfSSL_crypto_policy_is_enabled()) { + WOLFSSL_MSG_EX("error: crypto policy already enabled"); + return CRYPTO_POLICY_FORBIDDEN; + } + + if (buf == NULL || *buf == '\0') { + return BAD_FUNC_ARG; + } + + sz = XSTRLEN(buf); + + if (sz == 0 || sz > MAX_WOLFSSL_CRYPTO_POLICY_SIZE) { + return BAD_FUNC_ARG; + } + + XMEMSET(&crypto_policy, 0, sizeof(crypto_policy)); + XMEMCPY(crypto_policy.str, buf, sz); + + return crypto_policy_parse(); +} + +/* Returns whether the system wide crypto-policy is enabled. + * + * Returns 1 if enabled. + * 0 if disabled. + * */ +int wolfSSL_crypto_policy_is_enabled(void) +{ + WOLFSSL_ENTER("wolfSSL_crypto_policy_is_enabled"); + + return crypto_policy.enabled == 1; +} + +/* Disables the system wide crypto-policy. + * note: SSL and CTX structures already instantiated will + * keep their security policy parameters. This will only + * affect new instantiations. + * */ +void wolfSSL_crypto_policy_disable(void) +{ + WOLFSSL_ENTER("wolfSSL_crypto_policy_disable"); + crypto_policy.enabled = 0; + XMEMSET(&crypto_policy, 0, sizeof(crypto_policy)); + return; +} + +/* Get the crypto-policy bulk cipher list string. + * String is not owned by caller, should not be freed. + * + * Returns pointer to bulk cipher list string. + * Returns NULL if NOT enabled, or on error. + * */ +const char * wolfSSL_crypto_policy_get_ciphers(void) +{ + WOLFSSL_ENTER("wolfSSL_crypto_policy_get_ciphers"); + + if (crypto_policy.enabled == 1) { + int len = 0; + int hdr_len = XSTRLEN(WOLFSSL_CRYPTO_POLICY_HDR); + /* The crypto policy config will have + * this form: + * "@SECLEVEL=2:kEECDH:kRSA..." */ + + if (*crypto_policy.str == '\0') { + WOLFSSL_MSG("crypto_policy_get_ciphers: " + "empty policy config"); + return NULL; + } + + len = XSTRLEN(crypto_policy.str); + + if (len <= hdr_len + 2) { + WOLFSSL_MSG_EX("crypto_policy_get_ciphers: " + "invalid policy config: %d", + len); + return NULL; + } + + return crypto_policy.str; + } + + return NULL; +} + +/* Get the configured crypto-policy security level. + * A security level of 0 does not impose any additional + * restrictions. + * + * Returns 1 - 5 if enabled. + * Returns 0 if NOT enabled. + * */ +int wolfSSL_crypto_policy_get_level(void) +{ + if (crypto_policy.enabled == 1) { + return crypto_policy.secLevel; + } + + return 0; +} + +/* Get security level from ssl structure. + * @param ssl a pointer to WOLFSSL structure + */ +int wolfSSL_get_security_level(const WOLFSSL * ssl) +{ + if (ssl == NULL) { + return BAD_FUNC_ARG; + } + + return ssl->secLevel; +} + +#ifndef NO_WOLFSSL_STUB +/* + * Set security level (wolfSSL doesn't support setting the security level). + * + * The security level can only be set through a system wide crypto-policy + * with wolfSSL_crypto_policy_enable(). + * + * @param ssl a pointer to WOLFSSL structure + * @param level security level + */ +void wolfSSL_set_security_level(WOLFSSL * ssl, int level) +{ + WOLFSSL_ENTER("wolfSSL_set_security_level"); + (void)ssl; + (void)level; +} +#endif /* !NO_WOLFSSL_STUB */ + +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ + #define WOLFSSL_SSL_LOAD_INCLUDED #include @@ -10448,6 +10869,10 @@ int wolfSSL_Cleanup(void) if (!release) return ret; +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) + wolfSSL_crypto_policy_disable(); +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ + #ifdef OPENSSL_EXTRA wolfSSL_BN_free_one(); #endif @@ -10893,8 +11318,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) InitSuites(ssl->suites, ssl->version, keySz, haveRSA, TRUE, ssl->options.haveDH, ssl->options.haveECDSAsig, ssl->options.haveECC, TRUE, ssl->options.haveStaticECC, - ssl->options.haveFalconSig, ssl->options.haveDilithiumSig, - ssl->options.useAnon, TRUE, ssl->options.side); + ssl->options.useAnon, TRUE, TRUE, TRUE, TRUE, ssl->options.side); } #ifdef OPENSSL_EXTRA /** @@ -10950,8 +11374,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) InitSuites(ssl->suites, ssl->version, keySz, haveRSA, TRUE, ssl->options.haveDH, ssl->options.haveECDSAsig, ssl->options.haveECC, TRUE, ssl->options.haveStaticECC, - ssl->options.haveFalconSig, ssl->options.haveDilithiumSig, - ssl->options.useAnon, TRUE, ssl->options.side); + ssl->options.useAnon, TRUE, TRUE, TRUE, TRUE, ssl->options.side); } const char* wolfSSL_get_psk_identity_hint(const WOLFSSL* ssl) @@ -12682,6 +13105,7 @@ int wolfSSL_CTX_set_min_proto_version(WOLFSSL_CTX* ctx, int version) if (ctx == NULL) { return WOLFSSL_FAILURE; } + if (version != 0) { proto = version; ctx->minProto = 0; /* turn min proto flag off */ @@ -16348,9 +16772,8 @@ long wolfSSL_set_options(WOLFSSL* ssl, long op) InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK, ssl->options.haveDH, ssl->options.haveECDSAsig, ssl->options.haveECC, TRUE, ssl->options.haveStaticECC, - ssl->options.haveFalconSig, - ssl->options.haveDilithiumSig, ssl->options.useAnon, - TRUE, ssl->options.side); + ssl->options.useAnon, + TRUE, TRUE, TRUE, TRUE, ssl->options.side); } else { /* Only preserve overlapping suites */ @@ -16371,7 +16794,7 @@ long wolfSSL_set_options(WOLFSSL* ssl, long op) * - haveStaticECC turns off haveRSA * - haveECDSAsig turns off haveRSAsig */ InitSuites(&tmpSuites, ssl->version, 0, 1, 1, 1, haveECDSAsig, 1, 1, - haveStaticECC, 1, 1, 1, 1, ssl->options.side); + haveStaticECC, 1, 1, 1, 1, 1, ssl->options.side); for (in = 0, out = 0; in < ssl->suites->suiteSz; in += SUITE_LEN) { if (FindSuite(&tmpSuites, ssl->suites->suites[in], ssl->suites->suites[in+1]) >= 0) { @@ -23838,8 +24261,12 @@ int wolfSSL_CTX_set_dh_auto(WOLFSSL_CTX* ctx, int onoff) } /** - * set security level (wolfSSL doesn't support security level) - * @param ctx a pointer to WOLFSSL_EVP_PKEY_CTX structure + * Set security level (wolfSSL doesn't support setting the security level). + * + * The security level can only be set through a system wide crypto-policy + * with wolfSSL_crypto_policy_enable(). + * + * @param ctx a pointer to WOLFSSL_CTX structure * @param level security level */ void wolfSSL_CTX_set_security_level(WOLFSSL_CTX* ctx, int level) @@ -23848,16 +24275,20 @@ void wolfSSL_CTX_set_security_level(WOLFSSL_CTX* ctx, int level) (void)ctx; (void)level; } -/** - * get security level (wolfSSL doesn't support security level) - * @param ctx a pointer to WOLFSSL_EVP_PKEY_CTX structure - * @return always 0(level 0) - */ -int wolfSSL_CTX_get_security_level(const WOLFSSL_CTX* ctx) + +int wolfSSL_CTX_get_security_level(const WOLFSSL_CTX * ctx) { WOLFSSL_ENTER("wolfSSL_CTX_get_security_level"); + #if defined(WOLFSSL_SYS_CRYPTO_POLICY) + if (ctx == NULL) { + return BAD_FUNC_ARG; + } + + return ctx->secLevel; + #else (void)ctx; return 0; + #endif /* WOLFSSL_SYS_CRYPTO_POLICY */ } #if defined(OPENSSL_EXTRA) && defined(HAVE_SECRET_CALLBACK) diff --git a/src/ssl_load.c b/src/ssl_load.c index a15274b23f..752029e21c 100644 --- a/src/ssl_load.c +++ b/src/ssl_load.c @@ -2201,9 +2201,9 @@ static int ProcessBufferResetSuites(WOLFSSL_CTX* ctx, WOLFSSL* ssl, int type) InitSuites(ssl->suites, ssl->version, ssl->buffers.keySz, WOLFSSL_HAVE_RSA, SSL_HAVE_PSK(ssl), ssl->options.haveDH, ssl->options.haveECDSAsig, ssl->options.haveECC, TRUE, - ssl->options.haveStaticECC, ssl->options.haveFalconSig, - ssl->options.haveDilithiumSig, ssl->options.useAnon, TRUE, - ssl->options.side); + ssl->options.haveStaticECC, + ssl->options.useAnon, TRUE, + TRUE, TRUE, TRUE, ssl->options.side); } } } @@ -2218,8 +2218,8 @@ static int ProcessBufferResetSuites(WOLFSSL_CTX* ctx, WOLFSSL* ssl, int type) InitSuites(ctx->suites, ctx->method->version, ctx->privateKeySz, WOLFSSL_HAVE_RSA, CTX_HAVE_PSK(ctx), ctx->haveDH, ctx->haveECDSAsig, ctx->haveECC, TRUE, ctx->haveStaticECC, - ctx->haveFalconSig, ctx->haveDilithiumSig, CTX_USE_ANON(ctx), - TRUE, ctx->method->side); + CTX_USE_ANON(ctx), + TRUE, TRUE, TRUE, TRUE, ctx->method->side); } } @@ -5238,9 +5238,9 @@ static int wolfssl_set_tmp_dh(WOLFSSL* ssl, unsigned char* p, int pSz, InitSuites(ssl->suites, ssl->version, SSL_KEY_SZ(ssl), WOLFSSL_HAVE_RSA, SSL_HAVE_PSK(ssl), ssl->options.haveDH, ssl->options.haveECDSAsig, ssl->options.haveECC, TRUE, - ssl->options.haveStaticECC, ssl->options.haveFalconSig, - ssl->options.haveDilithiumSig, ssl->options.useAnon, TRUE, - ssl->options.side); + ssl->options.haveStaticECC, + ssl->options.useAnon, TRUE, + TRUE, TRUE, TRUE, ssl->options.side); } return ret; diff --git a/src/tls13.c b/src/tls13.c index 0d5a8b9365..12c37fb0c0 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -13955,8 +13955,7 @@ void wolfSSL_set_psk_client_cs_callback(WOLFSSL* ssl, InitSuites(ssl->suites, ssl->version, keySz, haveRSA, TRUE, ssl->options.haveDH, ssl->options.haveECDSAsig, ssl->options.haveECC, TRUE, ssl->options.haveStaticECC, - ssl->options.haveFalconSig, ssl->options.haveDilithiumSig, - ssl->options.useAnon, TRUE, ssl->options.side); + ssl->options.useAnon, TRUE, TRUE, TRUE, TRUE, ssl->options.side); } /* Set the PSK callback that returns the cipher suite for a client to use @@ -14008,8 +14007,7 @@ void wolfSSL_set_psk_client_tls13_callback(WOLFSSL* ssl, InitSuites(ssl->suites, ssl->version, keySz, haveRSA, TRUE, ssl->options.haveDH, ssl->options.haveECDSAsig, ssl->options.haveECC, TRUE, ssl->options.haveStaticECC, - ssl->options.haveFalconSig, ssl->options.haveDilithiumSig, - ssl->options.useAnon, TRUE, ssl->options.side); + ssl->options.useAnon, TRUE, TRUE, TRUE, TRUE, ssl->options.side); } /* Set the PSK callback that returns the cipher suite for a server to use @@ -14058,8 +14056,7 @@ void wolfSSL_set_psk_server_tls13_callback(WOLFSSL* ssl, InitSuites(ssl->suites, ssl->version, keySz, haveRSA, TRUE, ssl->options.haveDH, ssl->options.haveECDSAsig, ssl->options.haveECC, TRUE, ssl->options.haveStaticECC, - ssl->options.haveFalconSig, ssl->options.haveDilithiumSig, - ssl->options.useAnon, TRUE, ssl->options.side); + ssl->options.useAnon, TRUE, TRUE, TRUE, TRUE, ssl->options.side); } /* Get name of first supported cipher suite that uses the hash indicated. diff --git a/tests/api.c b/tests/api.c index e7b64124a6..64946b92fc 100644 --- a/tests/api.c +++ b/tests/api.c @@ -91896,7 +91896,11 @@ static int test_wolfSSL_security_level(void) #endif SSL_CTX_set_security_level(NULL, 1); SSL_CTX_set_security_level(ctx, 1); + #if defined(WOLFSSL_SYS_CRYPTO_POLICY) + ExpectIntEQ(SSL_CTX_get_security_level(NULL), BAD_FUNC_ARG); + #else ExpectIntEQ(SSL_CTX_get_security_level(NULL), 0); + #endif /* WOLFSSL_SYS_CRYPTO_POLICY */ /* Stub so nothing happens. */ ExpectIntEQ(SSL_CTX_get_security_level(ctx), 0); @@ -91908,6 +91912,690 @@ static int test_wolfSSL_security_level(void) return EXPECT_RESULT(); } +/* System wide crypto-policy test. + * + * Loads three different policies (legacy, default, future), + * then tests crypt_policy api. + * */ +static int test_wolfSSL_crypto_policy(void) +{ + EXPECT_DECLS; +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) + int rc = WC_NO_ERR_TRACE(WOLFSSL_FAILURE); + const char * policy_list[] = { + "examples/crypto_policies/legacy/wolfssl.txt", + "examples/crypto_policies/default/wolfssl.txt", + "examples/crypto_policies/future/wolfssl.txt", + }; + const char * ciphers_list[] = { + "@SECLEVEL=1:EECDH:kRSA:EDH:PSK:DHEPSK:ECDHEPSK:RSAPSK" + ":!eNULL:!aNULL", + "@SECLEVEL=2:EECDH:kRSA:EDH:PSK:DHEPSK:ECDHEPSK:RSAPSK" + ":!RC4:!eNULL:!aNULL", + "@SECLEVEL=3:EECDH:EDH:PSK:DHEPSK:ECDHEPSK:!RSAPSK:!kRSA" + ":!AES128:!RC4:!eNULL:!aNULL:!SHA1", + }; + int seclevel_list[] = { 1, 2, 3 }; + int i = 0; + + for (i = 0; i < 3; ++i) { + const char * ciphers = NULL; + int n_diff = 0; + WOLFSSL_CTX * ctx = NULL; + WOLFSSL * ssl = NULL; + + /* Enable crypto policy. */ + rc = wolfSSL_crypto_policy_enable(policy_list[i]); + ExpectIntEQ(rc, WOLFSSL_SUCCESS); + + rc = wolfSSL_crypto_policy_is_enabled(); + ExpectIntEQ(rc, 1); + + /* Trying to enable while already enabled should return + * forbidden. */ + rc = wolfSSL_crypto_policy_enable(policy_list[i]); + ExpectIntEQ(rc, CRYPTO_POLICY_FORBIDDEN); + + /* Security level and ciphers should match what is expected. */ + rc = wolfSSL_crypto_policy_get_level(); + ExpectIntEQ(rc, seclevel_list[i]); + + ciphers = wolfSSL_crypto_policy_get_ciphers(); + ExpectNotNull(ciphers); + + if (ciphers != NULL) { + n_diff = XSTRNCMP(ciphers, ciphers_list[i], strlen(ciphers)); + #ifdef DEBUG_WOLFSSL + if (n_diff) { + printf("error: got \n%s, expected \n%s\n", + ciphers, ciphers_list[i]); + } + #endif /* DEBUG_WOLFSSL */ + ExpectIntEQ(n_diff, 0); + } + + /* TLSv1_2_method should work for all policies. */ + ctx = wolfSSL_CTX_new(wolfTLSv1_2_method()); + ExpectNotNull(ctx); + + if (ctx != NULL) { + ssl = wolfSSL_new(ctx); + ExpectNotNull(ssl); + + /* These API should be rejected while enabled. */ + rc = wolfSSL_CTX_SetMinVersion(ctx, WOLFSSL_TLSV1_3); + ExpectIntEQ(rc, CRYPTO_POLICY_FORBIDDEN); + + rc = wolfSSL_SetMinVersion(ssl, WOLFSSL_TLSV1_3); + ExpectIntEQ(rc, CRYPTO_POLICY_FORBIDDEN); + } + + if (ctx != NULL) { + wolfSSL_CTX_free(ctx); + ctx = NULL; + } + + if (ssl != NULL) { + wolfSSL_free(ssl); + ssl = NULL; + } + + wolfSSL_crypto_policy_disable(); + + /* Do the same test by buffer. */ + rc = wolfSSL_crypto_policy_enable_buffer(ciphers_list[i]); + ExpectIntEQ(rc, WOLFSSL_SUCCESS); + + rc = wolfSSL_crypto_policy_is_enabled(); + ExpectIntEQ(rc, 1); + + /* Security level and ciphers should match what is expected. */ + rc = wolfSSL_crypto_policy_get_level(); + ExpectIntEQ(rc, seclevel_list[i]); + + ciphers = wolfSSL_crypto_policy_get_ciphers(); + ExpectNotNull(ciphers); + + if (ciphers != NULL) { + n_diff = XSTRNCMP(ciphers, ciphers_list[i], strlen(ciphers)); + #ifdef DEBUG_WOLFSSL + if (n_diff) { + printf("error: got \n%s, expected \n%s\n", + ciphers, ciphers_list[i]); + } + #endif /* DEBUG_WOLFSSL */ + ExpectIntEQ(n_diff, 0); + } + + wolfSSL_crypto_policy_disable(); + } + + wolfSSL_crypto_policy_disable(); + +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ + return EXPECT_RESULT(); +} + +/* System wide crypto-policy test: certs and keys. + * + * Loads three different policies (legacy, default, future), + * then tests loading different certificates and keys of + * varying strength. + * */ +static int test_wolfSSL_crypto_policy_certs_and_keys(void) +{ + EXPECT_DECLS; +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) + int rc = WC_NO_ERR_TRACE(WOLFSSL_FAILURE); + const char * policy_list[] = { + "examples/crypto_policies/legacy/wolfssl.txt", + "examples/crypto_policies/default/wolfssl.txt", + "examples/crypto_policies/future/wolfssl.txt", + }; + int i = 0; + + for (i = 0; i < 3; ++i) { + WOLFSSL_CTX * ctx = NULL; + WOLFSSL * ssl = NULL; + int is_legacy = 0; + int is_future = 0; + /* certs */ + const char * cert1024 = "certs/1024/client-cert.pem"; + const char * cert2048 = "certs/client-cert.pem"; + const char * cert3072 = "certs/3072/client-cert.pem"; + const char * cert256 = "certs/client-ecc-cert.pem"; + const char * cert384 = "certs/client-ecc384-cert.pem"; + /* keys */ + const char * key1024 = "certs/1024/client-key.pem"; + const char * key2048 = "certs/client-key.pem"; + const char * key3072 = "certs/3072/client-key.pem"; + const char * key256 = "certs/ecc-key.pem"; + const char * key384 = "certs/client-ecc384-key.pem"; + + is_legacy = (XSTRSTR(policy_list[i], "legacy") != NULL) ? 1 : 0; + is_future = (XSTRSTR(policy_list[i], "future") != NULL) ? 1 : 0; + + /* Enable crypto policy. */ + rc = wolfSSL_crypto_policy_enable(policy_list[i]); + ExpectIntEQ(rc, WOLFSSL_SUCCESS); + + rc = wolfSSL_crypto_policy_is_enabled(); + ExpectIntEQ(rc, 1); + + /* TLSv1_2_method should work for all policies. */ + ctx = wolfSSL_CTX_new(wolfTLSv1_2_method()); + ExpectNotNull(ctx); + + /* Test certs of varying strength. */ + if (ctx != NULL) { + /* VERIFY_PEER must be set for key/cert checks to be done. */ + wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL); + + /* Test loading a cert with 1024 RSA key size. + * This should fail for all but legacy. */ + rc = wolfSSL_CTX_use_certificate_chain_file(ctx, cert1024); + + if (is_legacy) { + ExpectIntEQ(rc, WOLFSSL_SUCCESS); + } + else { + ExpectIntEQ(rc, WOLFSSL_FAILURE); + } + + /* Test loading a cert with 2048 RSA key size. + * Future crypto-policy is min 3072 RSA and DH key size, + * and should fail. */ + rc = wolfSSL_CTX_use_certificate_chain_file(ctx, cert2048); + + if (is_future) { + /* Future crypto-policy is min 3072 RSA and DH key size, this + * and should fail. */ + ExpectIntEQ(rc, WOLFSSL_FAILURE); + + /* Set to VERIFY_NONE. This will disable key size checks, + * it should now succeed. */ + wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_NONE, NULL); + rc = wolfSSL_CTX_use_certificate_chain_file(ctx, cert2048); + + ExpectIntEQ(rc, WOLFSSL_SUCCESS); + + /* Set back to verify peer. */ + wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL); + + } + else { + ExpectIntEQ(rc, WOLFSSL_SUCCESS); + } + + /* Test loading a CA cert with 3072 RSA key size. + * This should succeed for all policies. */ + rc = wolfSSL_CTX_use_certificate_chain_file(ctx, cert3072); + ExpectIntEQ(rc, WOLFSSL_SUCCESS); + + /* Test loading an ecc cert with 256 key size. + * This should succeed for all policies. */ + rc = wolfSSL_CTX_use_certificate_chain_file(ctx, cert256); + ExpectIntEQ(rc, WOLFSSL_SUCCESS); + + /* Test loading an ecc cert with 384 key size. + * This should succeed for all policies. */ + rc = wolfSSL_CTX_use_certificate_chain_file(ctx, cert384); + ExpectIntEQ(rc, WOLFSSL_SUCCESS); + + /* cleanup */ + wolfSSL_CTX_free(ctx); + ctx = NULL; + } + + /* TLSv1_2_method should work for all policies. */ + ctx = wolfSSL_CTX_new(wolfTLSv1_2_method()); + ExpectNotNull(ctx); + + /* Repeat same tests for keys of varying strength. */ + if (ctx != NULL) { + /* 1024 RSA */ + rc = SSL_CTX_use_PrivateKey_file(ctx, key1024, + SSL_FILETYPE_PEM); + + if (is_legacy) { + ExpectIntEQ(rc, WOLFSSL_SUCCESS); + } + else { + ExpectIntEQ(rc, WOLFSSL_FAILURE); + } + + /* 2048 RSA */ + rc = SSL_CTX_use_PrivateKey_file(ctx, key2048, + SSL_FILETYPE_PEM); + + if (!is_future) { + ExpectIntEQ(rc, WOLFSSL_SUCCESS); + } + else { + ExpectIntEQ(rc, WOLFSSL_FAILURE); + } + + /* 3072 RSA */ + rc = SSL_CTX_use_PrivateKey_file(ctx, key3072, + SSL_FILETYPE_PEM); + ExpectIntEQ(rc, WOLFSSL_SUCCESS); + + /* 256 ecc */ + rc = SSL_CTX_use_PrivateKey_file(ctx, key256, + SSL_FILETYPE_PEM); + ExpectIntEQ(rc, WOLFSSL_SUCCESS); + + /* 384 ecc */ + rc = SSL_CTX_use_PrivateKey_file(ctx, key384, + SSL_FILETYPE_PEM); + ExpectIntEQ(rc, WOLFSSL_SUCCESS); + + /* cleanup */ + wolfSSL_CTX_free(ctx); + ctx = NULL; + } + + #ifdef HAVE_ECC + /* Test set ecc min key size. */ + ctx = wolfSSL_CTX_new(wolfTLSv1_2_method()); + ExpectNotNull(ctx); + + if (ctx != NULL) { + ssl = SSL_new(ctx); + ExpectNotNull(ssl); + + /* Test setting ctx. */ + rc = wolfSSL_CTX_SetMinEccKey_Sz(ctx, 160); + if (is_legacy) { + ExpectIntEQ(rc, WOLFSSL_SUCCESS); + } + else { + ExpectIntEQ(rc, CRYPTO_POLICY_FORBIDDEN); + } + + rc = wolfSSL_CTX_SetMinEccKey_Sz(ctx, 224); + if (!is_future) { + ExpectIntEQ(rc, WOLFSSL_SUCCESS); + } + else { + ExpectIntEQ(rc, CRYPTO_POLICY_FORBIDDEN); + } + + rc = wolfSSL_CTX_SetMinEccKey_Sz(ctx, 256); + ExpectIntEQ(rc, WOLFSSL_SUCCESS); + + /* Test setting ssl. */ + if (ssl != NULL) { + rc = wolfSSL_SetMinEccKey_Sz(ssl, 160); + if (is_legacy) { + ExpectIntEQ(rc, WOLFSSL_SUCCESS); + } + else { + ExpectIntEQ(rc, CRYPTO_POLICY_FORBIDDEN); + } + + rc = wolfSSL_SetMinEccKey_Sz(ssl, 224); + if (!is_future) { + ExpectIntEQ(rc, WOLFSSL_SUCCESS); + } + else { + ExpectIntEQ(rc, CRYPTO_POLICY_FORBIDDEN); + } + + rc = wolfSSL_SetMinEccKey_Sz(ssl, 256); + ExpectIntEQ(rc, WOLFSSL_SUCCESS); + + wolfSSL_free(ssl); + ssl = NULL; + } + + /* cleanup */ + wolfSSL_CTX_free(ctx); + ctx = NULL; + } + #endif /* HAVE_ECC */ + + #if !defined(NO_RSA) + /* Test set rsa min key size. */ + ctx = wolfSSL_CTX_new(wolfTLSv1_2_method()); + ExpectNotNull(ctx); + + if (ctx != NULL) { + ssl = SSL_new(ctx); + ExpectNotNull(ssl); + + /* Test setting ctx. */ + rc = wolfSSL_CTX_SetMinRsaKey_Sz(ctx, 1024); + if (is_legacy) { + ExpectIntEQ(rc, WOLFSSL_SUCCESS); + } + else { + ExpectIntEQ(rc, CRYPTO_POLICY_FORBIDDEN); + } + + rc = wolfSSL_CTX_SetMinRsaKey_Sz(ctx, 2048); + if (!is_future) { + ExpectIntEQ(rc, WOLFSSL_SUCCESS); + } + else { + ExpectIntEQ(rc, CRYPTO_POLICY_FORBIDDEN); + } + + rc = wolfSSL_CTX_SetMinRsaKey_Sz(ctx, 3072); + ExpectIntEQ(rc, WOLFSSL_SUCCESS); + + /* Test setting ssl. */ + if (ssl != NULL) { + rc = wolfSSL_SetMinRsaKey_Sz(ssl, 1024); + if (is_legacy) { + ExpectIntEQ(rc, WOLFSSL_SUCCESS); + } + else { + ExpectIntEQ(rc, CRYPTO_POLICY_FORBIDDEN); + } + + rc = wolfSSL_SetMinRsaKey_Sz(ssl, 2048); + if (!is_future) { + ExpectIntEQ(rc, WOLFSSL_SUCCESS); + } + else { + ExpectIntEQ(rc, CRYPTO_POLICY_FORBIDDEN); + } + + rc = wolfSSL_SetMinRsaKey_Sz(ssl, 3072); + ExpectIntEQ(rc, WOLFSSL_SUCCESS); + + wolfSSL_free(ssl); + ssl = NULL; + } + + /* cleanup */ + wolfSSL_CTX_free(ctx); + ctx = NULL; + } + #endif /* !NO_RSA */ + + wolfSSL_crypto_policy_disable(); + } + + wolfSSL_crypto_policy_disable(); +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ + return EXPECT_RESULT(); +} + +/* System wide crypto-policy test: tls and dtls methods. + * */ +static int test_wolfSSL_crypto_policy_tls_methods(void) +{ + EXPECT_DECLS; +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) + int rc = WC_NO_ERR_TRACE(WOLFSSL_FAILURE); + const char * policy_list[] = { + "examples/crypto_policies/legacy/wolfssl.txt", + "examples/crypto_policies/default/wolfssl.txt", + "examples/crypto_policies/future/wolfssl.txt", + }; + int i = 0; + + for (i = 0; i < 3; ++i) { + WOLFSSL_CTX * ctx = NULL; + int is_legacy = 0; + + is_legacy = (XSTRSTR(policy_list[i], "legacy") != NULL) ? 1 : 0; + + /* Enable crypto policy. */ + rc = wolfSSL_crypto_policy_enable(policy_list[i]); + ExpectIntEQ(rc, WOLFSSL_SUCCESS); + + rc = wolfSSL_crypto_policy_is_enabled(); + ExpectIntEQ(rc, 1); + + /* Try to use old TLS methods. Only allowed with legacy. */ + #if !defined(NO_OLD_TLS) + ctx = wolfSSL_CTX_new(wolfTLSv1_1_method()); + + if (is_legacy) { + ExpectNotNull(ctx); + } + else { + ExpectNull(ctx); + } + + if (ctx != NULL) { + wolfSSL_CTX_free(ctx); + ctx = NULL; + } + + #if defined(WOLFSSL_ALLOW_TLSV10) + ctx = wolfSSL_CTX_new(wolfTLSv1_method()); + + if (is_legacy) { + ExpectNotNull(ctx); + } + else { + ExpectNull(ctx); + } + + if (ctx != NULL) { + wolfSSL_CTX_free(ctx); + ctx = NULL; + } + #endif /* WOLFSSL_ALLOW_TLSV10 */ + #else + (void) is_legacy; + #endif /* !NO_OLD_TLS */ + + /* TLSv1_2_method should work for all policies. */ + ctx = wolfSSL_CTX_new(wolfTLSv1_2_method()); + ExpectNotNull(ctx); + + if (ctx != NULL) { + wolfSSL_CTX_free(ctx); + ctx = NULL; + } + + ctx = wolfSSL_CTX_new(wolfTLSv1_3_method()); + ExpectNotNull(ctx); + + if (ctx != NULL) { + wolfSSL_CTX_free(ctx); + ctx = NULL; + } + + ctx = wolfSSL_CTX_new(TLS_method()); + ExpectNotNull(ctx); + + if (ctx != NULL) { + wolfSSL_CTX_free(ctx); + ctx = NULL; + } + + #ifdef WOLFSSL_DTLS + ctx = wolfSSL_CTX_new(DTLS_method()); + ExpectNotNull(ctx); + + if (ctx != NULL) { + wolfSSL_CTX_free(ctx); + ctx = NULL; + } + + ctx = wolfSSL_CTX_new(wolfDTLSv1_2_method()); + ExpectNotNull(ctx); + + if (ctx != NULL) { + wolfSSL_CTX_free(ctx); + ctx = NULL; + } + + #ifndef NO_OLD_TLS + /* Only allowed with legacy. */ + ctx = wolfSSL_CTX_new(wolfDTLSv1_method()); + + if (is_legacy) { + ExpectNotNull(ctx); + } + else { + ExpectNull(ctx); + } + + if (ctx != NULL) { + wolfSSL_CTX_free(ctx); + ctx = NULL; + } + #endif /* !NO_OLD_TLS */ + #endif /* WOLFSSL_DTLS */ + + wolfSSL_crypto_policy_disable(); + } + + wolfSSL_crypto_policy_disable(); +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ + return EXPECT_RESULT(); +} + +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) +/* Helper function for test_wolfSSL_crypto_policy_ciphers. + * Searches ssl suites for cipher string. + * + * Returns 1 if found. + * Returns 0 if not found. + * Returns < 0 if error. + * */ +static int crypto_policy_cipher_found(const WOLFSSL * ssl, + const char * cipher, + int full_match) +{ + WOLF_STACK_OF(WOLFSSL_CIPHER) * sk = NULL; + WOLFSSL_CIPHER * current = NULL; + const char * suite; + int found = 0; + int i = 0; + + if (ssl == NULL || cipher == NULL || *cipher == '\0') { + return -1; + } + + sk = wolfSSL_get_ciphers_compat(ssl); + + if (sk == NULL) { + return -1; + } + + do { + current = wolfSSL_sk_SSL_CIPHER_value(sk, i++); + if (current) { + suite = wolfSSL_CIPHER_get_name(current); + if (suite) { + if (full_match == 2) { + /* literal match */ + if (XSTRLEN(suite) == XSTRLEN(cipher) && + XMEMCMP(suite, cipher, XSTRLEN(cipher)) == 0) { + found = 1; + break; + } + } + else if (full_match == 1) { + /* prefix match */ + if (XSTRNCMP(suite, cipher, XSTRLEN(cipher)) == 0) { + found = 1; + break; + } + } + else { + /* needle in haystack match */ + if (XSTRSTR(suite, cipher)) { + found = 1; + break; + } + } + } + } + } while (current); + + return found == 1; +} +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ + +/* System wide crypto-policy test: ciphers. + * */ +static int test_wolfSSL_crypto_policy_ciphers(void) +{ + EXPECT_DECLS; +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) + int rc = WC_NO_ERR_TRACE(WOLFSSL_FAILURE); + const char * policy_list[] = { + "examples/crypto_policies/legacy/wolfssl.txt", + "examples/crypto_policies/default/wolfssl.txt", + "examples/crypto_policies/future/wolfssl.txt", + }; + int seclevel_list[] = { 1, 2, 3 }; + int i = 0; + int is_legacy = 0; + int is_future = 0; + + for (i = 0; i < 3; ++i) { + WOLFSSL_CTX * ctx = NULL; + WOLFSSL * ssl = NULL; + int found = 0; + + is_legacy = (XSTRSTR(policy_list[i], "legacy") != NULL) ? 1 : 0; + is_future = (XSTRSTR(policy_list[i], "future") != NULL) ? 1 : 0; + + (void) is_legacy; + + /* Enable crypto policy. */ + rc = wolfSSL_crypto_policy_enable(policy_list[i]); + ExpectIntEQ(rc, WOLFSSL_SUCCESS); + + rc = wolfSSL_crypto_policy_is_enabled(); + ExpectIntEQ(rc, 1); + + ctx = wolfSSL_CTX_new(TLS_method()); + ExpectNotNull(ctx); + + ssl = SSL_new(ctx); + ExpectNotNull(ssl); + + rc = wolfSSL_CTX_get_security_level(ctx); + ExpectIntEQ(rc, seclevel_list[i]); + + rc = wolfSSL_get_security_level(ssl); + ExpectIntEQ(rc, seclevel_list[i]); + + found = crypto_policy_cipher_found(ssl, "RC4", 0); + ExpectIntEQ(found, is_legacy); + + found = crypto_policy_cipher_found(ssl, "AES128", 0); + ExpectIntEQ(found, !is_future); + + found = crypto_policy_cipher_found(ssl, "DHE-RSA-AES", 1); + ExpectIntEQ(found, !is_future); + + found = crypto_policy_cipher_found(ssl, "ECDHE-ECDSA-AES256-SHA", 2); + ExpectIntEQ(found, !is_future); + + found = crypto_policy_cipher_found(ssl, "ECDHE-RSA-AES256-SHA", 2); + ExpectIntEQ(found, !is_future); + + if (ssl != NULL) { + SSL_free(ssl); + ssl = NULL; + } + + if (ctx != NULL) { + wolfSSL_CTX_free(ctx); + ctx = NULL; + } + + wolfSSL_crypto_policy_disable(); + } + + wolfSSL_crypto_policy_disable(); + +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ + return EXPECT_RESULT(); +} + static int test_wolfSSL_SSL_in_init(void) { EXPECT_DECLS; @@ -101205,6 +101893,10 @@ TEST_CASE testCases[] = { #endif TEST_DECL(test_wolfSSL_CTX_get_min_proto_version), TEST_DECL(test_wolfSSL_security_level), + TEST_DECL(test_wolfSSL_crypto_policy), + TEST_DECL(test_wolfSSL_crypto_policy_certs_and_keys), + TEST_DECL(test_wolfSSL_crypto_policy_tls_methods), + TEST_DECL(test_wolfSSL_crypto_policy_ciphers), TEST_DECL(test_wolfSSL_SSL_in_init), TEST_DECL(test_wolfSSL_CTX_set_timeout), TEST_DECL(test_wolfSSL_set_psk_use_session_callback), diff --git a/wolfssl/error-ssl.h b/wolfssl/error-ssl.h index a819103da6..2d4d802112 100644 --- a/wolfssl/error-ssl.h +++ b/wolfssl/error-ssl.h @@ -221,6 +221,7 @@ enum wolfSSL_ErrorCodes { HRR_COOKIE_ERROR = -505, /* HRR msg cookie mismatch */ UNSUPPORTED_CERTIFICATE = -506, /* unsupported certificate type */ + /* PEM and EVP errors */ WOLFSSL_PEM_R_NO_START_LINE_E = -507, WOLFSSL_PEM_R_PROBLEMS_GETTING_PASSWORD_E = -508, WOLFSSL_PEM_R_BAD_PASSWORD_READ_E = -509, @@ -232,7 +233,10 @@ enum wolfSSL_ErrorCodes { WOLFSSL_EVP_R_DECODE_ERROR = -514, WOLFSSL_EVP_R_PRIVATE_KEY_DECODE_ERROR = -515, - WOLFSSL_LAST_E = -515 + CRYPTO_POLICY_FORBIDDEN = -516, /* operation forbidden by system + * crypto-policy */ + + WOLFSSL_LAST_E = -516 /* codes -1000 to -1999 are reserved for wolfCrypt. */ }; diff --git a/wolfssl/internal.h b/wolfssl/internal.h index f5ce5b02ef..d180cb8615 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1852,6 +1852,12 @@ enum Misc { #ifndef MAX_WOLFSSL_FILE_SIZE MAX_WOLFSSL_FILE_SIZE = 1024UL * 1024UL * 4, /* 4 mb file size alloc limit */ #endif +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) + MAX_WOLFSSL_CRYPTO_POLICY_SIZE = 1024UL, /* Crypto-policy file is one line. + * It should not be large. */ + MIN_WOLFSSL_SEC_LEVEL = 0, + MAX_WOLFSSL_SEC_LEVEL = 5, +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ CERT_MIN_SIZE = 256, /* min PEM cert size with header/footer */ @@ -2409,16 +2415,16 @@ typedef struct CipherSuite { /* use wolfSSL_API visibility to be able to test in tests/api.c */ WOLFSSL_API void InitSuitesHashSigAlgo(byte* hashSigAlgo, int have, - int tls1_2, int keySz, - word16* len); + int tls1_2, int keySz, word16* len); WOLFSSL_LOCAL int AllocateCtxSuites(WOLFSSL_CTX* ctx); WOLFSSL_LOCAL int AllocateSuites(WOLFSSL* ssl); WOLFSSL_LOCAL void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, word16 havePSK, word16 haveDH, word16 haveECDSAsig, word16 haveECC, word16 haveStaticRSA, word16 haveStaticECC, - word16 haveFalconSig, word16 haveDilithiumSig, - word16 haveAnon, word16 haveNull, int side); + word16 haveAnon, word16 haveNull, + word16 haveAES128, word16 haveSHA1, + word16 haveRC4, int side); typedef struct TLSX TLSX; WOLFSSL_LOCAL int MatchSuite_ex(const WOLFSSL* ssl, Suites* peerSuites, @@ -4177,6 +4183,9 @@ struct WOLFSSL_CTX { byte *sigSpec; word16 sigSpecSz; #endif +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) + int secLevel; /* The security level of system-wide crypto policy. */ +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ }; WOLFSSL_LOCAL @@ -6257,8 +6266,21 @@ struct WOLFSSL { byte *peerSigSpec; /* This pointer always owns the memory. */ word16 peerSigSpecSz; #endif +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) + int secLevel; /* The security level of system-wide crypto policy. */ +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ }; +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) +#define WOLFSSL_CRYPTO_POLICY_HDR "@SECLEVEL=" +#define WOLFSSL_SECLEVEL_STR "@SECLEVEL=" +struct SystemCryptoPolicy { + int enabled; + int secLevel; + char str[MAX_WOLFSSL_CRYPTO_POLICY_SIZE + 1]; /* + 1 for null term */ +}; +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ + /* * wolfSSL_PEM_read_bio_X509 pushes an ASN_NO_PEM_HEADER error * to the error queue on file end. This should not be left diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 22bb89f75f..d6b725ddf4 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -3193,6 +3193,22 @@ WOLFSSL_ABI WOLFSSL_API int wolfSSL_Init(void); /* call when done to cleanup/free session cache mutex / resources */ WOLFSSL_ABI WOLFSSL_API int wolfSSL_Cleanup(void); +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) +WOLFSSL_API int wolfSSL_crypto_policy_enable(const char * policy); +WOLFSSL_API int wolfSSL_crypto_policy_enable_buffer(const char * buf); +WOLFSSL_API void wolfSSL_crypto_policy_disable(void); +WOLFSSL_API int wolfSSL_crypto_policy_is_enabled(void); +WOLFSSL_API const char * wolfSSL_crypto_policy_get_ciphers(void); +WOLFSSL_API int wolfSSL_crypto_policy_get_level(void); +WOLFSSL_LOCAL int wolfSSL_crypto_policy_init_ctx(WOLFSSL_CTX * ctx, + WOLFSSL_METHOD * method); +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ +/* compat functions. */ +WOLFSSL_API int wolfSSL_get_security_level(const WOLFSSL * ssl); +#ifndef NO_WOLFSSL_STUB +WOLFSSL_API void wolfSSL_set_security_level(WOLFSSL * ssl, int level); +#endif /* !NO_WOLFSSL_STUB */ + /* which library version do we have */ WOLFSSL_API const char* wolfSSL_lib_version(void); #if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L @@ -5795,7 +5811,6 @@ WOLFSSL_API int wolfSSL_EVP_PKEY_param_check(WOLFSSL_EVP_PKEY_CTX* ctx); #endif WOLFSSL_API void wolfSSL_CTX_set_security_level(WOLFSSL_CTX* ctx, int level); WOLFSSL_API int wolfSSL_CTX_get_security_level(const WOLFSSL_CTX* ctx); - WOLFSSL_API int wolfSSL_SESSION_is_resumable(const WOLFSSL_SESSION *s); WOLFSSL_API void wolfSSL_CRYPTO_free(void *str, const char *file, int line); diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 1a7cf1b8b5..58a932000e 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -4252,6 +4252,12 @@ extern void uITRON4_free(void *p) ; #error "Please disable DSA if disabling SHA-1" #endif +#if defined(WOLFSSL_SYS_CRYPTO_POLICY) + #if !defined(WOLFSSL_CRYPTO_POLICY_FILE) + #error "WOLFSSL_SYS_CRYPTO_POLICY requires a crypto policy file" + #endif /* ! WOLFSSL_CRYPTO_POLICY_FILE */ +#endif /* WOLFSSL_SYS_CRYPTO_POLICY */ + /* if configure.ac turned on this feature, HAVE_ENTROPY_MEMUSE will be set, * also define HAVE_WOLFENTROPY */ #ifdef HAVE_ENTROPY_MEMUSE