diff --git a/IDE/WIN/user_settings.h b/IDE/WIN/user_settings.h index 919924e9e..225108946 100644 --- a/IDE/WIN/user_settings.h +++ b/IDE/WIN/user_settings.h @@ -37,6 +37,9 @@ #define WC_RSA_BLINDING #define NO_MULTIBYTE_PRINT + #define HAVE_CRL + #define HAVE_CRL_MONITOR + #if defined(WOLFSSL_LIB) /* The lib */ #define OPENSSL_EXTRA diff --git a/src/crl.c b/src/crl.c index 559e459c1..c7c210ebd 100644 --- a/src/crl.c +++ b/src/crl.c @@ -46,10 +46,11 @@ CRL Options: #endif #ifdef HAVE_CRL_MONITOR - #if (defined(__MACH__) || defined(__FreeBSD__) || defined(__linux__)) - static int StopMonitor(int mfd); + #if defined(__MACH__) || defined(__FreeBSD__) || defined(__linux__) || \ + defined(_MSC_VER) + static int StopMonitor(wolfSSL_CRL_mfd_t mfd); #else - #error "CRL monitor only currently supported on linux or mach" + #error "CRL monitor only currently supported on linux or mach or windows" #endif #endif /* HAVE_CRL_MONITOR */ @@ -68,10 +69,10 @@ int InitCRL(WOLFSSL_CRL* crl, WOLFSSL_CERT_MANAGER* cm) crl->monitors[0].path = NULL; crl->monitors[1].path = NULL; #ifdef HAVE_CRL_MONITOR - crl->tid = 0; - crl->mfd = -1; /* mfd for bsd is kqueue fd, eventfd for linux */ - crl->setup = 0; /* thread setup done predicate */ - if (pthread_cond_init(&crl->cond, 0) != 0) { + crl->tid = INVALID_THREAD_VAL; + crl->mfd = WOLFSSL_CRL_MFD_INIT_VAL; + crl->setup = 0; /* thread setup done predicate */ + if (wolfSSL_CondInit(&crl->cond) != 0) { WOLFSSL_MSG("Pthread condition init failed"); return BAD_COND_E; } @@ -221,22 +222,18 @@ void FreeCRL(WOLFSSL_CRL* crl, int dynamic) } #ifdef HAVE_CRL_MONITOR - if (crl->tid != 0) { + if (crl->tid != INVALID_THREAD_VAL) { WOLFSSL_MSG("stopping monitor thread"); if (StopMonitor(crl->mfd) == 0) { - int _pthread_ret = pthread_join(crl->tid, NULL); - if (_pthread_ret != 0) + if (wolfSSL_JoinThread(crl->tid) != 0) WOLFSSL_MSG("stop monitor failed in pthread_join"); } else { WOLFSSL_MSG("stop monitor failed"); } } - { - int _pthread_ret = pthread_cond_destroy(&crl->cond); - if (_pthread_ret != 0) - WOLFSSL_MSG("pthread_cond_destroy failed in FreeCRL"); - } + if (wolfSSL_CondFree(&crl->cond) != 0) + WOLFSSL_MSG("pthread_cond_destroy failed in FreeCRL"); #endif wc_FreeMutex(&crl->crlLock); if (dynamic) /* free self */ @@ -931,15 +928,19 @@ static int SignalSetup(WOLFSSL_CRL* crl, int status) int ret; /* signal to calling thread we're setup */ +#ifndef COND_NO_REQUIRE_LOCKED_MUTEX if (wc_LockMutex(&crl->crlLock) != 0) { WOLFSSL_MSG("wc_LockMutex crlLock failed"); return BAD_MUTEX_E; } +#endif - crl->setup = status; - ret = pthread_cond_signal(&crl->cond); + crl->setup = status; + ret = wolfSSL_CondSignal(&crl->cond); +#ifndef COND_NO_REQUIRE_LOCKED_MUTEX wc_UnLockMutex(&crl->crlLock); +#endif if (ret != 0) return BAD_COND_E; @@ -1047,7 +1048,7 @@ static int SwapLists(WOLFSSL_CRL* crl) /* shutdown monitor thread, 0 on success */ -static int StopMonitor(int mfd) +static int StopMonitor(wolfSSL_CRL_mfd_t mfd) { struct kevent change; @@ -1063,7 +1064,7 @@ static int StopMonitor(int mfd) /* OS X monitoring */ -static void* DoMonitor(void* arg) +static THREAD_RETURN WOLFSSL_THREAD DoMonitor(void* arg) { int fPEM, fDER; struct kevent change; @@ -1180,7 +1181,7 @@ static void* DoMonitor(void* arg) /* shutdown monitor thread, 0 on success */ -static int StopMonitor(int mfd) +static int StopMonitor(wolfSSL_CRL_mfd_t mfd) { word64 w64 = 1; @@ -1195,7 +1196,7 @@ static int StopMonitor(int mfd) /* linux monitoring */ -static void* DoMonitor(void* arg) +static THREAD_RETURN WOLFSSL_THREAD DoMonitor(void* arg) { int notifyFd; int wd = -1; @@ -1326,7 +1327,120 @@ static void* DoMonitor(void* arg) return NULL; } -#endif /* MACH or linux */ +#elif defined(_MSC_VER) + +/* shutdown monitor thread, 0 on success */ +static int StopMonitor(wolfSSL_CRL_mfd_t mfd) +{ + if (SetEvent(mfd) == 0) { + WOLFSSL_MSG("SetEvent custom event trigger failed"); + return -1; + } + return 0; +} + +#define DM_ERROR() do { status = MONITOR_SETUP_E; goto cleanup; } while(0) + +/* windows monitoring + * Tested initially by hand by running + * .\server.exe -A certs/ca-cert.pem + * and connecting to with + * .\client.exe -C -c certs/server-cert.pem -k certs/server-key.pem + * This connection succeeds by default. By deleting all files from certs/crl + * except for crl.revoked we disallow the client to connect. Deleting files + * is done while the server is running to show that the monitor reacts to + * changes in the crl directory. */ +static THREAD_RETURN WOLFSSL_THREAD DoMonitor(void* arg) +{ + WOLFSSL_CRL* crl = (WOLFSSL_CRL*)arg; + int status = 0; + HANDLE handles[WOLFSSL_CRL_MONITORS_LEN + 1]; + DWORD handlesLen = 0; + int i; + + WOLFSSL_ENTER("DoMonitor"); + + handles[0] = crl->mfd = CreateEventA(NULL, FALSE, FALSE, NULL); + if (crl->mfd == NULL) { + WOLFSSL_MSG("CreateEventA failed"); + DM_ERROR(); + } + handlesLen++; + + for (i = 0; i < WOLFSSL_CRL_MONITORS_LEN; i++) { + if (crl->monitors[i].path) { + handles[handlesLen] = FindFirstChangeNotificationA( + crl->monitors[i].path, TRUE, + /* Watch for any changes that may affect what CRL's we load. + * This may trigger on the same file multiple times but this + * way we are certain that we have the most up to date and + * accurate set of CRL's. We don't expect this to trigger + * often enough for it to be a bottleneck. */ + FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_ATTRIBUTES | + FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE | + FILE_NOTIFY_CHANGE_SECURITY); + if (handles[handlesLen] == INVALID_HANDLE_VALUE) { + WOLFSSL_MSG("FindFirstChangeNotificationA failed"); + DM_ERROR(); + } + handlesLen++; + } + } + + if (handlesLen == 1) { + WOLFSSL_MSG("Nothing to watch. Only custom event handle set."); + DM_ERROR(); + } + + if (SignalSetup(crl, 1) != 0) { + WOLFSSL_MSG("Call to SignalSetup failed"); + DM_ERROR(); + } + + for (;;) { + DWORD waitRet = WaitForMultipleObjects(handlesLen, handles, FALSE, + INFINITE); + WOLFSSL_MSG("Got notify event"); + + if (waitRet >= WAIT_OBJECT_0 && waitRet < WAIT_OBJECT_0 + handlesLen) { + if (waitRet == WAIT_OBJECT_0) { + WOLFSSL_MSG("got custom shutdown event, breaking out"); + break; + } + else if (SwapLists(crl) < 0) { + WOLFSSL_MSG("SwapLists problem, continue"); + } + } + else { + WOLFSSL_MSG("Unexpected WaitForMultipleObjects return. Continue."); + } + + for (i = 1; i < (int)handlesLen; i++) { + if (FindNextChangeNotification(handles[i]) == 0) { + WOLFSSL_MSG("FindNextChangeNotification failed"); + DM_ERROR(); + } + } + } + +cleanup: + if (status != 0) + SignalSetup(crl, status); + for (i = 0; i < (int)handlesLen; i++) { + BOOL closeRet; + if (i == 0) /* First handle is our custom event */ + closeRet = CloseHandle(handles[i]); + else + closeRet = FindCloseChangeNotification(handles[i]); + if (closeRet == 0) { + WOLFSSL_MSG("Failed to close handle"); + } + } + crl->mfd = INVALID_HANDLE_VALUE; + return 0; +} + +#endif /* MACH or linux or windows */ /* Start Monitoring the CRL path(s) in a thread */ @@ -1339,36 +1453,40 @@ static int StartMonitorCRL(WOLFSSL_CRL* crl) if (crl == NULL) return BAD_FUNC_ARG; - if (crl->tid != 0) { + if (crl->tid != INVALID_THREAD_VAL) { WOLFSSL_MSG("Monitor thread already running"); return ret; /* that's ok, someone already started */ } - if (pthread_create(&crl->tid, NULL, DoMonitor, crl) != 0) { + if (wolfSSL_NewThread(&crl->tid, DoMonitor, crl) != 0) { WOLFSSL_MSG("Thread creation error"); return THREAD_CREATE_E; } +#ifndef COND_NO_REQUIRE_LOCKED_MUTEX /* wait for setup to complete */ if (wc_LockMutex(&crl->crlLock) != 0) { WOLFSSL_MSG("wc_LockMutex crlLock error"); return BAD_MUTEX_E; } +#endif - while (crl->setup == 0) { - if (pthread_cond_wait(&crl->cond, &crl->crlLock) != 0) { - ret = BAD_COND_E; - break; - } + while (crl->setup == 0) { + if (wolfSSL_CondWait(&crl->cond, &crl->crlLock) != 0) { + ret = BAD_COND_E; + break; } - if (crl->setup < 0) - ret = crl->setup; /* store setup error */ + } + if (crl->setup < 0) + ret = crl->setup; /* store setup error */ +#ifndef COND_NO_REQUIRE_LOCKED_MUTEX wc_UnLockMutex(&crl->crlLock); +#endif if (ret < 0) { WOLFSSL_MSG("DoMonitor setup failure"); - crl->tid = 0; /* thread already done */ + crl->tid = INVALID_THREAD_VAL; /* thread already done */ } return ret; @@ -1451,13 +1569,14 @@ int LoadCRL(WOLFSSL_CRL* crl, const char* path, int type, int monitor) #endif if (monitor & WOLFSSL_CRL_MONITOR) { +#ifdef HAVE_CRL_MONITOR word32 pathLen; char* pathBuf; WOLFSSL_MSG("monitor path requested"); pathLen = (word32)XSTRLEN(path); - pathBuf = (char*)XMALLOC(pathLen+1, crl->heap,DYNAMIC_TYPE_CRL_MONITOR); + pathBuf = (char*)XMALLOC(pathLen+1, crl->heap, DYNAMIC_TYPE_CRL_MONITOR); if (pathBuf) { XMEMCPY(pathBuf, path, pathLen+1); @@ -1488,6 +1607,10 @@ int LoadCRL(WOLFSSL_CRL* crl, const char* path, int type, int monitor) else { ret = MEMORY_E; } +#else + WOLFSSL_MSG("CRL monitoring requested but not compiled in"); + ret = NOT_COMPILED_IN; +#endif } return ret; diff --git a/src/pk.c b/src/pk.c index 07a8c97c4..05ff40a22 100644 --- a/src/pk.c +++ b/src/pk.c @@ -10209,7 +10209,7 @@ static int ec_point_convert_to_affine(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *point) { int err = 0; - mp_digit mp; + mp_digit mp = 0; #ifdef WOLFSSL_SMALL_STACK mp_int* modulus; #else diff --git a/tests/api.c b/tests/api.c index 6881328e0..779ca74fb 100644 --- a/tests/api.c +++ b/tests/api.c @@ -54588,50 +54588,58 @@ static int test_wolfSSL_CTX_LoadCRL(void) const char* issuerCert = "./certs/client-cert.pem"; int derType = WOLFSSL_FILETYPE_ASN1; int pemType = WOLFSSL_FILETYPE_PEM; +#ifdef HAVE_CRL_MONITOR int monitor = WOLFSSL_CRL_MONITOR; +#else + int monitor = 0; +#endif WOLFSSL_CERT_MANAGER* cm = NULL; - ExpectIntEQ(wolfSSL_CTX_LoadCRL(ctx, validPath, pemType, monitor), - BAD_FUNC_ARG); - + #define FAIL_T1(x, y, z, p, d) AssertIntEQ((int) x(y, z, p, d), \ + BAD_FUNC_ARG) + #define FAIL_T2(x, y, z, p, d) AssertIntEQ((int) x(y, z, p, d), \ + NOT_COMPILED_IN) + #define SUCC_T(x, y, z, p, d) AssertIntEQ((int) x(y, z, p, d), \ + WOLFSSL_SUCCESS) #ifndef NO_WOLFSSL_CLIENT - ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method())); + #define NEW_CTX(ctx) AssertNotNull( \ + ctx = wolfSSL_CTX_new(wolfSSLv23_client_method())) +#elif !defined(NO_WOLFSSL_SERVER) + #define NEW_CTX(ctx) AssertNotNull( \ + ctx = wolfSSL_CTX_new(wolfSSLv23_server_method())) #else - ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method())); + #define NEW_CTX(ctx) return #endif - ExpectIntEQ(wolfSSL_CTX_LoadCRL(ctx, validPath, pemType, monitor), - WOLFSSL_SUCCESS); - ExpectIntEQ(wolfSSL_CTX_LoadCRL(ctx, badPath, pemType, monitor), - WOLFSSL_SUCCESS); - ExpectIntEQ(wolfSSL_CTX_LoadCRL(ctx, badPath, derType, monitor), - WOLFSSL_SUCCESS); + FAIL_T1(wolfSSL_CTX_LoadCRL, ctx, validPath, pemType, monitor); + + NEW_CTX(ctx); + +#ifndef HAVE_CRL_MONITOR + FAIL_T2(wolfSSL_CTX_LoadCRL, ctx, validPath, pemType, WOLFSSL_CRL_MONITOR); + wolfSSL_CTX_free(ctx); + NEW_CTX(ctx); +#endif + + SUCC_T (wolfSSL_CTX_LoadCRL, ctx, validPath, pemType, monitor); + SUCC_T (wolfSSL_CTX_LoadCRL, ctx, badPath, pemType, monitor); + SUCC_T (wolfSSL_CTX_LoadCRL, ctx, badPath, derType, monitor); wolfSSL_CTX_free(ctx); ctx = NULL; -#ifndef NO_WOLFSSL_CLIENT - ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method())); -#else - ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method())); -#endif - ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx, issuerCert, NULL), - WOLFSSL_SUCCESS); - ExpectIntEQ(wolfSSL_CTX_LoadCRLFile(ctx, validFilePath, pemType), - WOLFSSL_SUCCESS); + NEW_CTX(ctx); + AssertIntEQ(wolfSSL_CTX_load_verify_locations(ctx, issuerCert, NULL), + WOLFSSL_SUCCESS); + AssertIntEQ(wolfSSL_CTX_LoadCRLFile(ctx, validFilePath, pemType), WOLFSSL_SUCCESS); wolfSSL_CTX_free(ctx); ctx = NULL; -#ifndef NO_WOLFSSL_CLIENT - ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method())); -#else - ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method())); -#endif - ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx, issuerCert, NULL), - WOLFSSL_SUCCESS); - ExpectNotNull(ssl = wolfSSL_new(ctx)); - ExpectIntEQ(wolfSSL_LoadCRLFile(ssl, validFilePath, pemType), - WOLFSSL_SUCCESS); + NEW_CTX(ctx); + AssertIntEQ(wolfSSL_CTX_load_verify_locations(ctx, issuerCert, NULL), + WOLFSSL_SUCCESS); + AssertNotNull(ssl = wolfSSL_new(ctx)); + AssertIntEQ(wolfSSL_LoadCRLFile(ssl, validFilePath, pemType), WOLFSSL_SUCCESS); wolfSSL_free(ssl); ssl = NULL; wolfSSL_CTX_free(ctx); diff --git a/testsuite/testsuite.c b/testsuite/testsuite.c index a4e25a17b..25dd8f0f1 100644 --- a/testsuite/testsuite.c +++ b/testsuite/testsuite.c @@ -469,7 +469,7 @@ void wait_tcp_ready(func_args* args) * @param [in] args Object to send to function in thread. * @param [out] thread Handle to thread. */ -void start_thread(THREAD_FUNC fun, func_args* args, THREAD_TYPE* thread) +void start_thread(THREAD_CB fun, func_args* args, THREAD_TYPE* thread) { #if defined(HAVE_PTHREAD) PTHREAD_CHECK_RET(pthread_create(thread, 0, fun, args)); @@ -529,8 +529,8 @@ void start_thread(THREAD_FUNC fun, func_args* args, THREAD_TYPE* thread) } /* end if NETOS */ #else - /* custom / external thread type */ - *thread = (THREAD_TYPE)_beginthreadex(0, 0, fun, args, 0, 0); + /* windows thread type */ + *thread = (THREAD_TYPE)_beginthreadex(NULL, 0, fun, args, 0, 0); #endif /* thread types */ } @@ -554,7 +554,7 @@ void join_thread(THREAD_TYPE thread) #elif defined(NETOS) /* TODO: */ #else - int res = WaitForSingleObject((HANDLE)thread, INFINITE); + DWORD res = WaitForSingleObject((HANDLE)thread, INFINITE); assert(res == WAIT_OBJECT_0); res = CloseHandle((HANDLE)thread); assert(res); diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index 1318e78d9..10d41bb0e 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -3344,3 +3344,100 @@ char* mystrnstr(const char* s1, const char* s2, unsigned int n) #include /* sha256 */ #endif #endif + + +#ifndef SINGLE_THREADED + +#ifdef _MSC_VER + int wolfSSL_NewThread(THREAD_TYPE* thread, + THREAD_CB cb, void* arg) + { + if (thread == NULL || cb == NULL) + return BAD_FUNC_ARG; + + /* Use _beginthreadex instead of _beginthread because of: + * _beginthreadex is safer to use than _beginthread. If the thread + * that's generated by _beginthread exits quickly, the handle that's + * returned to the caller of _beginthread might be invalid or point + * to another thread. However, the handle that's returned by + * _beginthreadex has to be closed by the caller of _beginthreadex, + * so it's guaranteed to be a valid handle if _beginthreadex didn't + * return an error.*/ + *thread = _beginthreadex(NULL, 0, cb, arg, 0, NULL); + if (*thread == 0) { + *thread = INVALID_THREAD_VAL; + return MEMORY_ERROR; + } + + return 0; + } + + int wolfSSL_JoinThread(THREAD_TYPE thread) + { + if (thread == INVALID_THREAD_VAL) + return BAD_FUNC_ARG; + + if (WaitForSingleObject((HANDLE)thread, INFINITE) == WAIT_FAILED) + return MEMORY_ERROR; + + if (CloseHandle((HANDLE)thread) == 0) + return MEMORY_ERROR; + + return 0; + } + +#ifdef WOLFSSL_COND + int wolfSSL_CondInit(COND_TYPE* cond) + { + if (cond == NULL) + return BAD_FUNC_ARG; + + *cond = CreateEventA(NULL, FALSE, FALSE, NULL); + if (*cond == NULL) + return MEMORY_ERROR; + + return 0; + } + + int wolfSSL_CondFree(COND_TYPE* cond) + { + if (cond == NULL) + return BAD_FUNC_ARG; + + if (CloseHandle(*cond) == 0) + return MEMORY_ERROR; + + return 0; + } + + int wolfSSL_CondSignal(COND_TYPE* cond) + { + if (cond == NULL) + return BAD_FUNC_ARG; + + if (SetEvent(*cond) == 0) + return MEMORY_ERROR; + + return 0; + } + + int wolfSSL_CondWait(COND_TYPE* cond, + wolfSSL_Mutex* mutex) + { + (void)mutex; + + if (cond == NULL) + return BAD_FUNC_ARG; + + if (WaitForSingleObject(*cond, INFINITE) == WAIT_FAILED) + return MEMORY_ERROR; + + return 0; + } +#endif /* WOLFSSL_COND */ + +#else /* pthread */ + +#endif + +#endif /* SINGLE_THREADED */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index fba891061..ec47b4352 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2408,6 +2408,19 @@ struct CRL_Monitor { #undef HAVE_CRL_MONITOR #endif +/* PEM and DER possible */ +#define WOLFSSL_CRL_MONITORS_LEN (2) + +#if defined(__MACH__) || defined(__FreeBSD__) || defined(__linux__) +typedef int wolfSSL_CRL_mfd_t; /* monitor fd, -1 if no init yet */ +/* mfd for bsd is kqueue fd, eventfd for linux */ +#define WOLFSSL_CRL_MFD_INIT_VAL (-1) +#elif defined(_MSC_VER) +typedef HANDLE wolfSSL_CRL_mfd_t; /* monitor fd, INVALID_HANDLE_VALUE if + * no init yet */ +#define WOLFSSL_CRL_MFD_INIT_VAL (INVALID_HANDLE_VALUE) +#endif + /* wolfSSL CRL controller */ struct WOLFSSL_CRL { WOLFSSL_CERT_MANAGER* cm; /* pointer back to cert manager */ @@ -2417,11 +2430,11 @@ struct WOLFSSL_CRL { CbCrlIO crlIOCb; #endif wolfSSL_Mutex crlLock; /* CRL list lock */ - CRL_Monitor monitors[2]; /* PEM and DER possible */ + CRL_Monitor monitors[WOLFSSL_CRL_MONITORS_LEN]; #ifdef HAVE_CRL_MONITOR - pthread_cond_t cond; /* condition to signal setup */ - pthread_t tid; /* monitoring thread */ - int mfd; /* monitor fd, -1 if no init yet */ + COND_TYPE cond; /* condition to signal setup */ + THREAD_TYPE tid; /* monitoring thread */ + wolfSSL_CRL_mfd_t mfd; int setup; /* thread is setup predicate */ #endif void* heap; /* heap hint for dynamic memory */ diff --git a/wolfssl/test.h b/wolfssl/test.h index 0b36a5e74..63dfb97c9 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -633,13 +633,7 @@ typedef struct func_args { void wait_tcp_ready(func_args* args); -#ifdef WOLFSSL_ZEPHYR -typedef void THREAD_FUNC(void*, void*, void*); -#else -typedef THREAD_RETURN WOLFSSL_THREAD THREAD_FUNC(void*); -#endif - -void start_thread(THREAD_FUNC fun, func_args* args, THREAD_TYPE* thread); +void start_thread(THREAD_CB fun, func_args* args, THREAD_TYPE* thread); void join_thread(THREAD_TYPE thread); typedef int (*cbType)(WOLFSSL_CTX *ctx, WOLFSSL *ssl); diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index 17f774db8..4318174c0 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -1360,18 +1360,49 @@ typedef struct w64wrapper { typedef void* THREAD_RETURN; typedef pthread_t THREAD_TYPE; #define WOLFSSL_THREAD - #define INFINITE (-1) - #define WAIT_OBJECT_0 0L +#error TODO implement threading with pthreads #elif defined(FREERTOS) typedef unsigned int THREAD_RETURN; typedef TaskHandle_t THREAD_TYPE; #define WOLFSSL_THREAD + #elif defined(_MSC_VER) + typedef unsigned THREAD_RETURN; + typedef uintptr_t THREAD_TYPE; + typedef HANDLE COND_TYPE; + #define WOLFSSL_COND + #define INVALID_THREAD_VAL ((THREAD_TYPE)(INVALID_HANDLE_VALUE)) + #define COND_NO_REQUIRE_LOCKED_MUTEX + #define WOLFSSL_THREAD __stdcall #else typedef unsigned int THREAD_RETURN; typedef size_t THREAD_TYPE; #define WOLFSSL_THREAD __stdcall #endif + + #ifndef SINGLE_THREADED + /* Necessary headers should already be included. */ + + /* We don't support returns from threads */ + typedef THREAD_RETURN (WOLFSSL_THREAD *THREAD_CB)(void* arg); + + #ifndef INVALID_THREAD_VAL + #define INVALID_THREAD_VAL (-1) + #endif + + WOLFSSL_LOCAL int wolfSSL_NewThread(THREAD_TYPE* thread, + THREAD_CB cb, void* arg); + WOLFSSL_LOCAL int wolfSSL_JoinThread(THREAD_TYPE thread); + + #ifdef WOLFSSL_COND + WOLFSSL_LOCAL int wolfSSL_CondInit(COND_TYPE* cond); + WOLFSSL_LOCAL int wolfSSL_CondFree(COND_TYPE* cond); + WOLFSSL_LOCAL int wolfSSL_CondSignal(COND_TYPE* cond); + WOLFSSL_LOCAL int wolfSSL_CondWait(COND_TYPE* cond, + wolfSSL_Mutex* mutex); + #endif + #endif /* SINGLE_THREADED */ + #if defined(HAVE_STACK_SIZE) #define EXIT_TEST(ret) return (THREAD_RETURN)((size_t)(ret)) #else diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index 01e5ed6d9..975b668d7 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -77,6 +77,9 @@ #endif #endif /* WOLFSSL_SGX */ #endif + #ifndef SINGLE_THREADED + #include + #endif #elif defined(THREADX) #ifndef SINGLE_THREADED #ifdef NEED_THREADX_TYPES