|
|
/*++
Copyright (c) 1996, 1997 Microsoft Corporation
Module Name:
misc.cpp
Abstract:
Functionality in this module:
Globals management
Author:
Pete Skelly (petesk) 23-Mar-00
--*/
#include <pch.cpp>
#pragma hdrstop
//
// Registry Setable Globals, and handlign goo
//
// Must access key via api's
static HKEY g_hProtectedStorageKey = NULL;
static HANDLE g_hProtectedStorageChangeEvent = NULL;
static RTL_CRITICAL_SECTION g_csGlobals;
static BOOL g_fcsGlobalsInitialized = FALSE;
// key management globals
static DWORD g_IterationCount = DEFAULT_MASTERKEY_ITERATION_COUNT; static BOOL g_LegacyMode = FALSE; static BOOL g_LegacyModeNt4Domain = FALSE; static BOOL g_DistributeDomainBackupKey = FALSE; static DWORD g_dwMasterKeyDefaultPolicy = 0;
// define softcoded constants we use
static DWORD g_dwDefaultCryptProvType = PROV_RSA_FULL;
static DWORD g_dwAlgID_Encr_Alg = CALG_3DES; static DWORD g_dwAlgID_Encr_Alg_KeySize = -1; // any size
static DWORD g_dwAlgID_MAC_Alg = CALG_SHA1; static DWORD g_dwAlgID_MAC_Alg_KeySize = -1; // any size
typedef struct _ALG_TO_STRING { DWORD AlgId; LPCWSTR wszString; } ALG_TO_STRING;
ALG_TO_STRING g_AlgToString[] = { { CALG_MD2, L"MD2-%d " }, { CALG_MD4, L"MD4-%d " }, { CALG_MD5, L"MD5-%d " }, { CALG_SHA1, L"SHA1-%d " }, { CALG_DES, L"DES-%d " }, { CALG_3DES_112, L"3DES-%d " }, { CALG_3DES, L"3DES-%d " }, { CALG_DESX, L"DESX-%d " }, { CALG_RC2, L"RC2-%d " }, { CALG_RC4, L"RC4-%d " }, { CALG_SEAL, L"SEAL-%d " }, { CALG_RSA_SIGN, L"RSA Signature-%d " }, { CALG_RSA_KEYX, L"RSA Exchange-%d " }, { CALG_DSS_SIGN, L"DSS-%d " }, { CALG_DH_SF, L"DH-%d " }, { CALG_DH_EPHEM, L"DH Ephemeral-%d " }, { CALG_KEA_KEYX, L"KEA Exchange-%d " }, { CALG_SKIPJACK, L"SKIPJACK-%d " }, { CALG_TEK, L"TEK-%d " }, { CALG_RC5, L"RC5-%d " }, { CALG_HMAC, L"HMAC-%d " } };
DWORD g_cAlgToString = sizeof(g_AlgToString)/sizeof(g_AlgToString[0]);
// supply a new, delete operator
void * __cdecl operator new(size_t cb) { return SSAlloc( cb ); }
void __cdecl operator delete(void * pv) { SSFree( pv ); }
DWORD AlgIDToString(LPWSTR wszString, DWORD dwAlgID, DWORD dwStrength) { DWORD i; for(i=0; i < g_cAlgToString; i++) { if(dwAlgID == g_AlgToString[i].AlgId) { return wsprintf(wszString, g_AlgToString[i].wszString, dwStrength); } } return wsprintf(wszString, L"Unknown 0x%lx - %d", dwAlgID, dwStrength); }
DWORD UpdateGlobals(BOOL fForce) { DWORD lRet = ERROR_SUCCESS; DWORD dwDisposition;
if(NULL == g_fcsGlobalsInitialized || NULL == g_hProtectedStorageKey || NULL == g_hProtectedStorageChangeEvent) { return ERROR_SUCCESS; }
if(WAIT_OBJECT_0 == WaitForSingleObject(g_hProtectedStorageChangeEvent, 0)) { // Update the globals, as they have changed
DWORD dwParameterValue; DWORD cbParameter = sizeof(dwParameterValue); DWORD dwValueType;
RtlEnterCriticalSection(&g_csGlobals);
lRet = RegQueryValueExU( g_hProtectedStorageKey, REGVAL_MK_DEFAULT_ITERATION_COUNT, NULL, &dwValueType, (LPBYTE)&dwParameterValue, &cbParameter ); if( lRet == ERROR_SUCCESS && dwValueType == REG_DWORD ) { //
// Only allow policy to increase the iteration
// count, never decrease it.
//
if( dwParameterValue > g_IterationCount) { g_IterationCount = dwParameterValue; } }
lRet = RegQueryValueExU( g_hProtectedStorageKey, REGVAL_MK_LEGACY_COMPLIANCE, NULL, &dwValueType, (LPBYTE)&dwParameterValue, &cbParameter ); if( lRet == ERROR_SUCCESS && dwValueType == REG_DWORD ) { if( dwParameterValue != 0) { g_LegacyMode = TRUE; } }
lRet = RegQueryValueExU( g_hProtectedStorageKey, REGVAL_MK_LEGACY_NT4_DOMAIN, NULL, &dwValueType, (LPBYTE)&dwParameterValue, &cbParameter ); if((lRet == ERROR_SUCCESS) && (dwValueType == REG_DWORD) && (dwParameterValue != 0)) { g_LegacyModeNt4Domain = TRUE; } else { g_LegacyModeNt4Domain = FALSE; }
lRet = RegQueryValueExU( g_hProtectedStorageKey, REGVAL_DISTRIBUTE_BACKUP_KEY, NULL, &dwValueType, (LPBYTE)&dwParameterValue, &cbParameter ); if( lRet == ERROR_SUCCESS && dwValueType == REG_DWORD ) { // User specified registry value, so do what it says.
g_DistributeDomainBackupKey = (dwParameterValue != 0);
D_DebugLog((DEB_TRACE, "Registry: distribute whistler domain backup key: %s\n", g_DistributeDomainBackupKey ? "TRUE" : "FALSE")); } else { // Registry entry does not exist, so check to see if
// the domain is in "Whistler native mode" and if so
// then distribute the whistler domain backup key.
g_DistributeDomainBackupKey = LsaINoMoreWin2KDomain();
D_DebugLog((DEB_TRACE, "Policy: distribute whistler domain backup key: %s\n", g_DistributeDomainBackupKey ? "TRUE" : "FALSE")); }
lRet = RegQueryValueExU( g_hProtectedStorageKey, REGVAL_POLICY_MK, NULL, &dwValueType, (LPBYTE)&dwParameterValue, &cbParameter );
if( lRet == ERROR_SUCCESS && dwValueType == REG_DWORD ) { if( dwParameterValue == 1 ) { g_dwMasterKeyDefaultPolicy = POLICY_LOCAL_BACKUP; } }
cbParameter = sizeof(DWORD); lRet = RegQueryValueExU( g_hProtectedStorageKey, CRYPTPROTECT_DEFAULT_PROVIDER_ENCR_ALG, NULL, &dwValueType, (PBYTE)&dwParameterValue, &cbParameter ); if( lRet == ERROR_SUCCESS && dwValueType == REG_DWORD ) { // if successful, commit
g_dwAlgID_Encr_Alg = dwParameterValue; }
cbParameter = sizeof(DWORD); lRet = RegQueryValueExU( g_hProtectedStorageKey, CRYPTPROTECT_DEFAULT_PROVIDER_ENCR_ALG_KEYSIZE, NULL, &dwValueType, (PBYTE)&dwParameterValue, &cbParameter ); if( lRet == ERROR_SUCCESS && dwValueType == REG_DWORD ) { // if successful, commit
g_dwAlgID_Encr_Alg_KeySize = dwParameterValue; }
cbParameter = sizeof(DWORD); lRet = RegQueryValueExU( g_hProtectedStorageKey, CRYPTPROTECT_DEFAULT_PROVIDER_MAC_ALG, NULL, &dwValueType, (PBYTE)&dwParameterValue, &cbParameter ); if( lRet == ERROR_SUCCESS && dwValueType == REG_DWORD ) { // if successful, commit
g_dwAlgID_MAC_Alg = dwParameterValue; }
cbParameter = sizeof(DWORD); lRet = RegQueryValueExU( g_hProtectedStorageKey, CRYPTPROTECT_DEFAULT_PROVIDER_MAC_ALG_KEYSIZE, NULL, &dwValueType, (PBYTE)&dwParameterValue, &cbParameter ); if( lRet == ERROR_SUCCESS && dwValueType == REG_DWORD ) { // if successful, commit
g_dwAlgID_MAC_Alg_KeySize = dwParameterValue; }
cbParameter = sizeof(DWORD); lRet = RegQueryValueExU( g_hProtectedStorageKey, CRYPTPROTECT_DEFAULT_PROVIDER_CRYPT_PROV_TYPE, NULL, &dwValueType, (PBYTE)&dwParameterValue, &cbParameter ); if( lRet == ERROR_SUCCESS && dwValueType == REG_DWORD ) { // if successful, commit
g_dwDefaultCryptProvType = dwParameterValue; }
// Register to be notified of future registry changes.
lRet = RegNotifyChangeKeyValue(g_hProtectedStorageKey, TRUE, // bWatchSubtree
REG_NOTIFY_CHANGE_LAST_SET | REG_NOTIFY_CHANGE_NAME, g_hProtectedStorageChangeEvent, TRUE);
if(ERROR_SUCCESS != lRet) { //
// If notify failed, we no longer notify, so we don't need to handle anymore
CloseHandle(g_hProtectedStorageChangeEvent); g_hProtectedStorageChangeEvent = NULL; }
RtlLeaveCriticalSection(&g_csGlobals); }
return lRet; }
DWORD IntializeGlobals() { DWORD lRet = ERROR_SUCCESS; DWORD dwDisposition; static const WCHAR szProviderKeyName[] = REG_CRYPTPROTECT_LOC L"\\" REG_CRYPTPROTECT_PROVIDERS_SUBKEYLOC L"\\" CRYPTPROTECT_DEFAULT_PROVIDER_GUIDSZ ;
lRet = RtlInitializeCriticalSection(&g_csGlobals); if(!NT_SUCCESS(lRet)) { return lRet; } g_fcsGlobalsInitialized = TRUE;
lRet = RegCreateKeyExU( HKEY_LOCAL_MACHINE, szProviderKeyName, 0, NULL, 0, KEY_QUERY_VALUE | KEY_NOTIFY, NULL, &g_hProtectedStorageKey, &dwDisposition );
if(lRet != ERROR_SUCCESS) { goto error; } g_hProtectedStorageChangeEvent = CreateEvent(NULL, FALSE, TRUE, NULL);
lRet = UpdateGlobals(TRUE);
error:
return lRet; }
DWORD ShutdownGlobals() {
DWORD lRet = ERROR_SUCCESS; DWORD dwDisposition;
if(g_hProtectedStorageKey) { RegCloseKey(g_hProtectedStorageKey); g_hProtectedStorageKey = NULL; }
if(g_hProtectedStorageChangeEvent) { CloseHandle(g_hProtectedStorageChangeEvent); g_hProtectedStorageChangeEvent = NULL; }
if(g_fcsGlobalsInitialized) { RtlDeleteCriticalSection(&g_csGlobals); }
return lRet; }
DWORD GetIterationCount() { UpdateGlobals(FALSE); return g_IterationCount; }
BOOL FIsLegacyCompliant() { UpdateGlobals(FALSE); return g_LegacyMode; }
BOOL FIsLegacyNt4Domain() { UpdateGlobals(FALSE); return g_LegacyModeNt4Domain; }
BOOL FDistributeDomainBackupKey() { UpdateGlobals(FALSE); return g_DistributeDomainBackupKey; }
DWORD GetMasterKeyDefaultPolicy() { UpdateGlobals(FALSE); return g_dwMasterKeyDefaultPolicy; }
DWORD GetDefaultAlgInfo(DWORD *pdwProvType, DWORD *pdwEncryptionAlg, DWORD *pdwEncryptionAlgSize, DWORD *pdwMACAlg, DWORD *pdwMACAlgSize) { BOOL fCritSec = FALSE;
UpdateGlobals(FALSE);
if(g_fcsGlobalsInitialized) { RtlEnterCriticalSection(&g_csGlobals); fCritSec = TRUE; }
if(pdwProvType) { *pdwProvType = g_dwDefaultCryptProvType; } if(pdwEncryptionAlg) { *pdwEncryptionAlg = g_dwAlgID_Encr_Alg; } if(pdwEncryptionAlgSize) { *pdwEncryptionAlgSize = g_dwAlgID_Encr_Alg_KeySize; } if(pdwMACAlg) { *pdwMACAlg = g_dwAlgID_MAC_Alg; } if(pdwMACAlgSize) { *pdwMACAlgSize = g_dwAlgID_MAC_Alg_KeySize; } if(fCritSec) { RtlLeaveCriticalSection(&g_csGlobals); } return ERROR_SUCCESS; }
void InitLsaString( PLSA_UNICODE_STRING LsaString, LPWSTR String ) { DWORD StringLength;
if(String == NULL) { LsaString->Buffer = NULL; LsaString->Length = 0; LsaString->MaximumLength = 0; return; }
StringLength = lstrlenW(String); LsaString->Buffer = String; LsaString->Length = (USHORT) StringLength * sizeof(WCHAR); LsaString->MaximumLength=(USHORT)(StringLength+1) * sizeof(WCHAR); }
|