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

273 lines
6.6 KiB
C++

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1996 - 1999
//
// File: SIPObjPE.cpp
//
// Contents: Microsoft SIP Provider
//
// History: 15-Feb-1997 pberkman created
//
//--------------------------------------------------------------------------
#include "global.hxx"
#include "sipobjpe.hxx"
////////////////////////////////////////////////////////////////////////////
//
// construct/destruct:
//
SIPObjectPE_::SIPObjectPE_(DWORD id) : SIPObject_(id)
{
this->fUseFileMap = FALSE;
}
////////////////////////////////////////////////////////////////////////////
//
// public:
//
BOOL SIPObjectPE_::RemoveSignedDataMsg(SIP_SUBJECTINFO *pSI,DWORD dwIdx)
{
if (this->FileHandleFromSubject(pSI, GENERIC_READ | GENERIC_WRITE))
{
return(ImageRemoveCertificate(this->hFile, dwIdx));
}
return(FALSE);
}
BOOL SIPObjectPE_::CreateIndirectData(SIP_SUBJECTINFO *pSI,DWORD *pdwDLen,
SIP_INDIRECT_DATA *psData)
{
SPC_LINK PeLink;
BOOL fRet;
memset(&PeInfo,0x00,sizeof(SPC_PE_IMAGE_DATA));
PeLink.dwLinkChoice = SPC_FILE_LINK_CHOICE;
PeLink.pwszFile = OBSOLETE_TEXT_W;
PeInfo.pFile = &PeLink;
this->AllocateAndFillCryptBitBlob(&PeInfo.Flags,pSI->dwFlags,5);
fRet = SIPObject_::CreateIndirectData(pSI, pdwDLen, psData);
this->DestroyCryptBitBlob(&PeInfo.Flags);
return(fRet);
}
BOOL SIPObjectPE_::VerifyIndirectData(SIP_SUBJECTINFO *pSI,
SIP_INDIRECT_DATA *psData)
{
SPC_PE_IMAGE_DATA *pPeInfo;
DWORD cbPeInfo;
BOOL fRet;
pPeInfo = NULL;
if (!(psData))
{
if (this->FileHandleFromSubject(pSI)) // if the file exists, set bad parameter!
{
goto InvalidParameter;
}
goto FileOpenFailed;
}
if (!(this->FileHandleFromSubject(pSI)))
{
goto FileOpenFailed;
}
if (!(TrustDecode(WVT_MODID_MSSIP, (BYTE **)&pPeInfo, &cbPeInfo, 201,
PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, this->GetDataOIDHint(),
psData->Data.Value.pbData, psData->Data.Value.cbData,
CRYPT_DECODE_NOCOPY_FLAG)))
{
goto DecodeError;
}
if (uCertVersion < WIN_CERT_REVISION_2_0)
{
//
// We are looking at a PE that was signed PRIOR to this version.
// We need to:
// 1. if there is "extra" bits at the end (e.g.: InstallShield),
// FAIL!
// 2. if there is no "extra" bits, go through the old
// ImageHelper function to digest. (e.g.: set the version
// flag.)
//
if (!(imagehack_IsImagePEOnly(this->hFile)))
{
goto BadDigest;
}
}
pSI->dwFlags = this->CryptBitBlobToFlags(&pPeInfo->Flags);
fRet = SIPObject_::VerifyIndirectData(pSI, psData);
CommonReturn:
if (pPeInfo)
{
TrustFreeDecode(WVT_MODID_MSSIP, (BYTE **)&pPeInfo);
}
return(fRet);
ErrorReturn:
fRet = FALSE;
goto CommonReturn;
TRACE_ERROR_EX(DBG_SS, FileOpenFailed);
TRACE_ERROR_EX(DBG_SS, DecodeError);
SET_ERROR_VAR_EX(DBG_SS, BadDigest, TRUST_E_BAD_DIGEST);
SET_ERROR_VAR_EX(DBG_SS, InvalidParameter, ERROR_INVALID_PARAMETER);
}
////////////////////////////////////////////////////////////////////////////
//
// protected:
//
BOOL SIPObjectPE_::PutMessageInFile(SIP_SUBJECTINFO *pSI,
WIN_CERTIFICATE *pWinCert,DWORD *pdwIndex)
{
if (fSizeFileOnly)
{
goto FileResizedError;
}
//
// check to see if we are going to align the file
//
DWORD cbFSize;
DWORD cbCheck;
BOOL fRet;
cbFSize = GetFileSize(this->hFile, NULL);
cbCheck = (cbFSize + 7) & ~7;
cbCheck -= cbFSize;
fRet = ImageAddCertificate(this->hFile, pWinCert, pdwIndex);
if ((fRet) && (cbCheck > 0))
{
//
// we aligned the file, make sure we null out the padding!
//
if (SetFilePointer(this->hFile, cbFSize, NULL, FILE_BEGIN) == 0xFFFFFFFF)
{
goto SetFileError;
}
BYTE buf[8];
DWORD cbWritten;
memset(&buf[0], 0x00, cbCheck);
if (!(WriteFile(this->hFile, &buf[0], cbCheck, &cbWritten, NULL)) || (cbWritten != cbCheck))
{
goto WriteFileError;
}
}
CommonReturn:
return(fRet);
ErrorReturn:
fRet = FALSE;
goto CommonReturn;
TRACE_ERROR_EX(DBG_SS, WriteFileError);
TRACE_ERROR_EX(DBG_SS, SetFileError);
SET_ERROR_VAR_EX(DBG_SS, FileResizedError, CRYPT_E_FILERESIZED);
}
BOOL SIPObjectPE_::GetDigestStream(DIGEST_DATA *pDigestData,
DIGEST_FUNCTION pfnCallBack, DWORD dwFlags)
{
//
// Check the version flag here. We will have set this based
// on which version of the image helper function we want to
// call.
//
if (uCertVersion < WIN_CERT_REVISION_2_0)
{
return(ImageGetDigestStream( this->hFile,
dwFlags,
pfnCallBack,
pDigestData));
}
BOOL fRet;
DWORD dwDiskLength;
fRet = imagehack_AuImageGetDigestStream( this->hFile,
dwFlags,
pfnCallBack,
pDigestData);
dwDiskLength = GetFileSize(this->hFile, NULL);
dwDiskLength = (dwDiskLength + 7) & ~7; // padding before the certs?
dwDiskLength -= GetFileSize(this->hFile, NULL);
if ((fRet) && (dwDiskLength > 0))
{
BYTE *pb;
if (!(pb = (BYTE *)this->SIPNew(dwDiskLength)))
{
return(FALSE);
}
memset(pb, 0x00, dwDiskLength); // imagehlp put nulls before the signature!
fRet = (*pfnCallBack)(pDigestData, pb, dwDiskLength);
delete pb;
}
return(fRet);
}
DWORD SIPObjectPE_::ConvertSPCFlags(DWORD InFlags)
{
DWORD ret;
ret = 0;
if (InFlags & SPC_INC_PE_RESOURCES_FLAG)
{
ret |= CERT_PE_IMAGE_DIGEST_RESOURCES;
}
if (InFlags & SPC_INC_PE_DEBUG_INFO_FLAG)
{
ret |= CERT_PE_IMAGE_DIGEST_DEBUG_INFO;
}
if (InFlags & SPC_INC_PE_IMPORT_ADDR_TABLE_FLAG)
{
ret |= CERT_PE_IMAGE_DIGEST_ALL_IMPORT_INFO;
}
return(ret);
}