From 63b3cb97494201cce2c34b1c9a8b28f918846689 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Tue, 20 Sep 2011 16:17:42 -0400 Subject: [PATCH] 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 --- lib/hcrypto/rand-w32.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/lib/hcrypto/rand-w32.c b/lib/hcrypto/rand-w32.c index 07f52ca4c..4bb21c938 100644 --- a/lib/hcrypto/rand-w32.c +++ b/lib/hcrypto/rand-w32.c @@ -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