Leaked source code of windows server 2003
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.

374 lines
10 KiB

  1. #ifndef certvfy_inc
  2. #define certvfy_inc
  3. #include <wintrust.h>
  4. #define WIN_CERT_TYPE_STACK_DLL_SIGNATURE WIN_CERT_TYPE_TS_STACK_SIGNED
  5. typedef struct _DIGEST_PARA {
  6. HCRYPTHASH hHash;
  7. } DIGEST_PARA, *PDIGEST_PARA;
  8. /*****************************************************************************
  9. *
  10. * DigestFile
  11. *
  12. * Callback function for ImageGetDigestStream
  13. *
  14. * ENTRY:
  15. * hDigest (input)
  16. * Digest handle - pointer to a DIGEST_PARA structure
  17. * pb (input)
  18. * Pointer to a buffer of data to hash
  19. * cb (input)
  20. * Number of bytes in the buffer of data pointed to by pb
  21. *
  22. * EXIT:
  23. * TRUE - no error
  24. * FALSE - use GetLastError() to obtain error information
  25. *
  26. ****************************************************************************/
  27. static
  28. BOOL
  29. WINAPI
  30. DigestFile(
  31. DIGEST_HANDLE hDigest,
  32. PBYTE pb,
  33. DWORD cb
  34. )
  35. {
  36. PDIGEST_PARA pdp = (PDIGEST_PARA)hDigest;
  37. if (pb == (PBYTE)-1) {
  38. return( TRUE );
  39. } else {
  40. return( CryptHashData(pdp->hHash, pb, cb, 0) );
  41. }
  42. }
  43. /*****************************************************************************
  44. *
  45. * OpenImageFile
  46. *
  47. * Return a handle to the opened PE image file
  48. *
  49. * ENTRY:
  50. * wszFile (input)
  51. * Path of file to open
  52. * dwAccess (input)
  53. * Desired access
  54. *
  55. * EXIT:
  56. * INVALID_HANDLE_VALUE - File cannot be opened for the desired access
  57. *
  58. ****************************************************************************/
  59. static
  60. HANDLE
  61. OpenImageFile(
  62. LPCWSTR wszFile,
  63. DWORD dwAccess
  64. )
  65. {
  66. HANDLE hFile;
  67. if (wszFile) {
  68. hFile = CreateFile(
  69. wszFile,
  70. dwAccess,
  71. FILE_SHARE_READ,
  72. NULL,
  73. OPEN_EXISTING,
  74. FILE_ATTRIBUTE_NORMAL,
  75. NULL
  76. );
  77. return hFile;
  78. } else {
  79. return INVALID_HANDLE_VALUE;
  80. }
  81. }
  82. ///////////////////////////////////////////////////////////////////////
  83. //
  84. // Verify Code, Data, and Resources of a PE image file
  85. //
  86. ///////////////////////////////////////////////////////////////////////
  87. static
  88. BOOL
  89. VerifyFile(
  90. LPWSTR wszFile,
  91. PRTL_CRITICAL_SECTION VfyLock
  92. )
  93. {
  94. HCRYPTPROV hProv;
  95. HCRYPTKEY hSigPublicKey = 0;
  96. BOOL fResult = FALSE; // preset ERROR case
  97. HANDLE hFile;
  98. DWORD dwErr = ERROR_SUCCESS;
  99. DWORD dwSignatureLen;
  100. DWORD dwCert;
  101. DWORD cCert;
  102. DWORD dwCertIndex;
  103. DIGEST_PARA dp;
  104. LPWIN_CERTIFICATE pCertHdr;
  105. WIN_CERTIFICATE Hdr;
  106. if ( (hFile = OpenImageFile(
  107. wszFile,
  108. GENERIC_READ )) == INVALID_HANDLE_VALUE ) {
  109. #ifdef SIGN_DEBUG
  110. SIGN_DBGP( ("Error %x during OpenImageFile\n", GetLastError()) );
  111. #endif
  112. #ifdef SIGN_DEBUG_WINSTA
  113. TRACE((hTrace,TC_ICASRV,TT_API1,
  114. "Error %x during OpenImageFile\n", GetLastError()) );
  115. #endif
  116. goto OpenImageFileError;
  117. }
  118. RtlEnterCriticalSection( VfyLock );
  119. if (!CryptAcquireContext(
  120. &hProv,
  121. NULL,
  122. MS_DEF_PROV,
  123. PROV_RSA_FULL,
  124. CRYPT_VERIFYCONTEXT)) {
  125. #ifdef SIGN_DEBUG
  126. SIGN_DBGP( ("Error %x during CryptAcquireContext\n", GetLastError()) );
  127. #endif
  128. #ifdef SIGN_DEBUG_WINSTA
  129. TRACE((hTrace,TC_ICASRV,TT_API1, "Error %x during CryptAcquireContext\n",GetLastError()) );
  130. #endif
  131. RtlLeaveCriticalSection( VfyLock );
  132. goto CryptAcquireContextError;
  133. }
  134. RtlLeaveCriticalSection( VfyLock );
  135. memset( &dp, 0, sizeof(dp));
  136. if (!CryptCreateHash(
  137. hProv,
  138. CALG_MD5,
  139. 0,
  140. 0,
  141. &dp.hHash)) {
  142. #ifdef SIGN_DEBUG
  143. SIGN_DBGP( ("Error %x during CryptCreateHash\n", GetLastError()) );
  144. #endif
  145. #ifdef SIGN_DEBUG_WINSTA
  146. TRACE((hTrace,TC_ICASRV,TT_API1,
  147. "Error %x during CryptCreateHash\n", GetLastError()) );
  148. #endif
  149. goto CryptCreateHashError;
  150. }
  151. if (!ImageGetDigestStream(
  152. hFile,
  153. 0,
  154. DigestFile,
  155. (DIGEST_HANDLE)&dp)) {
  156. #ifdef SIGN_DEBUG
  157. SIGN_DBGP( ("Error %x during ImageGetDigestStream\n", GetLastError()) );
  158. #endif
  159. #ifdef SIGN_DEBUG_WINSTA
  160. TRACE((hTrace,TC_ICASRV,TT_API1,
  161. "Error %x during ImageGetDigestStream\n", GetLastError()) );
  162. #endif
  163. goto ImageGetDigestStreamError;
  164. }
  165. cCert = 0;
  166. if (!ImageEnumerateCertificates(
  167. hFile,
  168. WIN_CERT_TYPE_STACK_DLL_SIGNATURE,
  169. &cCert,
  170. &dwCertIndex,
  171. 1 // IndexCount
  172. )) {
  173. #ifdef SIGN_DEBUG
  174. SIGN_DBGP( ("Error %x during ImageEnumerateCertificates\n",
  175. GetLastError()) );
  176. #endif
  177. #ifdef SIGN_DEBUG_WINSTA
  178. TRACE((hTrace,TC_ICASRV,TT_API1,
  179. "Error %x during ImageEnumerateCertificates\n",GetLastError()) );
  180. #endif
  181. goto ImageEnumerateCertificatesError;
  182. }
  183. if (cCert == 0) {
  184. #ifdef SIGN_DEBUG
  185. SIGN_DBGP( ("Error there were no Certificates of type %x found\n",
  186. WIN_CERT_TYPE_STACK_DLL_SIGNATURE) );
  187. #endif
  188. #ifdef SIGN_DEBUG_WINSTA
  189. TRACE((hTrace,TC_ICASRV,TT_API1,
  190. "Error there were no Certificates of type %x found\n",
  191. WIN_CERT_TYPE_STACK_DLL_SIGNATURE) );
  192. #endif
  193. goto ImageEnumerateCertificatesError;
  194. }
  195. // Determine size of Certificate.
  196. if(!ImageGetCertificateHeader(
  197. hFile,
  198. dwCertIndex,
  199. &Hdr)) {
  200. #ifdef SIGN_DEBUG
  201. SIGN_DBGP( ("Error %x during ImageGetCertificateHeader!\n",
  202. GetLastError()) );
  203. #endif
  204. #ifdef SIGN_DEBUG_WINSTA
  205. TRACE((hTrace,TC_ICASRV,TT_API1,
  206. "Error %x during ImageGetCertificateHeader!\n",
  207. GetLastError()) );
  208. #endif
  209. goto ImageGetCertificateHeaderError;
  210. }
  211. dwCert = Hdr.dwLength;
  212. dwSignatureLen = dwCert - offsetof( WIN_CERTIFICATE, bCertificate );
  213. #ifdef SIGN_DEBUG
  214. SIGN_DBGP( ("Signature length = %d\n", dwSignatureLen) );
  215. #endif
  216. #ifdef SIGN_DEBUG_WINSTA
  217. TRACE((hTrace,TC_ICASRV,TT_API1,
  218. "Signature length = %d\n", dwSignatureLen) );
  219. #endif
  220. if (NULL == (pCertHdr = (LPWIN_CERTIFICATE) MemAlloc(dwCert))) {
  221. #ifdef SIGN_DEBUG
  222. SIGN_DBGP( ("Out of memory Cert!\n") );
  223. #endif
  224. #ifdef SIGN_DEBUG_WINSTA
  225. TRACE((hTrace,TC_ICASRV,TT_API1, "Out of memory Cert!\n") );
  226. #endif
  227. goto CertAllocError;
  228. }
  229. #ifdef SIGN_DEBUG
  230. SIGN_DBGP( ("Requested Cert size = %d\n", dwCert) );
  231. #endif
  232. #ifdef SIGN_DEBUG_WINSTA
  233. TRACE((hTrace,TC_ICASRV,TT_API1,
  234. "Requested Cert size = %d\n", dwCert) );
  235. #endif
  236. if (!ImageGetCertificateData(
  237. hFile,
  238. dwCertIndex,
  239. pCertHdr,
  240. &dwCert)) {
  241. #ifdef SIGN_DEBUG
  242. SIGN_DBGP( ("Error %x during ImageGetCertificate\n", GetLastError()) );
  243. #endif
  244. #ifdef SIGN_DEBUG_WINSTA
  245. TRACE((hTrace,TC_ICASRV,TT_API1,
  246. "Error %x during ImageGetCertificate\n", GetLastError()) );
  247. #endif
  248. goto ImageGetCertificateError;
  249. }
  250. #ifdef SIGN_DEBUG
  251. SIGN_DBGP( ("Returned Cert size = %d\n", dwCert) );
  252. #endif
  253. #ifdef SIGN_DEBUG_WINSTA
  254. TRACE((hTrace,TC_ICASRV,TT_API1,
  255. "Returned Cert size = %d\n", dwCert) );
  256. #endif
  257. if (!CryptImportKey(
  258. hProv,
  259. PublicKeySigBlob, // from #include "../inc/keyblobs.h"
  260. sizeof( PublicKeySigBlob ),
  261. 0,
  262. 0,
  263. &hSigPublicKey)) {
  264. #ifdef SIGN_DEBUG
  265. SIGN_DBGP( ("Error %x during CryptImportKey!\n", GetLastError()) );
  266. #endif
  267. #ifdef SIGN_DEBUG_WINSTA
  268. TRACE((hTrace,TC_ICASRV,TT_API1,
  269. "Error %x during CryptImportKey!\n", GetLastError()) );
  270. #endif
  271. goto CryptGetUserKeyError;
  272. }
  273. #ifdef SIGN_DEBUG
  274. SIGN_DBGP( ("Signature (from Certificate):\n") );
  275. {
  276. unsigned int cnt=0;
  277. while ( cnt < dwSignatureLen ) {
  278. int i;
  279. for ( i=0; (i < 16) && (cnt < dwSignatureLen); cnt++,i++) {
  280. SIGN_DBGP( ("%02x ", pCertHdr->bCertificate[cnt]) );
  281. }
  282. SIGN_DBGP( ("\n") );
  283. }
  284. }
  285. #endif
  286. #ifdef SIGN_DEBUG_WINSTA
  287. TRACE((hTrace,TC_ICASRV,TT_API1, "Signature (from Certificate):\n") );
  288. {
  289. unsigned int cnt=0;
  290. while ( cnt < dwSignatureLen ) {
  291. int i;
  292. for ( i=0; (i < 16) && (cnt < dwSignatureLen); cnt++,i++) {
  293. TRACE((hTrace,TC_ICASRV,TT_API1, "%02x ",
  294. pCertHdr->bCertificate[cnt]) );
  295. }
  296. TRACE((hTrace,TC_ICASRV,TT_API1, "\n"));
  297. }
  298. }
  299. #endif
  300. // Verify signature.
  301. if(!CryptVerifySignature(
  302. dp.hHash,
  303. &pCertHdr->bCertificate[0],
  304. dwSignatureLen,
  305. hSigPublicKey,
  306. NULL,
  307. 0)) {
  308. if(GetLastError() == NTE_BAD_SIGNATURE) {
  309. #ifdef SIGN_DEBUG
  310. SIGN_DBGP( ("Signature did not match!\n") );
  311. #endif
  312. #ifdef SIGN_DEBUG_WINSTA
  313. TRACE((hTrace,TC_ICASRV,TT_API1,"Signature did not match!\n") );
  314. #endif
  315. } else {
  316. #ifdef SIGN_DEBUG
  317. SIGN_DBGP( ("Error %x during CryptVerifySignature!\n",
  318. GetLastError()) );
  319. #endif
  320. #ifdef SIGN_DEBUG_WINSTA
  321. TRACE((hTrace,TC_ICASRV,TT_API1,
  322. "Error %x during CryptVerifySignature!\n", GetLastError()) );
  323. #endif
  324. }
  325. goto CryptVerifySignatureError;
  326. }
  327. fResult = TRUE;
  328. CryptVerifySignatureError:
  329. CryptDestroyKey(hSigPublicKey);
  330. CryptGetUserKeyError:
  331. ImageGetCertificateError:
  332. MemFree( pCertHdr );
  333. CertAllocError:
  334. ImageGetCertificateHeaderError:
  335. ImageEnumerateCertificatesError:
  336. ImageGetDigestStreamError:
  337. CryptDestroyHash( dp.hHash );
  338. CryptCreateHashError:
  339. dwErr = GetLastError();
  340. CryptReleaseContext( hProv, 0 );
  341. SetLastError( dwErr );
  342. CryptAcquireContextError:
  343. CloseHandle( hFile );
  344. OpenImageFileError:
  345. return fResult;
  346. }
  347. #endif // certvfy_inc