You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
797 lines
28 KiB
797 lines
28 KiB
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
//
|
|
// Copyright (C) Microsoft Corporation, 1996 - 1999
|
|
//
|
|
// File: msgprov.cpp
|
|
//
|
|
// Contents: Microsoft Internet Security Authenticode Policy Provider
|
|
//
|
|
// Functions: SoftpubLoadMessage
|
|
//
|
|
// *** local functions ***
|
|
// _LoadSIP
|
|
// _SetSubjectInfo
|
|
// _GetMessage
|
|
// _ExplodeMessage
|
|
// _NoContentWrap
|
|
// _SkipOverIdentifierAndLengthOctets
|
|
//
|
|
// History: 05-Jun-1997 pberkman created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
#include "global.hxx"
|
|
#include "crypthlp.h"
|
|
|
|
#include "sipguids.h" // located in pki/mssip32
|
|
|
|
BOOL _LoadSIP(CRYPT_PROVIDER_DATA *pProvData);
|
|
BOOL _SetSubjectInfo(CRYPT_PROVIDER_DATA *pProvData);
|
|
BOOL _GetMessage(CRYPT_PROVIDER_DATA *pProvData);
|
|
BOOL _ExplodeMessage(CRYPT_PROVIDER_DATA *pProvData);
|
|
BOOL _NoContentWrap(const BYTE *pbDER, DWORD cbDER);
|
|
DWORD _SkipOverIdentifierAndLengthOctets(const BYTE *pbDER, DWORD cbDER);
|
|
extern "C" BOOL MsCatConstructHashTag (IN DWORD cbDigest, IN LPBYTE pbDigest, OUT LPWSTR* ppwszHashTag);
|
|
extern "C" VOID MsCatFreeHashTag (IN LPWSTR pwszHashTag);
|
|
|
|
|
|
HRESULT WINAPI SoftpubLoadMessage(CRYPT_PROVIDER_DATA *pProvData)
|
|
{
|
|
if (!(pProvData->padwTrustStepErrors) ||
|
|
(pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_WVTINIT] != ERROR_SUCCESS) ||
|
|
(pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_INITPROV] != ERROR_SUCCESS))
|
|
{
|
|
return(S_FALSE);
|
|
}
|
|
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] = ERROR_SUCCESS;
|
|
|
|
switch (pProvData->pWintrustData->dwUnionChoice)
|
|
{
|
|
case WTD_CHOICE_CERT:
|
|
case WTD_CHOICE_SIGNER:
|
|
//
|
|
// this is handled in the signature provider
|
|
//
|
|
return(ERROR_SUCCESS);
|
|
|
|
case WTD_CHOICE_FILE:
|
|
case WTD_CHOICE_CATALOG:
|
|
case WTD_CHOICE_BLOB:
|
|
break;
|
|
|
|
default:
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] = ERROR_INVALID_PARAMETER;
|
|
return(S_FALSE);
|
|
}
|
|
|
|
//
|
|
// extract the message from object.
|
|
//
|
|
if (!(_SetSubjectInfo(pProvData)))
|
|
{
|
|
return(S_FALSE);
|
|
}
|
|
|
|
if (!(_LoadSIP(pProvData)))
|
|
{
|
|
return(S_FALSE);
|
|
}
|
|
|
|
if (!(_GetMessage(pProvData)))
|
|
{
|
|
return(S_FALSE);
|
|
}
|
|
|
|
if (!(_ExplodeMessage(pProvData)))
|
|
{
|
|
return(S_FALSE);
|
|
}
|
|
|
|
|
|
//
|
|
// verify the object that the message pertains to
|
|
//
|
|
if ((pProvData->pWintrustData->dwUnionChoice == WTD_CHOICE_CATALOG) &&
|
|
(_ISINSTRUCT(WINTRUST_CATALOG_INFO, pProvData->pWintrustData->pCatalog->cbStruct,
|
|
cbCalculatedFileHash)) &&
|
|
(pProvData->pWintrustData->pCatalog->pbCalculatedFileHash) &&
|
|
(pProvData->pWintrustData->pCatalog->cbCalculatedFileHash > 0))
|
|
{
|
|
//
|
|
// we've been passed in the calculated file hash so don't redo it, just check it!
|
|
//
|
|
if (!(pProvData->pPDSip->psIndirectData) ||
|
|
!(pProvData->pPDSip->psIndirectData->Digest.pbData) ||
|
|
(pProvData->pWintrustData->pCatalog->cbCalculatedFileHash !=
|
|
pProvData->pPDSip->psIndirectData->Digest.cbData) ||
|
|
(memcmp(pProvData->pWintrustData->pCatalog->pbCalculatedFileHash,
|
|
pProvData->pPDSip->psIndirectData->Digest.pbData,
|
|
pProvData->pPDSip->psIndirectData->Digest.cbData) != 0))
|
|
{
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] = TRUST_E_BAD_DIGEST;
|
|
return(S_FALSE);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// we need to calculate the hash from the file.... do it!
|
|
//
|
|
if (!(pProvData->pPDSip->pSip->pfVerify(pProvData->pPDSip->psSipSubjectInfo,
|
|
pProvData->pPDSip->psIndirectData)))
|
|
{
|
|
if (GetLastError() == CRYPT_E_SECURITY_SETTINGS)
|
|
{
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] = CRYPT_E_SECURITY_SETTINGS;
|
|
}
|
|
else
|
|
{
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] = TRUST_E_BAD_DIGEST;
|
|
}
|
|
|
|
return(S_FALSE);
|
|
}
|
|
}
|
|
|
|
return(ERROR_SUCCESS);
|
|
}
|
|
|
|
static GUID _gCATSubject = CRYPT_SUBJTYPE_CATALOG_IMAGE;
|
|
|
|
BOOL _LoadSIP(CRYPT_PROVIDER_DATA *pProvData)
|
|
{
|
|
if (!(pProvData->pPDSip->pSip))
|
|
{
|
|
if (!(pProvData->pPDSip->pSip = (SIP_DISPATCH_INFO *)pProvData->psPfns->pfnAlloc(sizeof(SIP_DISPATCH_INFO))))
|
|
{
|
|
pProvData->dwError = GetLastError();
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] = TRUST_E_SYSTEM_ERROR;
|
|
return(FALSE);
|
|
}
|
|
|
|
if (!(CryptSIPLoad(&pProvData->pPDSip->gSubject, 0, pProvData->pPDSip->pSip)))
|
|
{
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_SIP] = GetLastError();
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] = TRUST_E_PROVIDER_UNKNOWN;
|
|
return(FALSE);
|
|
}
|
|
}
|
|
|
|
if (pProvData->pWintrustData->dwUnionChoice == WTD_CHOICE_CATALOG)
|
|
{
|
|
if (!(pProvData->pPDSip->pCATSip))
|
|
{
|
|
if (!(pProvData->pPDSip->pCATSip = (SIP_DISPATCH_INFO *)pProvData->psPfns->pfnAlloc(sizeof(SIP_DISPATCH_INFO))))
|
|
{
|
|
pProvData->dwError = GetLastError();
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] = TRUST_E_SYSTEM_ERROR;
|
|
return(FALSE);
|
|
}
|
|
|
|
if (!(CryptSIPLoad(&_gCATSubject, 0, pProvData->pPDSip->pCATSip)))
|
|
{
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_SIP] = GetLastError();
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] = TRUST_E_PROVIDER_UNKNOWN;
|
|
return(FALSE);
|
|
}
|
|
}
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
BOOL _SetSubjectInfo(CRYPT_PROVIDER_DATA *pProvData)
|
|
{
|
|
SIP_SUBJECTINFO *pSubjInfo;
|
|
SIP_DISPATCH_INFO sSIPDisp;
|
|
|
|
switch (pProvData->pWintrustData->dwUnionChoice)
|
|
{
|
|
case WTD_CHOICE_BLOB:
|
|
if (!(pProvData->pWintrustData->pBlob) ||
|
|
!(_ISINSTRUCT(WINTRUST_BLOB_INFO, pProvData->pWintrustData->pBlob->cbStruct, pbMemSignedMsg)))
|
|
{
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] = (DWORD)ERROR_INVALID_PARAMETER;
|
|
return(FALSE);
|
|
}
|
|
|
|
memcpy(&pProvData->pPDSip->gSubject, &pProvData->pWintrustData->pBlob->gSubject, sizeof(GUID));
|
|
break;
|
|
|
|
case WTD_CHOICE_FILE:
|
|
if (!(pProvData->pWintrustData->pFile) ||
|
|
!(_ISINSTRUCT(WINTRUST_FILE_INFO, pProvData->pWintrustData->pFile->cbStruct, hFile)))
|
|
{
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] = (DWORD)ERROR_INVALID_PARAMETER;
|
|
return(FALSE);
|
|
}
|
|
|
|
if ((_ISINSTRUCT(WINTRUST_FILE_INFO, pProvData->pWintrustData->pFile->cbStruct, pgKnownSubject)) &&
|
|
(pProvData->pWintrustData->pFile->pgKnownSubject))
|
|
{
|
|
memcpy(&pProvData->pPDSip->gSubject, pProvData->pWintrustData->pFile->pgKnownSubject, sizeof(GUID));
|
|
}
|
|
else if (!(CryptSIPRetrieveSubjectGuid(pProvData->pWintrustData->pFile->pcwszFilePath,
|
|
pProvData->pWintrustData->pFile->hFile,
|
|
&pProvData->pPDSip->gSubject)))
|
|
{
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_SIP] = GetLastError();
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] = TRUST_E_SUBJECT_FORM_UNKNOWN;
|
|
return(FALSE);
|
|
}
|
|
break;
|
|
|
|
case WTD_CHOICE_CATALOG:
|
|
if (!(pProvData->pWintrustData->pCatalog) ||
|
|
!(_ISINSTRUCT(WINTRUST_CATALOG_INFO, pProvData->pWintrustData->pCatalog->cbStruct,
|
|
hMemberFile)))
|
|
{
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] = (DWORD)ERROR_INVALID_PARAMETER;
|
|
return(FALSE);
|
|
}
|
|
|
|
if ((_ISINSTRUCT(CRYPT_PROVIDER_DATA, pProvData->cbStruct, fRecallWithState)) &&
|
|
(pProvData->fRecallWithState))
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (!(pProvData->pPDSip->psSipCATSubjectInfo =
|
|
(SIP_SUBJECTINFO *)pProvData->psPfns->pfnAlloc(sizeof(SIP_SUBJECTINFO))))
|
|
{
|
|
pProvData->dwError = GetLastError();
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] = TRUST_E_SYSTEM_ERROR;
|
|
return(FALSE);
|
|
}
|
|
|
|
memset(pProvData->pPDSip->psSipCATSubjectInfo, 0x00, sizeof(SIP_SUBJECTINFO));
|
|
|
|
pProvData->pPDSip->psSipCATSubjectInfo->cbSize = sizeof(SIP_SUBJECTINFO);
|
|
pProvData->pPDSip->psSipCATSubjectInfo->hProv = pProvData->hProv;
|
|
pProvData->pPDSip->psSipCATSubjectInfo->pClientData = pProvData->pWintrustData->pSIPClientData;
|
|
pProvData->pPDSip->psSipCATSubjectInfo->pwsFileName =
|
|
(WCHAR *)pProvData->pWintrustData->pCatalog->pcwszCatalogFilePath;
|
|
pProvData->pPDSip->psSipCATSubjectInfo->pwsDisplayName =
|
|
pProvData->pPDSip->psSipCATSubjectInfo->pwsFileName;
|
|
|
|
pProvData->pPDSip->psSipCATSubjectInfo->fdwCAPISettings = pProvData->dwRegPolicySettings;
|
|
pProvData->pPDSip->psSipCATSubjectInfo->fdwSecuritySettings = pProvData->dwRegPolicySettings;
|
|
|
|
if (!(pProvData->pPDSip->psSipCATSubjectInfo->pgSubjectType =
|
|
(GUID *)pProvData->psPfns->pfnAlloc(sizeof(GUID))))
|
|
{
|
|
pProvData->dwError = GetLastError();
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] = TRUST_E_SYSTEM_ERROR;
|
|
return(FALSE);
|
|
}
|
|
|
|
memcpy(pProvData->pPDSip->psSipCATSubjectInfo->pgSubjectType, &_gCATSubject, sizeof(GUID));
|
|
break;
|
|
|
|
default:
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_CATALOGFILE] = GetLastError();
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] = CRYPT_E_FILE_ERROR;
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
//
|
|
// setup the subject info for the SIP
|
|
//
|
|
if (!(pProvData->pPDSip->psSipSubjectInfo))
|
|
{
|
|
if (!(pProvData->pPDSip->psSipSubjectInfo =
|
|
(SIP_SUBJECTINFO *)pProvData->psPfns->pfnAlloc(sizeof(SIP_SUBJECTINFO))))
|
|
{
|
|
pProvData->dwError = GetLastError();
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] = TRUST_E_SYSTEM_ERROR;
|
|
return(FALSE);
|
|
}
|
|
|
|
pSubjInfo = pProvData->pPDSip->psSipSubjectInfo;
|
|
|
|
memset(pSubjInfo, 0x00, sizeof(SIP_SUBJECTINFO));
|
|
|
|
pSubjInfo->cbSize = sizeof(SIP_SUBJECTINFO);
|
|
|
|
pSubjInfo->hProv = pProvData->hProv;
|
|
|
|
}
|
|
else
|
|
{
|
|
pSubjInfo = pProvData->pPDSip->psSipSubjectInfo;
|
|
}
|
|
|
|
|
|
pSubjInfo->pClientData = pProvData->pWintrustData->pSIPClientData;
|
|
|
|
pSubjInfo->pwsFileName = WTHelperGetFileName(pProvData->pWintrustData);
|
|
pSubjInfo->hFile = WTHelperGetFileHandle(pProvData->pWintrustData);
|
|
pSubjInfo->pwsDisplayName = pSubjInfo->pwsFileName;
|
|
|
|
pSubjInfo->fdwCAPISettings = pProvData->dwRegPolicySettings;
|
|
pSubjInfo->fdwSecuritySettings = pProvData->dwRegSecuritySettings;
|
|
|
|
if (!(pSubjInfo->pgSubjectType = (GUID *)pProvData->psPfns->pfnAlloc(sizeof(GUID))))
|
|
{
|
|
pProvData->dwError = GetLastError();
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] = TRUST_E_SYSTEM_ERROR;
|
|
return(FALSE);
|
|
}
|
|
|
|
switch(pProvData->pWintrustData->dwUnionChoice)
|
|
{
|
|
case WTD_CHOICE_FILE:
|
|
break;
|
|
|
|
case WTD_CHOICE_BLOB:
|
|
pSubjInfo->dwUnionChoice = MSSIP_ADDINFO_BLOB;
|
|
if (!(pSubjInfo->psBlob = (MS_ADDINFO_BLOB *)pProvData->psPfns->pfnAlloc(sizeof(MS_ADDINFO_BLOB))))
|
|
{
|
|
pProvData->dwError = GetLastError();
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] = TRUST_E_SYSTEM_ERROR;
|
|
return(FALSE);
|
|
}
|
|
|
|
memset(pSubjInfo->psBlob, 0x00, sizeof(MS_ADDINFO_BLOB));
|
|
pSubjInfo->psBlob->cbStruct = sizeof(MS_ADDINFO_BLOB);
|
|
pSubjInfo->psBlob->cbMemObject = pProvData->pWintrustData->pBlob->cbMemObject;
|
|
pSubjInfo->psBlob->pbMemObject = pProvData->pWintrustData->pBlob->pbMemObject;
|
|
pSubjInfo->psBlob->cbMemSignedMsg = pProvData->pWintrustData->pBlob->cbMemSignedMsg;
|
|
pSubjInfo->psBlob->pbMemSignedMsg = pProvData->pWintrustData->pBlob->pbMemSignedMsg;
|
|
|
|
pSubjInfo->pwsDisplayName = pProvData->pWintrustData->pBlob->pcwszDisplayName;
|
|
break;
|
|
|
|
case WTD_CHOICE_CATALOG:
|
|
// The following APIs are in DELAYLOAD'ed mscat32.dll. If the
|
|
// DELAYLOAD fails an exception is raised.
|
|
__try {
|
|
|
|
HANDLE hCatStore;
|
|
MS_ADDINFO_CATALOGMEMBER *pCatAdd;
|
|
|
|
|
|
if (!(pSubjInfo->psCatMember))
|
|
{
|
|
if (!(pSubjInfo->psCatMember =
|
|
(MS_ADDINFO_CATALOGMEMBER *)pProvData->psPfns->pfnAlloc(sizeof(MS_ADDINFO_CATALOGMEMBER))))
|
|
{
|
|
pProvData->dwError = GetLastError();
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] = TRUST_E_SYSTEM_ERROR;
|
|
return(FALSE);
|
|
}
|
|
|
|
memset(pSubjInfo->psCatMember, 0x00, sizeof(MS_ADDINFO_CATALOGMEMBER));
|
|
|
|
pSubjInfo->dwUnionChoice = MSSIP_ADDINFO_CATMEMBER;
|
|
|
|
pCatAdd = pSubjInfo->psCatMember;
|
|
pCatAdd->cbStruct = sizeof(MS_ADDINFO_CATALOGMEMBER);
|
|
|
|
hCatStore = CryptCATOpen((WCHAR *)pProvData->pWintrustData->pCatalog->pcwszCatalogFilePath,
|
|
CRYPTCAT_OPEN_EXISTING,
|
|
pProvData->hProv,
|
|
pProvData->pWintrustData->pCatalog->dwCatalogVersion,
|
|
NULL);
|
|
|
|
if (!(hCatStore) || (hCatStore == INVALID_HANDLE_VALUE))
|
|
{
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_CATALOGFILE] = GetLastError();
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] = CRYPT_E_FILE_ERROR;
|
|
return(FALSE);
|
|
}
|
|
|
|
pCatAdd->pStore = CryptCATStoreFromHandle(hCatStore);
|
|
}
|
|
else
|
|
{
|
|
pCatAdd = pSubjInfo->psCatMember;
|
|
hCatStore = CryptCATHandleFromStore(pCatAdd->pStore);
|
|
}
|
|
|
|
pCatAdd->pMember = NULL;
|
|
|
|
if ( ( pProvData->pWintrustData->pCatalog->pbCalculatedFileHash != NULL ) &&
|
|
( pProvData->pWintrustData->pCatalog->cbCalculatedFileHash != 0 ) )
|
|
{
|
|
LPWSTR pwszHashTag;
|
|
|
|
if ( MsCatConstructHashTag(
|
|
pProvData->pWintrustData->pCatalog->cbCalculatedFileHash,
|
|
pProvData->pWintrustData->pCatalog->pbCalculatedFileHash,
|
|
&pwszHashTag
|
|
) == TRUE )
|
|
{
|
|
pCatAdd->pMember = CryptCATGetMemberInfo(hCatStore, pwszHashTag);
|
|
MsCatFreeHashTag(pwszHashTag);
|
|
}
|
|
}
|
|
|
|
if (!(pCatAdd->pMember))
|
|
{
|
|
pCatAdd->pMember = CryptCATGetMemberInfo(hCatStore,
|
|
(WCHAR *)pProvData->pWintrustData->pCatalog->pcwszMemberTag);
|
|
}
|
|
|
|
if (!(pCatAdd->pMember))
|
|
{
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_CATALOGFILE] = GetLastError();
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] = TRUST_E_NOSIGNATURE;
|
|
return(FALSE);
|
|
}
|
|
|
|
memcpy(&pProvData->pPDSip->gSubject, &pCatAdd->pMember->gSubjectType, sizeof(GUID));
|
|
|
|
|
|
//
|
|
// assign the correct cert version so hashes will match if the file was already signed!
|
|
//
|
|
pSubjInfo->dwIntVersion = pCatAdd->pMember->dwCertVersion;
|
|
|
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
|
pProvData->dwError = GetExceptionCode();
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] =
|
|
TRUST_E_SYSTEM_ERROR;
|
|
return(FALSE);
|
|
}
|
|
break;
|
|
}
|
|
|
|
//
|
|
// set the GUID for the SIP... this is done at the end because the pProvData member
|
|
// can get changed above!
|
|
//
|
|
memcpy(pSubjInfo->pgSubjectType, &pProvData->pPDSip->gSubject, sizeof(GUID));
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
BOOL _GetMessage(CRYPT_PROVIDER_DATA *pProvData)
|
|
{
|
|
DWORD dwMsgEncoding;
|
|
SIP_SUBJECTINFO *pSubjInfo;
|
|
SIP_DISPATCH_INFO *pSip;
|
|
|
|
DWORD cbEncodedMsg;
|
|
BYTE *pbEncodedMsg;
|
|
|
|
DWORD dwMsgType;
|
|
HCRYPTMSG hMsg;
|
|
HCRYPTPROV hProv;
|
|
|
|
dwMsgEncoding = 0;
|
|
dwMsgType = 0;
|
|
|
|
switch(pProvData->pWintrustData->dwUnionChoice)
|
|
{
|
|
case WTD_CHOICE_CATALOG:
|
|
if ((_ISINSTRUCT(CRYPT_PROVIDER_DATA, pProvData->cbStruct, fRecallWithState)) &&
|
|
(pProvData->fRecallWithState) &&
|
|
(pProvData->hMsg))
|
|
{
|
|
return(TRUE);
|
|
}
|
|
|
|
pSip = pProvData->pPDSip->pCATSip;
|
|
pSubjInfo = pProvData->pPDSip->psSipCATSubjectInfo;
|
|
break;
|
|
|
|
case WTD_CHOICE_BLOB:
|
|
case WTD_CHOICE_FILE:
|
|
pSip = pProvData->pPDSip->pSip;
|
|
pSubjInfo = pProvData->pPDSip->psSipSubjectInfo;
|
|
break;
|
|
|
|
default:
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] = TRUST_E_NOSIGNATURE;
|
|
return(FALSE);
|
|
}
|
|
|
|
cbEncodedMsg = 0;
|
|
|
|
pSip->pfGet(pSubjInfo, &dwMsgEncoding, 0, &cbEncodedMsg, NULL);
|
|
|
|
if (cbEncodedMsg == 0)
|
|
{
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_SIP] = GetLastError();
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] = TRUST_E_NOSIGNATURE;
|
|
return(FALSE);
|
|
}
|
|
|
|
if (!(pbEncodedMsg = (BYTE *)pProvData->psPfns->pfnAlloc(cbEncodedMsg)))
|
|
{
|
|
pProvData->dwError = GetLastError();
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] = TRUST_E_SYSTEM_ERROR;
|
|
return(FALSE);
|
|
}
|
|
|
|
if (!(pSip->pfGet(pSubjInfo, &dwMsgEncoding, 0, &cbEncodedMsg, pbEncodedMsg)))
|
|
{
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_SIP] = GetLastError();
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] = TRUST_E_NOSIGNATURE;
|
|
|
|
pProvData->psPfns->pfnFree(pbEncodedMsg);
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
pProvData->dwEncoding = dwMsgEncoding;
|
|
|
|
if ((pProvData->dwEncoding & PKCS_7_ASN_ENCODING) &&
|
|
(_NoContentWrap(pbEncodedMsg, cbEncodedMsg)))
|
|
{
|
|
dwMsgType = CMSG_SIGNED; // support for IE v3.0
|
|
}
|
|
|
|
// The default hProv to use depends on the type of the public key used to
|
|
// do the signing.
|
|
hProv = pProvData->hProv;
|
|
if (hProv && hProv == I_CryptGetDefaultCryptProv(0))
|
|
hProv = 0;
|
|
|
|
if (!(hMsg = CryptMsgOpenToDecode(pProvData->dwEncoding, 0, dwMsgType,
|
|
hProv, NULL, NULL)))
|
|
{
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_MESSAGE] = GetLastError();
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] = CRYPT_E_BAD_MSG;
|
|
|
|
pProvData->psPfns->pfnFree(pbEncodedMsg);
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
pProvData->hMsg = hMsg;
|
|
|
|
// encoded message
|
|
if (!(CryptMsgUpdate(hMsg, pbEncodedMsg, cbEncodedMsg, TRUE)))
|
|
{
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_MESSAGE] = GetLastError();
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] = CRYPT_E_BAD_MSG;
|
|
|
|
pProvData->psPfns->pfnFree(pbEncodedMsg);
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
pProvData->psPfns->pfnFree(pbEncodedMsg);
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
BOOL _ExplodeMessage(CRYPT_PROVIDER_DATA *pProvData)
|
|
{
|
|
DWORD cbSize;
|
|
DWORD cbContent;
|
|
BYTE *pb;
|
|
HCERTSTORE hStore;
|
|
|
|
if (!(_ISINSTRUCT(CRYPT_PROVIDER_DATA, pProvData->cbStruct, fRecallWithState)) ||
|
|
!(pProvData->fRecallWithState))
|
|
{
|
|
// message cert store
|
|
hStore = CertOpenStore(CERT_STORE_PROV_MSG,
|
|
pProvData->dwEncoding,
|
|
pProvData->hProv,
|
|
CERT_STORE_NO_CRYPT_RELEASE_FLAG,
|
|
pProvData->hMsg);
|
|
if (hStore)
|
|
{
|
|
if (!(pProvData->psPfns->pfnAddStore2Chain(pProvData, hStore)))
|
|
{
|
|
pProvData->dwError = GetLastError();
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] = TRUST_E_SYSTEM_ERROR;
|
|
|
|
CertCloseStore(hStore, 0);
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
CertCloseStore(hStore, 0);
|
|
}
|
|
else
|
|
{
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] = GetLastError();
|
|
return(FALSE);
|
|
}
|
|
}
|
|
|
|
// inner content type
|
|
cbSize = 0;
|
|
|
|
CryptMsgGetParam(pProvData->hMsg, CMSG_INNER_CONTENT_TYPE_PARAM, 0, NULL, &cbSize);
|
|
|
|
if (cbSize == 0)
|
|
{
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = CRYPT_E_BAD_MSG;
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_MSG_INNERCNTTYPE] = GetLastError();
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
if (!(pb = (BYTE *)pProvData->psPfns->pfnAlloc(cbSize + 1)))
|
|
{
|
|
pProvData->dwError = GetLastError();
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = TRUST_E_SYSTEM_ERROR;
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
if (!(CryptMsgGetParam(pProvData->hMsg, CMSG_INNER_CONTENT_TYPE_PARAM, 0,
|
|
pb, &cbSize)))
|
|
{
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_MSG_INNERCNTTYPE] = GetLastError();
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = CRYPT_E_BAD_MSG;
|
|
|
|
delete pb;
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
pb[cbSize] = NULL;
|
|
|
|
if (strcmp((char *)pb, SPC_INDIRECT_DATA_OBJID) == 0)
|
|
{
|
|
pProvData->psPfns->pfnFree(pb);
|
|
|
|
cbContent = 0;
|
|
|
|
CryptMsgGetParam(pProvData->hMsg, CMSG_CONTENT_PARAM, 0, NULL, &cbContent);
|
|
|
|
if (cbContent == 0)
|
|
{
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = CRYPT_E_BAD_MSG;
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_MSG_INNERCNT] = GetLastError();
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
if (!(pb = (BYTE *)pProvData->psPfns->pfnAlloc(cbContent)))
|
|
{
|
|
pProvData->dwError = GetLastError();
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = TRUST_E_SYSTEM_ERROR;
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
if (!(CryptMsgGetParam(pProvData->hMsg, CMSG_CONTENT_PARAM, 0,
|
|
pb, &cbContent)))
|
|
{
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = CRYPT_E_BAD_MSG;
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_MSG_INNERCNT] = GetLastError();
|
|
|
|
pProvData->psPfns->pfnFree(pb);
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
if (!(TrustDecode(WVT_MODID_SOFTPUB, (BYTE **)&pProvData->pPDSip->psIndirectData, &cbSize, 202,
|
|
pProvData->dwEncoding, SPC_INDIRECT_DATA_CONTENT_STRUCT,
|
|
pb, cbContent, 0)))
|
|
{
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = CRYPT_E_BAD_MSG;
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_MSG_INNERCNT] = GetLastError();
|
|
|
|
pProvData->psPfns->pfnFree(pb);
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
pProvData->psPfns->pfnFree(pb);
|
|
}
|
|
else
|
|
{
|
|
pProvData->psPfns->pfnFree(pb);
|
|
|
|
if ((pProvData->pWintrustData->dwUnionChoice == WTD_CHOICE_CATALOG) &&
|
|
(pProvData->pPDSip->psSipSubjectInfo->dwUnionChoice == MSSIP_ADDINFO_CATMEMBER))
|
|
{
|
|
//
|
|
// get the indirect data from the pMember!!! Also, we want to
|
|
// allocate just the structure and copy the pointers over to it.
|
|
// this is so we can have a generic cleanup.
|
|
//
|
|
MS_ADDINFO_CATALOGMEMBER *pCatAdd;
|
|
|
|
pCatAdd = pProvData->pPDSip->psSipSubjectInfo->psCatMember;
|
|
|
|
if ((pCatAdd) && (pCatAdd->pMember) && (pCatAdd->pMember->pIndirectData))
|
|
{
|
|
if (!(pProvData->pPDSip->psIndirectData =
|
|
(SIP_INDIRECT_DATA *)pProvData->psPfns->pfnAlloc(sizeof(SIP_INDIRECT_DATA))))
|
|
{
|
|
pProvData->dwError = GetLastError();
|
|
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = TRUST_E_SYSTEM_ERROR;
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
memcpy(pProvData->pPDSip->psIndirectData, pCatAdd->pMember->pIndirectData,
|
|
sizeof(SIP_INDIRECT_DATA));
|
|
}
|
|
}
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
DWORD _SkipOverIdentifierAndLengthOctets(const BYTE *pbDER, DWORD cbDER)
|
|
{
|
|
# define TAG_MASK 0x1f
|
|
|
|
DWORD cb;
|
|
DWORD cbLength;
|
|
const BYTE *pb = pbDER;
|
|
|
|
// Need minimum of 2 bytes
|
|
if (cbDER < 2)
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
// Skip over the identifier octet(s)
|
|
if (TAG_MASK == (*pb++ & TAG_MASK))
|
|
{
|
|
// high-tag-number form
|
|
for (cb=2; *pb++ & 0x80; cb++)
|
|
{
|
|
if (cb >= cbDER)
|
|
{
|
|
return(0);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// low-tag-number form
|
|
cb = 1;
|
|
}
|
|
|
|
// need at least one more byte for length
|
|
if (cb >= cbDER)
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
if (0x80 == *pb)
|
|
{
|
|
// Indefinite
|
|
cb++;
|
|
}
|
|
else if ((cbLength = *pb) & 0x80)
|
|
{
|
|
cbLength &= ~0x80; // low 7 bits have number of bytes
|
|
cb += cbLength + 1;
|
|
|
|
if (cb > cbDER)
|
|
{
|
|
return(0);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
cb++;
|
|
}
|
|
|
|
return(cb);
|
|
}
|
|
|
|
|
|
BOOL _NoContentWrap(const BYTE *pbDER, DWORD cbDER)
|
|
{
|
|
DWORD cb;
|
|
|
|
cb = _SkipOverIdentifierAndLengthOctets(pbDER, cbDER);
|
|
if ((cb > 0) && (cb < cbDER) && (pbDER[cb] == 0x02))
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
|