1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

HCRYPTPROV is not a HANDLE

Even though it is called "handle" and prefixed with "H", and its
value looks like a handle.
This commit is contained in:
Nobuyoshi Nakada 2021-09-24 11:36:42 +09:00
parent 61aedb28ef
commit 0eb679f70c
No known key found for this signature in database
GPG key ID: 7CD2805BFA3770C6

View file

@ -544,11 +544,18 @@ fill_random_bytes_syscall(void *buf, size_t size, int unused)
#endif #endif
} }
#elif defined(_WIN32) #elif defined(_WIN32)
STATIC_ASSERT(sizeof_HCRYPTPROV, sizeof(HCRYPTPROV) == sizeof(size_t));
/* Although HCRYPTPROV is not a HANDLE, it looks like
* INVALID_HANDLE_VALUE is not a valid value */
static const HCRYPTPROV INVALID_HCRYPTPROV = (HCRYPTPROV)INVALID_HANDLE_VALUE;
static void static void
release_crypt(void *p) release_crypt(void *p)
{ {
HCRYPTPROV prov = (HCRYPTPROV)ATOMIC_PTR_EXCHANGE(*(HCRYPTPROV *)p, INVALID_HANDLE_VALUE); HCRYPTPROV *ptr = p;
if (prov && prov != (HCRYPTPROV)INVALID_HANDLE_VALUE) { HCRYPTPROV prov = (HCRYPTPROV)ATOMIC_SIZE_EXCHANGE(*ptr, INVALID_HCRYPTPROV);
if (prov && prov != INVALID_HCRYPTPROV) {
CryptReleaseContext(prov, 0); CryptReleaseContext(prov, 0);
} }
} }
@ -560,24 +567,24 @@ fill_random_bytes_syscall(void *seed, size_t size, int unused)
HCRYPTPROV prov = perm_prov, old_prov; HCRYPTPROV prov = perm_prov, old_prov;
if (!prov) { if (!prov) {
if (!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { if (!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
prov = (HCRYPTPROV)INVALID_HANDLE_VALUE; prov = INVALID_HCRYPTPROV;
} }
old_prov = (HCRYPTPROV)ATOMIC_PTR_CAS(perm_prov, 0, prov); old_prov = (HCRYPTPROV)ATOMIC_SIZE_CAS(perm_prov, 0, prov);
if (LIKELY(!old_prov)) { /* no other threads acquired */ if (LIKELY(!old_prov)) { /* no other threads acquired */
if (prov != (HCRYPTPROV)INVALID_HANDLE_VALUE) { if (prov != INVALID_HCRYPTPROV) {
#undef RUBY_UNTYPED_DATA_WARNING #undef RUBY_UNTYPED_DATA_WARNING
#define RUBY_UNTYPED_DATA_WARNING 0 #define RUBY_UNTYPED_DATA_WARNING 0
rb_gc_register_mark_object(Data_Wrap_Struct(0, 0, release_crypt, &perm_prov)); rb_gc_register_mark_object(Data_Wrap_Struct(0, 0, release_crypt, &perm_prov));
} }
} }
else { /* another thread acquired */ else { /* another thread acquired */
if (prov != (HCRYPTPROV)INVALID_HANDLE_VALUE) { if (prov != INVALID_HCRYPTPROV) {
CryptReleaseContext(prov, 0); CryptReleaseContext(prov, 0);
} }
prov = old_prov; prov = old_prov;
} }
} }
if (prov == (HCRYPTPROV)INVALID_HANDLE_VALUE) return -1; if (prov == INVALID_HCRYPTPROV) return -1;
CryptGenRandom(prov, size, seed); CryptGenRandom(prov, size, seed);
return 0; return 0;
} }