windows-nt/Source/XPSP1/NT/ds/security/cryptoapi/pkitrust/mscat32/mscatapi.cpp
2020-09-26 16:20:57 +08:00

1079 lines
28 KiB
C++

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1996 - 1999
//
// File: mscatapi.cpp
//
// Contents: Microsoft Internet Security Catalog Utilities
//
// Functions: CryptCATOpen
// CryptCATClose
// CryptCATStoreFromHandle
// CryptCATGetMemberInfo
// CryptCATPutMemberInfo
// CryptCATVerifyMember
// CryptCATGetAttrInfo
// CryptCATPutAttrInfo
// CryptCATEnumerateMember
// CryptCATEnumerateAttr
//
// *** local functions ***
//
// CryptCATCreateStore
// CryptCATOpenStore
// FillNameValue
// CatalogCheckForDuplicateMember
//
// History: 29-Apr-1997 pberkman created
//
//--------------------------------------------------------------------------
#include "global.hxx"
#include "mscat32.h"
BOOL CryptCATCreateStore(CRYPTCATSTORE *pCat, LPWSTR pwszCatFile);
BOOL CryptCATOpenStore(CRYPTCATSTORE *pCat, LPWSTR pwszCatFile);
BOOL FillNameValue(CRYPTCATSTORE *pCatStore, CRYPTCATATTRIBUTE *pAttr);
BOOL CatalogCheckForDuplicateMember(Stack_ *pMembers, WCHAR *pwszReferenceTag);
/////////////////////////////////////////////////////////////////////////////
//
// Exported Functions
//
HANDLE WINAPI CryptCATOpen(LPWSTR pwszCatFile, DWORD fdwOpenFlags, HCRYPTPROV hProv,
DWORD dwPublicVersion, DWORD dwEncodingType)
{
CRYPTCATSTORE *pCatStore;
if (!(pwszCatFile))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return((HANDLE)INVALID_HANDLE_VALUE);
}
if (!(pCatStore = (CRYPTCATSTORE *)CatalogNew(sizeof(CRYPTCATSTORE))))
{
return((HANDLE)INVALID_HANDLE_VALUE);
}
memset(pCatStore, 0x00, sizeof(CRYPTCATSTORE));
pCatStore->cbStruct = sizeof(CRYPTCATSTORE);
pCatStore->hProv = hProv;
pCatStore->dwPublicVersion = (dwPublicVersion) ? dwPublicVersion : 0x00000100;
pCatStore->dwEncodingType = (dwEncodingType) ? dwEncodingType :
PKCS_7_ASN_ENCODING | X509_ASN_ENCODING;
if (!(hProv))
{
pCatStore->hProv = I_CryptGetDefaultCryptProv(0); // get the default and DONT RELEASE IT!!!!
if (!(pCatStore->hProv))
{
goto ErrorReturn;
}
}
if (fdwOpenFlags & CRYPTCAT_OPEN_CREATENEW)
{
if (!CryptCATCreateStore(pCatStore, pwszCatFile))
{
goto ErrorReturn;
}
}
else
{
BOOL fRet;
fRet = CryptCATOpenStore(pCatStore, pwszCatFile);
if (!(fRet) && (fdwOpenFlags & CRYPTCAT_OPEN_ALWAYS))
{
fRet = CryptCATCreateStore(pCatStore, pwszCatFile);
}
if (fRet == FALSE)
{
goto ErrorReturn;
}
}
return((HANDLE)pCatStore);
ErrorReturn:
DWORD dwLastError;
dwLastError = GetLastError();
CryptCATClose((HANDLE)pCatStore);
SetLastError(dwLastError);
return(INVALID_HANDLE_VALUE);
}
BOOL WINAPI CryptCATClose(HANDLE hCatalog)
{
if (!(hCatalog) ||
(hCatalog == INVALID_HANDLE_VALUE))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(FALSE);
}
CRYPTCATSTORE *pCatStore;
pCatStore = (CRYPTCATSTORE *)hCatalog;
__try
{
if (!(_ISINSTRUCT(CRYPTCATSTORE, pCatStore->cbStruct, hReserved)))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(FALSE);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(FALSE);
}
BOOL fRet;
DWORD dwlerr;
dwlerr = GetLastError();
fRet = TRUE;
//
// file name
//
DELETE_OBJECT(pCatStore->pwszP7File);
//
// attributes
//
if (_ISINSTRUCT(CRYPTCATSTORE, pCatStore->cbStruct, hAttrs))
{
if (pCatStore->hAttrs)
{
Stack_ *ps;
DWORD cStack;
CRYPTCATATTRIBUTE *pAttr;
ps = (Stack_ *)pCatStore->hAttrs;
cStack = 0;
while (pAttr = (CRYPTCATATTRIBUTE *)ps->Get(cStack))
{
CatalogFreeAttribute(pAttr);
cStack++;
}
DELETE_OBJECT(ps);
pCatStore->hAttrs = NULL;
}
}
//
// check hReserved to see if we used pStack
//
if (pCatStore->hReserved)
{
Stack_ *pStack;
CRYPTCATMEMBER *pCatMember;
DWORD dwCurPos;
pStack = (Stack_ *)pCatStore->hReserved;
dwCurPos = 0;
while (pCatMember = (CRYPTCATMEMBER *)pStack->Get(dwCurPos))
{
CatalogFreeMember(pCatMember);
dwCurPos++;
}
DELETE_OBJECT(pStack);
pCatStore->hReserved = NULL;
}
pCatStore->cbStruct = 0; // just in case they try to re-open it!
DELETE_OBJECT(pCatStore);
//
// restore last error
//
SetLastError(dwlerr);
return(fRet);
}
CRYPTCATSTORE * WINAPI CryptCATStoreFromHandle(IN HANDLE hCatalog)
{
return((CRYPTCATSTORE *)hCatalog);
}
HANDLE WINAPI CryptCATHandleFromStore(IN CRYPTCATSTORE *pCatStore)
{
return((HANDLE)pCatStore);
}
BOOL WINAPI CryptCATPersistStore(IN HANDLE hCatalog)
{
CRYPTCATSTORE *pStore;
if (!(hCatalog) ||
(hCatalog == INVALID_HANDLE_VALUE))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(FALSE);
}
pStore = CryptCATStoreFromHandle(hCatalog);
if (!(pStore->pwszP7File))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(FALSE);
}
return(CatalogSaveP7UData(pStore));
}
CRYPTCATATTRIBUTE * WINAPI CryptCATGetCatAttrInfo(HANDLE hCatalog, LPWSTR pwszReferenceTag)
{
CRYPTCATATTRIBUTE *pAttr;
CRYPTCATSTORE *pCatStore;
pAttr = NULL;
if (!(hCatalog) ||
(hCatalog == INVALID_HANDLE_VALUE) ||
!(pwszReferenceTag))
{
goto ErrorInvalidParam;
}
pCatStore = CryptCATStoreFromHandle(hCatalog);
if (!(_ISINSTRUCT(CRYPTCATSTORE, pCatStore->cbStruct, hAttrs)))
{
goto ErrorInvalidParam;
}
while (pAttr = CryptCATEnumerateCatAttr(hCatalog, pAttr))
{
if (pAttr->pwszReferenceTag)
{
if (_wcsicmp(pwszReferenceTag, pAttr->pwszReferenceTag) == 0)
{
goto CommonReturn;
}
}
}
goto ErrorNotFound;
CommonReturn:
ErrorReturn:
return(pAttr);
SET_ERROR_VAR_EX(DBG_SS, ErrorInvalidParam, ERROR_INVALID_PARAMETER);
SET_ERROR_VAR_EX(DBG_SS, ErrorNotFound, CRYPT_E_NOT_FOUND);
}
CRYPTCATATTRIBUTE * WINAPI CryptCATPutCatAttrInfo(HANDLE hCatalog, LPWSTR pwszReferenceTag,
DWORD dwAttrTypeAndAction, DWORD cbData,
BYTE *pbData)
{
CRYPTCATATTRIBUTE *pAttr;
pAttr = NULL;
if (!(hCatalog) ||
(hCatalog == INVALID_HANDLE_VALUE) ||
!(pwszReferenceTag) ||
((cbData > 0) && !(pbData)))
{
goto ErrorInvalidParam;
}
if (!(dwAttrTypeAndAction & CRYPTCAT_ATTR_DATABASE64) &&
!(dwAttrTypeAndAction & CRYPTCAT_ATTR_DATAASCII) &&
!(dwAttrTypeAndAction & CRYPTCAT_ATTR_DATAREPLACE))
{
goto ErrorInvalidParam;
}
CRYPTCATSTORE *pCatStore;
pCatStore = (CRYPTCATSTORE *)hCatalog;
if (!(_ISINSTRUCT(CRYPTCATSTORE, pCatStore->cbStruct, hAttrs)))
{
goto ErrorInvalidParam;
}
Stack_ *pStack;
if (!(pCatStore->hAttrs))
{
pStack = new Stack_(&MSCAT_CriticalSection);
if (!(pStack))
{
goto ErrorMemory;
}
pCatStore->hAttrs = (HANDLE)pStack;
}
pStack = (Stack_ *)pCatStore->hAttrs;
if (!(dwAttrTypeAndAction & CRYPTCAT_ATTR_DATAREPLACE))
{
if (!(pAttr = (CRYPTCATATTRIBUTE *)pStack->Add(sizeof(CRYPTCATATTRIBUTE))))
{
goto StackError;
}
memset(pAttr, 0x00, sizeof(CRYPTCATATTRIBUTE));
pAttr->cbStruct = sizeof(CRYPTCATATTRIBUTE);
if (!(pAttr->pwszReferenceTag = (LPWSTR)CatalogNew((wcslen(pwszReferenceTag) + 1) *
sizeof(WCHAR))))
{
goto ErrorMemory;
}
wcscpy(pAttr->pwszReferenceTag, pwszReferenceTag);
pAttr->dwAttrTypeAndAction = dwAttrTypeAndAction;
if (pbData)
{
if (dwAttrTypeAndAction & CRYPTCAT_ATTR_DATABASE64)
{
CryptStringToBinaryW((WCHAR *)pbData, cbData / sizeof(WCHAR), CRYPT_STRING_ANY, NULL, &pAttr->cbValue, NULL, NULL);
if (pAttr->cbValue < 1)
{
goto DecodeError;
}
if (!(pAttr->pbValue = (BYTE *)CatalogNew(pAttr->cbValue)))
{
pAttr->cbValue = 0;
goto ErrorMemory;
}
if (!CryptStringToBinaryW((WCHAR *)pbData, cbData / sizeof(WCHAR), CRYPT_STRING_ANY, pAttr->pbValue, &pAttr->cbValue, NULL, NULL))
{
goto DecodeError;
}
}
else if (dwAttrTypeAndAction & CRYPTCAT_ATTR_DATAASCII)
{
if (!(pAttr->pbValue = (BYTE *)CatalogNew(cbData)))
{
goto ErrorMemory;
}
memcpy(pAttr->pbValue, pbData, cbData);
pAttr->cbValue = cbData;
}
}
}
else
{
DWORD pos = 0;
pAttr = (CRYPTCATATTRIBUTE *) pStack->Get(pos++, NULL);
while ((pAttr != NULL) && (wcscmp(pAttr->pwszReferenceTag, pwszReferenceTag) != 0))
{
pAttr = (CRYPTCATATTRIBUTE *) pStack->Get(pos++, NULL);
}
if (pAttr != NULL)
{
DELETE_OBJECT(pAttr->pbValue);
pAttr->pbValue = NULL;
pAttr->cbValue = 0;
if (!(pAttr->pbValue = (BYTE *)CatalogNew(cbData)))
{
goto ErrorMemory;
}
memcpy(pAttr->pbValue, pbData, cbData);
pAttr->cbValue = cbData;
}
}
// CommonReturn:
ErrorReturn:
return(pAttr);
TRACE_ERROR_EX(DBG_SS, StackError);
TRACE_ERROR_EX(DBG_SS, DecodeError);
SET_ERROR_VAR_EX(DBG_SS, ErrorMemory, ERROR_NOT_ENOUGH_MEMORY);
SET_ERROR_VAR_EX(DBG_SS, ErrorInvalidParam, ERROR_INVALID_PARAMETER);
}
CRYPTCATATTRIBUTE * WINAPI CryptCATEnumerateCatAttr(HANDLE hCatalog, CRYPTCATATTRIBUTE *pPrevAttr)
{
CRYPTCATATTRIBUTE *pAttr;
pAttr = NULL;
if (!(hCatalog) ||
(hCatalog == (HANDLE)INVALID_HANDLE_VALUE))
{
goto ErrorInvalidParam;
}
CRYPTCATSTORE *pStore;
pStore = CryptCATStoreFromHandle(hCatalog);
if (!(_ISINSTRUCT(CRYPTCATSTORE, pStore->cbStruct, hAttrs)))
{
goto ErrorInvalidParam;
}
DWORD dwNext;
dwNext = 0;
if (pPrevAttr)
{
if (!(_ISINSTRUCT(CRYPTCATATTRIBUTE, pPrevAttr->cbStruct, dwReserved)))
{
goto ErrorInvalidParam;
}
dwNext = pPrevAttr->dwReserved + 1;
}
if (pStore->hAttrs)
{
Stack_ *ps;
ps = (Stack_ *)pStore->hAttrs;
if (pAttr = (CRYPTCATATTRIBUTE *)ps->Get(dwNext))
{
//
// save our "id" for next time
//
pAttr->dwReserved = dwNext;
//
// Done!
//
goto CommonReturn;
}
}
goto ErrorNotFound;
CommonReturn:
ErrorReturn:
return(pAttr);
SET_ERROR_VAR_EX(DBG_SS, ErrorInvalidParam, ERROR_INVALID_PARAMETER);
SET_ERROR_VAR_EX(DBG_SS, ErrorNotFound, CRYPT_E_NOT_FOUND);
}
CRYPTCATMEMBER * WINAPI CryptCATGetMemberInfo(IN HANDLE hCatalog,
IN LPWSTR pwszReferenceTag)
{
if (!(hCatalog) ||
(hCatalog == (HANDLE)INVALID_HANDLE_VALUE) ||
!(pwszReferenceTag))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(NULL);
}
CRYPTCATSTORE *pCatStore;
CRYPTCATMEMBER *pCatMember;
pCatStore = (CRYPTCATSTORE *)hCatalog;
if (!(_ISINSTRUCT(CRYPTCATSTORE, pCatStore->cbStruct, hReserved)))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(NULL);
}
pCatMember = NULL;
if (pCatStore->hReserved)
{
Stack_ *ps;
ps = (Stack_ *)pCatStore->hReserved;
if (pCatMember = (CRYPTCATMEMBER *)ps->Get(WVT_OFFSETOF(CRYPTCATMEMBER, pwszReferenceTag),
sizeof(WCHAR *),
STACK_SORTTYPE_PWSZ,
pwszReferenceTag))
{
if (!(pCatMember->pIndirectData))
{
CatalogReallyDecodeIndirectData(pCatStore, pCatMember, &pCatMember->sEncodedIndirectData);
}
if ((pCatMember->gSubjectType.Data1 == 0) &&
(pCatMember->gSubjectType.Data2 == 0) &&
(pCatMember->gSubjectType.Data3 == 0))
{
CatalogReallyDecodeMemberInfo(pCatStore, pCatMember, &pCatMember->sEncodedMemberInfo);
}
return(pCatMember);
}
}
return(NULL);
}
CRYPTCATMEMBER * WINAPI CryptCATPutMemberInfo(HANDLE hCatalog,
LPWSTR pwszFileName,
LPWSTR pwszReferenceTag,
GUID *pgSubjectType,
DWORD dwCertVersion,
DWORD cbIndirectData,
BYTE *pbIndirectData)
{
if (!(hCatalog) ||
(hCatalog == (HANDLE)INVALID_HANDLE_VALUE) ||
!(pwszReferenceTag) ||
!(pgSubjectType) ||
!(pbIndirectData) ||
(wcslen(pwszReferenceTag) > CRYPTCAT_MAX_MEMBERTAG))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(NULL);
}
CRYPTCATSTORE *pCatStore;
pCatStore = (CRYPTCATSTORE *)hCatalog;
if (!(_ISINSTRUCT(CRYPTCATSTORE, pCatStore->cbStruct, hReserved)))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(NULL);
}
Stack_ *pStack;
CRYPTCATMEMBER *pCatMember;
if (!(pCatStore->hReserved))
{
pStack = new Stack_(&MSCAT_CriticalSection);
if (!(pStack))
{
assert(0);
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return(NULL);
}
pCatStore->hReserved = (HANDLE)pStack;
}
//
// the following is commented out -- too slow!!!!
//
// else if (CatalogCheckForDuplicateMember((Stack_ *)pCatStore->hReserved, pwszReferenceTag))
// {
// SetLastError(CRYPT_E_EXISTS);
// return(NULL);
// }
pStack = (Stack_ *)pCatStore->hReserved;
if (!(pCatMember = (CRYPTCATMEMBER *)pStack->Add(sizeof(CRYPTCATMEMBER))))
{
return(NULL);
}
memset(pCatMember, 0x00, sizeof(CRYPTCATMEMBER));
pCatMember->cbStruct = sizeof(CRYPTCATMEMBER);
if (pwszFileName)
{
if (!(pCatMember->pwszFileName = (LPWSTR)CatalogNew((wcslen(pwszFileName) + 1) *
sizeof(WCHAR))))
{
return(NULL);
}
wcscpy(pCatMember->pwszFileName, pwszFileName);
}
if (!(pCatMember->pwszReferenceTag = (LPWSTR)CatalogNew((wcslen(pwszReferenceTag) + 1) *
sizeof(WCHAR))))
{
return(NULL);
}
wcscpy(pCatMember->pwszReferenceTag, pwszReferenceTag);
if (cbIndirectData > 0)
{
SIP_INDIRECT_DATA *pInd;
if (!(pCatMember->pIndirectData = (SIP_INDIRECT_DATA *)CatalogNew(sizeof(SIP_INDIRECT_DATA))))
{
return(NULL);
}
memset(pCatMember->pIndirectData, 0x00, sizeof(SIP_INDIRECT_DATA));
pInd = (SIP_INDIRECT_DATA *)pbIndirectData;
if (pInd->Data.pszObjId)
{
if (!(pCatMember->pIndirectData->Data.pszObjId =
(LPSTR)CatalogNew(strlen(pInd->Data.pszObjId) + 1)))
{
return(NULL);
}
strcpy(pCatMember->pIndirectData->Data.pszObjId, pInd->Data.pszObjId);
}
if (pInd->Data.Value.cbData > 0)
{
if (!(pCatMember->pIndirectData->Data.Value.pbData =
(BYTE *)CatalogNew(pInd->Data.Value.cbData)))
{
return(NULL);
}
memcpy(pCatMember->pIndirectData->Data.Value.pbData,
pInd->Data.Value.pbData, pInd->Data.Value.cbData);
}
pCatMember->pIndirectData->Data.Value.cbData = pInd->Data.Value.cbData;
if (!(pCatMember->pIndirectData->DigestAlgorithm.pszObjId =
(LPSTR)CatalogNew(strlen(pInd->DigestAlgorithm.pszObjId) + 1)))
{
return(NULL);
}
strcpy(pCatMember->pIndirectData->DigestAlgorithm.pszObjId,
pInd->DigestAlgorithm.pszObjId);
if (!(pCatMember->pIndirectData->Digest.pbData =
(BYTE *)CatalogNew(pInd->Digest.cbData)))
{
return(NULL);
}
memcpy(pCatMember->pIndirectData->Digest.pbData,
pInd->Digest.pbData, pInd->Digest.cbData);
pCatMember->pIndirectData->Digest.cbData = pInd->Digest.cbData;
}
memcpy(&pCatMember->gSubjectType, pgSubjectType, sizeof(GUID));
pCatMember->dwCertVersion = dwCertVersion;
return(pCatMember);
}
BOOL WINAPI CryptCATVerifyMember(HANDLE hCatalog,
CRYPTCATMEMBER *pCatMember,
HANDLE hFileOrMemory)
{
if (!(hCatalog) ||
(hCatalog == (HANDLE)INVALID_HANDLE_VALUE) ||
!(pCatMember) ||
!(_ISINSTRUCT(CRYPTCATMEMBER, pCatMember->cbStruct, hReserved)) ||
!(hFileOrMemory) ||
(hFileOrMemory == INVALID_HANDLE_VALUE))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(FALSE);
}
CRYPTCATSTORE *pCatStore;
pCatStore = (CRYPTCATSTORE *)hCatalog;
if (!(_ISINSTRUCT(CRYPTCATSTORE, pCatStore->cbStruct, hReserved)))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(FALSE);
}
// TBDTBD!!!
return(FALSE);
}
CRYPTCATATTRIBUTE * WINAPI CryptCATGetAttrInfo(HANDLE hCatalog,
CRYPTCATMEMBER *pCatMember,
LPWSTR pwszReferenceTag)
{
if (!(hCatalog) ||
(hCatalog == (HANDLE)INVALID_HANDLE_VALUE) ||
!(pCatMember) ||
!(_ISINSTRUCT(CRYPTCATMEMBER, pCatMember->cbStruct, hReserved)) ||
!(pwszReferenceTag))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(NULL);
}
CRYPTCATSTORE *pCatStore;
CRYPTCATATTRIBUTE *pCatAttr;
pCatStore = (CRYPTCATSTORE *)hCatalog;
if (!(_ISINSTRUCT(CRYPTCATSTORE, pCatStore->cbStruct, hReserved)))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(NULL);
}
pCatAttr = NULL;
while (pCatAttr = CryptCATEnumerateAttr(hCatalog, pCatMember, pCatAttr))
{
if (pCatAttr->pwszReferenceTag)
{
if (_wcsicmp(pwszReferenceTag, pCatAttr->pwszReferenceTag) == 0)
{
return(pCatAttr);
}
}
}
SetLastError(CRYPT_E_NOT_FOUND);
return(NULL);
}
CRYPTCATATTRIBUTE * WINAPI CryptCATPutAttrInfo(HANDLE hCatalog,
CRYPTCATMEMBER *pCatMember,
LPWSTR pwszReferenceTag,
DWORD dwAttrTypeAndAction,
DWORD cbData,
BYTE *pbData)
{
if (!(hCatalog) ||
(hCatalog == (HANDLE)INVALID_HANDLE_VALUE) ||
!(pCatMember) ||
!(_ISINSTRUCT(CRYPTCATMEMBER, pCatMember->cbStruct, hReserved)) ||
!(pwszReferenceTag) ||
((cbData > 0) && !(pbData)))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(NULL);
}
if (!(dwAttrTypeAndAction & CRYPTCAT_ATTR_DATABASE64) &&
!(dwAttrTypeAndAction & CRYPTCAT_ATTR_DATAASCII))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(NULL);
}
CRYPTCATSTORE *pCatStore;
pCatStore = (CRYPTCATSTORE *)hCatalog;
if (!(_ISINSTRUCT(CRYPTCATSTORE, pCatStore->cbStruct, hReserved)))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(NULL);
}
Stack_ *pStack;
CRYPTCATATTRIBUTE *pAttr;
if (!(pCatMember->hReserved))
{
pStack = new Stack_(&MSCAT_CriticalSection);
if (!(pStack))
{
assert(0);
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return(NULL);
}
pCatMember->hReserved = (HANDLE)pStack;
}
pStack = (Stack_ *)pCatMember->hReserved;
if (!(pAttr = (CRYPTCATATTRIBUTE *)pStack->Add(sizeof(CRYPTCATATTRIBUTE))))
{
return(NULL);
}
memset(pAttr, 0x00, sizeof(CRYPTCATATTRIBUTE));
pAttr->cbStruct = sizeof(CRYPTCATATTRIBUTE);
if (!(pAttr->pwszReferenceTag = (LPWSTR)CatalogNew((wcslen(pwszReferenceTag) + 1) *
sizeof(WCHAR))))
{
return(NULL);
}
wcscpy(pAttr->pwszReferenceTag, pwszReferenceTag);
pAttr->dwAttrTypeAndAction = dwAttrTypeAndAction;
if (pbData)
{
if (dwAttrTypeAndAction & CRYPTCAT_ATTR_DATABASE64)
{
CryptStringToBinaryW((WCHAR *)pbData, cbData / sizeof(WCHAR), CRYPT_STRING_ANY, NULL, &pAttr->cbValue, NULL, NULL);
if (pAttr->cbValue < 1)
{
return(NULL);
}
if (!(pAttr->pbValue = (BYTE *)CatalogNew(pAttr->cbValue)))
{
pAttr->cbValue = 0;
return(NULL);
}
memset(pAttr->pbValue, 0x00, pAttr->cbValue);
if (!CryptStringToBinaryW((WCHAR *)pbData, cbData / sizeof(WCHAR), CRYPT_STRING_ANY, pAttr->pbValue, &pAttr->cbValue, NULL, NULL))
{
return(NULL);
}
}
else if (dwAttrTypeAndAction & CRYPTCAT_ATTR_DATAASCII)
{
if (!(pAttr->pbValue = (BYTE *)CatalogNew(cbData)))
{
return(NULL);
}
memcpy(pAttr->pbValue, pbData, cbData);
pAttr->cbValue = cbData;
}
}
return(pAttr);
}
CRYPTCATMEMBER * WINAPI CryptCATEnumerateMember(HANDLE hCatalog,
CRYPTCATMEMBER *pPrevMember)
{
if (!(hCatalog) ||
(hCatalog == (HANDLE)INVALID_HANDLE_VALUE))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(NULL);
}
CRYPTCATSTORE *pCatStore;
pCatStore = (CRYPTCATSTORE *)hCatalog;
if (!(_ISINSTRUCT(CRYPTCATSTORE, pCatStore->cbStruct, hReserved)))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(NULL);
}
DWORD dwNext;
dwNext = 0;
if (pPrevMember)
{
if (!(_ISINSTRUCT(CRYPTCATMEMBER, pPrevMember->cbStruct, hReserved)))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(NULL);
}
dwNext = pPrevMember->dwReserved + 1;
}
if (pCatStore->hReserved)
{
CRYPTCATMEMBER *pCatMember;
Stack_ *ps;
ps = (Stack_ *)pCatStore->hReserved;
if (pCatMember = (CRYPTCATMEMBER *)ps->Get(dwNext))
{
//
// save our "id" for next time
//
pCatMember->dwReserved = dwNext;
if (!(pCatMember->pIndirectData))
{
CatalogReallyDecodeIndirectData(pCatStore, pCatMember, &pCatMember->sEncodedIndirectData);
}
if ((pCatMember->gSubjectType.Data1 == 0) &&
(pCatMember->gSubjectType.Data2 == 0) &&
(pCatMember->gSubjectType.Data3 == 0))
{
CatalogReallyDecodeMemberInfo(pCatStore, pCatMember, &pCatMember->sEncodedMemberInfo);
}
//
// Done!
//
return(pCatMember);
}
}
return(NULL);
}
CRYPTCATATTRIBUTE * WINAPI CryptCATEnumerateAttr(HANDLE hCatalog,
CRYPTCATMEMBER *pCatMember,
CRYPTCATATTRIBUTE *pPrevAttr)
{
if (!(hCatalog) ||
(hCatalog == (HANDLE)INVALID_HANDLE_VALUE))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(NULL);
}
CRYPTCATSTORE *pCatStore;
pCatStore = (CRYPTCATSTORE *)hCatalog;
if (!(_ISINSTRUCT(CRYPTCATSTORE, pCatStore->cbStruct, hReserved)))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(NULL);
}
DWORD dwNext;
dwNext = 0;
if (pPrevAttr)
{
if (!(_ISINSTRUCT(CRYPTCATATTRIBUTE, pPrevAttr->cbStruct, dwReserved)))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(NULL);
}
dwNext = pPrevAttr->dwReserved + 1;
}
if (!(pCatStore) ||
!(_ISINSTRUCT(CRYPTCATSTORE, pCatStore->cbStruct, hReserved)) ||
!(pCatMember) ||
!(_ISINSTRUCT(CRYPTCATMEMBER, pCatMember->cbStruct, hReserved)))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(NULL);
}
if (pCatMember->hReserved)
{
CRYPTCATATTRIBUTE *pCatAttr;
Stack_ *ps;
ps = (Stack_ *)pCatMember->hReserved;
if (pCatAttr = (CRYPTCATATTRIBUTE *)ps->Get(dwNext))
{
//
// save our "id" for next time
//
pCatAttr->dwReserved = dwNext;
//
// Done!
//
return(pCatAttr);
}
}
return(NULL);
}
/////////////////////////////////////////////////////////////////////////////
//
// Local Functions
//
BOOL CryptCATCreateStore(CRYPTCATSTORE *pCatStore, LPWSTR pwszCatFile)
{
HANDLE hFile;
DWORD lErr;
lErr = GetLastError();
if ((hFile = CreateFileU(pwszCatFile,
GENERIC_WRITE | GENERIC_READ,
0, // no sharing!!
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL)) == INVALID_HANDLE_VALUE)
{
return(FALSE);
}
CloseHandle(hFile);
SetLastError(lErr);
return(CryptCATOpenStore(pCatStore, pwszCatFile));
}
BOOL CryptCATOpenStore(CRYPTCATSTORE *pCatStore, LPWSTR pwszCatFile)
{
if (!(pCatStore->pwszP7File = (LPWSTR)CatalogNew((wcslen(pwszCatFile) + 1) *
sizeof(WCHAR))))
{
return(FALSE);
}
wcscpy(pCatStore->pwszP7File, pwszCatFile);
return(CatalogLoadFileData(pCatStore));
}