//+------------------------------------------------------------------------- // // 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); }