summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main/main.c7
-rw-r--r--win32/winutil.c81
-rw-r--r--win32/winutil.h10
3 files changed, 63 insertions, 35 deletions
diff --git a/main/main.c b/main/main.c
index 038981ca45..9e139eff72 100644
--- a/main/main.c
+++ b/main/main.c
@@ -2095,10 +2095,7 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod
#endif
#ifdef PHP_WIN32
- if (!php_win32_init_random_bytes()) {
- php_printf("\ncrypto service provider failed\n");
- return FAILURE;
- }
+ php_win32_init_rng_lock();
#endif
module_shutdown = 0;
@@ -2412,7 +2409,7 @@ void php_module_shutdown(void)
#endif
#ifdef PHP_WIN32
- (void)php_win32_shutdown_random_bytes();
+ php_win32_free_rng_lock();
#endif
sapi_flush();
diff --git a/win32/winutil.c b/win32/winutil.c
index f735597468..b30ff0394d 100644
--- a/win32/winutil.c
+++ b/win32/winutil.c
@@ -51,50 +51,77 @@ int php_win32_check_trailing_space(const char * path, const int path_len) {
}
}
-static HCRYPTPROV hCryptProv;
-static BOOL has_crypto_ctx = 0;
+HCRYPTPROV hCryptProv;
+unsigned int has_crypto_ctx = 0;
-#ifdef PHP_EXPORTS
-BOOL php_win32_init_random_bytes(void)
+#ifdef ZTS
+MUTEX_T php_lock_win32_cryptoctx;
+void php_win32_init_rng_lock()
{
- int err;
-
- /* CRYPT_VERIFYCONTEXT > only hashing&co-like use, no need to acces prv keys */
- has_crypto_ctx = CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET|CRYPT_VERIFYCONTEXT);
- err = GetLastError();
- if (!has_crypto_ctx) {
- /* Could mean that the key container does not exist, let try
- again by asking for a new one. If it fails here, it surely means that the user running
- this process does not have the permission(s) to use this container.
- */
- if (NTE_BAD_KEYSET == err) {
- has_crypto_ctx = CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET | CRYPT_MACHINE_KEYSET | CRYPT_VERIFYCONTEXT);
- }
- }
-
- return has_crypto_ctx;
+ php_lock_win32_cryptoctx = tsrm_mutex_alloc();
}
-BOOL php_win32_shutdown_random_bytes(void)
+void php_win32_free_rng_lock()
{
- BOOL ret = TRUE;
-
- if (has_crypto_ctx) {
- ret = CryptReleaseContext(hCryptProv, 0);
+ tsrm_mutex_lock(php_lock_win32_cryptoctx);
+ if (has_crypto_ctx == 1) {
+ CryptReleaseContext(hCryptProv, 0);
+ has_crypto_ctx = 0;
}
+ tsrm_mutex_unlock(php_lock_win32_cryptoctx);
+ tsrm_mutex_free(php_lock_win32_cryptoctx);
- return ret;
}
+#else
+#define php_win32_init_rng_lock();
+#define php_win32_free_rng_lock();
#endif
+
+
PHP_WINUTIL_API int php_win32_get_random_bytes(unsigned char *buf, size_t size) { /* {{{ */
BOOL ret;
+#ifdef ZTS
+ tsrm_mutex_lock(php_lock_win32_cryptoctx);
+#endif
+
+ if (has_crypto_ctx == 0) {
+ /* CRYPT_VERIFYCONTEXT > only hashing&co-like use, no need to acces prv keys */
+ if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET|CRYPT_VERIFYCONTEXT )) {
+ /* Could mean that the key container does not exist, let try
+ again by asking for a new one. If it fails here, it surely means that the user running
+ this process does not have the permission(s) to use this container.
+ */
+ if (GetLastError() == NTE_BAD_KEYSET) {
+ if (CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET | CRYPT_MACHINE_KEYSET | CRYPT_VERIFYCONTEXT )) {
+ has_crypto_ctx = 1;
+ } else {
+ has_crypto_ctx = 0;
+ }
+ }
+ } else {
+ has_crypto_ctx = 1;
+ }
+ }
+
+#ifdef ZTS
+ tsrm_mutex_unlock(php_lock_win32_cryptoctx);
+#endif
+
+ if (has_crypto_ctx == 0) {
+ return FAILURE;
+ }
+
/* XXX should go in the loop if size exceeds UINT_MAX */
ret = CryptGenRandom(hCryptProv, (DWORD)size, buf);
- return ret ? SUCCESS : FAILURE;
+ if (ret) {
+ return SUCCESS;
+ } else {
+ return FAILURE;
+ }
}
/* }}} */
diff --git a/win32/winutil.h b/win32/winutil.h
index ebd57f10a6..2898aad8b8 100644
--- a/win32/winutil.h
+++ b/win32/winutil.h
@@ -27,9 +27,13 @@ PHP_WINUTIL_API char *php_win32_error_to_msg(HRESULT error);
#define php_win_err() php_win32_error_to_msg(GetLastError())
int php_win32_check_trailing_space(const char * path, const int path_len);
PHP_WINUTIL_API int php_win32_get_random_bytes(unsigned char *buf, size_t size);
-#ifdef PHP_EXPORTS
-BOOL php_win32_init_random_bytes(void);
-BOOL php_win32_shutdown_random_bytes(void);
+
+#ifdef ZTS
+void php_win32_init_rng_lock();
+void php_win32_free_rng_lock();
+#else
+#define php_win32_init_rng_lock();
+#define php_win32_free_rng_lock();
#endif
#if !defined(ECURDIR)