- 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

@ -49,26 +49,61 @@ int php_win32_check_trailing_space(const char * path, const int path_len) {
}
}
HCRYPTPROV hCryptProv;
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) { /* {{{ */
HCRYPTPROV hCryptProv;
int has_context = 0;
unsigned int has_contextg = 0;
BOOL ret;
size_t i = 0;
if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0)) {
/* 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;
} else {
return FAILURE;
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_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 {