- init win32 rng context once per process

This commit is contained in:
Pierre Joye 2011-06-16 01:31:10 +00:00
parent b498b5dfe5
commit 23c4c46b36
3 changed files with 63 additions and 11 deletions

View file

@ -32,6 +32,7 @@
#include "win32/time.h"
#include "win32/signal.h"
#include "win32/php_win32_globals.h"
#include "win32/winutil.h"
#include <process.h>
#elif defined(NETWARE)
#include <sys/timeval.h>
@ -1829,6 +1830,10 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod
tsrm_ls = ts_resource(0);
#endif
#ifdef PHP_WIN32
php_win32_init_rng_lock();
#endif
module_shutdown = 0;
module_startup = 1;
sapi_initialize_empty_request(TSRMLS_C);
@ -2148,6 +2153,10 @@ void php_module_shutdown(TSRMLS_D)
WSACleanup();
#endif
#ifdef PHP_WIN32
php_win32_free_rng_lock();
#endif
sapi_flush(TSRMLS_C);
zend_shutdown(TSRMLS_C);

View file

@ -49,26 +49,61 @@ int php_win32_check_trailing_space(const char * path, const int path_len) {
}
}
PHPAPI int php_win32_get_random_bytes(unsigned char *buf, size_t size) { /* {{{ */
HCRYPTPROV hCryptProv;
int has_context = 0;
unsigned int has_crypto_ctx = 0;
#ifdef ZTS
MUTEX_T php_lock_win32_cryptoctx;
void php_win32_init_rng_lock()
{
php_lock_win32_cryptoctx = tsrm_mutex_alloc();
}
void php_win32_free_rng_lock()
{
tsrm_mutex_lock(php_lock_win32_cryptoctx);
CryptReleaseContext(hCryptProv, 0);
has_crypto_ctx = 0;
tsrm_mutex_unlock(php_lock_win32_cryptoctx);
tsrm_mutex_free(php_lock_win32_cryptoctx);
}
#else
#define php_win32_init_rng_lock();
#define php_win32_free_rng_lock();
#endif
PHPAPI int php_win32_get_random_bytes(unsigned char *buf, size_t size) { /* {{{ */
unsigned int has_contextg = 0;
BOOL ret;
size_t i = 0;
if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0)) {
tsrm_mutex_lock(php_lock_win32_cryptoctx);
if (has_crypto_ctx == 0) {
if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET)) {
/* Could mean that the key container does not exist, let try
again by asking for a new one */
if (GetLastError() == NTE_BAD_KEYSET) {
if (CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)) {
has_context = 1;
has_crypto_ctx = 1;
} else {
has_crypto_ctx = 0;
}
}
}
}
tsrm_mutex_unlock(php_lock_win32_cryptoctx);
if (has_crypto_ctx == 0) {
return FAILURE;
}
}
}
ret = CryptGenRandom(hCryptProv, size, buf);
CryptReleaseContext(hCryptProv, 0);
if (ret) {
return SUCCESS;
} else {

View file

@ -21,3 +21,11 @@ PHPAPI char *php_win_err(int error);
#define php_win_err() php_win_err(GetLastError())
int php_win32_check_trailing_space(const char * path, const int path_len);
PHPAPI php_win32_get_random_bytes(unsigned char *buf, size_t size);
#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