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.

338 lines
11 KiB

  1. #include "windows.h"
  2. #include "wincrypt.h"
  3. #include "mscat.h"
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <vector>
  7. VOID
  8. DumpBytes(PBYTE pbBuffer, DWORD dwLength)
  9. {
  10. for (DWORD dw = 0; dw < dwLength; dw++)
  11. {
  12. if ((dw % 4 == 0) && (dw != 0))
  13. ::wprintf(L" ");
  14. if ((dw % 32 == 0) && (dw != 0))
  15. ::wprintf(L"\n");
  16. ::wprintf(L"%02x", pbBuffer[dw]);
  17. }
  18. }
  19. #pragma pack(1)
  20. typedef struct _PublicKeyBlob
  21. {
  22. unsigned int SigAlgID;
  23. unsigned int HashAlgID;
  24. ULONG cbPublicKey;
  25. BYTE PublicKey[1];
  26. } PublicKeyBlob, *PPublicKeyBlob;
  27. VOID
  28. GenerateFusionStrongNameAndKeyFromCertificate(PCCERT_CONTEXT pContext)
  29. {
  30. HCRYPTPROV hProvider = NULL;
  31. HCRYPTKEY hKey = NULL;
  32. std::vector<BYTE> pbBlobData;
  33. DWORD cbBlobData = 8192;
  34. pbBlobData.resize(cbBlobData);
  35. DWORD cbFusionKeyBlob = 0;
  36. DWORD dwTemp = 0;
  37. PPublicKeyBlob pFusionKeyStruct = NULL;
  38. if (!::CryptAcquireContextW(
  39. &hProvider,
  40. NULL,
  41. NULL,
  42. PROV_RSA_FULL,
  43. CRYPT_VERIFYCONTEXT))
  44. {
  45. // NTRAID#NTBUG9 - 590964 - 2002/03/30 - mgrier - Use common error reporting function that
  46. // will format the win32 last error.
  47. ::wprintf(L"Failed opening the crypt context: 0x%08x", ::GetLastError());
  48. return;
  49. }
  50. //
  51. // Load the public key info into a key to start with
  52. //
  53. if (!::CryptImportPublicKeyInfo(
  54. hProvider,
  55. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  56. &pContext->pCertInfo->SubjectPublicKeyInfo,
  57. &hKey))
  58. {
  59. // NTRAID#NTBUG9 - 590964 - 2002/03/30 - mgrier - Use common error reporting function that
  60. // will format the win32 last error.
  61. ::wprintf(L"Failed importing public key info from the cert-context, 0x%08x", ::GetLastError());
  62. return;
  63. }
  64. //
  65. // Export the key info to a public-key blob
  66. //
  67. if (!::CryptExportKey(
  68. hKey,
  69. NULL,
  70. PUBLICKEYBLOB,
  71. 0,
  72. &pbBlobData[0],
  73. &cbBlobData))
  74. {
  75. // NTRAID#NTBUG9 - 590964 - 2002/03/30 - mgrier - Use common error reporting function that
  76. // will format the win32 last error.
  77. ::wprintf(L"Failed exporting public key info back from an hcryptkey: 0x%08x\n", ::GetLastError());
  78. return;
  79. }
  80. //
  81. // Allocate the Fusion public key blob
  82. //
  83. // NTRAID#NTBUG9 - 590964 - 2002/03/30 - mgrier - use of -1 here obscure; use offsetof instead
  84. cbFusionKeyBlob = sizeof(PublicKeyBlob) + cbBlobData - 1;
  85. pFusionKeyStruct = (PPublicKeyBlob)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbFusionKeyBlob);
  86. // NTRAID#NTBUG9 - 590964 - 2002/03/30 - mgrier - missing allocation failure check
  87. //
  88. // Key parameter for the signing algorithm
  89. //
  90. dwTemp = sizeof(pFusionKeyStruct->SigAlgID);
  91. // NTRAID#NTBUG9 - 590964 - 2002/03/30 - mgrier - missing return status check; missing
  92. // verification of dwTemp
  93. ::CryptGetKeyParam(hKey, KP_ALGID, (PBYTE)&pFusionKeyStruct->SigAlgID, &dwTemp, 0);
  94. //
  95. // Move over the public key bits from CryptExportKey
  96. //
  97. pFusionKeyStruct->cbPublicKey = cbBlobData;
  98. pFusionKeyStruct->HashAlgID = CALG_SHA1;
  99. ::memcpy(pFusionKeyStruct->PublicKey, &pbBlobData[0], cbBlobData);
  100. ::wprintf(L"\n Public key structure:\n");
  101. ::DumpBytes((PBYTE)pFusionKeyStruct, cbFusionKeyBlob);
  102. //
  103. // Now let's go hash it.
  104. //
  105. {
  106. HCRYPTHASH hKeyHash = NULL;
  107. DWORD cbHashedKeyInfo = 8192;
  108. std::vector<BYTE> bHashedKeyInfo;
  109. bHashedKeyInfo.resize(cbHashedKeyInfo);
  110. if (!::CryptCreateHash(hProvider, pFusionKeyStruct->HashAlgID, NULL, 0, &hKeyHash))
  111. {
  112. // NTRAID#NTBUG9 - 590964 - 2002/03/30 - mgrier - Use common error reporting function that
  113. // will format the win32 last error.
  114. ::wprintf(L"Failed creating a hash for this key: 0x%08x\n", ::GetLastError());
  115. return;
  116. }
  117. if (!::CryptHashData(hKeyHash, (PBYTE)pFusionKeyStruct, cbFusionKeyBlob, 0))
  118. {
  119. // NTRAID#NTBUG9 - 590964 - 2002/03/30 - mgrier - Use common error reporting function that
  120. // will format the win32 last error.
  121. ::wprintf(L"Failed hashing data: 0x%08x\n", ::GetLastError());
  122. return;
  123. }
  124. if (!::CryptGetHashParam(hKeyHash, HP_HASHVAL, &bHashedKeyInfo[0], &cbHashedKeyInfo, 0))
  125. {
  126. // NTRAID#NTBUG9 - 590964 - 2002/03/30 - mgrier - Use common error reporting function that
  127. // will format the win32 last error.
  128. ::wprintf(L"Can't get hashed key info 0x%08x\n", ::GetLastError());
  129. return;
  130. }
  131. ::CryptDestroyHash(hKeyHash);
  132. hKeyHash = NULL;
  133. ::wprintf(L"\n Hash of public key bits: ");
  134. ::DumpBytes(&bHashedKeyInfo[0], cbHashedKeyInfo);
  135. ::wprintf(L"\n Fusion-compatible strong name: ");
  136. ::DumpBytes(&bHashedKeyInfo[0] + (cbHashedKeyInfo - 8), 8);
  137. }
  138. }
  139. // NTRAID#NTBUG9 - 590964 - 2002/03/30 - mgrier - this function should be static
  140. VOID
  141. PrintKeyContextInfo(PCCERT_CONTEXT pContext)
  142. {
  143. DWORD cbHash = 0;
  144. std::vector<BYTE> bHash;
  145. const SIZE_T sizeof_bHash = 8192;
  146. bHash.resize(sizeof_bHash);
  147. DWORD cchBuffer = 8192;
  148. std::vector<WCHAR> wszBuffer;
  149. wszBuffer.resize(cchBuffer);
  150. ::wprintf(L"\n\n");
  151. // NTRAID#NTBUG9 - 590964 - 2002/03/30 - mgrier - missing error check
  152. ::CertGetNameStringW(pContext, CERT_NAME_FRIENDLY_DISPLAY_TYPE,
  153. 0, NULL, &wszBuffer[0], cchBuffer);
  154. ::wprintf(L"Certificate owner: %ls\n", &wszBuffer[0]);
  155. //
  156. // Spit out the key bits
  157. //
  158. ::wprintf(L"Found key info:\n");
  159. ::DumpBytes(
  160. pContext->pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData,
  161. pContext->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData);
  162. //
  163. // And now the "strong name" (ie: sha1 hash) of the public key bits
  164. //
  165. if (::CryptHashPublicKeyInfo(
  166. NULL,
  167. CALG_SHA1,
  168. 0,
  169. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  170. &pContext->pCertInfo->SubjectPublicKeyInfo,
  171. &bHash[0],
  172. &(cbHash = sizeof_bHash)))
  173. {
  174. ::wprintf(L"\nPublic key hash: ");
  175. ::DumpBytes(&bHash[0], cbHash);
  176. ::wprintf(L"\nStrong name is: ");
  177. ::DumpBytes(&bHash[0], cbHash < 8 ? cbHash : 8);
  178. }
  179. else
  180. {
  181. // NTRAID#NTBUG9 - 590964 - 2002/03/30 - mgrier - Use common error reporting function that
  182. // will format the win32 last error.
  183. ::wprintf(L"Unable to hash public key info: 0x%08x\n", ::GetLastError());
  184. }
  185. ::GenerateFusionStrongNameAndKeyFromCertificate(pContext);
  186. ::wprintf(L"\n\n");
  187. }
  188. int __cdecl wmain(int argc, WCHAR* argv[])
  189. {
  190. HANDLE hCatalog = NULL;
  191. HANDLE hMapping = NULL;
  192. PBYTE pByte = NULL;
  193. SIZE_T cBytes = 0;
  194. PCCTL_CONTEXT pContext = NULL;
  195. hCatalog = ::CreateFileW(argv[1], GENERIC_READ,
  196. FILE_SHARE_READ, NULL,
  197. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  198. if (hCatalog == INVALID_HANDLE_VALUE)
  199. {
  200. // NTRAID#NTBUG9 - 590964 - 2002/03/30 - mgrier - Use common error reporting function that
  201. // will format the win32 last error.
  202. ::wprintf(L"Ensure that %ls exists.\n", argv[1]);
  203. return 0;
  204. }
  205. hMapping = ::CreateFileMappingW(hCatalog, NULL, PAGE_READONLY, 0, 0, NULL);
  206. if (!hMapping || (hMapping == INVALID_HANDLE_VALUE))
  207. {
  208. ::CloseHandle(hCatalog);
  209. // NTRAID#NTBUG9 - 590964 - 2002/03/30 - mgrier - Use common error reporting function that
  210. // will format the win32 last error. Don't forget that calling CloseHandle
  211. // may have overwritten the last error
  212. ::wprintf(L"Unable to map file into address space.\n");
  213. return 1;
  214. }
  215. pByte = (PBYTE) ::MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
  216. ::CloseHandle(hMapping);
  217. hMapping = INVALID_HANDLE_VALUE;
  218. if (pByte == NULL)
  219. {
  220. // NTRAID#NTBUG9 - 590964 - 2002/03/30 - mgrier - MapViewOfFile failure cause not reported;
  221. // don't forget that above call to CloseHandle may have lost the last error
  222. ::wprintf(L"Unable to open view of file.\n");
  223. ::CloseHandle(hCatalog);
  224. return 2;
  225. }
  226. // NTRAID#NTBUG9 - 590964 - 2002/03/30 - mgrier - GetFileSize error cause not reported
  227. if (((cBytes = ::GetFileSize(hCatalog, NULL)) == -1) || (cBytes < 1))
  228. {
  229. ::wprintf(L"Bad file size %d\n", cBytes);
  230. return 3;
  231. }
  232. if (pByte[0] != 0x30)
  233. {
  234. ::wprintf(L"File is not a catalog.\n");
  235. return 4;
  236. }
  237. pContext = (PCCTL_CONTEXT) ::CertCreateCTLContext(
  238. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  239. pByte,
  240. (DWORD)cBytes);
  241. if (pContext != NULL)
  242. {
  243. BYTE bIdent[8192];
  244. DWORD cbIdent = 0;
  245. PCERT_ID cIdent = NULL;
  246. if (!::CryptMsgGetParam(
  247. pContext->hCryptMsg,
  248. CMSG_SIGNER_CERT_ID_PARAM,
  249. 0,
  250. bIdent,
  251. &(cbIdent = sizeof(bIdent))))
  252. {
  253. // NTRAID#NTBUG9 - 590964 - 2002/03/30 - mgrier - Use common error reporting function that
  254. // will format the win32 last error.
  255. ::wprintf(L"Unable to get top-level signer's certificate ID: 0x%08x\n", ::GetLastError());
  256. return 6;
  257. }
  258. cIdent = (PCERT_ID)bIdent;
  259. HCERTSTORE hStore = NULL;
  260. //
  261. // Maybe it's there in the message?
  262. //
  263. {
  264. PCCERT_CONTEXT pThisContext = NULL;
  265. hStore = ::CertOpenStore(
  266. CERT_STORE_PROV_MSG,
  267. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  268. NULL,
  269. 0,
  270. pContext->hCryptMsg);
  271. // NTRAID#NTBUG9 - 590964 - 2002/03/30 - mgrier - What does hStore == NULL indicate?
  272. // There seems to be a lack of error path handling here.
  273. if ((hStore != NULL) && (hStore != INVALID_HANDLE_VALUE))
  274. {
  275. while (pThisContext = ::CertEnumCertificatesInStore(hStore, pThisContext))
  276. {
  277. ::PrintKeyContextInfo(pThisContext);
  278. }
  279. // NTRAID#NTBUG9 - 590964 - 2002/03/30 - mgrier - CertEnumCertificatesInStore could
  280. // fail for reasons other than end-of-list.
  281. }
  282. }
  283. }
  284. else
  285. {
  286. // NTRAID#NTBUG9 - 590964 - 2002/03/30 - mgrier - Use common error reporting function that
  287. // will format the win32 last error.
  288. ::wprintf(L"Failed creating certificate context: 0x%08x\n", ::GetLastError());
  289. return 5;
  290. }
  291. }