mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-01 03:34:39 +02:00
Add support for wolfSSL_CTX_load_system_CA_certs on Windows and Mac.
Additionally, fix CMake build to add WOLFSSL_X86_64_BUILD when building for x86_64.
This commit is contained in:
committed by
Hayden Roche
parent
cb5828235b
commit
b50a786cb2
@@ -66,6 +66,18 @@ if(CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
|
||||
set(CMAKE_CXX_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
find_library(CORE_FOUNDATION_FRAMEWORK CoreFoundation)
|
||||
if(NOT CORE_FOUNDATION_FRAMEWORK)
|
||||
message(FATAL_ERROR "Couldn't find CoreFoundation framework.")
|
||||
endif()
|
||||
|
||||
find_library(SECURITY_FRAMEWORK Security)
|
||||
if(NOT SECURITY_FRAMEWORK)
|
||||
message(FATAL_ERROR "Couldn't find Security framework.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include(CheckIncludeFile)
|
||||
|
||||
check_include_file("arpa/inet.h" HAVE_ARPA_INET_H)
|
||||
@@ -1526,6 +1538,10 @@ endif()
|
||||
|
||||
# TODO: - Fast huge math
|
||||
|
||||
if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64")
|
||||
list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_X86_64_BUILD")
|
||||
endif()
|
||||
|
||||
# SP math all
|
||||
add_option("WOLFSSL_SP_MATH_ALL"
|
||||
"Enable Single Precision math implementation for full algorithm suite (default: enabled)"
|
||||
@@ -1900,6 +1916,10 @@ if(WIN32)
|
||||
# For Windows link ws2_32
|
||||
target_link_libraries(wolfssl PUBLIC
|
||||
$<$<PLATFORM_ID:Windows>:ws2_32>)
|
||||
elseif(APPLE)
|
||||
target_link_libraries(wolfssl PUBLIC
|
||||
${CORE_FOUNDATION_FRAMEWORK}
|
||||
${SECURITY_FRAMEWORK})
|
||||
else()
|
||||
# DH requires math (m) library
|
||||
target_link_libraries(wolfssl
|
||||
|
@@ -940,7 +940,6 @@ then
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_HAVE_ISSUER_NAMES"
|
||||
fi
|
||||
|
||||
|
||||
# liboqs
|
||||
ENABLED_LIBOQS="no"
|
||||
tryliboqsdir=""
|
||||
@@ -7985,13 +7984,12 @@ then
|
||||
AM_CFLAGS="$AM_CFLAGS -DHAVE___UINT128_T=1"
|
||||
fi
|
||||
|
||||
|
||||
LIB_SOCKET_NSL
|
||||
AX_HARDEN_CC_COMPILER_FLAGS
|
||||
|
||||
# if mingw then link to ws2_32 for sockets
|
||||
case $host_os in
|
||||
mingw*)
|
||||
# if mingw then link to ws2_32 for sockets
|
||||
LDFLAGS="$LDFLAGS -lws2_32"
|
||||
if test "$enable_shared" = "yes"
|
||||
then
|
||||
@@ -8001,6 +7999,10 @@ case $host_os in
|
||||
MINGW_LIB_WARNING="yes"
|
||||
fi
|
||||
fi ;;
|
||||
*darwin*)
|
||||
# For Mac we need these frameworks to load system CA certs
|
||||
LDFLAGS="$LDFLAGS -framework CoreFoundation -framework Security"
|
||||
;;
|
||||
esac
|
||||
|
||||
if test "$enable_shared" = "no"; then
|
||||
|
@@ -1267,12 +1267,13 @@ const char** wolfSSL_get_system_CA_dirs(word32* num);
|
||||
\ingroup CertsKeys
|
||||
|
||||
\brief This function attempts to load CA certificates into a WOLFSSL_CTX
|
||||
from conventional CA cert directories, which is OS-dependent.
|
||||
from an OS-dependent CA certificate store. Loaded certificates will be
|
||||
trusted.
|
||||
|
||||
\return WOLFSSL_SUCCESS on success.
|
||||
\return WOLFSSL_BAD_PATH if no system CA certs were loaded.
|
||||
\return WOLFSSL_NOT_IMPLEMENTED if the function isn't supported for the
|
||||
target OS.
|
||||
\return WOLFSSL_FAILURE for other failure types (e.g. Windows cert store
|
||||
wasn't properly closed).
|
||||
|
||||
\param ctx pointer to the SSL context, created with wolfSSL_CTX_new().
|
||||
|
||||
|
208
src/ssl.c
208
src/ssl.c
@@ -162,6 +162,15 @@
|
||||
#endif
|
||||
#endif /* !WOLFCRYPT_ONLY || OPENSSL_EXTRA */
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Wincrypt.h>
|
||||
#pragma comment(lib, "crypt32")
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
# include <Security/SecTrustSettings.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* OPENSSL_COMPATIBLE_DEFAULTS:
|
||||
* Enable default behaviour that is compatible with OpenSSL. For example
|
||||
@@ -8041,7 +8050,119 @@ int wolfSSL_CTX_load_verify_locations(WOLFSSL_CTX* ctx, const char* file,
|
||||
return WS_RETURN_CODE(ret,WOLFSSL_FAILURE);
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
#ifdef USE_WINDOWS_API
|
||||
|
||||
static int LoadSystemCaCertsWindows(WOLFSSL_CTX* ctx, byte* loaded)
|
||||
{
|
||||
int ret = WOLFSSL_SUCCESS;
|
||||
word32 i;
|
||||
HANDLE handle = NULL;
|
||||
PCCERT_CONTEXT certCtx = NULL;
|
||||
LPCSTR storeNames[2] = {"ROOT", "CA"};
|
||||
HCRYPTPROV_LEGACY hProv = (HCRYPTPROV_LEGACY)NULL;
|
||||
|
||||
if (ctx == NULL || loaded == NULL) {
|
||||
ret = WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
for (i = 0; ret == WOLFSSL_SUCCESS &&
|
||||
i < sizeof(storeNames)/sizeof(*storeNames); ++i) {
|
||||
handle = CertOpenSystemStoreA(hProv, storeNames[i]);
|
||||
if (handle != NULL) {
|
||||
while (certCtx = CertEnumCertificatesInStore(handle,
|
||||
certCtx)) {
|
||||
if (certCtx->dwCertEncodingType == X509_ASN_ENCODING) {
|
||||
if (ProcessBuffer(ctx, certCtx->pbCertEncoded,
|
||||
certCtx->cbCertEncoded, WOLFSSL_FILETYPE_ASN1,
|
||||
CA_TYPE, NULL, NULL, 0,
|
||||
GET_VERIFY_SETTING_CTX(ctx)) == WOLFSSL_SUCCESS) {
|
||||
/*
|
||||
* Set "loaded" as long as we've loaded one CA
|
||||
* cert.
|
||||
*/
|
||||
*loaded = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
WOLFSSL_MSG_EX("Failed to open cert store %s.", storeNames[i]);
|
||||
}
|
||||
|
||||
if (handle != NULL && !CertCloseStore(handle, 0)) {
|
||||
WOLFSSL_MSG_EX("Failed to close cert store %s.", storeNames[i]);
|
||||
ret = WOLFSSL_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
static int LoadSystemCaCertsMac(WOLFSSL_CTX* ctx, byte* loaded)
|
||||
{
|
||||
int ret = WOLFSSL_SUCCESS;
|
||||
word32 i;
|
||||
const unsigned int trustDomains[] = {
|
||||
kSecTrustSettingsDomainUser,
|
||||
kSecTrustSettingsDomainAdmin,
|
||||
kSecTrustSettingsDomainSystem
|
||||
};
|
||||
CFArrayRef certs;
|
||||
OSStatus stat;
|
||||
CFIndex numCerts;
|
||||
CFDataRef der;
|
||||
CFIndex j;
|
||||
|
||||
if (ctx == NULL || loaded == NULL) {
|
||||
ret = WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
for (i = 0; ret == WOLFSSL_SUCCESS &&
|
||||
i < sizeof(trustDomains)/sizeof(*trustDomains); ++i) {
|
||||
stat = SecTrustSettingsCopyCertificates(trustDomains[i], &certs);
|
||||
|
||||
if (stat == errSecSuccess) {
|
||||
numCerts = CFArrayGetCount(certs);
|
||||
for (j = 0; j < numCerts; ++j) {
|
||||
der = SecCertificateCopyData((SecCertificateRef)
|
||||
CFArrayGetValueAtIndex(certs, j));
|
||||
if (der != NULL) {
|
||||
if (ProcessBuffer(ctx, CFDataGetBytePtr(der),
|
||||
CFDataGetLength(der), WOLFSSL_FILETYPE_ASN1,
|
||||
CA_TYPE, NULL, NULL, 0,
|
||||
GET_VERIFY_SETTING_CTX(ctx)) == WOLFSSL_SUCCESS) {
|
||||
/*
|
||||
* Set "loaded" as long as we've loaded one CA
|
||||
* cert.
|
||||
*/
|
||||
*loaded = 1;
|
||||
}
|
||||
|
||||
CFRelease(der);
|
||||
}
|
||||
}
|
||||
|
||||
CFRelease(certs);
|
||||
}
|
||||
else if (stat == errSecNoTrustSettings) {
|
||||
WOLFSSL_MSG_EX("No trust settings for domain %d, moving to next "
|
||||
"domain.", trustDomains[i]);
|
||||
}
|
||||
else {
|
||||
WOLFSSL_MSG_EX("SecTrustSettingsCopyCertificates failed with"
|
||||
" status %d.", stat);
|
||||
ret = WOLFSSL_FAILURE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Potential system CA certs directories on Linux distros. */
|
||||
static const char* systemCaDirs[] = {
|
||||
"/etc/ssl/certs", /* Debian, Ubuntu, Gentoo, others */
|
||||
@@ -8063,53 +8184,61 @@ const char** wolfSSL_get_system_CA_dirs(word32* num)
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* !_WIN32 */
|
||||
|
||||
static int LoadSystemCaCertsNix(WOLFSSL_CTX* ctx, byte* loaded) {
|
||||
int ret = WOLFSSL_SUCCESS;
|
||||
word32 i;
|
||||
|
||||
if (ctx == NULL || loaded == NULL) {
|
||||
ret = WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
for (i = 0; ret == WOLFSSL_SUCCESS &&
|
||||
i < sizeof(systemCaDirs)/sizeof(*systemCaDirs); ++i) {
|
||||
WOLFSSL_MSG_EX("Attempting to load system CA certs from %s.",
|
||||
systemCaDirs[i]);
|
||||
/*
|
||||
* We want to keep trying to load more CAs even if one cert in
|
||||
* the directory is bad and can't be used (e.g. if one is expired),
|
||||
* so we use WOLFSSL_LOAD_FLAG_IGNORE_ERR.
|
||||
*/
|
||||
if (wolfSSL_CTX_load_verify_locations_ex(ctx, NULL, systemCaDirs[i],
|
||||
WOLFSSL_LOAD_FLAG_IGNORE_ERR) != WOLFSSL_SUCCESS) {
|
||||
WOLFSSL_MSG_EX("Failed to load CA certs from %s, trying "
|
||||
"next possible location.", systemCaDirs[i]);
|
||||
}
|
||||
else {
|
||||
WOLFSSL_MSG_EX("Loaded CA certs from %s.",
|
||||
systemCaDirs[i]);
|
||||
*loaded = 1;
|
||||
/* Stop searching after we've loaded one directory. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int wolfSSL_CTX_load_system_CA_certs(WOLFSSL_CTX* ctx)
|
||||
{
|
||||
int ret;
|
||||
#ifndef _WIN32
|
||||
word32 i;
|
||||
byte loaded = 0;
|
||||
#endif
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_CTX_load_system_CA_certs");
|
||||
|
||||
#ifdef _WIN32
|
||||
(void)ctx;
|
||||
ret = WOLFSSL_NOT_IMPLEMENTED;
|
||||
#ifdef USE_WINDOWS_API
|
||||
ret = LoadSystemCaCertsWindows(ctx, &loaded);
|
||||
#elif defined(__APPLE__)
|
||||
ret = LoadSystemCaCertsMac(ctx, &loaded);
|
||||
#else
|
||||
if (ctx != NULL) {
|
||||
for (i = 0; i < sizeof(systemCaDirs)/sizeof(*systemCaDirs); ++i) {
|
||||
WOLFSSL_MSG_EX("Attempting to load system CA certs from %s.",
|
||||
systemCaDirs[i]);
|
||||
/*
|
||||
* We want to keep trying to load more CAs even if one cert in
|
||||
* the directory is bad and can't be used (e.g. if one is expired),
|
||||
* so we use WOLFSSL_LOAD_FLAG_IGNORE_ERR.
|
||||
*/
|
||||
if (wolfSSL_CTX_load_verify_locations_ex(ctx, NULL, systemCaDirs[i],
|
||||
WOLFSSL_LOAD_FLAG_IGNORE_ERR) != WOLFSSL_SUCCESS) {
|
||||
WOLFSSL_MSG_EX("Failed to load CA certs from %s, trying "
|
||||
"next possible location.", systemCaDirs[i]);
|
||||
}
|
||||
else {
|
||||
WOLFSSL_MSG_EX("Loaded CA certs from %s.",
|
||||
systemCaDirs[i]);
|
||||
loaded = 1;
|
||||
/* Stop searching after we've loaded one directory. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = LoadSystemCaCertsNix(ctx, &loaded);
|
||||
#endif
|
||||
|
||||
if (loaded) {
|
||||
ret = WOLFSSL_SUCCESS;
|
||||
}
|
||||
else {
|
||||
if (ret == WOLFSSL_SUCCESS && !loaded) {
|
||||
ret = WOLFSSL_BAD_PATH;
|
||||
}
|
||||
#endif
|
||||
|
||||
WOLFSSL_LEAVE("wolfSSL_CTX_load_system_CA_certs", ret);
|
||||
|
||||
@@ -16249,13 +16378,6 @@ cleanup:
|
||||
*/
|
||||
ret = WOLFSSL_SUCCESS;
|
||||
}
|
||||
else if (ret != WOLFSSL_SUCCESS) {
|
||||
/*
|
||||
* All other failure types map to WOLFSSL_FAILURE (0), same as
|
||||
* OpenSSL.
|
||||
*/
|
||||
ret = WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
WOLFSSL_LEAVE("wolfSSL_CTX_set_default_verify_paths", ret);
|
||||
|
||||
|
56
tests/api.c
56
tests/api.c
@@ -1352,31 +1352,26 @@ static int test_wolfSSL_CTX_load_system_CA_certs(void)
|
||||
|
||||
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_WOLFSSL_CLIENT)
|
||||
WOLFSSL_CTX* ctx;
|
||||
byte dirValid = 0;
|
||||
|
||||
ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
|
||||
if (ctx == NULL) {
|
||||
fprintf(stderr, "wolfSSL_CTX_new failed.\n");
|
||||
ret = -1;
|
||||
}
|
||||
if (ret == 0) {
|
||||
#ifdef _WIN32
|
||||
if (wolfSSL_CTX_load_system_CA_certs(ctx) != WOLFSSL_NOT_IMPLEMENTED) {
|
||||
ret = -1;
|
||||
}
|
||||
#ifdef OPENSSL_EXTRA
|
||||
if (wolfSSL_CTX_set_default_verify_paths(ctx) != WOLFSSL_FAILURE) {
|
||||
ret = -1;
|
||||
}
|
||||
#endif /* OPENSSL_EXTRA */
|
||||
#else
|
||||
#if defined(USE_WINDOWS_API) || defined(__APPLE__)
|
||||
dirValid = 1;
|
||||
#else
|
||||
word32 numDirs;
|
||||
const char** caDirs = wolfSSL_get_system_CA_dirs(&numDirs);
|
||||
|
||||
if (caDirs == NULL || numDirs == 0) {
|
||||
fprintf(stderr, "wolfSSL_get_system_CA_dirs failed.\n");
|
||||
ret = -1;
|
||||
}
|
||||
else {
|
||||
ReadDirCtx dirCtx;
|
||||
byte dirValid = 0;
|
||||
word32 i;
|
||||
|
||||
for (i = 0; i < numDirs; ++i) {
|
||||
@@ -1387,29 +1382,26 @@ static int test_wolfSSL_CTX_load_system_CA_certs(void)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If the directory isn't empty, we should be able to load CA
|
||||
* certs from it.
|
||||
*/
|
||||
if (dirValid && wolfSSL_CTX_load_system_CA_certs(ctx) !=
|
||||
WOLFSSL_SUCCESS) {
|
||||
ret = -1;
|
||||
}
|
||||
#ifdef OPENSSL_EXTRA
|
||||
/*
|
||||
* Even if we don't have a valid directory to load system CA
|
||||
* certs from, the OpenSSL compat layer function should return
|
||||
* success.
|
||||
*/
|
||||
if (wolfSSL_CTX_set_default_verify_paths(ctx)
|
||||
!= WOLFSSL_SUCCESS) {
|
||||
ret = -1;
|
||||
}
|
||||
#endif /* OPENSSL_EXTRA */
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
* If the directory isn't empty, we should be able to load CA
|
||||
* certs from it. On Windows/Mac, we assume the CA cert stores are
|
||||
* usable.
|
||||
*/
|
||||
if (ret == 0 && dirValid && wolfSSL_CTX_load_system_CA_certs(ctx) !=
|
||||
WOLFSSL_SUCCESS) {
|
||||
fprintf(stderr, "wolfSSL_CTX_load_system_CA_certs failed.\n");
|
||||
ret = -1;
|
||||
}
|
||||
#ifdef OPENSSL_EXTRA
|
||||
if (ret == 0 &&
|
||||
wolfSSL_CTX_set_default_verify_paths(ctx) != WOLFSSL_SUCCESS) {
|
||||
fprintf(stderr, "wolfSSL_CTX_set_default_verify_paths failed.\n");
|
||||
ret = -1;
|
||||
}
|
||||
#endif /* OPENSSL_EXTRA */
|
||||
|
||||
wolfSSL_CTX_free(ctx);
|
||||
#endif /* !NO_FILESYSTEM && !NO_CERTS && !NO_WOLFSSL_CLIENT */
|
||||
|
Reference in New Issue
Block a user