738 lines
19 KiB
C++
738 lines
19 KiB
C++
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// FILE : protstor.c //
|
||
|
// DESCRIPTION : Code for storing keys in the protected store: //
|
||
|
// AUTHOR : //
|
||
|
// HISTORY : //
|
||
|
// Dec 4 1996 jeffspel Created //
|
||
|
// Apr 21 1997 jeffspel Changes for NT 5 tree //
|
||
|
// Jul 28 1997 jeffspel Added ability to delete a persisted key //
|
||
|
// May 5 2000 dbarlow Modify error return handling //
|
||
|
// //
|
||
|
// Copyright (C) 1996 - 2000, Microsoft Corporation //
|
||
|
// All Rights Reserved //
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
#include "precomp.h"
|
||
|
#include "wincrypt.h"
|
||
|
#include "pstore.h"
|
||
|
#include "protstor.h"
|
||
|
#include "ntagum.h"
|
||
|
|
||
|
#define CRYPTO_KEY_TYPE_STRING L"Cryptographic Keys"
|
||
|
static GUID l_DefTypeGuid
|
||
|
= { 0x4d1fa410, 0x6fd9, 0x11d0,
|
||
|
{ 0x8C, 0x58, 0x00, 0xC0, 0x4F, 0xD9, 0x12, 0x6B } };
|
||
|
|
||
|
#define CRYPTO_SIG_SUBTYPE_STRING L"RSA Signature Keys"
|
||
|
static GUID l_DefSigGuid
|
||
|
= { 0x4d1fa411, 0x6fd9, 0x11D0,
|
||
|
{ 0x8C, 0x58, 0x00, 0xC0, 0x4F, 0xD9, 0x12, 0x6B } };
|
||
|
|
||
|
#define CRYPTO_EXCH_SUBTYPE_STRING L"RSA Exchange Keys"
|
||
|
static GUID l_DefExchGuid
|
||
|
= { 0x4d1fa412, 0x6fd9, 0x11D0,
|
||
|
{ 0x8C, 0x58, 0x00, 0xC0, 0x4F, 0xD9, 0x12, 0x6B } };
|
||
|
|
||
|
static GUID l_SysProv = MS_BASE_PSTPROVIDER_ID;
|
||
|
|
||
|
|
||
|
void
|
||
|
FreePSInfo(
|
||
|
PSTORE_INFO *pPStore)
|
||
|
{
|
||
|
IPStore *pIPS;
|
||
|
|
||
|
if (NULL != pPStore)
|
||
|
{
|
||
|
pIPS = (IPStore*)pPStore->pProv;
|
||
|
if (NULL != pIPS)
|
||
|
pIPS->Release();
|
||
|
if (NULL != pPStore->hInst)
|
||
|
FreeLibrary(pPStore->hInst);
|
||
|
if (NULL != pPStore->szPrompt)
|
||
|
_nt_free(pPStore->szPrompt, pPStore->cbPrompt);
|
||
|
_nt_free(pPStore, sizeof(PSTORE_INFO));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
CheckPStoreAvailability(
|
||
|
PSTORE_INFO *pPStore)
|
||
|
{
|
||
|
BOOL fRet = FALSE;
|
||
|
|
||
|
if (S_OK != PStoreCreateInstance((IPStore**)(&pPStore->pProv),
|
||
|
&l_SysProv, NULL, 0))
|
||
|
goto ErrorExit;
|
||
|
|
||
|
memcpy(&pPStore->SigType, &l_DefTypeGuid, sizeof(GUID));
|
||
|
memcpy(&pPStore->SigSubtype, &l_DefSigGuid, sizeof(GUID));
|
||
|
memcpy(&pPStore->ExchType, &l_DefTypeGuid, sizeof(GUID));
|
||
|
memcpy(&pPStore->ExchSubtype, &l_DefExchGuid, sizeof(GUID));
|
||
|
fRet = TRUE;
|
||
|
|
||
|
ErrorExit:
|
||
|
return fRet;
|
||
|
}
|
||
|
|
||
|
|
||
|
DWORD
|
||
|
CreateNewPSKeyset(
|
||
|
PSTORE_INFO *pPStore,
|
||
|
DWORD dwFlags)
|
||
|
{
|
||
|
DWORD dwReturn = ERROR_INTERNAL_ERROR;
|
||
|
PST_ACCESSRULE rgRules[2];
|
||
|
PST_ACCESSRULESET Rules;
|
||
|
PST_TYPEINFO Info;
|
||
|
PST_PROMPTINFO PromptInfo = {NULL, NULL};
|
||
|
HRESULT hr;
|
||
|
IPStore *pIPS = (IPStore*)pPStore->pProv;
|
||
|
DWORD dwRegLoc = PST_KEY_CURRENT_USER;
|
||
|
|
||
|
if (dwFlags & CRYPT_MACHINE_KEYSET)
|
||
|
dwRegLoc = PST_KEY_LOCAL_MACHINE;
|
||
|
|
||
|
// if type is not available the create it
|
||
|
memset(&Info, 0, sizeof(Info));
|
||
|
Info.cbSize = sizeof(PST_TYPEINFO);
|
||
|
Info.szDisplayName = CRYPTO_KEY_TYPE_STRING;
|
||
|
hr = pIPS->CreateType(dwRegLoc, &pPStore->SigType, &Info, 0);
|
||
|
if ((S_OK != hr) && (PST_E_TYPE_EXISTS != hr))
|
||
|
{
|
||
|
dwReturn = (DWORD)hr;
|
||
|
goto ErrorExit;
|
||
|
}
|
||
|
|
||
|
// make same rules for read, write access
|
||
|
rgRules[0].cbSize = sizeof(PST_ACCESSRULE);
|
||
|
rgRules[0].AccessModeFlags = PST_READ;
|
||
|
rgRules[0].cClauses = 0;
|
||
|
rgRules[0].rgClauses = NULL;
|
||
|
rgRules[1].cbSize = sizeof(PST_ACCESSRULE);
|
||
|
rgRules[1].AccessModeFlags = PST_WRITE;
|
||
|
rgRules[1].cClauses = 0;
|
||
|
rgRules[1].rgClauses = NULL;
|
||
|
|
||
|
Rules.cbSize = sizeof(PST_ACCESSRULESET);
|
||
|
Rules.cRules = 2;
|
||
|
Rules.rgRules = rgRules;
|
||
|
|
||
|
// create the signature subtype
|
||
|
Info.szDisplayName = CRYPTO_SIG_SUBTYPE_STRING;
|
||
|
PromptInfo.szPrompt = L"";
|
||
|
hr = pIPS->CreateSubtype(dwRegLoc, &pPStore->SigType,
|
||
|
&pPStore->SigSubtype, &Info, &Rules, 0);
|
||
|
if ((S_OK != hr) && (PST_E_TYPE_EXISTS != hr))
|
||
|
{
|
||
|
dwReturn = (DWORD)hr;
|
||
|
goto ErrorExit;
|
||
|
}
|
||
|
|
||
|
// create the exchange subtype
|
||
|
Info.szDisplayName = CRYPTO_EXCH_SUBTYPE_STRING;
|
||
|
hr = pIPS->CreateSubtype(dwRegLoc, &pPStore->SigType,
|
||
|
&pPStore->ExchSubtype, &Info, &Rules, 0);
|
||
|
if ((S_OK != hr) && (PST_E_TYPE_EXISTS != hr))
|
||
|
{
|
||
|
dwReturn = (DWORD)hr;
|
||
|
goto ErrorExit;
|
||
|
}
|
||
|
|
||
|
dwReturn = ERROR_SUCCESS;
|
||
|
|
||
|
ErrorExit:
|
||
|
return dwReturn;
|
||
|
}
|
||
|
|
||
|
|
||
|
DWORD
|
||
|
GetKeysetTypeAndSubType(
|
||
|
PNTAGUserList pUser)
|
||
|
{
|
||
|
DWORD dwReturn = ERROR_INTERNAL_ERROR;
|
||
|
BYTE *pb1 = NULL;
|
||
|
DWORD cb1;
|
||
|
BYTE *pb2 = NULL;
|
||
|
DWORD cb2;
|
||
|
DWORD dwSts;
|
||
|
|
||
|
memcpy(&pUser->pPStore->SigType, &l_DefTypeGuid, sizeof(GUID));
|
||
|
memcpy(&pUser->pPStore->SigSubtype, &l_DefSigGuid, sizeof(GUID));
|
||
|
memcpy(&pUser->pPStore->ExchType, &l_DefTypeGuid, sizeof(GUID));
|
||
|
memcpy(&pUser->pPStore->ExchSubtype, &l_DefExchGuid, sizeof(GUID));
|
||
|
|
||
|
// look in registry and see if the type and subtype Guids are there
|
||
|
dwSts = ReadRegValue(pUser->hKeys, "SigTypeSubtype", &pb1, &cb1, TRUE);
|
||
|
if (ERROR_SUCCESS != dwSts)
|
||
|
{
|
||
|
dwReturn = dwSts;
|
||
|
goto ErrorExit;
|
||
|
}
|
||
|
|
||
|
dwSts = ReadRegValue(pUser->hKeys, "ExchTypeSubtype", &pb2, &cb2, TRUE);
|
||
|
if (ERROR_SUCCESS != dwSts)
|
||
|
{
|
||
|
dwReturn = dwSts;
|
||
|
goto ErrorExit;
|
||
|
}
|
||
|
|
||
|
if (pb1)
|
||
|
{
|
||
|
memcpy(&pUser->pPStore->SigType, pb1, sizeof(GUID));
|
||
|
memcpy(&pUser->pPStore->SigSubtype, pb1 + sizeof(GUID), sizeof(GUID));
|
||
|
}
|
||
|
|
||
|
if (pb2)
|
||
|
{
|
||
|
memcpy(&pUser->pPStore->ExchType, pb2, sizeof(GUID));
|
||
|
memcpy(&pUser->pPStore->ExchSubtype, pb2 + sizeof(GUID), sizeof(GUID));
|
||
|
}
|
||
|
|
||
|
dwReturn = ERROR_SUCCESS;
|
||
|
|
||
|
ErrorExit:
|
||
|
if (pb1)
|
||
|
_nt_free(pb1, cb1);
|
||
|
if (pb2)
|
||
|
_nt_free(pb2, cb2);
|
||
|
return dwReturn;
|
||
|
}
|
||
|
|
||
|
|
||
|
DWORD
|
||
|
SetUIPrompt(
|
||
|
PNTAGUserList pUser,
|
||
|
LPWSTR szPrompt)
|
||
|
{
|
||
|
DWORD dwReturn = ERROR_INTERNAL_ERROR;
|
||
|
DWORD cb = 0;
|
||
|
LPWSTR sz = NULL;
|
||
|
|
||
|
// check if sig or exch keys are loaded and if so error
|
||
|
if (NULL == pUser->pPStore)
|
||
|
{
|
||
|
dwReturn = (DWORD)NTE_BAD_KEYSET;
|
||
|
goto ErrorExit;
|
||
|
}
|
||
|
|
||
|
if (NULL != szPrompt)
|
||
|
{
|
||
|
cb = (lstrlenW(szPrompt) + 1) * sizeof(WCHAR);
|
||
|
|
||
|
sz = (LPWSTR)_nt_malloc(cb);
|
||
|
if (NULL == sz)
|
||
|
{
|
||
|
dwReturn = ERROR_NOT_ENOUGH_MEMORY;
|
||
|
goto ErrorExit;
|
||
|
}
|
||
|
|
||
|
lstrcpyW(sz, szPrompt);
|
||
|
}
|
||
|
|
||
|
if (pUser->pPStore->szPrompt)
|
||
|
_nt_free(pUser->pPStore->szPrompt, pUser->pPStore->cbPrompt);
|
||
|
|
||
|
pUser->pPStore->cbPrompt = cb;
|
||
|
pUser->pPStore->szPrompt = sz;
|
||
|
|
||
|
dwReturn = ERROR_SUCCESS;
|
||
|
|
||
|
ErrorExit:
|
||
|
return dwReturn;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*static*/ DWORD
|
||
|
PickleKey(
|
||
|
BOOL fExportable,
|
||
|
size_t cbPriv,
|
||
|
PBYTE pbPriv,
|
||
|
PBYTE *ppbData,
|
||
|
PDWORD pcbData)
|
||
|
{
|
||
|
DWORD dwReturn = ERROR_INTERNAL_ERROR;
|
||
|
|
||
|
if (NULL != pbPriv)
|
||
|
{
|
||
|
// alloc the appropriate amount of space
|
||
|
*pcbData = cbPriv + sizeof(DWORD) + sizeof(BOOL);
|
||
|
*ppbData = (PBYTE)_nt_malloc(*pcbData);
|
||
|
if (NULL == *ppbData)
|
||
|
{
|
||
|
dwReturn = ERROR_NOT_ENOUGH_MEMORY;
|
||
|
goto ErrorExit;
|
||
|
}
|
||
|
|
||
|
// copy exportable info into buffer
|
||
|
memcpy(*ppbData, &fExportable, sizeof(BOOL));
|
||
|
|
||
|
// copy length of keying material into buffer
|
||
|
memcpy(*ppbData + sizeof(BOOL), &cbPriv, sizeof(DWORD));
|
||
|
|
||
|
// copy keying material into buffer
|
||
|
memcpy(*ppbData + sizeof(DWORD) + sizeof(BOOL), pbPriv, cbPriv);
|
||
|
}
|
||
|
|
||
|
dwReturn = ERROR_SUCCESS;
|
||
|
|
||
|
ErrorExit:
|
||
|
return dwReturn;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*static*/ DWORD
|
||
|
UnpickleKey(
|
||
|
PBYTE pbData,
|
||
|
BOOL *pfExportable,
|
||
|
DWORD *pcbPriv,
|
||
|
PBYTE *ppbPriv)
|
||
|
{
|
||
|
DWORD dwReturn = ERROR_INTERNAL_ERROR;
|
||
|
|
||
|
if (NULL != pbData)
|
||
|
{
|
||
|
// pull out the exportable info
|
||
|
memcpy(pfExportable, pbData, sizeof(BOOL));
|
||
|
|
||
|
// pull out the length of the key material
|
||
|
memcpy(pcbPriv, pbData + sizeof(BOOL), sizeof(DWORD));
|
||
|
|
||
|
// free the current key material memory
|
||
|
if (NULL != *ppbPriv)
|
||
|
_nt_free(*ppbPriv, *pcbPriv);
|
||
|
|
||
|
// alloc new memory for the key material
|
||
|
*ppbPriv = (PBYTE)_nt_malloc(*pcbPriv);
|
||
|
if (NULL == *ppbPriv)
|
||
|
{
|
||
|
dwReturn = ERROR_NOT_ENOUGH_MEMORY;
|
||
|
goto ErrorExit;
|
||
|
}
|
||
|
|
||
|
// copy key material
|
||
|
memcpy(*ppbPriv, pbData + sizeof(DWORD) + sizeof(BOOL), *pcbPriv);
|
||
|
}
|
||
|
|
||
|
dwReturn = ERROR_SUCCESS;
|
||
|
|
||
|
ErrorExit:
|
||
|
return dwReturn;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*static*/ DWORD
|
||
|
RestoreKeyFromProtectedStorage(
|
||
|
PNTAGUserList pUser,
|
||
|
LPWSTR szKeyName,
|
||
|
BYTE **ppbKey,
|
||
|
DWORD *pcbKey,
|
||
|
LPWSTR szPrompt,
|
||
|
BOOL fSigKey,
|
||
|
BOOL fMachineKeySet,
|
||
|
BOOL *pfUIOnKey)
|
||
|
{
|
||
|
DWORD dwReturn = ERROR_INTERNAL_ERROR;
|
||
|
HRESULT hr;
|
||
|
DWORD cb;
|
||
|
BYTE *pb = NULL;
|
||
|
GUID *pType;
|
||
|
GUID *pSubtype;
|
||
|
BOOL *pf;
|
||
|
PST_PROMPTINFO PromptInfo;
|
||
|
IPStore *pIPS = (IPStore*)(pUser->pPStore->pProv);
|
||
|
DWORD dwRegLoc = PST_KEY_CURRENT_USER;
|
||
|
DWORD dwSts;
|
||
|
|
||
|
*pfUIOnKey = FALSE;
|
||
|
|
||
|
if (fMachineKeySet)
|
||
|
dwRegLoc = PST_KEY_LOCAL_MACHINE;
|
||
|
|
||
|
memset(&PromptInfo, 0, sizeof(PromptInfo));
|
||
|
PromptInfo.cbSize = sizeof(PST_PROMPTINFO);
|
||
|
if (fSigKey)
|
||
|
{
|
||
|
if (0 == pUser->ContInfo.ContLens.cbSigPub)
|
||
|
{
|
||
|
dwReturn = ERROR_SUCCESS;
|
||
|
goto ErrorExit;
|
||
|
}
|
||
|
|
||
|
pType = &pUser->pPStore->SigType;
|
||
|
pSubtype = &pUser->pPStore->SigSubtype;
|
||
|
pf = &pUser->ContInfo.fSigExportable;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (0 == pUser->ContInfo.ContLens.cbExchPub)
|
||
|
{
|
||
|
dwReturn = ERROR_SUCCESS;
|
||
|
goto ErrorExit;
|
||
|
}
|
||
|
|
||
|
pType = &pUser->pPStore->ExchType;
|
||
|
pSubtype = &pUser->pPStore->ExchSubtype;
|
||
|
pf = &pUser->ContInfo.fExchExportable;
|
||
|
}
|
||
|
|
||
|
// read the item from secure storage
|
||
|
PromptInfo.hwndApp = NULL;
|
||
|
if (NULL == pUser->pPStore->szPrompt)
|
||
|
PromptInfo.szPrompt = szPrompt;
|
||
|
else
|
||
|
PromptInfo.szPrompt = pUser->pPStore->szPrompt;
|
||
|
|
||
|
hr = pIPS->ReadItem(dwRegLoc, pType, pSubtype, szKeyName, &cb,
|
||
|
&pb, &PromptInfo,
|
||
|
PST_PROMPT_QUERY | PST_NO_UI_MIGRATION);
|
||
|
if (S_OK != hr)
|
||
|
{
|
||
|
// this function returns PST_E_ITEM_EXISTS if there is UI on the item
|
||
|
if (PST_E_ITEM_EXISTS == hr)
|
||
|
*pfUIOnKey = TRUE;
|
||
|
else
|
||
|
{
|
||
|
dwReturn = (DWORD)hr;
|
||
|
goto ErrorExit;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
dwSts = UnpickleKey(pb, pf, pcbKey, ppbKey);
|
||
|
if (ERROR_SUCCESS != dwSts)
|
||
|
{
|
||
|
dwReturn = dwSts;
|
||
|
goto ErrorExit;
|
||
|
}
|
||
|
|
||
|
dwReturn = ERROR_SUCCESS;
|
||
|
|
||
|
ErrorExit:
|
||
|
if (pb)
|
||
|
CoTaskMemFree(pb);
|
||
|
return dwReturn;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*static*/ DWORD
|
||
|
MakeUnicodeKeysetName(
|
||
|
BYTE *pszName,
|
||
|
LPWSTR *ppszWName)
|
||
|
{
|
||
|
// ?BUGBUG? -- We don't really do this, do we?
|
||
|
DWORD dwReturn = ERROR_INTERNAL_ERROR;
|
||
|
long i;
|
||
|
DWORD cb;
|
||
|
|
||
|
cb = (DWORD)lstrlenA((LPSTR)pszName);
|
||
|
*ppszWName = (LPWSTR)_nt_malloc((cb + 1) * sizeof(WCHAR));
|
||
|
if (NULL == *ppszWName)
|
||
|
{
|
||
|
dwReturn = ERROR_NOT_ENOUGH_MEMORY;
|
||
|
goto ErrorExit;
|
||
|
}
|
||
|
|
||
|
for (i=0;i<(long)cb;i++)
|
||
|
(*ppszWName)[i] = (WCHAR)(pszName[i]);
|
||
|
|
||
|
dwReturn = ERROR_SUCCESS;
|
||
|
|
||
|
ErrorExit:
|
||
|
return dwReturn;
|
||
|
}
|
||
|
|
||
|
|
||
|
DWORD
|
||
|
RestoreKeysetFromProtectedStorage(
|
||
|
PNTAGUserList pUser,
|
||
|
LPWSTR szPrompt,
|
||
|
BYTE **ppbKey,
|
||
|
DWORD *pcbKey,
|
||
|
BOOL fSigKey,
|
||
|
BOOL fMachineKeySet,
|
||
|
BOOL *pfUIOnKey)
|
||
|
{
|
||
|
DWORD dwReturn = ERROR_INTERNAL_ERROR;
|
||
|
LPWSTR pszWName = NULL;
|
||
|
DWORD dwSts;
|
||
|
|
||
|
// convert the keyset name to unicode
|
||
|
dwSts = MakeUnicodeKeysetName((BYTE*)pUser->ContInfo.pszUserName,
|
||
|
&pszWName);
|
||
|
if (ERROR_SUCCESS != dwSts)
|
||
|
{
|
||
|
dwReturn = dwSts;
|
||
|
goto ErrorExit;
|
||
|
}
|
||
|
|
||
|
// restore the signature key
|
||
|
dwSts = RestoreKeyFromProtectedStorage(pUser, pszWName, ppbKey, pcbKey,
|
||
|
szPrompt, fSigKey, fMachineKeySet,
|
||
|
pfUIOnKey);
|
||
|
if (ERROR_SUCCESS != dwSts)
|
||
|
{
|
||
|
dwReturn = dwSts;
|
||
|
goto ErrorExit;
|
||
|
}
|
||
|
|
||
|
dwReturn = ERROR_SUCCESS;
|
||
|
|
||
|
ErrorExit:
|
||
|
if (pszWName)
|
||
|
_nt_free(pszWName, (wcslen(pszWName) + 1) * sizeof(WCHAR));
|
||
|
return dwReturn;
|
||
|
}
|
||
|
|
||
|
|
||
|
void
|
||
|
RemoveKeysetFromMemory(
|
||
|
PNTAGUserList pUser)
|
||
|
{
|
||
|
pUser->ContInfo.fSigExportable = FALSE;
|
||
|
if (pUser->pSigPrivKey)
|
||
|
{
|
||
|
_nt_free(pUser->pSigPrivKey, pUser->SigPrivLen);
|
||
|
pUser->SigPrivLen = 0;
|
||
|
pUser->pSigPrivKey = NULL;
|
||
|
}
|
||
|
|
||
|
pUser->ContInfo.fExchExportable = FALSE;
|
||
|
if (pUser->pExchPrivKey)
|
||
|
{
|
||
|
_nt_free(pUser->pExchPrivKey, pUser->ExchPrivLen);
|
||
|
pUser->ExchPrivLen = 0;
|
||
|
pUser->pExchPrivKey = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
DWORD
|
||
|
SaveKeyToProtectedStorage(
|
||
|
PNTAGUserList pUser,
|
||
|
DWORD dwFlags,
|
||
|
LPWSTR szPrompt,
|
||
|
BOOL fSigKey,
|
||
|
BOOL fMachineKeySet)
|
||
|
{
|
||
|
DWORD dwReturn = ERROR_INTERNAL_ERROR;
|
||
|
HRESULT hr;
|
||
|
PBYTE pb = NULL;
|
||
|
DWORD cb;
|
||
|
GUID *pType;
|
||
|
GUID *pSubtype;
|
||
|
BOOL f;
|
||
|
BYTE *pbKey = NULL;
|
||
|
size_t cbKey;
|
||
|
LPWSTR pszWName = NULL;
|
||
|
LPSTR szKeyName;
|
||
|
PST_PROMPTINFO PromptInfo;
|
||
|
IPStore *pIPS = (IPStore*)(pUser->pPStore->pProv);
|
||
|
DWORD dwRegLoc = PST_KEY_CURRENT_USER;
|
||
|
DWORD dwConfirm = PST_CF_NONE;
|
||
|
DWORD dwSts;
|
||
|
|
||
|
if (fMachineKeySet)
|
||
|
dwRegLoc = PST_KEY_LOCAL_MACHINE;
|
||
|
|
||
|
memset(&PromptInfo, 0, sizeof(PromptInfo));
|
||
|
PromptInfo.cbSize = sizeof(PST_PROMPTINFO);
|
||
|
if (fSigKey)
|
||
|
{
|
||
|
pType = &pUser->pPStore->SigType;
|
||
|
pSubtype = &pUser->pPStore->SigSubtype;
|
||
|
f = pUser->ContInfo.fSigExportable;
|
||
|
cbKey = pUser->SigPrivLen;
|
||
|
pbKey = pUser->pSigPrivKey;
|
||
|
szKeyName = "SPbK";
|
||
|
if (dwFlags & CRYPT_USER_PROTECTED)
|
||
|
dwConfirm = PST_CF_DEFAULT;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pType = &pUser->pPStore->ExchType;
|
||
|
pSubtype = &pUser->pPStore->ExchSubtype;
|
||
|
f = pUser->ContInfo.fExchExportable;
|
||
|
cbKey = pUser->ExchPrivLen;
|
||
|
pbKey = pUser->pExchPrivKey;
|
||
|
szKeyName = "EPbK";
|
||
|
if (dwFlags & CRYPT_USER_PROTECTED)
|
||
|
dwConfirm = PST_CF_DEFAULT;
|
||
|
}
|
||
|
|
||
|
// format the signature key and exportable info
|
||
|
dwSts = PickleKey(f, cbKey, pbKey, &pb, &cb);
|
||
|
if (ERROR_SUCCESS != dwSts)
|
||
|
{
|
||
|
dwReturn = dwSts;
|
||
|
goto ErrorExit;
|
||
|
}
|
||
|
|
||
|
if (pb)
|
||
|
{
|
||
|
// make a unicode version of the keyset name
|
||
|
dwSts = MakeUnicodeKeysetName((BYTE*)pUser->ContInfo.pszUserName,
|
||
|
&pszWName);
|
||
|
if (ERROR_SUCCESS != dwSts)
|
||
|
{
|
||
|
dwReturn = dwSts;
|
||
|
goto ErrorExit;
|
||
|
}
|
||
|
|
||
|
PromptInfo.hwndApp = NULL;
|
||
|
if (NULL == pUser->pPStore->szPrompt)
|
||
|
PromptInfo.szPrompt = szPrompt;
|
||
|
else
|
||
|
PromptInfo.szPrompt = pUser->pPStore->szPrompt;
|
||
|
|
||
|
hr = pIPS->WriteItem(dwRegLoc, pType, pSubtype, pszWName,
|
||
|
cb, pb, &PromptInfo, dwConfirm, 0);
|
||
|
if (S_OK != hr)
|
||
|
{
|
||
|
dwReturn = (DWORD)hr;
|
||
|
goto ErrorExit;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
dwReturn = ERROR_SUCCESS;
|
||
|
|
||
|
ErrorExit:
|
||
|
if (pb)
|
||
|
_nt_free(pb, cb);
|
||
|
if (pszWName)
|
||
|
_nt_free(pszWName, (wcslen(pszWName) + 1) * sizeof(WCHAR));
|
||
|
return dwReturn;
|
||
|
}
|
||
|
|
||
|
|
||
|
DWORD
|
||
|
DeleteKeyFromProtectedStorage(
|
||
|
NTAGUserList *pUser,
|
||
|
PCSP_STRINGS pStrings,
|
||
|
DWORD dwKeySpec,
|
||
|
BOOL fMachineKeySet,
|
||
|
BOOL fMigration)
|
||
|
{
|
||
|
DWORD dwReturn = ERROR_INTERNAL_ERROR;
|
||
|
LPWSTR szWUserName = NULL;
|
||
|
PST_PROMPTINFO PromptInfo;
|
||
|
IPStore *pIPS;
|
||
|
DWORD dwRegLoc = PST_KEY_CURRENT_USER;
|
||
|
DWORD dwSts;
|
||
|
|
||
|
memset(&PromptInfo, 0, sizeof(PromptInfo));
|
||
|
PromptInfo.cbSize = sizeof(PST_PROMPTINFO);
|
||
|
PromptInfo.hwndApp = NULL;
|
||
|
|
||
|
if (fMachineKeySet)
|
||
|
dwRegLoc = PST_KEY_LOCAL_MACHINE;
|
||
|
|
||
|
// make a unicode name
|
||
|
dwSts = MakeUnicodeKeysetName((BYTE*)pUser->ContInfo.pszUserName,
|
||
|
&szWUserName);
|
||
|
if (ERROR_SUCCESS != dwSts)
|
||
|
{
|
||
|
dwReturn = dwSts;
|
||
|
goto ErrorExit;
|
||
|
}
|
||
|
|
||
|
pIPS = (IPStore*)(pUser->pPStore->pProv);
|
||
|
|
||
|
if (AT_SIGNATURE == dwKeySpec)
|
||
|
{
|
||
|
if (fMigration)
|
||
|
PromptInfo.szPrompt = pStrings->pwszDeleteMigrSig;
|
||
|
else
|
||
|
PromptInfo.szPrompt = pStrings->pwszDeleteSig;
|
||
|
pIPS->DeleteItem(dwRegLoc,
|
||
|
&pUser->pPStore->SigType,
|
||
|
&pUser->pPStore->SigSubtype,
|
||
|
szWUserName,
|
||
|
&PromptInfo,
|
||
|
PST_NO_UI_MIGRATION);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (fMigration)
|
||
|
PromptInfo.szPrompt = pStrings->pwszDeleteMigrExch;
|
||
|
else
|
||
|
PromptInfo.szPrompt = pStrings->pwszDeleteExch;
|
||
|
pIPS->DeleteItem(dwRegLoc,
|
||
|
&pUser->pPStore->ExchType,
|
||
|
&pUser->pPStore->ExchSubtype,
|
||
|
szWUserName,
|
||
|
&PromptInfo,
|
||
|
PST_NO_UI_MIGRATION);
|
||
|
}
|
||
|
|
||
|
dwReturn = ERROR_SUCCESS;
|
||
|
|
||
|
ErrorExit:
|
||
|
if (szWUserName)
|
||
|
_nt_free(szWUserName, (wcslen(szWUserName) + 1) * sizeof(WCHAR));
|
||
|
return dwReturn;
|
||
|
}
|
||
|
|
||
|
|
||
|
DWORD
|
||
|
DeleteFromProtectedStorage(
|
||
|
CONST char *pszUserID,
|
||
|
PCSP_STRINGS pStrings,
|
||
|
HKEY hRegKey,
|
||
|
BOOL fMachineKeySet)
|
||
|
{
|
||
|
DWORD dwReturn = ERROR_INTERNAL_ERROR;
|
||
|
NTAGUserList User;
|
||
|
DWORD dwSts;
|
||
|
|
||
|
// set up the User List structure
|
||
|
memset(&User, 0, sizeof(User));
|
||
|
User.ContInfo.pszUserName = (LPSTR)pszUserID;
|
||
|
User.hKeys = hRegKey;
|
||
|
|
||
|
User.pPStore = (PSTORE_INFO*)_nt_malloc(sizeof(PSTORE_INFO));
|
||
|
if (NULL == User.pPStore)
|
||
|
{
|
||
|
dwReturn = ERROR_NOT_ENOUGH_MEMORY;
|
||
|
goto ErrorExit;
|
||
|
}
|
||
|
|
||
|
if (!CheckPStoreAvailability(User.pPStore))
|
||
|
{
|
||
|
dwReturn = (DWORD)NTE_FAIL;
|
||
|
goto ErrorExit;
|
||
|
}
|
||
|
|
||
|
// get type and subtypes
|
||
|
dwSts = GetKeysetTypeAndSubType(&User);
|
||
|
if (ERROR_SUCCESS != dwSts)
|
||
|
{
|
||
|
dwReturn = dwSts;
|
||
|
goto ErrorExit;
|
||
|
}
|
||
|
|
||
|
// delete each key
|
||
|
dwSts = DeleteKeyFromProtectedStorage(&User, pStrings, AT_SIGNATURE,
|
||
|
fMachineKeySet, FALSE);
|
||
|
if (ERROR_SUCCESS != dwSts)
|
||
|
{
|
||
|
dwReturn = dwSts;
|
||
|
goto ErrorExit;
|
||
|
}
|
||
|
dwSts = DeleteKeyFromProtectedStorage(&User, pStrings, AT_KEYEXCHANGE,
|
||
|
fMachineKeySet, FALSE);
|
||
|
if (ERROR_SUCCESS != dwSts)
|
||
|
{
|
||
|
dwReturn = dwSts;
|
||
|
goto ErrorExit;
|
||
|
}
|
||
|
|
||
|
dwReturn = ERROR_SUCCESS;
|
||
|
|
||
|
ErrorExit:
|
||
|
if (User.pPStore)
|
||
|
FreePSInfo(User.pPStore);
|
||
|
return dwReturn;
|
||
|
}
|
||
|
|