Source code of Windows XP (NT5)
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.

272 lines
6.6 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1996 - 1999
  6. //
  7. // File: SIPObjPE.cpp
  8. //
  9. // Contents: Microsoft SIP Provider
  10. //
  11. // History: 15-Feb-1997 pberkman created
  12. //
  13. //--------------------------------------------------------------------------
  14. #include "global.hxx"
  15. #include "sipobjpe.hxx"
  16. ////////////////////////////////////////////////////////////////////////////
  17. //
  18. // construct/destruct:
  19. //
  20. SIPObjectPE_::SIPObjectPE_(DWORD id) : SIPObject_(id)
  21. {
  22. this->fUseFileMap = FALSE;
  23. }
  24. ////////////////////////////////////////////////////////////////////////////
  25. //
  26. // public:
  27. //
  28. BOOL SIPObjectPE_::RemoveSignedDataMsg(SIP_SUBJECTINFO *pSI,DWORD dwIdx)
  29. {
  30. if (this->FileHandleFromSubject(pSI, GENERIC_READ | GENERIC_WRITE))
  31. {
  32. return(ImageRemoveCertificate(this->hFile, dwIdx));
  33. }
  34. return(FALSE);
  35. }
  36. BOOL SIPObjectPE_::CreateIndirectData(SIP_SUBJECTINFO *pSI,DWORD *pdwDLen,
  37. SIP_INDIRECT_DATA *psData)
  38. {
  39. SPC_LINK PeLink;
  40. BOOL fRet;
  41. memset(&PeInfo,0x00,sizeof(SPC_PE_IMAGE_DATA));
  42. PeLink.dwLinkChoice = SPC_FILE_LINK_CHOICE;
  43. PeLink.pwszFile = OBSOLETE_TEXT_W;
  44. PeInfo.pFile = &PeLink;
  45. this->AllocateAndFillCryptBitBlob(&PeInfo.Flags,pSI->dwFlags,5);
  46. fRet = SIPObject_::CreateIndirectData(pSI, pdwDLen, psData);
  47. this->DestroyCryptBitBlob(&PeInfo.Flags);
  48. return(fRet);
  49. }
  50. BOOL SIPObjectPE_::VerifyIndirectData(SIP_SUBJECTINFO *pSI,
  51. SIP_INDIRECT_DATA *psData)
  52. {
  53. SPC_PE_IMAGE_DATA *pPeInfo;
  54. DWORD cbPeInfo;
  55. BOOL fRet;
  56. pPeInfo = NULL;
  57. if (!(psData))
  58. {
  59. if (this->FileHandleFromSubject(pSI)) // if the file exists, set bad parameter!
  60. {
  61. goto InvalidParameter;
  62. }
  63. goto FileOpenFailed;
  64. }
  65. if (!(this->FileHandleFromSubject(pSI)))
  66. {
  67. goto FileOpenFailed;
  68. }
  69. if (!(TrustDecode(WVT_MODID_MSSIP, (BYTE **)&pPeInfo, &cbPeInfo, 201,
  70. PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, this->GetDataOIDHint(),
  71. psData->Data.Value.pbData, psData->Data.Value.cbData,
  72. CRYPT_DECODE_NOCOPY_FLAG)))
  73. {
  74. goto DecodeError;
  75. }
  76. if (uCertVersion < WIN_CERT_REVISION_2_0)
  77. {
  78. //
  79. // We are looking at a PE that was signed PRIOR to this version.
  80. // We need to:
  81. // 1. if there is "extra" bits at the end (e.g.: InstallShield),
  82. // FAIL!
  83. // 2. if there is no "extra" bits, go through the old
  84. // ImageHelper function to digest. (e.g.: set the version
  85. // flag.)
  86. //
  87. if (!(imagehack_IsImagePEOnly(this->hFile)))
  88. {
  89. goto BadDigest;
  90. }
  91. }
  92. pSI->dwFlags = this->CryptBitBlobToFlags(&pPeInfo->Flags);
  93. fRet = SIPObject_::VerifyIndirectData(pSI, psData);
  94. CommonReturn:
  95. if (pPeInfo)
  96. {
  97. TrustFreeDecode(WVT_MODID_MSSIP, (BYTE **)&pPeInfo);
  98. }
  99. return(fRet);
  100. ErrorReturn:
  101. fRet = FALSE;
  102. goto CommonReturn;
  103. TRACE_ERROR_EX(DBG_SS, FileOpenFailed);
  104. TRACE_ERROR_EX(DBG_SS, DecodeError);
  105. SET_ERROR_VAR_EX(DBG_SS, BadDigest, TRUST_E_BAD_DIGEST);
  106. SET_ERROR_VAR_EX(DBG_SS, InvalidParameter, ERROR_INVALID_PARAMETER);
  107. }
  108. ////////////////////////////////////////////////////////////////////////////
  109. //
  110. // protected:
  111. //
  112. BOOL SIPObjectPE_::PutMessageInFile(SIP_SUBJECTINFO *pSI,
  113. WIN_CERTIFICATE *pWinCert,DWORD *pdwIndex)
  114. {
  115. if (fSizeFileOnly)
  116. {
  117. goto FileResizedError;
  118. }
  119. //
  120. // check to see if we are going to align the file
  121. //
  122. DWORD cbFSize;
  123. DWORD cbCheck;
  124. BOOL fRet;
  125. cbFSize = GetFileSize(this->hFile, NULL);
  126. cbCheck = (cbFSize + 7) & ~7;
  127. cbCheck -= cbFSize;
  128. fRet = ImageAddCertificate(this->hFile, pWinCert, pdwIndex);
  129. if ((fRet) && (cbCheck > 0))
  130. {
  131. //
  132. // we aligned the file, make sure we null out the padding!
  133. //
  134. if (SetFilePointer(this->hFile, cbFSize, NULL, FILE_BEGIN) == 0xFFFFFFFF)
  135. {
  136. goto SetFileError;
  137. }
  138. BYTE buf[8];
  139. DWORD cbWritten;
  140. memset(&buf[0], 0x00, cbCheck);
  141. if (!(WriteFile(this->hFile, &buf[0], cbCheck, &cbWritten, NULL)) || (cbWritten != cbCheck))
  142. {
  143. goto WriteFileError;
  144. }
  145. }
  146. CommonReturn:
  147. return(fRet);
  148. ErrorReturn:
  149. fRet = FALSE;
  150. goto CommonReturn;
  151. TRACE_ERROR_EX(DBG_SS, WriteFileError);
  152. TRACE_ERROR_EX(DBG_SS, SetFileError);
  153. SET_ERROR_VAR_EX(DBG_SS, FileResizedError, CRYPT_E_FILERESIZED);
  154. }
  155. BOOL SIPObjectPE_::GetDigestStream(DIGEST_DATA *pDigestData,
  156. DIGEST_FUNCTION pfnCallBack, DWORD dwFlags)
  157. {
  158. //
  159. // Check the version flag here. We will have set this based
  160. // on which version of the image helper function we want to
  161. // call.
  162. //
  163. if (uCertVersion < WIN_CERT_REVISION_2_0)
  164. {
  165. return(ImageGetDigestStream( this->hFile,
  166. dwFlags,
  167. pfnCallBack,
  168. pDigestData));
  169. }
  170. BOOL fRet;
  171. DWORD dwDiskLength;
  172. fRet = imagehack_AuImageGetDigestStream( this->hFile,
  173. dwFlags,
  174. pfnCallBack,
  175. pDigestData);
  176. dwDiskLength = GetFileSize(this->hFile, NULL);
  177. dwDiskLength = (dwDiskLength + 7) & ~7; // padding before the certs?
  178. dwDiskLength -= GetFileSize(this->hFile, NULL);
  179. if ((fRet) && (dwDiskLength > 0))
  180. {
  181. BYTE *pb;
  182. if (!(pb = (BYTE *)this->SIPNew(dwDiskLength)))
  183. {
  184. return(FALSE);
  185. }
  186. memset(pb, 0x00, dwDiskLength); // imagehlp put nulls before the signature!
  187. fRet = (*pfnCallBack)(pDigestData, pb, dwDiskLength);
  188. delete pb;
  189. }
  190. return(fRet);
  191. }
  192. DWORD SIPObjectPE_::ConvertSPCFlags(DWORD InFlags)
  193. {
  194. DWORD ret;
  195. ret = 0;
  196. if (InFlags & SPC_INC_PE_RESOURCES_FLAG)
  197. {
  198. ret |= CERT_PE_IMAGE_DIGEST_RESOURCES;
  199. }
  200. if (InFlags & SPC_INC_PE_DEBUG_INFO_FLAG)
  201. {
  202. ret |= CERT_PE_IMAGE_DIGEST_DEBUG_INFO;
  203. }
  204. if (InFlags & SPC_INC_PE_IMPORT_ADDR_TABLE_FLAG)
  205. {
  206. ret |= CERT_PE_IMAGE_DIGEST_ALL_IMPORT_INFO;
  207. }
  208. return(ret);
  209. }