Windows: fallback to PROV_RNG if no PROV_RSA_FULL

Heimdal can be executed in environments in which the user
account profile is not loaded.  In such environments it is
not possible to use PROV_RSA_FULL as it stores required
data within the profile.  Instead, fallback to PROV_RNG which
does not store data within the profile and can be used to access
secure random number generator routines.

Change-Id: If600246f39645ed6bf5af0dd237f5adfddcf6c0c
This commit is contained in:
Jeffrey Altman
2011-09-20 16:17:42 -04:00
parent 9081ab775f
commit 63b3cb9749

View File

@@ -56,13 +56,30 @@ _hc_CryptProvider(void)
rv = CryptAcquireContext(&cryptprovider, NULL,
MS_ENHANCED_PROV, PROV_RSA_FULL,
0);
CRYPT_VERIFYCONTEXT);
if (GetLastError() == NTE_BAD_KEYSET) {
if(!rv)
rv = CryptAcquireContext(&cryptprovider, NULL,
MS_ENHANCED_PROV, PROV_RSA_FULL,
CRYPT_NEWKEYSET);
}
if (rv) {
/* try the default provider */
rv = CryptAcquireContext(&cryptprovider, NULL, 0, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT);
if (GetLastError() == NTE_BAD_KEYSET) {
rv = CryptAcquireContext(&cryptprovider, NULL,
MS_ENHANCED_PROV, PROV_RSA_FULL,
CRYPT_NEWKEYSET);
MS_ENHANCED_PROV, PROV_RSA_FULL,
CRYPT_NEWKEYSET);
}
}
if (rv) {
/* try just a default random number generator */
rv = CryptAcquireContext(&cryptprovider, NULL, 0, PROV_RNG,
CRYPT_VERIFYCONTEXT);
}
if (rv &&
@@ -98,6 +115,12 @@ w32crypto_bytes(unsigned char *outdata, int size)
static void
w32crypto_cleanup(void)
{
HCRYPTPROV cryptprovider;
if (InterlockedCompareExchangePointer((PVOID *) &cryptprovider,
0, (PVOID) g_cryptprovider) == 0) {
CryptReleaseContext(cryptprovider, 0);
}
}
static void