📄 contman.c
字号:
/*++
Copyright (c) 1997, 1998, 1999 Microsoft Corporation
Module Name:
keyman.cpp
Abstract:
This module contains routines to read and write data (key containers) from and to files.
Author:
16 Mar 98 jeffspel
--*/
#include <windows.h>
#include <userenv.h>
#include <wincrypt.h>
#include <rpc.h>
#include <shlobj.h>
#include "contman.h"
#include "md5.h"
#include "des.h"
#include "modes.h"
#include "csprc.h"
#ifdef USE_HW_RNG
#ifdef _M_IX86
#include <winioctl.h>
// INTEL h files for on chip RNG
#include "deftypes.h" //ISD typedefs and constants
#include "ioctldef.h" //ISD ioctl definitions
#endif // _M_IX86
#endif // USE_HW_RNG
#if DBG // NOTE: This section not compiled for retail builds
DWORD g_dwDebugCount = 0;
#endif // DBG
BYTE *g_pbStringBlock = NULL;
CSP_STRINGS g_Strings = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL};
typedef struct _OLD_KEY_CONTAINER_LENS_ {
DWORD cbSigPub;
DWORD cbSigEncPriv;
DWORD cbExchPub;
DWORD cbExchEncPriv;
} OLD_KEY_CONTAINER_LENS, *POLD_KEY_CONTAINER_LENS;
#define OLD_KEY_CONTAINER_FILE_FORMAT_VER 1
#define ContInfoAlloc(cb) LocalAlloc(LMEM_ZEROINIT, cb)
#define ContInfoReAlloc(pb, cb) LocalReAlloc(pb, cb, LMEM_ZEROINIT | LMEM_MOVEABLE)
#define ContInfoFree(pb) LocalFree(pb)
#define MACHINE_KEYS_DIR L"MachineKeys"
// Location of the keys in the registry (minus the logon name)
// Length of the full location (including the logon name)
#define RSA_REG_KEY_LOC "Software\\Microsoft\\Cryptography\\UserKeys"
#define RSA_REG_KEY_LOC_LEN sizeof(RSA_REG_KEY_LOC)
#define RSA_MACH_REG_KEY_LOC "Software\\Microsoft\\Cryptography\\MachineKeys"
#define RSA_MACH_REG_KEY_LOC_LEN sizeof(RSA_MACH_REG_KEY_LOC)
#define DSS_REG_KEY_LOC "Software\\Microsoft\\Cryptography\\DSSUserKeys"
#define DSS_REG_KEY_LOC_LEN sizeof(DSS_REG_KEY_LOC)
#define DSS_MACH_REG_KEY_LOC "Software\\Microsoft\\Cryptography\\DSSUserKeys"
#define DSS_MACH_REG_KEY_LOC_LEN sizeof(DSS_MACH_REG_KEY_LOC)
#define MAX_DPAPI_RETRY_COUNT 5
BOOL
MyCryptProtectData(
IN DATA_BLOB* pDataIn,
IN LPCWSTR szDataDescr,
IN OPTIONAL DATA_BLOB* pOptionalEntropy,
IN PVOID pvReserved,
IN OPTIONAL CRYPTPROTECT_PROMPTSTRUCT* pPromptStruct,
IN DWORD dwFlags,
OUT DATA_BLOB* pDataOut // out encr blob
)
{
DWORD dwRetryCount = 0;
DWORD dwMilliseconds = 10;
DWORD dwErr;
BOOL fResult;
while (1)
{
fResult = CryptProtectData(pDataIn,
szDataDescr,
pOptionalEntropy,
pvReserved,
pPromptStruct,
dwFlags,
pDataOut);
if(!fResult)
{
dwErr = GetLastError();
if ((RPC_S_SERVER_TOO_BUSY == dwErr) &&
(MAX_DPAPI_RETRY_COUNT > dwRetryCount))
{
Sleep(dwMilliseconds);
dwMilliseconds *= 2;
dwRetryCount++;
}
else
{
break;
}
}
else
{
break;
}
}
return fResult;
}
BOOL
MyCryptUnprotectData(
IN DATA_BLOB* pDataIn, // in encr blob
OUT OPTIONAL LPWSTR* ppszDataDescr, // out
IN OPTIONAL DATA_BLOB* pOptionalEntropy,
IN PVOID pvReserved,
IN OPTIONAL CRYPTPROTECT_PROMPTSTRUCT* pPromptStruct,
IN DWORD dwFlags,
OUT DATA_BLOB* pDataOut
)
{
DWORD dwRetryCount = 0;
DWORD dwMilliseconds = 10;
DWORD dwErr;
BOOL fResult;
while (1)
{
fResult = CryptUnprotectData(pDataIn, // in encr blob
ppszDataDescr, // out
pOptionalEntropy,
pvReserved,
pPromptStruct,
dwFlags,
pDataOut);
if(!fResult)
{
dwErr = GetLastError();
if ((RPC_S_SERVER_TOO_BUSY == dwErr) &&
(MAX_DPAPI_RETRY_COUNT > dwRetryCount))
{
Sleep(dwMilliseconds);
dwMilliseconds *= 2;
dwRetryCount++;
}
else
{
break;
}
}
else
{
break;
}
}
return fResult;
}
void FreeEnumOldMachKeyEntries(
PKEY_CONTAINER_INFO pInfo
)
{
if (pInfo)
{
if (pInfo->pchEnumOldMachKeyEntries)
{
ContInfoFree(pInfo->pchEnumOldMachKeyEntries);
pInfo->dwiOldMachKeyEntry = 0;
pInfo->cMaxOldMachKeyEntry = 0;
pInfo->cbOldMachKeyEntry = 0;
pInfo->pchEnumOldMachKeyEntries = NULL;
}
}
}
void FreeEnumRegEntries(
PKEY_CONTAINER_INFO pInfo
)
{
if (pInfo)
{
if (pInfo->pchEnumRegEntries)
{
ContInfoFree(pInfo->pchEnumRegEntries);
pInfo->dwiRegEntry = 0;
pInfo->cMaxRegEntry = 0;
pInfo->cbRegEntry = 0;
pInfo->pchEnumRegEntries = NULL;
}
}
}
void FreeContainerInfo(
PKEY_CONTAINER_INFO pInfo
)
{
if (pInfo)
{
if (pInfo->pbSigPub)
{
ContInfoFree(pInfo->pbSigPub);
pInfo->ContLens.cbSigPub = 0;
pInfo->pbSigPub = NULL;
}
if (pInfo->pbSigEncPriv)
{
ZeroMemory(pInfo->pbSigEncPriv, pInfo->ContLens.cbSigEncPriv);
ContInfoFree(pInfo->pbSigEncPriv);
pInfo->ContLens.cbSigEncPriv = 0;
pInfo->pbSigEncPriv = NULL;
}
if (pInfo->pbExchPub)
{
ContInfoFree(pInfo->pbExchPub);
pInfo->ContLens.cbExchPub = 0;
pInfo->pbExchPub = NULL;
}
if (pInfo->pbExchEncPriv)
{
ZeroMemory(pInfo->pbExchEncPriv, pInfo->ContLens.cbExchEncPriv);
ContInfoFree(pInfo->pbExchEncPriv);
pInfo->ContLens.cbExchEncPriv = 0;
pInfo->pbExchEncPriv = NULL;
}
if (pInfo->pbRandom)
{
ContInfoFree(pInfo->pbRandom);
pInfo->ContLens.cbRandom = 0;
pInfo->pbRandom = NULL;
}
if (pInfo->pszUserName)
{
ContInfoFree(pInfo->pszUserName);
pInfo->ContLens.cbName = 0;
pInfo->pszUserName = NULL;
}
FreeEnumOldMachKeyEntries(pInfo);
FreeEnumRegEntries(pInfo);
if (pInfo->hFind)
FindClose(pInfo->hFind);
}
}
DWORD GetHashOfContainer(
LPCSTR pszContainer,
LPWSTR pszHash
)
{
MD5_CTX MD5;
LPSTR pszLowerContainer = NULL;
DWORD *pdw1;
DWORD *pdw2;
DWORD *pdw3;
DWORD *pdw4;
DWORD dwErr = 0;
if (NULL == (pszLowerContainer =
(LPSTR)ContInfoAlloc(strlen(pszContainer) + sizeof(CHAR))))
{
dwErr = ERROR_NOT_ENOUGH_MEMORY;
goto Ret;
}
lstrcpy(pszLowerContainer, pszContainer);
_strlwr(pszLowerContainer);
MD5Init(&MD5);
MD5Update(&MD5, pszLowerContainer, strlen(pszLowerContainer) + sizeof(CHAR));
MD5Final(&MD5);
pdw1 = (DWORD*)&MD5.digest[0];
pdw2 = (DWORD*)&MD5.digest[4];
pdw3 = (DWORD*)&MD5.digest[8];
pdw4 = (DWORD*)&MD5.digest[12];
wsprintfW(pszHash, L"%08hx%08hx%08hx%08hx", *pdw1, *pdw2, *pdw3, *pdw4);
Ret:
if (pszLowerContainer)
ContInfoFree(pszLowerContainer);
return dwErr;
}
DWORD GetMachineGUID(
LPWSTR *ppwszUuid
)
{
HKEY hRegKey = 0;
// UUID Uuid;
LPSTR pszUuid = NULL;
LPWSTR pwszUuid = NULL;
DWORD cbUuid = sizeof(UUID);
DWORD cch = 0;
DWORD dwErr = 0;
DWORD dwSts;
*ppwszUuid = NULL;
// read the GUID from the Local Machine portion of the registry
dwSts = RegOpenKeyEx(HKEY_LOCAL_MACHINE, SZLOCALMACHINECRYPTO,
0, KEY_READ, &hRegKey);
if (ERROR_FILE_NOT_FOUND == dwSts)
{
goto Ret; // Return a success code, but a null GUID.
}
else if (ERROR_SUCCESS != dwSts)
{
dwErr = (DWORD)NTE_FAIL;
goto Ret;
}
dwSts = RegQueryValueEx(hRegKey, SZCRYPTOMACHINEGUID,
0, NULL, NULL,
&cbUuid);
if (ERROR_FILE_NOT_FOUND == dwSts)
{
goto Ret; // Return a success code, but a null GUID.
}
else if (ERROR_SUCCESS != dwSts)
{
dwErr = (DWORD)NTE_FAIL;
goto Ret;
}
if (NULL == (pszUuid = (LPSTR)ContInfoAlloc(cbUuid)))
{
dwErr = ERROR_NOT_ENOUGH_MEMORY;
goto Ret;
}
if (ERROR_SUCCESS != RegQueryValueEx(hRegKey, SZCRYPTOMACHINEGUID,
0, NULL, pszUuid,
&cbUuid))
{
dwErr = (DWORD)NTE_FAIL;
goto Ret;
}
// convert from ansi to unicode
if (0 == (cch = MultiByteToWideChar(CP_ACP, MB_COMPOSITE,
pszUuid,
-1, NULL, cch)))
{
dwErr = GetLastError();
goto Ret;
}
if (NULL == (pwszUuid = ContInfoAlloc((cch + 1) * sizeof(WCHAR))))
{
dwErr = ERROR_NOT_ENOUGH_MEMORY;
goto Ret;
}
if (0 == (cch = MultiByteToWideChar(CP_ACP, MB_COMPOSITE,
pszUuid,
-1, pwszUuid, cch)))
{
dwErr = GetLastError();
goto Ret;
}
*ppwszUuid = pwszUuid;
pwszUuid = NULL;
Ret:
if (pwszUuid)
ContInfoFree(pwszUuid);
if (pszUuid)
ContInfoFree(pszUuid);
if (hRegKey)
RegCloseKey(hRegKey);
return dwErr;
}
DWORD SetMachineGUID()
{
HKEY hRegKey = 0;
UUID Uuid;
LPSTR pszUuid = NULL;
DWORD cbUuid;
HANDLE hRPCRT4Dll = 0;
FARPROC pUuidCreate = NULL;
FARPROC pUuidToStringA = NULL;
FARPROC pRpcStringFreeA = NULL;
LPWSTR pwszOldUuid = NULL;
DWORD dwResult;
DWORD dwErr = 0;
if (0 != (dwErr = GetMachineGUID(&pwszOldUuid)))
{
goto Ret;
}
if (NULL != pwszOldUuid)
{
dwErr = (DWORD)NTE_FAIL;
goto Ret;
}
if (NULL == (hRPCRT4Dll = LoadLibraryA("rpcrt4.dll")))
{
dwErr = (DWORD)NTE_FAIL;
goto Ret;
}
if (NULL == (pUuidCreate = GetProcAddress(hRPCRT4Dll, "UuidCreate")))
{
dwErr = (DWORD)NTE_FAIL;
goto Ret;
}
if (NULL == (pUuidToStringA = GetProcAddress(hRPCRT4Dll, "UuidToStringA")))
{
dwErr = (DWORD)NTE_FAIL;
goto Ret;
}
if (NULL == (pRpcStringFreeA = GetProcAddress(hRPCRT4Dll, "RpcStringFreeA")))
{
dwErr = (DWORD)NTE_FAIL;
goto Ret;
}
// read the GUID from the Local Machine portion of the registry
if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_LOCAL_MACHINE,
SZLOCALMACHINECRYPTO,
0, NULL, REG_OPTION_NON_VOLATILE,
KEY_WRITE, NULL, &hRegKey,
&dwResult))
{
dwErr = (DWORD)NTE_FAIL;
goto Ret;
}
if (ERROR_SUCCESS == RegQueryValueEx(hRegKey, SZCRYPTOMACHINEGUID,
0, NULL, NULL,
&cbUuid))
{
goto Ret;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -