mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
refactor php_win32_get_random_bytes()
- avoid locking - initialize only once - the process will fail, if no init failed
This commit is contained in:
parent
02991f75ce
commit
23bd7bcde0
3 changed files with 37 additions and 65 deletions
|
@ -51,77 +51,50 @@ int php_win32_check_trailing_space(const char * path, const int path_len) {
|
|||
}
|
||||
}
|
||||
|
||||
HCRYPTPROV hCryptProv;
|
||||
unsigned int has_crypto_ctx = 0;
|
||||
static HCRYPTPROV hCryptProv;
|
||||
static BOOL has_crypto_ctx = 0;
|
||||
|
||||
#ifdef ZTS
|
||||
MUTEX_T php_lock_win32_cryptoctx;
|
||||
void php_win32_init_rng_lock()
|
||||
#ifdef PHP_EXPORTS
|
||||
BOOL php_win32_init_random_bytes(void)
|
||||
{
|
||||
php_lock_win32_cryptoctx = tsrm_mutex_alloc();
|
||||
}
|
||||
int err;
|
||||
|
||||
void php_win32_free_rng_lock()
|
||||
{
|
||||
tsrm_mutex_lock(php_lock_win32_cryptoctx);
|
||||
if (has_crypto_ctx == 1) {
|
||||
CryptReleaseContext(hCryptProv, 0);
|
||||
has_crypto_ctx = 0;
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
tsrm_mutex_unlock(php_lock_win32_cryptoctx);
|
||||
tsrm_mutex_free(php_lock_win32_cryptoctx);
|
||||
|
||||
return has_crypto_ctx;
|
||||
}
|
||||
|
||||
BOOL php_win32_shutdown_random_bytes(void)
|
||||
{
|
||||
BOOL ret = TRUE;
|
||||
|
||||
if (has_crypto_ctx) {
|
||||
ret = CryptReleaseContext(hCryptProv, 0);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (ret) {
|
||||
return SUCCESS;
|
||||
} else {
|
||||
return FAILURE;
|
||||
}
|
||||
return ret ? SUCCESS : FAILURE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue