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.

508 lines
14 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1995 - 1999
  6. //
  7. // File: makectl.cpp
  8. //
  9. // Contents: Make a CTL
  10. //
  11. // See Usage() for list of options.
  12. //
  13. //
  14. // Functions: wmain
  15. //
  16. // History: 17-June-97 xiaohs created
  17. //
  18. //--------------------------------------------------------------------------
  19. #include <windows.h>
  20. #include <assert.h>
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include <string.h>
  24. #include <memory.h>
  25. #include <unicode.h>
  26. #include <wchar.h>
  27. #include "wincrypt.h"
  28. #include "mssip.h"
  29. #include "softpub.h"
  30. #include "resource.h"
  31. #include "toolutl.h"
  32. #include "cryptui.h" //the UI version of the tool
  33. //--------------------------------------------------------------------------
  34. //
  35. // Global Data
  36. //
  37. //----------------------------------------------------------------------------
  38. HMODULE hModule=NULL;
  39. BYTE **g_rgpHash=NULL;
  40. DWORD *g_rgcbHash=NULL;
  41. DWORD g_dwCount=0;
  42. DWORD g_dwMsgAndCertEncodingType=CRYPT_ASN_ENCODING | PKCS_7_ASN_ENCODING;
  43. DWORD g_dwCertEncodingType=CRYPT_ASN_ENCODING;
  44. //---------------------------------------------------------------------------
  45. // Get the hModule hanlder and init two DLLMain.
  46. //
  47. //---------------------------------------------------------------------------
  48. BOOL InitModule()
  49. {
  50. if(!(hModule=GetModuleHandle(NULL)))
  51. return FALSE;
  52. return TRUE;
  53. }
  54. static void Usage(void)
  55. {
  56. IDSwprintf(hModule, IDS_SYNTAX);
  57. IDSwprintf(hModule, IDS_SYNTAX1);
  58. IDSwprintf(hModule, IDS_OPTIONS);
  59. IDSwprintf(hModule, IDS_OPTION_U_DESC);
  60. IDSwprintf(hModule, IDS_OPTION_U_DESC1);
  61. IDSwprintf(hModule, IDS_OPTION_U_DESC2);
  62. IDSwprintf(hModule,IDS_OPTION_S_DESC);
  63. IDSwprintf(hModule,IDS_OPTION_R_DESC);
  64. IDS_IDS_IDS_IDSwprintf(hModule,IDS_OPTION_MORE_VALUE,IDS_R_CU,IDS_R_LM,IDS_R_CU);
  65. }
  66. //----------------------------------------------------------------------------
  67. //
  68. //Build the CTL_INFO struct and encode/sign it with no signer info
  69. //----------------------------------------------------------------------------
  70. HRESULT BuildAndEncodeCTL(DWORD dwMsgEncodingType, LPSTR szOid, DWORD dwCount, BYTE **rgpHash,
  71. DWORD *rgcbHash, BYTE **ppbEncodedCTL, DWORD *pcbEncodedCTL)
  72. {
  73. HRESULT hr=E_FAIL;
  74. CMSG_SIGNED_ENCODE_INFO sSignInfo;
  75. CTL_INFO CTLInfo;
  76. DWORD dwIndex=0;
  77. if(dwCount==0 || !rgpHash || !ppbEncodedCTL || !pcbEncodedCTL)
  78. return E_INVALIDARG;
  79. //init
  80. *ppbEncodedCTL=NULL;
  81. *pcbEncodedCTL=0;
  82. memset(&sSignInfo, 0, sizeof(CMSG_SIGNED_ENCODE_INFO));
  83. sSignInfo.cbSize = sizeof(CMSG_SIGNED_ENCODE_INFO);
  84. memset(&CTLInfo, 0, sizeof(CTL_INFO));
  85. //set up CTL
  86. CTLInfo.dwVersion=CTL_V1;
  87. CTLInfo.SubjectUsage.cUsageIdentifier = 1;
  88. CTLInfo.SubjectUsage.rgpszUsageIdentifier = (LPSTR *)&szOid;
  89. GetSystemTimeAsFileTime(&(CTLInfo.ThisUpdate));
  90. CTLInfo.SubjectAlgorithm.pszObjId=szOID_OIWSEC_sha1;
  91. CTLInfo.cCTLEntry=dwCount;
  92. CTLInfo.rgCTLEntry=(CTL_ENTRY *)ToolUtlAlloc(sizeof(CTL_ENTRY)*dwCount);
  93. if(!(CTLInfo.rgCTLEntry))
  94. {
  95. hr=E_OUTOFMEMORY;
  96. goto CLEANUP;
  97. }
  98. //memset
  99. memset(CTLInfo.rgCTLEntry, 0, sizeof(CTL_ENTRY)*dwCount);
  100. for(dwIndex=0; dwIndex<dwCount; dwIndex++)
  101. {
  102. CTLInfo.rgCTLEntry[dwIndex].SubjectIdentifier.cbData=rgcbHash[dwIndex];
  103. CTLInfo.rgCTLEntry[dwIndex].SubjectIdentifier.pbData=rgpHash[dwIndex];
  104. }
  105. //encode and sign the CTL
  106. if(!CryptMsgEncodeAndSignCTL(dwMsgEncodingType,
  107. &CTLInfo,
  108. &sSignInfo,
  109. 0,
  110. NULL,
  111. pcbEncodedCTL))
  112. {
  113. hr=HRESULT_FROM_WIN32(GetLastError());
  114. goto CLEANUP;
  115. }
  116. //memory allocation
  117. *ppbEncodedCTL=(BYTE *)ToolUtlAlloc(*pcbEncodedCTL);
  118. if(!(*ppbEncodedCTL))
  119. {
  120. hr=E_OUTOFMEMORY;
  121. goto CLEANUP;
  122. }
  123. if(!CryptMsgEncodeAndSignCTL(dwMsgEncodingType,
  124. &CTLInfo,
  125. &sSignInfo,
  126. 0,
  127. *ppbEncodedCTL,
  128. pcbEncodedCTL))
  129. {
  130. hr=HRESULT_FROM_WIN32(GetLastError());
  131. goto CLEANUP;
  132. }
  133. hr=S_OK;
  134. CLEANUP:
  135. if(hr!=S_OK)
  136. {
  137. if(*ppbEncodedCTL)
  138. {
  139. ToolUtlFree(*ppbEncodedCTL);
  140. *ppbEncodedCTL=NULL;
  141. }
  142. *pcbEncodedCTL=0;
  143. }
  144. if(CTLInfo.rgCTLEntry)
  145. ToolUtlFree(CTLInfo.rgCTLEntry);
  146. return hr;
  147. }
  148. //----------------------------------------------------------------------------
  149. //
  150. //Get the hash of the certificates from the store
  151. //----------------------------------------------------------------------------
  152. HRESULT GetCertFromStore(LPWSTR wszStoreName, BOOL fSystemStore, DWORD dwStoreFlag)
  153. {
  154. HCERTSTORE hStore=NULL;
  155. HRESULT hr=E_FAIL;
  156. PCCERT_CONTEXT pCertContext=NULL;
  157. PCCERT_CONTEXT pCertPre=NULL;
  158. BYTE *pbData=NULL;
  159. DWORD cbData=0;
  160. void *p = NULL;
  161. //open the store
  162. if(fSystemStore)
  163. {
  164. hStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
  165. g_dwMsgAndCertEncodingType,
  166. NULL,
  167. dwStoreFlag | CERT_STORE_READONLY_FLAG,
  168. wszStoreName);
  169. }
  170. else
  171. {
  172. //Serialized Store, PKCS#7, Encoded Cert
  173. hStore=CertOpenStore(CERT_STORE_PROV_FILENAME_W,
  174. g_dwMsgAndCertEncodingType,
  175. NULL,
  176. 0,
  177. wszStoreName);
  178. }
  179. if(!hStore)
  180. {
  181. hr=GetLastError();
  182. IDSwprintf(hModule, IDS_ERR_OPEN_STORE);
  183. goto CLEANUP;
  184. }
  185. //now, we need to enum all the certs in the store
  186. while(pCertContext=CertEnumCertificatesInStore(hStore, pCertPre))
  187. {
  188. //get the SHA1 hash of the certificate
  189. if(!CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID,NULL,&cbData))
  190. {
  191. hr=GetLastError();
  192. IDSwprintf(hModule, IDS_ERR_HASH);
  193. goto CLEANUP;
  194. }
  195. pbData=(BYTE *)ToolUtlAlloc(cbData);
  196. if(!pbData)
  197. {
  198. hr=E_OUTOFMEMORY;
  199. IDSwprintf(hModule, IDS_ERR_MEMORY);
  200. goto CLEANUP;
  201. }
  202. //get the SHA1 hash of the certificate
  203. if(!CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID,pbData,&cbData))
  204. {
  205. hr=GetLastError();
  206. IDSwprintf(hModule, IDS_ERR_HASH);
  207. ToolUtlFree(pbData);
  208. goto CLEANUP;
  209. }
  210. //add to our global list
  211. g_dwCount++;
  212. //re-alloc memory
  213. p = (void *)g_rgpHash;
  214. #pragma prefast(suppress:308, "the pointer was saved above (PREfast bug 506)")
  215. g_rgpHash=(BYTE **)realloc(g_rgpHash, sizeof(BYTE *)*g_dwCount);
  216. if(!g_rgpHash)
  217. {
  218. g_rgpHash = (BYTE **)p;
  219. hr=E_OUTOFMEMORY;
  220. IDSwprintf(hModule, IDS_ERR_HASH);
  221. ToolUtlFree(pbData);
  222. goto CLEANUP;
  223. }
  224. p = (void *)g_rgcbHash;
  225. #pragma prefast(suppress:308, "the pointer was saved above (PREfast bug 506)")
  226. g_rgcbHash=(DWORD *)realloc(g_rgcbHash, sizeof(DWORD)*g_dwCount);
  227. if(!g_rgcbHash)
  228. {
  229. g_rgcbHash = (DWORD *)p;
  230. hr=E_OUTOFMEMORY;
  231. IDSwprintf(hModule, IDS_ERR_HASH);
  232. ToolUtlFree(pbData);
  233. goto CLEANUP;
  234. }
  235. g_rgpHash[g_dwCount-1]=pbData;
  236. g_rgcbHash[g_dwCount-1]=cbData;
  237. pCertPre=pCertContext;
  238. }
  239. hr=S_OK;
  240. CLEANUP:
  241. if(pCertContext)
  242. CertFreeCertificateContext(pCertContext);
  243. if(hStore)
  244. CertCloseStore(hStore, 0);
  245. return hr;
  246. }
  247. extern "C" int __cdecl wmain(int argc, WCHAR *wargv[])
  248. {
  249. int ReturnStatus=-1;
  250. HRESULT hr=E_FAIL;
  251. LPWSTR pwszOutputFilename=NULL;
  252. DWORD dwIndex=0;
  253. LPSTR szOid=szOID_PKIX_KP_CODE_SIGNING;
  254. BOOL fAllocated=FALSE;
  255. LPWSTR pwszOption=NULL;
  256. BYTE *pbEncodedCTL=NULL;
  257. DWORD cbEncodedCTL=0;
  258. WCHAR wszSwitch1[10];
  259. WCHAR wszSwitch2[10];
  260. BOOL fSystemstore=FALSE;
  261. LPWSTR wszStoreLocation=NULL;
  262. DWORD dwStoreFlag=CERT_SYSTEM_STORE_CURRENT_USER;
  263. //we call the UI version of the makectl if no parameters are passed into
  264. //the command line
  265. if(1==argc)
  266. {
  267. //build the CTL file without signing process
  268. //call the wizard which provides feedback
  269. if(CryptUIWizBuildCTL(CRYPTUI_WIZ_BUILDCTL_SKIP_SIGNING,
  270. NULL,
  271. NULL,
  272. NULL,
  273. NULL,
  274. NULL))
  275. return 0;
  276. else
  277. return -1;
  278. }
  279. if(argc<3)
  280. {
  281. Usage();
  282. return ReturnStatus;
  283. }
  284. if(!InitModule())
  285. goto ErrorReturn;
  286. //process the stores one at a time
  287. for (dwIndex=1; dwIndex<(DWORD)(argc-1); dwIndex++)
  288. {
  289. //see if this is the options
  290. if(IDSwcsnicmp(hModule, wargv[dwIndex], IDS_SWITCH1, 1)==0 ||
  291. IDSwcsnicmp(hModule, wargv[dwIndex], IDS_SWITCH2, 1)==0)
  292. {
  293. pwszOption=wargv[dwIndex];
  294. //get the OIDs
  295. if(IDSwcsicmp(hModule, &(pwszOption[1]),IDS_OPTION_U)==0)
  296. {
  297. dwIndex++;
  298. if(dwIndex >= (DWORD)((argc-1)))
  299. {
  300. IDSwprintf(hModule,IDS_TOO_FEW_PARAM);
  301. goto ErrorReturn;
  302. }
  303. if(!fAllocated)
  304. {
  305. if(S_OK != WSZtoSZ(wargv[dwIndex], &szOid))
  306. goto ErrorReturn;
  307. fAllocated=TRUE;
  308. }
  309. else
  310. {
  311. IDSwprintf(hModule,IDS_TOO_MANY_PARAM);
  312. goto ErrorReturn;
  313. }
  314. }
  315. //check for -s options
  316. else if(IDSwcsicmp(hModule, &(pwszOption[1]),IDS_OPTION_S)==0)
  317. {
  318. fSystemstore=TRUE;
  319. }
  320. //check for -r options
  321. else if(IDSwcsicmp(hModule, &(pwszOption[1]),IDS_OPTION_R)==0)
  322. {
  323. dwIndex++;
  324. if(dwIndex >= (DWORD)((argc-1)))
  325. {
  326. IDSwprintf(hModule,IDS_TOO_FEW_PARAM);
  327. goto ErrorReturn;
  328. }
  329. if(NULL==wszStoreLocation)
  330. {
  331. wszStoreLocation=wargv[dwIndex];
  332. if(IDSwcsicmp(hModule, wszStoreLocation, IDS_R_CU)==0)
  333. dwStoreFlag=CERT_SYSTEM_STORE_CURRENT_USER;
  334. else
  335. {
  336. if(IDSwcsicmp(hModule,wszStoreLocation, IDS_R_LM)==0)
  337. dwStoreFlag=CERT_SYSTEM_STORE_LOCAL_MACHINE;
  338. else
  339. {
  340. IDSwprintf(hModule, IDS_INVALID_R);
  341. goto ErrorReturn;
  342. }
  343. }
  344. }
  345. else
  346. {
  347. IDSwprintf(hModule,IDS_TOO_MANY_PARAM);
  348. goto ErrorReturn;
  349. }
  350. }
  351. else
  352. {
  353. //print out the Usage
  354. Usage();
  355. return ReturnStatus;
  356. }
  357. }
  358. else
  359. {
  360. //build the cert hash from the store
  361. if(S_OK !=(hr=GetCertFromStore(wargv[dwIndex], fSystemstore, dwStoreFlag)))
  362. goto ErrorReturn;
  363. //int for the next cycle
  364. fSystemstore=FALSE;
  365. wszStoreLocation=NULL;
  366. dwStoreFlag=CERT_SYSTEM_STORE_CURRENT_USER;
  367. hr=E_FAIL;
  368. }
  369. }
  370. if(0==g_dwCount)
  371. {
  372. IDSwprintf(hModule, IDS_TOO_FEW_PARAM);
  373. hr=E_FAIL;
  374. goto ErrorReturn;
  375. }
  376. //set up the CTL_INFO structure
  377. if(S_OK!=(hr=BuildAndEncodeCTL(g_dwMsgAndCertEncodingType, szOid, g_dwCount, g_rgpHash, g_rgcbHash, &pbEncodedCTL,
  378. &cbEncodedCTL)))
  379. {
  380. IDSwprintf(hModule, IDS_ERR_ENCODE_CTL);
  381. goto ErrorReturn;
  382. }
  383. //get the output file name
  384. pwszOutputFilename = wargv[argc-1];
  385. if(S_OK!=(hr=OpenAndWriteToFile(pwszOutputFilename, pbEncodedCTL, cbEncodedCTL)))
  386. {
  387. IDSwprintf(hModule, IDS_ERR_SAVE_CTL);
  388. goto ErrorReturn;
  389. }
  390. //mark succeed
  391. ReturnStatus = 0;
  392. hr=S_OK;
  393. IDSwprintf(hModule, IDS_SUCCEEDED);
  394. goto CommonReturn;
  395. ErrorReturn:
  396. ReturnStatus = -1;
  397. //print out an error msg
  398. IDSwprintf(hModule, IDS_FAILED,hr,hr);
  399. CommonReturn:
  400. if(g_rgpHash)
  401. {
  402. for(dwIndex=0; dwIndex<g_dwCount; dwIndex++)
  403. ToolUtlFree(g_rgpHash[dwIndex]);
  404. ToolUtlFree(g_rgpHash);
  405. }
  406. if(fAllocated)
  407. ToolUtlFree(szOid);
  408. if(g_rgcbHash)
  409. ToolUtlFree(g_rgcbHash);
  410. if(pbEncodedCTL)
  411. ToolUtlFree(pbEncodedCTL);
  412. return ReturnStatus;
  413. }