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.

2069 lines
55 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1999
  5. //
  6. // File: signcode.cpp
  7. //
  8. // Contents: The signcode console tool
  9. //
  10. // History: July-1st-1997 Xiaohs Created
  11. //----------------------------------------------------------------------------
  12. #include <windows.h>
  13. #include <stdio.h>
  14. #include <malloc.h>
  15. #include <assert.h>
  16. #include <wincrypt.h>
  17. #include <signer.h>
  18. #include "mssip.h"
  19. #include "resource.h"
  20. #include "unicode.h"
  21. #include "signhlp.h"
  22. #include "pvkhlpr.h"
  23. #include "toolutl.h"
  24. #include "javaAttr.h"
  25. #include "cryptui.h"
  26. #define ACTION_SIGN 0x01
  27. #define ACTION_STAMP 0x02
  28. #define ACTION_REQUEST 0x04
  29. #define ACTION_RESPONSE 0x08
  30. #define STORE_DEFAULT_NAME_MAX 40
  31. #define SHA1_LENGTH 20
  32. // Global data for parsing the input parameters
  33. DWORD dwAction = 0;
  34. DWORD dwExpectedError = 0;
  35. BOOL fSigning = TRUE;
  36. BOOL fTesting = FALSE;
  37. BOOL fStoreTechnology=TRUE;
  38. BOOL fUndocumented = FALSE;
  39. LPWSTR pwszFile = NULL;
  40. LPWSTR pwszCapiProvider=NULL;
  41. LPWSTR pwszProviderType=NULL;
  42. LPWSTR pwszPvkFile = NULL;
  43. LPWSTR pwszKeyContainer= NULL;
  44. LPWSTR pwszOpusName = NULL;
  45. LPWSTR pwszOpusInfo = NULL;
  46. LPWSTR pwszAlgorithm = NULL;
  47. LPWSTR pwszAuthority = NULL;
  48. LPWSTR pwszSpcFile = NULL;
  49. LPWSTR pwszCertFile =NULL;
  50. LPWSTR pwszCommonName =NULL;
  51. LPWSTR pwszStoreName= NULL;
  52. LPWSTR pwszStoreLocation=NULL;
  53. LPWSTR pwszStorePolicy= NULL;
  54. LPWSTR pwszHttpTime = NULL;
  55. LPWSTR pwszRequestFile =NULL;
  56. LPWSTR pwszResponseFile =NULL;
  57. LPWSTR pwszWait=NULL;
  58. LPWSTR pwszRepeat=NULL;
  59. LPWSTR pwszKeySpec=NULL;
  60. LPWSTR pwszSignerIndex=NULL;
  61. LPWSTR pwszSha1Hash = NULL;
  62. BYTE *g_pbHash=NULL;
  63. DWORD g_cbHash=0;
  64. DWORD dwCertEncodingType=X509_ASN_ENCODING;
  65. DWORD dwStoreEncodingType=X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
  66. DWORD dwWait=0;
  67. DWORD dwRepeat=1;
  68. DWORD dwProviderType = PROV_RSA_FULL;
  69. BOOL fCommercial = FALSE;
  70. BOOL fIndividual = FALSE;
  71. DWORD dwKeySpec=0;
  72. DWORD dwSignerIndex=0;
  73. LPWSTR *prgwszDllName=NULL;
  74. LPWSTR *prgwszDllParam=NULL;
  75. DWORD dwDllIndex=0;
  76. DWORD dwParamIndex=0;
  77. //default:
  78. //Assume the store is on CERT_SYSTEM_STORE_CURRENT_USER
  79. DWORD dwStoreFlag = CERT_SYSTEM_STORE_CURRENT_USER;
  80. DWORD dwStorePolicy=SIGNER_CERT_POLICY_SPC;
  81. WCHAR wszMyStore[STORE_DEFAULT_NAME_MAX];
  82. //Use MD5 as the default hashing algorithm
  83. ALG_ID dwAlgorithmOid = CALG_MD5;
  84. //Global Data for loading the string
  85. #define OPTION_SWITCH_SIZE 5
  86. #define WSTR_LENGTH_MAX 30
  87. WCHAR wszCaption[WSTR_LENGTH_MAX];
  88. WCHAR wszNULL[WSTR_LENGTH_MAX];
  89. WCHAR wszPlus[WSTR_LENGTH_MAX];
  90. HMODULE hModule=NULL;
  91. //////////////////////////////////////////////////////////////////////////
  92. //////////////////////////////////////////////////////////////////////////
  93. // function prototypes
  94. HRESULT InitDllParameter(PCRYPT_ATTRIBUTES pAuthAttr,
  95. PCRYPT_ATTRIBUTES pUnauthAttr,
  96. PCRYPT_ATTRIBUTES *ppAuthAttr,
  97. PCRYPT_ATTRIBUTES *ppUnauthAttr);
  98. void ReleaseDllParameter(PCRYPT_ATTRIBUTES * ppAuthAttr,
  99. PCRYPT_ATTRIBUTES * ppUnauthAttr);
  100. HRESULT SetUpSubjectInfo(SIGNER_SUBJECT_INFO *pSubjectInfo,
  101. SIGNER_FILE_INFO *pFileInfo);
  102. HRESULT SetUpParameter(SIGNER_SUBJECT_INFO *pSubjectInfo,
  103. SIGNER_FILE_INFO *pFileInfo,
  104. SIGNER_SIGNATURE_INFO *pSignatureInfo,
  105. SIGNER_ATTR_AUTHCODE *pAttrAuthcode,
  106. SIGNER_PROVIDER_INFO *pProviderInfo,
  107. SIGNER_CERT_STORE_INFO *pCertStoreInfo,
  108. SIGNER_CERT *pSignerCert,
  109. CRYPT_ATTRIBUTES *pAuthenticated,
  110. CRYPT_ATTRIBUTES *pUnauthenticated,
  111. HCERTSTORE *phCertStore);
  112. PCCERT_CONTEXT GetSigningCert(HCERTSTORE *phCertStore, BOOL *pfMore);
  113. HRESULT GetCertHashFromFile(LPWSTR pwszCertFile,
  114. BYTE **pHash,
  115. DWORD *pcbHash,
  116. BOOL *pfMore);
  117. //--------------------------------------------------------------------------
  118. // Get the hModule hanlder and init two DLLMain.
  119. //
  120. //---------------------------------------------------------------------------
  121. BOOL InitModule()
  122. {
  123. if(!(hModule=GetModuleHandle(NULL)))
  124. return FALSE;
  125. return TRUE;
  126. }
  127. //--------------------------------------------------------------------------------
  128. //
  129. // Help command
  130. //--------------------------------------------------------------------------------
  131. void Usage()
  132. {
  133. IDSwprintf(hModule,IDS_SYNTAX);
  134. IDSwprintf(hModule,IDS_OPTIONS);
  135. IDSwprintf(hModule,IDS_OPTION_SPC_DESC);
  136. IDSwprintf(hModule,IDS_OPTION_V_DESC);
  137. IDSwprintf(hModule,IDS_OPTION_K_DESC);
  138. IDSwprintf(hModule,IDS_OPTION_N_DESC);
  139. IDSwprintf(hModule,IDS_OPTION_I_DESC);
  140. IDSwprintf(hModule,IDS_OPTION_P_DESC);
  141. IDSwprintf(hModule,IDS_OPTION_Y_DESC);
  142. IDSwprintf(hModule,IDS_OPTION_KY_DESC);
  143. IDS_IDS_IDSwprintf(hModule, IDS_OPTION_KY_VALUES, IDS_OPTION_KY_SIG,
  144. IDS_OPTION_KY_EXC);
  145. IDSwprintf(hModule,IDS_OPTION_AUTH_DESC);
  146. IDS_IDS_IDSwprintf(hModule,IDS_OPTION_AUTH_VALUE, IDS_AUTHORITY_ID,
  147. IDS_AUTHORITY_CM);
  148. IDS_IDSwprintf(hModule,IDS_OPTION_AUTH_VALUE1, IDS_AUTHORITY_DEFAULT);
  149. IDSwprintf(hModule,IDS_OPTION_A_DESC);
  150. IDS_IDS_IDS_IDSwprintf(hModule,IDS_OPTION_MORE_VALUE, IDS_A_MD5,
  151. IDS_A_SHA, IDS_A_MD5);
  152. IDSwprintf(hModule,IDS_OPTION_T_DESC);
  153. IDSwprintf(hModule,IDS_OPTION_TR_DESC);
  154. IDSwprintf(hModule,IDS_OPTION_TW_DESC);
  155. IDSwprintf(hModule,IDS_OPTION_J_DESC);
  156. IDSwprintf(hModule,IDS_OPTION_JP_DESC);
  157. IDSwprintf(hModule,IDS_OPTION_C_DESC);
  158. IDSwprintf(hModule,IDS_OPTION_S_DESC);
  159. IDSwprintf(hModule,IDS_OPTION_R_DESC);
  160. IDS_IDS_IDS_IDSwprintf(hModule,IDS_OPTION_MORE_VALUE, IDS_R_LM, IDS_R_CU,IDS_R_CU);
  161. IDSwprintf(hModule,IDS_OPTION_SP_DESC);
  162. IDSwprintf(hModule,IDS_OPTION_SP_DESC1);
  163. IDS_IDS_IDS_IDSwprintf(hModule,IDS_OPTION_MORE_VALUE, IDS_OPTION_SP_CHAIN,
  164. IDS_OPTION_SP_SPCSTORE, IDS_OPTION_SP_SPCSTORE);
  165. IDSwprintf(hModule, IDS_OPTION_CN_DESC);
  166. IDSwprintf(hModule, IDS_OPTION_SHA1_DESC);
  167. IDSwprintf(hModule,IDS_OPTION_X_DESC);
  168. IDSwprintf(hModule,IDS_ENFLN);
  169. IDSwprintf(hModule, IDS_MORE_INFO_1);
  170. IDSwprintf(hModule, IDS_MORE_INFO_2);
  171. IDSwprintf(hModule, IDS_MORE_INFO_3);
  172. }
  173. void UndocumentedUsage()
  174. {
  175. IDSwprintf(hModule,IDS_SYNTAX);
  176. IDSwprintf(hModule,IDS_OPTIONS);
  177. IDSwprintf(hModule, IDS_OPTION_H_DESC);
  178. IDSwprintf(hModule, IDS_OPTION_TQ_DESC);
  179. IDSwprintf(hModule, IDS_OPTION_TS_DESC);
  180. IDSwprintf(hModule, IDS_OPTION_INDEX_DESC);
  181. //mark this is undocumented
  182. fUndocumented=TRUE;
  183. }
  184. //--------------------------------------------------------------------------------
  185. // Print out error msg based on the HRESULT
  186. //--------------------------------------------------------------------------------
  187. BOOL PrintBasedOnHResult(HRESULT hr)
  188. {
  189. BOOL fKnownResult=TRUE;
  190. switch(hr)
  191. {
  192. //0x80070002 is the HRESULT_FROM_WIN32(GetLastError()) when CreateFile failed
  193. case 0x80070002:
  194. IDSwprintf(hModule,IDS_ERR_INPUT_INVALID);
  195. break;
  196. case HRESULT_FROM_WIN32(ERROR_INVALID_DATA):
  197. IDSwprintf(hModule,IDS_ERR_RESPONSE_INVALID);
  198. break;
  199. case HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION):
  200. IDSwprintf(hModule, IDS_ERR_INVALID_ADDRESS);
  201. break;
  202. case CRYPT_E_NO_MATCH:
  203. IDSwprintf(hModule,IDS_ERR_NOMATCH);
  204. break;
  205. case TYPE_E_TYPEMISMATCH:
  206. IDSwprintf(hModule,IDS_ERR_AUTH);
  207. break;
  208. case CRYPT_E_FILERESIZED:
  209. IDSwprintf(hModule,IDS_ERR_RESIZE);
  210. break;
  211. case TRUST_E_TIME_STAMP:
  212. IDSwprintf(hModule, IDS_ERR_TS_CERT_INVALID);
  213. break;
  214. case CRYPT_E_NO_DECRYPT_CERT:
  215. IDSwprintf(hModule, IDS_ERR_NO_CERT, pwszStoreName);
  216. break;
  217. case CRYPT_E_DELETED_PREV:
  218. IDSwprintf(hModule, IDS_ERR_TOO_MANY_CERT, pwszStoreName);
  219. break;
  220. case CRYPT_E_NO_PROVIDER:
  221. IDSwprintf(hModule, IDS_ERR_NO_PROVIDER);
  222. break;
  223. case CERT_E_CHAINING:
  224. IDSwprintf(hModule, IDS_ERR_NO_CHAINING);
  225. break;
  226. case CERT_E_EXPIRED:
  227. IDSwprintf(hModule, IDS_ERR_EXPRIED);
  228. break;
  229. default:
  230. fKnownResult=FALSE;
  231. }
  232. return fKnownResult;
  233. }
  234. //--------------------------------------------------------------------------------
  235. // Convert an array of wchars to a BLOB
  236. //--------------------------------------------------------------------------------
  237. HRESULT WSZtoBLOB(LPWSTR pwsz, BYTE **ppbByte, DWORD *pcbByte)
  238. {
  239. HRESULT hr=E_FAIL;
  240. DWORD dwIndex=0;
  241. ULONG ulHalfByte=0;
  242. DWORD dw1st=0;
  243. DWORD dw2nd=0;
  244. if((!pwsz) || (!ppbByte) || (!pcbByte))
  245. return E_INVALIDARG;
  246. *ppbByte=NULL;
  247. *pcbByte=0;
  248. //make sure the pwsz consists of 20 characters
  249. if(wcslen(pwsz)!= 2*SHA1_LENGTH)
  250. return E_FAIL;
  251. //memory allocation
  252. *ppbByte=(BYTE *)ToolUtlAlloc(SHA1_LENGTH);
  253. if(NULL==(*ppbByte))
  254. return E_INVALIDARG;
  255. memset(*ppbByte, 0, SHA1_LENGTH);
  256. //go through two characters (one byte) at a time
  257. for(dwIndex=0; dwIndex<SHA1_LENGTH; dwIndex++)
  258. {
  259. dw1st=dwIndex * 2;
  260. dw2nd=dwIndex * 2 +1;
  261. //1st character
  262. if(((int)(pwsz[dw1st])-(int)(L'0')) <=9 &&
  263. ((int)(pwsz[dw1st])-(int)(L'0')) >=0)
  264. {
  265. ulHalfByte=(ULONG)((ULONG)(pwsz[dw1st])-(ULONG)(L'0'));
  266. }
  267. else
  268. {
  269. if(((int)(towupper(pwsz[dw1st]))-(int)(L'A')) >=0 &&
  270. ((int)(towupper(pwsz[dw1st]))-(int)(L'A')) <=5 )
  271. ulHalfByte=10+(ULONG)((ULONG)(towupper(pwsz[dw1st]))-(ULONG)(L'A'));
  272. else
  273. {
  274. hr=E_INVALIDARG;
  275. goto CLEANUP;
  276. }
  277. }
  278. //copy the 1st character
  279. (*ppbByte)[dwIndex]=(BYTE)ulHalfByte;
  280. //left shift 4 bits
  281. (*ppbByte)[dwIndex]= (*ppbByte)[dwIndex] <<4;
  282. //2nd character
  283. if(((int)(pwsz[dw2nd])-(int)(L'0')) <=9 &&
  284. ((int)(pwsz[dw2nd])-(int)(L'0')) >=0)
  285. {
  286. ulHalfByte=(ULONG)((ULONG)(pwsz[dw2nd])-(ULONG)(L'0'));
  287. }
  288. else
  289. {
  290. if(((int)(towupper(pwsz[dw2nd]))-(int)(L'A')) >=0 &&
  291. ((int)(towupper(pwsz[dw2nd]))-(int)(L'A')) <=5 )
  292. ulHalfByte=10+(ULONG)((ULONG)(towupper(pwsz[dw2nd]))-(ULONG)(L'A'));
  293. else
  294. {
  295. hr=E_INVALIDARG;
  296. goto CLEANUP;
  297. }
  298. }
  299. //ORed the second character
  300. (*ppbByte)[dwIndex]=(*ppbByte)[dwIndex] | ((BYTE)ulHalfByte);
  301. }
  302. hr=S_OK;
  303. CLEANUP:
  304. if(hr!=S_OK)
  305. {
  306. if(*ppbByte)
  307. ToolUtlFree(*ppbByte);
  308. *ppbByte=NULL;
  309. }
  310. else
  311. *pcbByte=SHA1_LENGTH;
  312. return hr;
  313. }
  314. //--------------------------------------------------------------------------------
  315. //make sure the input parameters make sense for signing
  316. //--------------------------------------------------------------------------------
  317. BOOL CheckSignParam()
  318. {
  319. //make sure pwszPvkFile and pwszKeyContainer name are not set at the same time
  320. if(pwszPvkFile && pwszKeyContainer)
  321. {
  322. IDSwprintf(hModule,IDS_ERR_BOTH_PVK);
  323. return FALSE;
  324. }
  325. //make sure spc/pvk information and store related information can not be set
  326. //at the same time
  327. if(pwszSpcFile || pwszPvkFile || pwszKeyContainer || pwszProviderType ||
  328. pwszCapiProvider ||pwszKeySpec)
  329. {
  330. fStoreTechnology=FALSE;
  331. if(pwszStoreName || pwszCertFile || pwszStoreName || pwszStorePolicy ||
  332. pwszStoreLocation || pwszCommonName || pwszSha1Hash)
  333. {
  334. IDSwprintf(hModule,IDS_ERR_BOTH_SPC);
  335. return FALSE;
  336. }
  337. //now that we are not using certStore, spc file has to be set
  338. if(!pwszSpcFile)
  339. {
  340. IDSwprintf(hModule, IDS_ERR_NO_SPC);
  341. return FALSE;
  342. }
  343. //either PVKFile or KeyContainer has to be set
  344. if(pwszPvkFile == NULL && pwszKeyContainer ==NULL)
  345. {
  346. IDSwprintf(hModule,IDS_ERR_NO_PVK);
  347. return FALSE;
  348. }
  349. }
  350. //pwszCommonName, pwszCertFile and pwszSha1Hash can not be set at the same time
  351. if(pwszCertFile)
  352. {
  353. if(pwszCommonName || pwszSha1Hash)
  354. {
  355. IDSwprintf(hModule, IDS_ERR_BOTH_CN_SHA1);
  356. return FALSE;
  357. }
  358. }
  359. if(pwszCommonName && pwszSha1Hash)
  360. {
  361. IDSwprintf(hModule, IDS_ERR_BOTH_CN_SHA1);
  362. return FALSE;
  363. }
  364. //if pwszStoreLocation is set, then the storeName as to be set
  365. if(pwszStoreLocation && (pwszStoreName==NULL))
  366. {
  367. IDSwprintf(hModule, IDS_STORE_LOCATION_NAME);
  368. return FALSE;
  369. }
  370. return TRUE;
  371. }
  372. //--------------------------------------------------------------------------------
  373. //make sure the user has passed in a valid set of parameters
  374. //--------------------------------------------------------------------------------
  375. BOOL CheckParameter()
  376. {
  377. BOOL fValid=FALSE;
  378. //has to set the file name
  379. if(!pwszFile)
  380. {
  381. IDSwprintf(hModule,IDS_ERR_NO_FILE);
  382. return FALSE;
  383. }
  384. if(fSigning==TRUE)
  385. {
  386. dwAction |= ACTION_SIGN;
  387. //make sure the input parameters make sense
  388. if(!CheckSignParam())
  389. return FALSE;
  390. }
  391. if(pwszResponseFile)
  392. {
  393. dwAction |= ACTION_RESPONSE;
  394. }
  395. if(pwszHttpTime)
  396. {
  397. dwAction |= ACTION_STAMP;
  398. //make sure that we have http:// in the address
  399. if(wcslen(pwszHttpTime)<=7)
  400. {
  401. IDSwprintf(hModule,IDS_ERR_ADDR_INVALID);
  402. return FALSE;
  403. }
  404. if(IDSwcsnicmp(hModule, pwszHttpTime, IDS_HTTP,7)!=0)
  405. {
  406. IDSwprintf(hModule,IDS_ERR_HTTP);
  407. return FALSE;
  408. }
  409. }
  410. if(pwszRequestFile)
  411. {
  412. dwAction |= ACTION_REQUEST;
  413. }
  414. //make sure timestamping and applying response do not go together
  415. if((dwAction & ACTION_RESPONSE) && (dwAction & ACTION_STAMP))
  416. {
  417. IDSwprintf(hModule,IDS_ERR_TIME_RESPONSE);
  418. return FALSE;
  419. }
  420. //make sure apply response can not be done after a new signature
  421. if((dwAction & ACTION_SIGN) && (dwAction & ACTION_RESPONSE))
  422. {
  423. IDSwprintf(hModule,IDS_ERR_SIGN_RESPONSE);
  424. return FALSE;
  425. }
  426. //determine the algorithm OID
  427. if(pwszAlgorithm)
  428. {
  429. if(IDSwcsicmp(hModule, pwszAlgorithm, IDS_A_MD5) == 0)
  430. dwAlgorithmOid = CALG_MD5;
  431. else
  432. {
  433. if(IDSwcsicmp(hModule,pwszAlgorithm, IDS_A_SHA) == 0)
  434. dwAlgorithmOid = CALG_SHA1;
  435. else
  436. {
  437. IDSwprintf(hModule,IDS_ERR_NO_ALGO);
  438. return FALSE;
  439. }
  440. }
  441. }
  442. //determing the store location
  443. if(pwszStoreLocation)
  444. {
  445. if(IDSwcsicmp(hModule,pwszStoreLocation, IDS_R_CU) == 0)
  446. dwStoreFlag = CERT_SYSTEM_STORE_CURRENT_USER;
  447. else
  448. {
  449. if(IDSwcsicmp(hModule,pwszStoreLocation, IDS_R_LM) == 0)
  450. dwStoreFlag = CERT_SYSTEM_STORE_LOCAL_MACHINE;
  451. else
  452. {
  453. IDSwprintf(hModule,IDS_ERR_NO_REG);
  454. return FALSE;
  455. }
  456. }
  457. }
  458. //determing the store policy
  459. if(pwszStorePolicy)
  460. {
  461. if(IDSwcsicmp(hModule,pwszStorePolicy, IDS_OPTION_SP_CHAIN) == 0)
  462. dwStorePolicy=SIGNER_CERT_POLICY_CHAIN;
  463. else
  464. {
  465. if(IDSwcsicmp(hModule, pwszStorePolicy, IDS_OPTION_SP_SPCSTORE) == 0)
  466. dwStorePolicy=SIGNER_CERT_POLICY_SPC;
  467. else
  468. {
  469. IDSwprintf(hModule,IDS_ERR_NO_POLICY);
  470. return FALSE;
  471. }
  472. }
  473. }
  474. //determine the signing authority, either individual or commercial
  475. if(pwszAuthority)
  476. {
  477. if(IDSwcsicmp(hModule,pwszAuthority, IDS_AUTHORITY_ID) == 0)
  478. fIndividual = TRUE;
  479. else
  480. {
  481. if(IDSwcsicmp(hModule,pwszAuthority, IDS_AUTHORITY_CM) == 0)
  482. fCommercial = TRUE;
  483. else
  484. {
  485. IDSwprintf(hModule,IDS_ERR_NO_AUTH);
  486. return FALSE;
  487. }
  488. }
  489. }
  490. //determine the key specificatioin
  491. if(pwszKeySpec)
  492. {
  493. if(IDSwcsicmp(hModule,pwszKeySpec, IDS_OPTION_KY_SIG) == 0)
  494. dwKeySpec = AT_SIGNATURE;
  495. else
  496. {
  497. if(IDSwcsicmp(hModule,pwszKeySpec, IDS_OPTION_KY_EXC) == 0)
  498. dwKeySpec = AT_KEYEXCHANGE;
  499. else
  500. dwKeySpec=_wtol(pwszKeySpec);
  501. }
  502. }
  503. //get the hash
  504. if(pwszSha1Hash)
  505. {
  506. if(S_OK != WSZtoBLOB(pwszSha1Hash, &g_pbHash, &g_cbHash))
  507. {
  508. //sha1 hash is invalid
  509. IDSwprintf(hModule, IDS_ERR_SHA1_HASH);
  510. return FALSE;
  511. }
  512. }
  513. //determine the provider Type
  514. if(pwszProviderType)
  515. dwProviderType = _wtoi(pwszProviderType);
  516. //get the # of timestamp trial and the # of seconds of delay between
  517. //each trial
  518. if(pwszWait)
  519. dwWait = _wtoi(pwszWait);
  520. if(pwszRepeat)
  521. dwRepeat = _wtoi(pwszRepeat);
  522. //determine the default store name
  523. if(!pwszStoreName)
  524. pwszStoreName=wszMyStore;
  525. //determin the signerIndex. Default to 0
  526. if(pwszSignerIndex)
  527. dwSignerIndex=_wtol(pwszSignerIndex);
  528. return TRUE;
  529. }
  530. //--------------------------------------------------------------------------------
  531. // Set the parameters. They can only be set once
  532. //--------------------------------------------------------------------------------
  533. BOOL SetParam(WCHAR **ppwszParam, WCHAR *pwszValue)
  534. {
  535. if(*ppwszParam!=NULL)
  536. {
  537. IDSwprintf(hModule,IDS_ERR_TOO_MANY_PARAM);
  538. return FALSE;
  539. }
  540. *ppwszParam=pwszValue;
  541. return TRUE;
  542. }
  543. //--------------------------------------------------------------------------------
  544. // Parse arguements
  545. //--------------------------------------------------------------------------------
  546. BOOL
  547. ParseSwitch (int *pArgc,
  548. WCHAR **pArgv[])
  549. {
  550. WCHAR* param = **pArgv;
  551. //move pass '/' or '-'
  552. param++;
  553. if (IDSwcsicmp(hModule, param, IDS_OPTION_H) == 0)
  554. {
  555. fTesting = TRUE;
  556. if (!(param[1]))
  557. {
  558. if (!--(*pArgc))
  559. return FALSE;
  560. (*pArgv)++;
  561. param = **pArgv;
  562. dwExpectedError = wcstoul(&param[0], NULL, 16);
  563. }
  564. else
  565. {
  566. dwExpectedError = wcstoul(&param[1], NULL, 16);
  567. }
  568. return TRUE;
  569. }
  570. else if(IDSwcsicmp(hModule, param, IDS_OPTION_SPC)==0) {
  571. if (!--(*pArgc))
  572. return FALSE;
  573. (*pArgv)++;
  574. return SetParam(&pwszSpcFile, **pArgv);
  575. }
  576. else if(IDSwcsicmp(hModule, param, IDS_OPTION_C)==0) {
  577. if (!--(*pArgc))
  578. return FALSE;
  579. (*pArgv)++;
  580. return SetParam(&pwszCertFile, **pArgv);
  581. }
  582. else if(IDSwcsicmp(hModule,param, IDS_OPTION_S)==0) {
  583. if (!--(*pArgc))
  584. return FALSE;
  585. (*pArgv)++;
  586. return SetParam(&pwszStoreName, **pArgv);
  587. }
  588. else if(IDSwcsicmp(hModule,param, IDS_OPTION_R)==0) {
  589. if (!--(*pArgc))
  590. return FALSE;
  591. (*pArgv)++;
  592. return SetParam(&pwszStoreLocation, **pArgv);
  593. }
  594. else if(IDSwcsicmp(hModule,param, IDS_OPTION_SP)==0) {
  595. if (!--(*pArgc))
  596. return FALSE;
  597. (*pArgv)++;
  598. return SetParam(&pwszStorePolicy, **pArgv);
  599. }
  600. else if(IDSwcsicmp(hModule,param, IDS_OPTION_CN)==0) {
  601. if (!--(*pArgc))
  602. return FALSE;
  603. (*pArgv)++;
  604. return SetParam(&pwszCommonName, **pArgv);
  605. }
  606. else if(IDSwcsicmp(hModule,param, IDS_OPTION_SHA1)==0) {
  607. if (!--(*pArgc))
  608. return FALSE;
  609. (*pArgv)++;
  610. return SetParam(&pwszSha1Hash, **pArgv);
  611. }
  612. else if(IDSwcsicmp(hModule,param, IDS_OPTION_V)==0) {
  613. if (!--(*pArgc))
  614. return FALSE;
  615. (*pArgv)++;
  616. return SetParam(&pwszPvkFile, **pArgv);
  617. }
  618. else if(IDSwcsicmp(hModule,param, IDS_OPTION_K)==0) {
  619. if (!--(*pArgc))
  620. return FALSE;
  621. (*pArgv)++;
  622. return SetParam(&pwszKeyContainer, **pArgv);
  623. }
  624. else if(IDSwcsicmp(hModule,param, IDS_OPTION_N)==0) {
  625. if (!--(*pArgc))
  626. return FALSE;
  627. (*pArgv)++;
  628. return SetParam(&pwszOpusName, **pArgv);
  629. }
  630. else if(IDSwcsicmp(hModule,param, IDS_OPTION_I)==0) {
  631. if (!--(*pArgc))
  632. return FALSE;
  633. (*pArgv)++;
  634. return SetParam(&pwszOpusInfo, **pArgv);
  635. }
  636. else if(IDSwcsicmp(hModule,param, IDS_OPTION_P)==0) {
  637. if (!--(*pArgc))
  638. return FALSE;
  639. (*pArgv)++;
  640. return SetParam(&pwszCapiProvider, **pArgv);
  641. }
  642. else if(IDSwcsicmp(hModule,param, IDS_OPTION_Y)==0) {
  643. if (!--(*pArgc))
  644. return FALSE;
  645. (*pArgv)++;
  646. return SetParam(&pwszProviderType, **pArgv);
  647. }
  648. else if(IDSwcsicmp(hModule,param, IDS_OPTION_KY)==0) {
  649. if (!--(*pArgc))
  650. return FALSE;
  651. (*pArgv)++;
  652. return SetParam(&pwszKeySpec, **pArgv);
  653. }
  654. else if(IDSwcsicmp(hModule,param, IDS_OPTION_AUTH)==0) {
  655. if (!--(*pArgc))
  656. return FALSE;
  657. (*pArgv)++;
  658. return SetParam(&pwszAuthority, **pArgv);
  659. }
  660. else if(IDSwcsicmp(hModule,param, IDS_OPTION_A)==0) {
  661. if (!--(*pArgc))
  662. return FALSE;
  663. (*pArgv)++;
  664. return SetParam(&pwszAlgorithm, **pArgv);
  665. }
  666. else if(IDSwcsicmp(hModule,param, IDS_OPTION_X)==0) {
  667. fSigning=FALSE;
  668. return TRUE;
  669. }
  670. else if(IDSwcsicmp(hModule,param, IDS_OPTION_T)==0) {
  671. if (!--(*pArgc))
  672. return FALSE;
  673. (*pArgv)++;
  674. return SetParam(&pwszHttpTime, **pArgv);
  675. }
  676. else if(IDSwcsicmp(hModule,param, IDS_OPTION_TW)==0) {
  677. if (!--(*pArgc))
  678. return FALSE;
  679. (*pArgv)++;
  680. return SetParam(&pwszWait,**pArgv);
  681. }
  682. else if(IDSwcsicmp(hModule,param, IDS_OPTION_TR)==0) {
  683. if (!--(*pArgc))
  684. return FALSE;
  685. (*pArgv)++;
  686. return SetParam(&pwszRepeat,**pArgv);
  687. }
  688. else if(IDSwcsicmp(hModule,param, IDS_OPTION_J)==0) {
  689. if (!--(*pArgc))
  690. return FALSE;
  691. (*pArgv)++;
  692. prgwszDllName[dwDllIndex]=**pArgv;
  693. //mark its corresponding parameter as NULL
  694. dwParamIndex=dwDllIndex;
  695. prgwszDllParam[dwParamIndex]=NULL;
  696. dwDllIndex++;
  697. return TRUE;
  698. }
  699. else if(IDSwcsicmp(hModule,param, IDS_OPTION_JP)==0) {
  700. if (!--(*pArgc))
  701. return FALSE;
  702. (*pArgv)++;
  703. //make sure there is only one or less parameter per dll
  704. if(dwParamIndex+1!=dwDllIndex)
  705. return FALSE;
  706. prgwszDllParam[dwParamIndex]=**pArgv;
  707. dwParamIndex++;
  708. return TRUE;
  709. }
  710. else if(IDSwcsicmp(hModule,param, IDS_OPTION_TS)==0) {
  711. if (!--(*pArgc))
  712. return FALSE;
  713. (*pArgv)++;
  714. return SetParam(&pwszResponseFile, **pArgv);
  715. }
  716. else if(IDSwcsicmp(hModule,param, IDS_OPTION_TQ)==0) {
  717. if (!--(*pArgc))
  718. return FALSE;
  719. (*pArgv)++;
  720. return SetParam(&pwszRequestFile, **pArgv);
  721. }
  722. else if(IDSwcsicmp(hModule,param, IDS_OPTION_INDEX)==0) {
  723. if (!--(*pArgc))
  724. return FALSE;
  725. (*pArgv)++;
  726. return SetParam(&pwszSignerIndex, **pArgv);
  727. }
  728. else if(IDSwcsicmp(hModule,param, IDS_OPTION_TEST)==0) {
  729. UndocumentedUsage();
  730. return FALSE;
  731. }
  732. return FALSE;
  733. }
  734. //--------------------------------------------------------------------------------
  735. //
  736. // wmain
  737. //
  738. //--------------------------------------------------------------------------------
  739. extern "C" int __cdecl wmain(int argc, WCHAR ** wargv)
  740. {
  741. HRESULT hr = E_FAIL;
  742. int idsAction=IDS_ACTION_SIGNCODE;
  743. BYTE *pbStampResponse=NULL;
  744. DWORD cbStampResponse=0;
  745. BYTE *pbStampRequest=NULL;
  746. DWORD cbStampRequest=0;
  747. HANDLE hFile=NULL;
  748. DWORD dwWriteBytes=0;
  749. WCHAR *pwChar;
  750. WCHAR wszSwitch1[OPTION_SWITCH_SIZE];
  751. WCHAR wszSwitch2[OPTION_SWITCH_SIZE];
  752. CRYPT_ATTRIBUTES AuthAttr;
  753. CRYPT_ATTRIBUTES UnauthAttr;
  754. PCRYPT_ATTRIBUTES *ppAuthAttr=NULL;
  755. PCRYPT_ATTRIBUTES *ppUnauthAttr=NULL;
  756. DWORD dwIndex=0;
  757. DWORD dwMilliSeconds=0;
  758. SIGNER_SUBJECT_INFO subjectInfo;
  759. SIGNER_FILE_INFO fileInfo;
  760. SIGNER_SIGNATURE_INFO signatureInfo;
  761. SIGNER_ATTR_AUTHCODE attrAuthcode;
  762. SIGNER_PROVIDER_INFO providerInfo;
  763. SIGNER_CERT_STORE_INFO certStoreInfo;
  764. SIGNER_CERT signerCert;
  765. HCERTSTORE hCertStore=NULL;
  766. CRYPTUI_WIZ_DIGITAL_SIGN_INFO DigitalSignInfo;
  767. //call the UI version of the signcode
  768. if(1==argc)
  769. {
  770. //memset
  771. memset(&DigitalSignInfo, 0, sizeof(CRYPTUI_WIZ_DIGITAL_SIGN_INFO));
  772. DigitalSignInfo.dwSize=sizeof(CRYPTUI_WIZ_DIGITAL_SIGN_INFO);
  773. //call the signing wizard, which provides
  774. //the confirmation result.
  775. if(CryptUIWizDigitalSign(0,
  776. NULL,
  777. NULL,
  778. &DigitalSignInfo,
  779. NULL))
  780. return 0;
  781. else
  782. return -1;
  783. }
  784. //get the module handle
  785. if(!InitModule())
  786. return -1;
  787. //load the strings necessary for parsing the parameters
  788. if( !LoadStringU(hModule, IDS_SWITCH1, wszSwitch1, OPTION_SWITCH_SIZE)
  789. ||!LoadStringU(hModule, IDS_SWITCH2, wszSwitch2, OPTION_SWITCH_SIZE)
  790. ||!LoadStringU(hModule, IDS_CAPITION, wszCaption, WSTR_LENGTH_MAX)
  791. ||!LoadStringU(hModule, IDS_PLUS, wszPlus, WSTR_LENGTH_MAX)
  792. ||!LoadStringU(hModule, IDS_MY, wszMyStore, STORE_DEFAULT_NAME_MAX)
  793. )
  794. return -1;
  795. //load wszNULL
  796. LoadStringU(hModule, IDS_NULL, wszNULL, WSTR_LENGTH_MAX);
  797. if ( argc <= 1 )
  798. {
  799. Usage ();
  800. return -1;
  801. }
  802. //allocate memory for prgwszDllName and prgwszDllParam
  803. prgwszDllName=(LPWSTR *)ToolUtlAlloc(sizeof(LPWSTR)*argc);
  804. prgwszDllParam=(LPWSTR *)ToolUtlAlloc(sizeof(LPWSTR)*argc);
  805. dwDllIndex=0;
  806. dwParamIndex=0;
  807. if(!prgwszDllName || !prgwszDllParam)
  808. {
  809. hr=E_OUTOFMEMORY;
  810. goto CLEANUP;
  811. }
  812. //memset
  813. memset(prgwszDllName, 0, sizeof(LPWSTR)*argc);
  814. memset(prgwszDllParam, 0, sizeof(LPWSTR)*argc);
  815. memset(&AuthAttr, 0, sizeof(CRYPT_ATTRIBUTES));
  816. memset(&UnauthAttr, 0, sizeof(CRYPT_ATTRIBUTES));
  817. //parse the parameters
  818. while (--argc)
  819. {
  820. pwChar = *++wargv;
  821. if (*pwChar == *wszSwitch1 || *pwChar == *wszSwitch2)
  822. {
  823. //parse the options
  824. if(!ParseSwitch (&argc, &wargv))
  825. {
  826. if(FALSE==fUndocumented)
  827. Usage();
  828. return -1;
  829. }
  830. }
  831. else
  832. {
  833. //parse the file name
  834. if(!SetParam(&pwszFile, pwChar))
  835. {
  836. Usage();
  837. hr=E_FAIL;
  838. goto CLEANUP;
  839. }
  840. }
  841. }
  842. //Determine the parameter sets passed in by the user
  843. if(!CheckParameter())
  844. {
  845. Usage();
  846. hr=E_INVALIDARG;
  847. goto CLEANUP;
  848. }
  849. //memory allocation for the dlls
  850. if(dwDllIndex)
  851. {
  852. ppAuthAttr=(PCRYPT_ATTRIBUTES *)ToolUtlAlloc(sizeof(PCRYPT_ATTRIBUTES)*dwDllIndex);
  853. ppUnauthAttr=(PCRYPT_ATTRIBUTES *)ToolUtlAlloc(sizeof(PCRYPT_ATTRIBUTES)*dwDllIndex);
  854. if(!ppAuthAttr || !ppUnauthAttr)
  855. {
  856. hr=E_OUTOFMEMORY;
  857. goto CLEANUP;
  858. }
  859. memset(ppAuthAttr, 0,sizeof(PCRYPT_ATTRIBUTES)*dwDllIndex);
  860. memset(ppUnauthAttr, 0,sizeof(PCRYPT_ATTRIBUTES)*dwDllIndex);
  861. }
  862. //init the dll parameters, call the GetAttr entry points of the dlls
  863. if(dwDllIndex)
  864. {
  865. if(S_OK!=(hr=InitDllParameter(&AuthAttr, &UnauthAttr,
  866. ppAuthAttr, ppUnauthAttr)))
  867. goto CLEANUP;
  868. }
  869. //Perform the requested action one at a time
  870. if(dwAction & ACTION_SIGN)
  871. {
  872. idsAction=IDS_ACTION_SIGN;
  873. //set up the parameters for signing
  874. if(S_OK != (hr=SetUpParameter(&subjectInfo, &fileInfo, &signatureInfo,
  875. &attrAuthcode, &providerInfo,
  876. &certStoreInfo, &signerCert,&AuthAttr,
  877. &UnauthAttr, &hCertStore)))
  878. goto CLEANUP;
  879. hr=SignerSign(&subjectInfo,
  880. &signerCert,
  881. &signatureInfo,
  882. fStoreTechnology ? NULL : &providerInfo,
  883. NULL,
  884. NULL,
  885. NULL);
  886. if (hr != S_OK)
  887. {
  888. idsAction=IDS_ACTION_SIGN;
  889. goto CLEANUP;
  890. }
  891. #if (0) //DSIE: Bug 236022
  892. //warn the user that the file is not timeStamped
  893. if (!(dwAction & ACTION_STAMP) && !(dwAction & ACTION_RESPONSE) && !(fTesting))
  894. IDSwprintf(hModule,IDS_WARNING);
  895. #endif
  896. //free the certificate context
  897. if(certStoreInfo.pSigningCert)
  898. CertFreeCertificateContext(certStoreInfo.pSigningCert);
  899. //close the cert store which includes the signing certificate
  900. if(hCertStore)
  901. CertCloseStore(hCertStore, 0);
  902. }
  903. if(dwAction & ACTION_STAMP)
  904. {
  905. //timestamp the code
  906. dwMilliSeconds=dwWait*1000;
  907. //set up subject information
  908. if((dwAction & ACTION_SIGN) ==0)
  909. {
  910. if(S_OK!=(hr=SetUpSubjectInfo(&subjectInfo, &fileInfo)))
  911. goto CLEANUP;
  912. }
  913. //perform the # of trials
  914. for(dwIndex=0; dwIndex<dwRepeat; dwIndex++)
  915. {
  916. hr=SignerTimeStamp(&subjectInfo,pwszHttpTime,NULL,NULL);
  917. if(hr==S_OK)
  918. break;
  919. //wait per timestamp request
  920. if(dwWait!=0)
  921. Sleep(dwMilliSeconds);
  922. }
  923. if (hr != S_OK)
  924. {
  925. idsAction=IDS_ACTION_TIMESTAMP;
  926. goto CLEANUP;
  927. }
  928. }
  929. if(dwAction & ACTION_RESPONSE)
  930. {
  931. hr=RetrieveBLOBFromFile(pwszResponseFile,&cbStampResponse,
  932. &pbStampResponse);
  933. if (hr != S_OK)
  934. {
  935. idsAction=IDS_ACTION_RESPONSE;
  936. goto CLEANUP;
  937. }
  938. //set up subject information
  939. if(S_OK!=(hr=SetUpSubjectInfo(&subjectInfo, &fileInfo)))
  940. goto CLEANUP;
  941. hr=SignerAddTimeStampResponse(&subjectInfo,
  942. pbStampResponse,
  943. cbStampResponse,
  944. NULL);
  945. if (hr != S_OK)
  946. {
  947. idsAction=IDS_ACTION_RESPONSE;
  948. goto CLEANUP;
  949. }
  950. }
  951. if(dwAction & ACTION_REQUEST)
  952. {
  953. cbStampRequest=0;
  954. //set up subject information
  955. if(S_OK!=(hr=SetUpSubjectInfo(&subjectInfo, &fileInfo)))
  956. goto CLEANUP;
  957. hr=SignerCreateTimeStampRequest(
  958. &subjectInfo,
  959. NULL,
  960. NULL,
  961. NULL,
  962. &cbStampRequest);
  963. if (hr != S_OK)
  964. {
  965. idsAction=IDS_ACTION_REQUEST;
  966. goto CLEANUP;
  967. }
  968. pbStampRequest=(BYTE *)ToolUtlAlloc(cbStampRequest);
  969. if(!pbStampRequest)
  970. {
  971. hr=E_OUTOFMEMORY;
  972. idsAction=IDS_ACTION_REQUEST;
  973. goto CLEANUP;
  974. }
  975. hr=SignerCreateTimeStampRequest(
  976. &subjectInfo,
  977. NULL,
  978. NULL,
  979. pbStampRequest,
  980. &cbStampRequest);
  981. if ( hr != S_OK)
  982. {
  983. idsAction=IDS_ACTION_REQUEST;
  984. goto CLEANUP;
  985. }
  986. //put the stamp request into a file
  987. if((hFile = CreateFileU(pwszRequestFile,
  988. GENERIC_WRITE,
  989. 0,
  990. NULL,
  991. OPEN_ALWAYS,
  992. FILE_ATTRIBUTE_NORMAL,
  993. NULL)) == INVALID_HANDLE_VALUE)
  994. {
  995. hr=SignError();
  996. idsAction=IDS_ACTION_REQUEST;
  997. goto CLEANUP;
  998. }
  999. if(WriteFile(hFile,
  1000. pbStampRequest,
  1001. cbStampRequest,
  1002. &dwWriteBytes,
  1003. NULL) == FALSE ||
  1004. dwWriteBytes != cbStampRequest)
  1005. {
  1006. hr=SignError();
  1007. idsAction=IDS_ACTION_REQUEST;
  1008. goto CLEANUP;
  1009. }
  1010. }
  1011. CLEANUP:
  1012. if (fTesting)
  1013. {
  1014. if (hr == (HRESULT)dwExpectedError)
  1015. IDSwprintf(hModule,IDS_TEST_SUCCEEDED, hr);
  1016. else
  1017. IDSwprintf(hModule,IDS_TEST_FAILED, dwExpectedError, hr);
  1018. }
  1019. else
  1020. {
  1021. if(hr==S_OK)
  1022. {
  1023. IDSwprintf(hModule,IDS_SUCCEEDED);
  1024. //we need to tell user the returned index of signature/timestamp
  1025. if(pwszSignerIndex)
  1026. IDSwprintf(hModule, IDS_SIGNER_INDEX, *(subjectInfo.pdwIndex));
  1027. }
  1028. else
  1029. {
  1030. //first try to print out dedebug info
  1031. if(!PrintBasedOnHResult(hr))
  1032. {
  1033. //print out addtional info for timestamping
  1034. if(idsAction==IDS_ACTION_TIMESTAMP)
  1035. {
  1036. /*if(dwIndex!=1)
  1037. IDSwprintf(hModule,IDS_TIMESTAMP_TIMES_DELAY, dwIndex+1,dwWait); */
  1038. //file needs to be signed in order to timestamp it
  1039. if((dwAction & ACTION_SIGN) ==0)
  1040. //file may needs to be resigned
  1041. IDSwprintf(hModule,IDS_RESIGN);
  1042. }
  1043. }
  1044. //then print out general information
  1045. IDS_IDS_DW_DWwprintf(hModule,IDS_ERROR, idsAction, hr, hr);
  1046. }
  1047. }
  1048. if(hFile)
  1049. CloseHandle(hFile);
  1050. //release the authenticated attributes
  1051. ReleaseDllParameter(ppAuthAttr, ppUnauthAttr);
  1052. //release prgwszDllName
  1053. if(prgwszDllName)
  1054. ToolUtlFree(prgwszDllName);
  1055. //release prgwszDllParam
  1056. if(prgwszDllParam)
  1057. ToolUtlFree(prgwszDllParam);
  1058. //release pAuthAttr
  1059. if(AuthAttr.rgAttr)
  1060. ToolUtlFree(AuthAttr.rgAttr);
  1061. if(UnauthAttr.rgAttr)
  1062. ToolUtlFree(UnauthAttr.rgAttr);
  1063. //free ppAuthAttr and ppUnauthAttr
  1064. if(ppAuthAttr)
  1065. ToolUtlFree(ppAuthAttr);
  1066. if(ppUnauthAttr)
  1067. ToolUtlFree(ppUnauthAttr);
  1068. if(pbStampResponse)
  1069. UnmapViewOfFile(pbStampResponse);
  1070. if(pbStampRequest)
  1071. ToolUtlFree(pbStampRequest);
  1072. if(g_pbHash)
  1073. ToolUtlFree(g_pbHash);
  1074. if(hr==S_OK)
  1075. return 0;
  1076. else
  1077. return -1;
  1078. }
  1079. //-----------------------------------------------------------------------
  1080. //
  1081. // Get the hash from a cert file
  1082. //
  1083. //--------------------------------------------------------------------------
  1084. HRESULT GetCertHashFromFile(LPWSTR pwszCertFile,
  1085. BYTE **ppHash,
  1086. DWORD *pcbHash,
  1087. BOOL *pfMore)
  1088. {
  1089. HRESULT hr=S_OK;
  1090. HCERTSTORE hCertStore=NULL;
  1091. PCCERT_CONTEXT pSigningCert=NULL;
  1092. PCCERT_CONTEXT pPreCert=NULL;
  1093. PCCERT_CONTEXT pDupCert=NULL;
  1094. DWORD dwCount=0;
  1095. if(!ppHash || !pcbHash || !pfMore)
  1096. return E_INVALIDARG;
  1097. //init
  1098. *pcbHash=0;
  1099. *ppHash=NULL;
  1100. *pfMore=FALSE;
  1101. //open a cert store
  1102. hCertStore=CertOpenStore(CERT_STORE_PROV_FILENAME_W,
  1103. dwStoreEncodingType,
  1104. NULL,
  1105. 0,
  1106. pwszCertFile);
  1107. if(hCertStore==NULL)
  1108. {
  1109. hr=SignError();
  1110. goto CLEANUP;
  1111. }
  1112. while(pDupCert=CertEnumCertificatesInStore(hCertStore,
  1113. pPreCert))
  1114. {
  1115. dwCount++;
  1116. if(dwCount > 1)
  1117. {
  1118. CertFreeCertificateContext(pDupCert);
  1119. pDupCert=NULL;
  1120. CertFreeCertificateContext(pSigningCert);
  1121. pSigningCert=NULL;
  1122. *pfMore=TRUE;
  1123. hr=S_FALSE;
  1124. goto CLEANUP;
  1125. }
  1126. pPreCert=pDupCert;
  1127. pSigningCert=CertDuplicateCertificateContext(pDupCert);
  1128. }
  1129. if(pSigningCert==NULL)
  1130. {
  1131. hr=CRYPT_E_NO_DECRYPT_CERT;
  1132. goto CLEANUP;
  1133. }
  1134. //get the hash
  1135. if(!CertGetCertificateContextProperty(pSigningCert,
  1136. CERT_SHA1_HASH_PROP_ID,
  1137. NULL,
  1138. pcbHash))
  1139. {
  1140. hr=SignError();
  1141. goto CLEANUP;
  1142. }
  1143. *ppHash=(BYTE *)ToolUtlAlloc(*pcbHash);
  1144. if(!(*ppHash))
  1145. {
  1146. hr=E_OUTOFMEMORY;
  1147. goto CLEANUP;
  1148. }
  1149. if(!CertGetCertificateContextProperty(pSigningCert,
  1150. CERT_SHA1_HASH_PROP_ID,
  1151. *ppHash,
  1152. pcbHash))
  1153. {
  1154. hr=SignError();
  1155. goto CLEANUP;
  1156. }
  1157. CLEANUP:
  1158. if(pSigningCert)
  1159. CertFreeCertificateContext(pSigningCert);
  1160. if(hCertStore)
  1161. CertCloseStore(hCertStore, 0);
  1162. if(hr!=S_OK)
  1163. {
  1164. if(*ppHash)
  1165. {
  1166. ToolUtlFree(*ppHash);
  1167. *ppHash=NULL;
  1168. }
  1169. }
  1170. return hr;
  1171. }
  1172. //-----------------------------------------------------------------------
  1173. //
  1174. // Get the signing certificate
  1175. //
  1176. //--------------------------------------------------------------------------
  1177. PCCERT_CONTEXT GetSigningCert(HCERTSTORE *phCertStore, BOOL *pfMore)
  1178. {
  1179. PCCERT_CONTEXT pSigningCert=NULL;
  1180. PCCERT_CONTEXT pPreCert=NULL;
  1181. PCCERT_CONTEXT pDupCert=NULL;
  1182. BYTE *pHash=NULL;
  1183. DWORD cbHash;
  1184. HCERTSTORE hCertStore=NULL;
  1185. CRYPT_HASH_BLOB HashBlob;
  1186. DWORD dwCount=0;
  1187. //init the output
  1188. if(!phCertStore || !pfMore)
  1189. return NULL;
  1190. *phCertStore=NULL;
  1191. *pfMore=FALSE;
  1192. //open a cert store
  1193. hCertStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
  1194. dwStoreEncodingType,
  1195. NULL,
  1196. dwStoreFlag |CERT_STORE_READONLY_FLAG,
  1197. pwszStoreName);
  1198. if(!hCertStore)
  1199. return NULL;
  1200. //get the hash of the certificate. Find the cert based on
  1201. //pwszCertFile
  1202. if(pwszCertFile)
  1203. {
  1204. if(S_OK != GetCertHashFromFile(pwszCertFile, &pHash, &cbHash, pfMore))
  1205. goto CLEANUP;
  1206. HashBlob.cbData=cbHash;
  1207. HashBlob.pbData=pHash;
  1208. pSigningCert=CertFindCertificateInStore(hCertStore,
  1209. dwCertEncodingType,
  1210. 0,
  1211. CERT_FIND_SHA1_HASH,
  1212. &HashBlob,
  1213. NULL);
  1214. }
  1215. else
  1216. {
  1217. //find the certificate with the common name
  1218. if(pwszCommonName)
  1219. {
  1220. while(pDupCert=CertFindCertificateInStore(hCertStore,
  1221. dwCertEncodingType,
  1222. 0,
  1223. CERT_FIND_SUBJECT_STR_W,
  1224. pwszCommonName,
  1225. pPreCert))
  1226. {
  1227. dwCount++;
  1228. if(dwCount > 1)
  1229. {
  1230. CertFreeCertificateContext(pDupCert);
  1231. pDupCert=NULL;
  1232. CertFreeCertificateContext(pSigningCert);
  1233. pSigningCert=NULL;
  1234. *pfMore=TRUE;
  1235. goto CLEANUP;
  1236. }
  1237. pPreCert=pDupCert;
  1238. pSigningCert=CertDuplicateCertificateContext(pDupCert);
  1239. }
  1240. }
  1241. else
  1242. {
  1243. //find the certificate based on the hash
  1244. if(g_pbHash)
  1245. {
  1246. HashBlob.cbData=g_cbHash;
  1247. HashBlob.pbData=g_pbHash;
  1248. pSigningCert=CertFindCertificateInStore(hCertStore,
  1249. dwCertEncodingType,
  1250. 0,
  1251. CERT_FIND_SHA1_HASH,
  1252. &HashBlob,
  1253. NULL);
  1254. }
  1255. else
  1256. {
  1257. //no searching criteria, find the only cert in the store
  1258. while(pDupCert=CertEnumCertificatesInStore(hCertStore,
  1259. pPreCert))
  1260. {
  1261. dwCount++;
  1262. if(dwCount > 1)
  1263. {
  1264. CertFreeCertificateContext(pDupCert);
  1265. pDupCert=NULL;
  1266. CertFreeCertificateContext(pSigningCert);
  1267. pSigningCert=NULL;
  1268. *pfMore=TRUE;
  1269. goto CLEANUP;
  1270. }
  1271. pPreCert=pDupCert;
  1272. pSigningCert=CertDuplicateCertificateContext(pDupCert);
  1273. }
  1274. }
  1275. }
  1276. }
  1277. CLEANUP:
  1278. if(pHash)
  1279. ToolUtlFree(pHash);
  1280. if(pSigningCert)
  1281. {
  1282. *phCertStore=hCertStore;
  1283. }
  1284. else
  1285. {
  1286. //free the hCertStore
  1287. CertCloseStore(hCertStore, 0);
  1288. }
  1289. return pSigningCert;
  1290. }
  1291. //-----------------------------------------------------------------------
  1292. //
  1293. // Set up the subject info
  1294. //
  1295. //--------------------------------------------------------------------------
  1296. HRESULT SetUpSubjectInfo(SIGNER_SUBJECT_INFO *pSubjectInfo,
  1297. SIGNER_FILE_INFO *pFileInfo)
  1298. {
  1299. if(!pSubjectInfo || !pFileInfo)
  1300. return E_INVALIDARG;
  1301. //init
  1302. memset(pSubjectInfo, 0, sizeof(SIGNER_SUBJECT_INFO));
  1303. memset(pFileInfo, 0, sizeof(SIGNER_FILE_INFO));
  1304. //init cbSize
  1305. pSubjectInfo->cbSize=sizeof(SIGNER_SUBJECT_INFO);
  1306. pFileInfo->cbSize=sizeof(SIGNER_FILE_INFO);
  1307. //init pSubjectInfo
  1308. pSubjectInfo->pdwIndex=&dwSignerIndex;
  1309. pSubjectInfo->dwSubjectChoice=SIGNER_SUBJECT_FILE;
  1310. pSubjectInfo->pSignerFileInfo=pFileInfo;
  1311. pFileInfo->pwszFileName=pwszFile;
  1312. return S_OK;
  1313. }
  1314. //-----------------------------------------------------------------------
  1315. //
  1316. // Set up the signing parameters
  1317. //
  1318. //--------------------------------------------------------------------------
  1319. HRESULT SetUpParameter(SIGNER_SUBJECT_INFO *pSubjectInfo,
  1320. SIGNER_FILE_INFO *pFileInfo,
  1321. SIGNER_SIGNATURE_INFO *pSignatureInfo,
  1322. SIGNER_ATTR_AUTHCODE *pAttrAuthcode,
  1323. SIGNER_PROVIDER_INFO *pProviderInfo,
  1324. SIGNER_CERT_STORE_INFO *pCertStoreInfo,
  1325. SIGNER_CERT *pSignerCert,
  1326. CRYPT_ATTRIBUTES *pAuthenticated,
  1327. CRYPT_ATTRIBUTES *pUnauthenticated,
  1328. HCERTSTORE *phCertStore
  1329. )
  1330. {
  1331. HRESULT hr;
  1332. PCCERT_CONTEXT pCertContext=NULL;
  1333. BOOL fMore=FALSE;
  1334. if(S_OK!=(hr=SetUpSubjectInfo(pSubjectInfo, pFileInfo)))
  1335. return hr;
  1336. if(!pSignatureInfo || !pAttrAuthcode || !pProviderInfo ||
  1337. !pCertStoreInfo || !pSignerCert)
  1338. return E_INVALIDARG;
  1339. //init
  1340. memset(pSignatureInfo, 0, sizeof(SIGNER_SIGNATURE_INFO));
  1341. memset(pAttrAuthcode, 0, sizeof(SIGNER_ATTR_AUTHCODE));
  1342. memset(pProviderInfo, 0, sizeof(SIGNER_PROVIDER_INFO));
  1343. memset(pCertStoreInfo, 0, sizeof(SIGNER_CERT_STORE_INFO));
  1344. memset(pSignerCert, 0, sizeof(SIGNER_CERT));
  1345. //init cbSize
  1346. pSignatureInfo->cbSize=sizeof(SIGNER_SIGNATURE_INFO);
  1347. pAttrAuthcode->cbSize=sizeof(SIGNER_ATTR_AUTHCODE);
  1348. pProviderInfo->cbSize=sizeof(SIGNER_PROVIDER_INFO);
  1349. pCertStoreInfo->cbSize=sizeof(SIGNER_CERT_STORE_INFO);
  1350. pSignerCert->cbSize=sizeof(SIGNER_CERT);
  1351. //init pAttrAuthcode
  1352. pAttrAuthcode->fCommercial=fCommercial;
  1353. pAttrAuthcode->fIndividual=fIndividual;
  1354. pAttrAuthcode->pwszName=pwszOpusName;
  1355. pAttrAuthcode->pwszInfo=pwszOpusInfo;
  1356. //init pSignatureInfo
  1357. pSignatureInfo->algidHash=dwAlgorithmOid;
  1358. pSignatureInfo->dwAttrChoice=SIGNER_AUTHCODE_ATTR;
  1359. pSignatureInfo->pAttrAuthcode=pAttrAuthcode;
  1360. pSignatureInfo->psAuthenticated=pAuthenticated;
  1361. pSignatureInfo->psUnauthenticated=pUnauthenticated;
  1362. //init pProviderInfo only if we are using non-cerStore tech
  1363. if(fStoreTechnology!=TRUE)
  1364. {
  1365. pProviderInfo->pwszProviderName=pwszCapiProvider;
  1366. pProviderInfo->dwProviderType=dwProviderType;
  1367. pProviderInfo->dwKeySpec=dwKeySpec;
  1368. if(pwszPvkFile)
  1369. {
  1370. pProviderInfo->dwPvkChoice=PVK_TYPE_FILE_NAME;
  1371. pProviderInfo->pwszPvkFileName=pwszPvkFile;
  1372. }
  1373. else
  1374. {
  1375. pProviderInfo->dwPvkChoice=PVK_TYPE_KEYCONTAINER;
  1376. pProviderInfo->pwszKeyContainer=pwszKeyContainer;
  1377. }
  1378. }
  1379. //init pSignerCert
  1380. if(fStoreTechnology)
  1381. {
  1382. //get the signing cert context
  1383. pCertContext=GetSigningCert(phCertStore,&fMore );
  1384. if(!pCertContext)
  1385. {
  1386. if(fMore==FALSE)
  1387. return CRYPT_E_NO_DECRYPT_CERT;
  1388. else
  1389. return CRYPT_E_DELETED_PREV;
  1390. }
  1391. pSignerCert->dwCertChoice=SIGNER_CERT_STORE;
  1392. pSignerCert->pCertStoreInfo=pCertStoreInfo;
  1393. //init pCertStoreInfo
  1394. pCertStoreInfo->pSigningCert=pCertContext;
  1395. pCertStoreInfo->dwCertPolicy=dwStorePolicy;
  1396. }
  1397. else
  1398. {
  1399. pSignerCert->dwCertChoice=SIGNER_CERT_SPC_FILE;
  1400. pSignerCert->pwszSpcFile=pwszSpcFile;
  1401. }
  1402. return S_OK;
  1403. }
  1404. //-----------------------------------------------------------------------
  1405. //
  1406. //get the attributes from the dlls
  1407. //
  1408. //--------------------------------------------------------------------------
  1409. HRESULT InitDllParameter(PCRYPT_ATTRIBUTES pAuthAttr,
  1410. PCRYPT_ATTRIBUTES pUnauthAttr,
  1411. PCRYPT_ATTRIBUTES *ppAuthAttr,
  1412. PCRYPT_ATTRIBUTES *ppUnauthAttr)
  1413. {
  1414. DWORD dwIndex=0;
  1415. DWORD dwIndex2=0;
  1416. DWORD dwAttrIndex=0;
  1417. HRESULT hr=E_FAIL;
  1418. HINSTANCE hAuthInst=NULL;
  1419. LPSTR pszName=NULL;
  1420. FARPROC pProc=NULL;
  1421. PCRYPT_ATTRIBUTES pDllAuthAttr=NULL;
  1422. PCRYPT_ATTRIBUTES pDllUnauthAttr=NULL;
  1423. DWORD dwAuthAttrSum=0;
  1424. DWORD dwUnauthAttrSum=0;
  1425. if(dwDllIndex==0)
  1426. return S_OK;
  1427. if(!ppAuthAttr || !ppUnauthAttr ||!pAuthAttr || !pUnauthAttr)
  1428. return E_INVALIDARG;
  1429. //process each dll
  1430. for(dwIndex=0; dwIndex<dwDllIndex; dwIndex++)
  1431. {
  1432. //get the char version of the dll name
  1433. if((prgwszDllName[dwIndex] == NULL) ||
  1434. (S_OK!=(hr=WSZtoSZ(prgwszDllName[dwIndex], &pszName))))
  1435. goto CLEANUP;
  1436. //load the libriary
  1437. hAuthInst=LoadLibrary(pszName);
  1438. if(!hAuthInst)
  1439. {
  1440. hr=SignError();
  1441. goto CLEANUP;
  1442. }
  1443. //init
  1444. if(!(pProc=GetProcAddress(hAuthInst, "InitAttr")))
  1445. {
  1446. hr=SignError();
  1447. goto CLEANUP;
  1448. }
  1449. if(S_OK!=(hr=((pInitAttr)pProc)(prgwszDllParam[dwIndex])))
  1450. goto CLEANUP;
  1451. //get the attributes for either GetAttr or GetAttrEx
  1452. if(!(pProc=GetProcAddress(hAuthInst, "GetAttrEx")))
  1453. {
  1454. if(!(pProc=GetProcAddress(hAuthInst, "GetAttr")))
  1455. {
  1456. hr=SignError();
  1457. goto CLEANUP;
  1458. }
  1459. if(S_OK!=(hr=((pGetAttr)pProc)(&pDllAuthAttr, &pDllUnauthAttr)))
  1460. goto CLEANUP;
  1461. }
  1462. else
  1463. {
  1464. if(S_OK!=(hr=((pGetAttrEx)pProc)(0,
  1465. pwszFile,
  1466. prgwszDllParam[dwIndex],
  1467. &pDllAuthAttr,
  1468. &pDllUnauthAttr)))
  1469. goto CLEANUP;
  1470. }
  1471. //make sure valid return
  1472. if(!pDllAuthAttr || !pDllUnauthAttr)
  1473. {
  1474. hr=E_UNEXPECTED;
  1475. goto CLEANUP;
  1476. }
  1477. //add the sum pf authenticated
  1478. if(pDllAuthAttr->cAttr)
  1479. dwAuthAttrSum+=pDllAuthAttr->cAttr;
  1480. ppAuthAttr[dwIndex]=pDllAuthAttr;
  1481. //add the sume of unauthenticated
  1482. if(pDllUnauthAttr->cAttr)
  1483. dwUnauthAttrSum+=pDllUnauthAttr->cAttr;
  1484. ppUnauthAttr[dwIndex]=pDllUnauthAttr;
  1485. //exit
  1486. if(!(pProc=GetProcAddress(hAuthInst, "ExitAttr")))
  1487. {
  1488. hr=SignError();
  1489. goto CLEANUP;
  1490. }
  1491. if(S_OK!=(hr=((pExitAttr)pProc)()))
  1492. goto CLEANUP;
  1493. //free library
  1494. FreeLibrary(hAuthInst);
  1495. hAuthInst=NULL;
  1496. //free memory
  1497. ToolUtlFree(pszName);
  1498. pszName=NULL;
  1499. }
  1500. //build up authenticated attribute
  1501. if(dwAuthAttrSum)
  1502. {
  1503. pAuthAttr->cAttr=dwAuthAttrSum;
  1504. pAuthAttr->rgAttr=(PCRYPT_ATTRIBUTE)ToolUtlAlloc(sizeof(CRYPT_ATTRIBUTE)*
  1505. pAuthAttr->cAttr);
  1506. if(!(pAuthAttr->rgAttr) )
  1507. {
  1508. hr=E_OUTOFMEMORY;
  1509. goto CLEANUP;
  1510. }
  1511. //build up autheticated attributes
  1512. dwAttrIndex=0;
  1513. for(dwIndex=0; dwIndex<dwDllIndex; dwIndex++)
  1514. {
  1515. for(dwIndex2=0;dwIndex2<ppAuthAttr[dwIndex]->cAttr; dwIndex2++)
  1516. {
  1517. pAuthAttr->rgAttr[dwAttrIndex]= ppAuthAttr[dwIndex]->rgAttr[dwIndex2];
  1518. dwAttrIndex++;
  1519. }
  1520. }
  1521. //make sure dwAttrIndex==pAuthAttr->cAttr
  1522. if(dwAttrIndex!=pAuthAttr->cAttr)
  1523. {
  1524. hr=E_UNEXPECTED;
  1525. goto CLEANUP;
  1526. }
  1527. }
  1528. else
  1529. {
  1530. memset(pAuthAttr, 0, sizeof(CRYPT_ATTRIBUTES));
  1531. }
  1532. //build up unauthenticated attribute
  1533. if(dwUnauthAttrSum)
  1534. {
  1535. pUnauthAttr->cAttr=dwUnauthAttrSum;
  1536. pUnauthAttr->rgAttr=(PCRYPT_ATTRIBUTE)ToolUtlAlloc(sizeof(CRYPT_ATTRIBUTE)*
  1537. pUnauthAttr->cAttr);
  1538. if(!(pUnauthAttr->rgAttr))
  1539. {
  1540. hr=E_OUTOFMEMORY;
  1541. goto CLEANUP;
  1542. }
  1543. //build up the unauthenticated attributes
  1544. dwAttrIndex=0;
  1545. for(dwIndex=0; dwIndex<dwDllIndex; dwIndex++)
  1546. {
  1547. for(dwIndex2=0; dwIndex2<ppUnauthAttr[dwIndex]->cAttr; dwIndex2++)
  1548. {
  1549. pUnauthAttr->rgAttr[dwAttrIndex]=ppUnauthAttr[dwIndex]->rgAttr[dwIndex2];
  1550. dwAttrIndex++;
  1551. }
  1552. }
  1553. if(dwAttrIndex != pUnauthAttr->cAttr)
  1554. {
  1555. hr=E_UNEXPECTED;
  1556. goto CLEANUP;
  1557. }
  1558. }
  1559. else
  1560. {
  1561. memset(pUnauthAttr, 0, sizeof(CRYPT_ATTRIBUTES));
  1562. }
  1563. hr=S_OK;
  1564. CLEANUP:
  1565. if(hAuthInst)
  1566. FreeLibrary(hAuthInst);
  1567. if(pszName)
  1568. ToolUtlFree(pszName);
  1569. //free up memory when hr!=S_OK
  1570. if(hr!=S_OK)
  1571. {
  1572. if(pAuthAttr->rgAttr)
  1573. {
  1574. ToolUtlFree(pAuthAttr->rgAttr);
  1575. pAuthAttr->rgAttr=NULL;
  1576. }
  1577. if(pUnauthAttr->rgAttr)
  1578. {
  1579. ToolUtlFree(pUnauthAttr->rgAttr);
  1580. pUnauthAttr->rgAttr=NULL;
  1581. }
  1582. }
  1583. return hr;
  1584. }
  1585. //-----------------------------------------------------------------------
  1586. //
  1587. // Release the attributes by calling the dlls's ReleaseAttr entry point
  1588. //
  1589. //--------------------------------------------------------------------------
  1590. void ReleaseDllParameter(PCRYPT_ATTRIBUTES * ppAuthAttr,
  1591. PCRYPT_ATTRIBUTES * ppUnauthAttr)
  1592. {
  1593. DWORD dwIndex=0;
  1594. HRESULT hr=E_FAIL;
  1595. HINSTANCE hAuthInst=NULL;
  1596. LPSTR pszName=NULL;
  1597. FARPROC pProc=NULL;
  1598. if((dwDllIndex==0) ||(!ppAuthAttr) || (!ppUnauthAttr))
  1599. return;
  1600. //process each dll
  1601. for(dwIndex=0; dwIndex<dwDllIndex; dwIndex++)
  1602. {
  1603. //free library
  1604. if(hAuthInst)
  1605. {
  1606. FreeLibrary(hAuthInst);
  1607. hAuthInst=NULL;
  1608. }
  1609. //free memory
  1610. if(pszName)
  1611. {
  1612. ToolUtlFree(pszName);
  1613. pszName=NULL;
  1614. }
  1615. //get the char version of the dll name
  1616. if((prgwszDllName[dwIndex]==NULL) ||
  1617. (S_OK!=(hr=WSZtoSZ(prgwszDllName[dwIndex], &pszName))))
  1618. continue;
  1619. //load the libriary
  1620. hAuthInst=LoadLibrary(pszName);
  1621. if(!hAuthInst)
  1622. continue;
  1623. //init
  1624. if(!(pProc=GetProcAddress(hAuthInst, "InitAttr")))
  1625. continue;
  1626. if(S_OK!=(hr=((pInitAttr)pProc)(prgwszDllParam[dwIndex])))
  1627. continue;
  1628. //release the attributes
  1629. if(!(pProc=GetProcAddress(hAuthInst, "ReleaseAttr")))
  1630. continue;
  1631. if(S_OK!=(hr=((pReleaseAttr)pProc)(
  1632. ppAuthAttr[dwIndex], ppUnauthAttr[dwIndex])))
  1633. continue;
  1634. //exit
  1635. if(!(pProc=GetProcAddress(hAuthInst, "ExitAttr")))
  1636. continue;
  1637. ((pExitAttr)pProc)();
  1638. }
  1639. //cleanup
  1640. if(hAuthInst)
  1641. {
  1642. FreeLibrary(hAuthInst);
  1643. hAuthInst=NULL;
  1644. }
  1645. //free memory
  1646. if(pszName)
  1647. {
  1648. ToolUtlFree(pszName);
  1649. pszName=NULL;
  1650. }
  1651. return;
  1652. }