From 98ac4a6f9cd95df34a97f3733d0340d7839748db Mon Sep 17 00:00:00 2001 From: Hayden Roche Date: Fri, 7 Oct 2022 11:19:34 -0700 Subject: [PATCH] Add ability to toggle system CA certs support. --- CMakeLists.txt | 11 ++++++++++ configure.ac | 39 ++++++++++++++++++++++++++++++------ examples/client/client.c | 14 +++++++------ src/ssl.c | 11 ++++++++-- tests/api.c | 4 ++-- wolfssl/wolfcrypt/settings.h | 11 ++++++++++ 6 files changed, 74 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b4cb2bfc4..2e3e10c7d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1668,6 +1668,17 @@ add_option("WOLFSSL_OPTFLAGS" "Enable default optimization CFLAGS for the compiler (default: enabled)" "yes" "yes;no") +add_option("WOLFSSL_SYS_CA_CERTS" + "Enable ability to load CA certs from OS (default: enabled)" + "yes" "yes;no") +if(WOLFSSL_SYS_CA_CERTS) + if(NOT WOLFSSL_FILESYSTEM) + message(FATAL_ERROR "Cannot use system CA certs without a filesystem.") + else() + list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_SYS_CA_CERTS") + endif() +endif() + # FLAGS operations if(WOLFSSL_AESCCM) diff --git a/configure.ac b/configure.ac index 0fd523e95..935109b66 100644 --- a/configure.ac +++ b/configure.ac @@ -1097,7 +1097,6 @@ AC_ARG_ENABLE([cryptonly], AS_IF([test "x$FIPS_VERSION" = "xrand"],[ENABLED_CRYPTONLY="yes"]) - # DTLS # DTLS is a prereq for the options mcast, sctp, and jni. Enabling any of those # without DTLS will also enable DTLS. @@ -7346,6 +7345,12 @@ AC_ARG_ENABLE([optflags], [ ENABLED_OPTFLAGS=yes ] ) +# Adds functionality to load CA certificates from the operating system. +AC_ARG_ENABLE([sys-ca-certs], + [AS_HELP_STRING([--enable-sys-ca-certs],[Enable ability to load CA certs from OS (default: enabled)])], + [ ENABLED_SYS_CA_CERTS=$enableval ], + [ ENABLED_SYS_CA_CERTS=yes ] + ) # check if should run the trusted peer certs test # (for now checking both C_FLAGS and C_EXTRA_FLAGS) @@ -7408,6 +7413,24 @@ esac # Update ENABLE_* variables # ################################################################################ +if test "x$ENABLED_LEANPSK" = "xyes" || test "x$ENABLED_CERTS" = "xno" || \ + test "x$ENABLED_ASN" = "xno" +then + ENABLED_CERTS=no + ENABLED_ASN=no +fi + +if test "x$ENABLED_SYS_CA_CERTS" = "xyes" +then + if test "x$ENABLED_FILESYSTEM" = "xno" + then + ENABLED_SYS_CA_CERTS="no" + elif test "x$ENABLED_CERTS" = "xno" + then + ENABLED_SYS_CA_CERTS="no" + fi +fi + if test "x$ENABLED_WOLFCLU" = "xyes" then if test "x$ENABLED_CERTGEN" = "xno" @@ -7621,6 +7644,14 @@ AS_IF([test "x$ENABLED_16BIT" = "xyes" && \ ################################################################################ # Update CFLAGS based on options # ################################################################################ +AS_IF([test "x$ENABLED_CERTS" = "xno"], + [AM_CFLAGS="$AM_CFLAGS -DNO_CERTS"]) + +AS_IF([test "x$ENABLED_ASN" = "xno"], + [AM_CFLAGS="$AM_CFLAGS -DNO_ASN"]) + +AS_IF([test "x$ENABLED_SYS_CA_CERTS" = "xyes"], + [AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SYS_CA_CERTS"]) AS_IF([test "x$ENABLED_ALTNAMES" = "xyes"], [AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ALT_NAMES"]) @@ -7894,11 +7925,6 @@ fi AS_IF([test "x$ENABLED_WOLFSSH" = "xyes"],[AM_CPPFLAGS="$AM_CPPFLAGS -DWOLFSSL_WOLFSSH"]) -if test "x$ENABLED_CERTS" = "xno" || test "x$ENABLED_LEANPSK" = "xyes" || test "x$ENABLED_ASN" = "xno"; then - AM_CFLAGS="$AM_CFLAGS -DNO_ASN -DNO_CERTS" - ENABLED_ASN=no -fi - # only allow secure renegotiation info with TLSV12 and ASN if test "x$ENABLED_ASN" = "xno" || \ test "x$ENABLED_TLSV12" = "xno" || \ @@ -8664,6 +8690,7 @@ echo " * IoT-Safe: $ENABLED_IOTSAFE" echo " * IoT-Safe HWRNG: $ENABLED_IOTSAFE_HWRNG" echo " * NXP SE050: $ENABLED_SE050" echo " * PSA: $ENABLED_PSA" +echo " * System CA certs: $ENABLED_SYS_CA_CERTS" echo "" echo "---" diff --git a/examples/client/client.c b/examples/client/client.c index 5c58e078b..c30aeb29d 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -1318,7 +1318,7 @@ static const char* client_usage_msg[][70] = { #ifdef WOLFSSL_SRTP "--srtp (default is SRTP_AES128_CM_SHA1_80)\n", /* 71 */ #endif -#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) +#ifdef WOLFSSL_SYS_CA_CERTS "--sys-ca-certs Load system CA certs for server cert verification\n", /* 72 */ #endif "\n" @@ -1767,7 +1767,7 @@ static void Usage(void) printf("%s", msg[++msgid]); /* more --pqc options */ printf("%s", msg[++msgid]); /* more --pqc options */ #endif -#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) +#ifdef WOLFSSL_SYS_CA_CERTS printf("%s", msg[++msgid]); /* --sys-ca-certs */ #endif #ifdef WOLFSSL_SRTP @@ -1903,7 +1903,9 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #ifdef WOLFSSL_DTLS_CID {"cid", 2, 262}, #endif /* WOLFSSL_DTLS_CID */ +#ifdef WOLFSSL_SYS_CA_CERTS { "sys-ca-certs", 0, 263 }, +#endif { 0, 0, 0 } }; #endif @@ -2013,7 +2015,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) char* pqcAlg = NULL; int exitWithRet = 0; int loadCertKeyIntoSSLObj = 0; -#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) +#ifdef WOLFSSL_SYS_CA_CERTS byte loadSysCaCerts = 0; #endif @@ -2716,7 +2718,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) pqcAlg = myoptarg; break; #endif -#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) +#ifdef WOLFSSL_SYS_CA_CERTS case 263: loadSysCaCerts = 1; break; @@ -2977,12 +2979,12 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) } #endif -#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) +#ifdef WOLFSSL_SYS_CA_CERTS if (loadSysCaCerts && wolfSSL_CTX_load_system_CA_certs(ctx) != WOLFSSL_SUCCESS) { err_sys("wolfSSL_CTX_load_system_CA_certs failed"); } -#endif +#endif /* WOLFSSL_SYS_CA_CERTS */ if (minVersion != CLIENT_INVALID_VERSION) { #ifdef WOLFSSL_DTLS diff --git a/src/ssl.c b/src/ssl.c index 13e7cb6a8..a34315223 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -183,6 +183,9 @@ * ClientCache by default for backwards compatibility. This define will * make wolfSSL_get_session return a reference to ssl->session. The returned * pointer will be freed with the related WOLFSSL object. + * WOLFSSL_SYS_CA_CERTS + * Enables ability to load system CA certs from the OS via + * wolfSSL_CTX_load_system_CA_certs. */ #define WOLFSSL_EVP_INCLUDED @@ -8050,6 +8053,8 @@ int wolfSSL_CTX_load_verify_locations(WOLFSSL_CTX* ctx, const char* file, return WS_RETURN_CODE(ret,WOLFSSL_FAILURE); } +#ifdef WOLFSSL_SYS_CA_CERTS + #ifdef USE_WINDOWS_API static int LoadSystemCaCertsWindows(WOLFSSL_CTX* ctx, byte* loaded) @@ -8245,6 +8250,8 @@ int wolfSSL_CTX_load_system_CA_certs(WOLFSSL_CTX* ctx) return ret; } +#endif /* WOLFSSL_SYS_CA_CERTS */ + #ifdef WOLFSSL_TRUST_PEER_CERT /* Used to specify a peer cert to match when connecting ctx : the ctx structure to load in peer cert @@ -16355,7 +16362,7 @@ cleanup: #ifdef OPENSSL_EXTRA - #ifndef NO_FILESYSTEM + #ifdef WOLFSSL_SYS_CA_CERTS /* * This is an OpenSSL compatibility layer function, but it doesn't mirror * the exact functionality of its OpenSSL counterpart. We don't support the @@ -16383,7 +16390,7 @@ cleanup: return ret; } - #endif /* !NO_FILESYSTEM */ + #endif /* WOLFSSL_SYS_CA_CERTS */ #if defined(WOLFCRYPT_HAVE_SRP) && !defined(NO_SHA256) \ && !defined(WC_NO_RNG) diff --git a/tests/api.c b/tests/api.c index e7d5b4aac..1e28de3b0 100644 --- a/tests/api.c +++ b/tests/api.c @@ -1350,7 +1350,7 @@ static int test_wolfSSL_CTX_load_system_CA_certs(void) { int ret = 0; -#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_WOLFSSL_CLIENT) +#if defined(WOLFSSL_SYS_CA_CERTS) && !defined(NO_WOLFSSL_CLIENT) WOLFSSL_CTX* ctx; byte dirValid = 0; @@ -1404,7 +1404,7 @@ static int test_wolfSSL_CTX_load_system_CA_certs(void) #endif /* OPENSSL_EXTRA */ wolfSSL_CTX_free(ctx); -#endif /* !NO_FILESYSTEM && !NO_CERTS && !NO_WOLFSSL_CLIENT */ +#endif /* WOLFSSL_SYS_CA_CERTS && !NO_WOLFSSL_CLIENT */ return ret; } diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index dbf000605..3b0e889a3 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -2857,6 +2857,17 @@ extern void uITRON4_free(void *p) ; #define WOLFSSL_ASYNC_IO #endif +#ifdef WOLFSSL_SYS_CA_CERTS + #ifdef NO_FILESYSTEM + #warning "Turning off WOLFSSL_SYS_CA_CERTS b/c NO_FILESYSTEM is defined." + #undef WOLFSSL_SYS_CA_CERTS + #endif + #ifdef NO_CERTS + #warning "Turning off WOLFSSL_SYS_CA_CERTS b/c NO_CERTS is defined." + #undef WOLFSSL_SYS_CA_CERTS + #endif +#endif /* WOLFSSL_SYS_CA_CERTS */ + #ifdef __cplusplus } /* extern "C" */ #endif