⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 contman.c

📁 windows的加密api源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*++

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 + -