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.

7298 lines
177 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1995 - 1999
  6. //
  7. // File: CertMgr
  8. //
  9. // Contents: Certificate store management tools
  10. //
  11. // See Usage() for list of options.
  12. //
  13. //
  14. // Functions: wmain
  15. //
  16. // History: July 21st xiaohs created
  17. //
  18. //--------------------------------------------------------------------------
  19. #include "certmgr.h"
  20. //--------------------------------------------------------------------------
  21. //
  22. // Global Flags
  23. //
  24. //----------------------------------------------------------------------------
  25. #define ITEM_VERBOSE 0x00010000
  26. #define ITEM_CERT 0x00000001
  27. #define ITEM_CTL 0x00000002
  28. #define ITEM_CRL 0x00000004
  29. #define ACTION_DISPLAY 0x01
  30. #define ACTION_ADD 0x02
  31. #define ACTION_DELETE 0x04
  32. #define ACTION_PUT 0x08
  33. #define OPTION_SWITCH_SIZE 10
  34. #define SHA1_LENGTH 20
  35. #define MAX_HASH_LEN 20
  36. #define MAX_STRING_RSC_SIZE 512
  37. //--------------------------------------------------------------------------
  38. //
  39. // Global Variable
  40. //
  41. //----------------------------------------------------------------------------
  42. HMODULE hModule=NULL;
  43. //varibles for installable formatting routines
  44. HCRYPTOIDFUNCSET hFormatFuncSet;
  45. const CRYPT_OID_FUNC_ENTRY g_FormatTable[] = {
  46. szOID_BASIC_CONSTRAINTS2, FormatBasicConstraints2};
  47. DWORD g_dwFormatCount=sizeof(g_FormatTable)/sizeof(g_FormatTable[0]);
  48. typedef BOOL (WINAPI *PFN_FORMAT_FUNC)(
  49. IN DWORD dwCertEncodingType,
  50. IN DWORD dwFormatType,
  51. IN DWORD dwFormatStrType,
  52. IN void *pFormatStruct,
  53. IN LPCSTR lpszStructType,
  54. IN const BYTE *pbEncoded,
  55. IN DWORD cbEncoded,
  56. OUT void *pbFormat,
  57. IN OUT DWORD *pcbFormat
  58. );
  59. //variables for installing OID information
  60. typedef struct _CERTMGR_OID_INFO
  61. {
  62. LPCSTR pszOID;
  63. int idsOIDName;
  64. }CERTMGR_OID_INFO;
  65. CERTMGR_OID_INFO g_rgOIDInfo[]={
  66. SPC_SP_AGENCY_INFO_OBJID, IDS_SPC_SP_NAME,
  67. SPC_FINANCIAL_CRITERIA_OBJID, IDS_SPC_FIN_NAME,
  68. SPC_MINIMAL_CRITERIA_OBJID, IDS_SPC_MIN_NAME,
  69. szOID_NETSCAPE_CERT_TYPE, IDS_NTSP_CERT_NAME,
  70. szOID_NETSCAPE_BASE_URL, IDS_NTSP_BASE_NAME,
  71. szOID_NETSCAPE_REVOCATION_URL, IDS_NTSP_REV_NAME,
  72. szOID_NETSCAPE_CA_REVOCATION_URL, IDS_NTSP_CA_REV_NAME,
  73. szOID_NETSCAPE_CERT_RENEWAL_URL, IDS_NTSP_RENEW_NAME,
  74. szOID_NETSCAPE_CA_POLICY_URL, IDS_NTSP_POL_NAME,
  75. szOID_NETSCAPE_SSL_SERVER_NAME, IDS_NTSP_SSL_SERVER_NAME,
  76. szOID_NETSCAPE_COMMENT, IDS_NTSP_COMMENT};
  77. DWORD g_dwOIDInfo=sizeof(g_rgOIDInfo)/sizeof(g_rgOIDInfo[0]);
  78. //varibles for string manipulations
  79. WCHAR g_wszBuffer[MAX_STRING_RSC_SIZE];
  80. DWORD g_dwBufferSize=sizeof(g_wszBuffer)/sizeof(g_wszBuffer[0]);
  81. //varibles for options
  82. DWORD g_dwAction=0;
  83. DWORD g_dwItem=0;
  84. LPWSTR g_wszCertEncodingType=NULL;
  85. DWORD g_dwCertEncodingType = X509_ASN_ENCODING;
  86. DWORD g_dwMsgEncodingType = PKCS_7_ASN_ENCODING;
  87. DWORD g_dwMsgAndCertEncodingType = PKCS_7_ASN_ENCODING | X509_ASN_ENCODING;
  88. BOOL g_fSaveAs7 = FALSE;
  89. LPWSTR g_wszCertCN = NULL;
  90. LPWSTR g_wszSha1Hash = NULL;
  91. BYTE *g_pbHash=NULL;
  92. DWORD g_cbHash=0;
  93. BOOL g_fAll=FALSE;
  94. HCRYPTMSG g_hMsg=NULL;
  95. LPWSTR g_wszEKU=NULL;
  96. LPWSTR g_wszName=NULL;
  97. BOOL g_fMulti=FALSE;
  98. BOOL g_fUndocumented=FALSE;
  99. BOOL g_fSrcSystemStore = FALSE;
  100. LPWSTR g_wszSrcStoreLocation=NULL;
  101. DWORD g_dwSrcStoreFlag=CERT_SYSTEM_STORE_CURRENT_USER;
  102. LPWSTR g_wszSrcStoreName=NULL;
  103. BOOL g_fSameSrcDes=FALSE;
  104. BOOL g_fDesSystemStore = FALSE;
  105. LPWSTR g_wszDesStoreLocation=NULL;
  106. DWORD g_dwDesStoreFlag=CERT_SYSTEM_STORE_CURRENT_USER;
  107. LPWSTR g_wszDesStoreName=NULL;
  108. LPWSTR g_wszSrcStoreProvider = NULL;
  109. LPSTR g_szSrcStoreProvider = NULL;
  110. LPWSTR g_wszSrcStoreOpenFlag = NULL;
  111. DWORD g_dwSrcStoreOpenFlag = 0;
  112. LPWSTR g_wszDesStoreProvider = NULL;
  113. LPSTR g_szDesStoreProvider = NULL;
  114. LPWSTR g_wszDesStoreOpenFlag = NULL;
  115. DWORD g_dwDesStoreOpenFlag = 0;
  116. CHAR g_szNULL[OPTION_SWITCH_SIZE];
  117. WCHAR g_wszSHA1[OPTION_SWITCH_SIZE];
  118. WCHAR g_wszMD5[OPTION_SWITCH_SIZE];
  119. WCHAR g_wszUnKnown[OPTION_SWITCH_SIZE*2];
  120. //---------------------------------------------------------------------------
  121. // wmain
  122. //
  123. //---------------------------------------------------------------------------
  124. extern "C" int __cdecl wmain(int argc, WCHAR *wargv[])
  125. {
  126. int ReturnStatus=-1;
  127. //variables for parse the options
  128. WCHAR *pwChar;
  129. WCHAR wszSwitch1[OPTION_SWITCH_SIZE];
  130. WCHAR wszSwitch2[OPTION_SWITCH_SIZE];
  131. HCERTSTORE hCertStore=NULL;
  132. CRYPTUI_CERT_MGR_STRUCT CertMgrStruct;
  133. //get the module handler
  134. if(!InitModule())
  135. goto ErrorReturn;
  136. //load the strings necessary for parsing the parameters
  137. if( !LoadStringU(hModule, IDS_SWITCH1, wszSwitch1, OPTION_SWITCH_SIZE)
  138. ||!LoadStringU(hModule, IDS_SWITCH2, wszSwitch2, OPTION_SWITCH_SIZE)
  139. //<NULL>
  140. ||!LoadStringA(hModule, IDS_NULL, g_szNULL, OPTION_SWITCH_SIZE)
  141. ||!LoadStringU(hModule, IDS_SHA1, g_wszSHA1, OPTION_SWITCH_SIZE)
  142. ||!LoadStringU(hModule, IDS_MD5, g_wszMD5, OPTION_SWITCH_SIZE)
  143. //<UNKNOWN OID>
  144. ||!LoadStringU(hModule, IDS_UNKNOWN, g_wszUnKnown, OPTION_SWITCH_SIZE*2))
  145. goto ErrorReturn;
  146. //call the UI versino of certmgr if no parameter is passed
  147. //memset
  148. if(1== argc)
  149. {
  150. memset(&CertMgrStruct, 0, sizeof(CRYPTUI_CERT_MGR_STRUCT));
  151. CertMgrStruct.dwSize=sizeof(CRYPTUI_CERT_MGR_STRUCT);
  152. CryptUIDlgCertMgr(&CertMgrStruct);
  153. ReturnStatus = 0;
  154. IDSwprintf(hModule, IDS_SUCCEEDED);
  155. goto CommonReturn;
  156. }
  157. //parse the parameters
  158. while (--argc)
  159. {
  160. pwChar = *++wargv;
  161. if (*pwChar == *wszSwitch1 || *pwChar == *wszSwitch2)
  162. {
  163. //parse the options
  164. if(!ParseSwitch (&argc, &wargv))
  165. {
  166. if(TRUE==g_fUndocumented)
  167. goto UndocReturn;
  168. else
  169. goto UsageReturn;
  170. }
  171. }
  172. else
  173. {
  174. //set the source file name
  175. if(NULL==g_wszSrcStoreName)
  176. g_wszSrcStoreName=pwChar;
  177. else
  178. {
  179. //set the destination file name
  180. if(!SetParam(&g_wszDesStoreName, pwChar))
  181. goto UsageReturn;
  182. }
  183. }
  184. }
  185. //check the parameters. Make sure that they are valid and make sense
  186. if(!CheckParameter())
  187. goto UsageReturn;
  188. //open the destination store, which includes all the CERTS, CRTs, and CTLs
  189. if(!OpenGenericStore(g_wszSrcStoreName,
  190. g_fSrcSystemStore,
  191. g_dwSrcStoreFlag,
  192. g_szSrcStoreProvider,
  193. g_dwSrcStoreOpenFlag,
  194. TRUE,
  195. &hCertStore))
  196. {
  197. IDSwprintf(hModule,IDS_ERR_OPEN_SOURCE_STORE);
  198. goto ErrorReturn;
  199. }
  200. //error if we opened a signed file and there is a delete option with on destination
  201. if(g_hMsg)
  202. {
  203. if(g_dwAction & ACTION_DELETE)
  204. {
  205. if(g_fSameSrcDes)
  206. {
  207. IDSwprintf(hModule, IDS_ERR_DELETE_SIGNED_FILE);
  208. goto ErrorReturn;
  209. }
  210. }
  211. }
  212. //Display
  213. if(g_dwAction & ACTION_DISPLAY)
  214. {
  215. //if the msg is signed, disply the signer info
  216. if(g_hMsg)
  217. {
  218. if(!DisplaySignerInfo(g_hMsg, g_dwItem))
  219. goto ErrorReturn;
  220. }
  221. if(!DisplayCertStore(hCertStore))
  222. goto ErrorReturn;
  223. IDSwprintf(hModule, IDS_SEPERATOR);
  224. }
  225. //Delete
  226. if(g_dwAction & ACTION_DELETE)
  227. {
  228. if(!DeleteCertStore(hCertStore))
  229. goto ErrorReturn;
  230. }
  231. //Add
  232. if(g_dwAction & ACTION_ADD)
  233. {
  234. if(!AddCertStore(hCertStore))
  235. goto ErrorReturn;
  236. }
  237. if(g_dwAction & ACTION_PUT)
  238. {
  239. if(!PutCertStore(hCertStore))
  240. goto ErrorReturn;
  241. }
  242. //mark succeed
  243. ReturnStatus = 0;
  244. IDSwprintf(hModule, IDS_SUCCEEDED);
  245. goto CommonReturn;
  246. UndocReturn:
  247. //print out the undocuemted Usage
  248. UndocumentedUsage();
  249. goto CommonReturn;
  250. //print out the Usage.
  251. UsageReturn:
  252. Usage();
  253. goto CommonReturn;
  254. ErrorReturn:
  255. //print out an error msg
  256. IDSwprintf(hModule, IDS_FAILED);
  257. goto CommonReturn;
  258. CommonReturn:
  259. //clean up memory. Return the status
  260. if(g_szSrcStoreProvider)
  261. ToolUtlFree(g_szSrcStoreProvider);
  262. if(g_szDesStoreProvider)
  263. ToolUtlFree(g_szDesStoreProvider);
  264. if(g_pbHash)
  265. ToolUtlFree(g_pbHash);
  266. if(g_hMsg)
  267. CryptMsgClose(g_hMsg);
  268. if(hCertStore)
  269. CertCloseStore(hCertStore, 0);
  270. return ReturnStatus;
  271. }
  272. //---------------------------------------------------------------------------
  273. // The private version of wcscat
  274. //----------------------------------------------------------------------------
  275. wchar_t *IDSwcscat(HMODULE hModule, WCHAR *pwsz, int idsString)
  276. {
  277. //load the string
  278. if(!LoadStringU(hModule, idsString, g_wszBuffer, g_dwBufferSize))
  279. return pwsz;
  280. return wcscat(pwsz, g_wszBuffer);
  281. }
  282. //---------------------------------------------------------------------------
  283. // Get the hModule hanlder and init two DLLMain.
  284. //
  285. //---------------------------------------------------------------------------
  286. BOOL InitModule()
  287. {
  288. WCHAR wszOIDName[MAX_STRING_RSC_SIZE];
  289. DWORD dwIndex=0;
  290. CRYPT_OID_INFO OIDInfo;
  291. if(!(hModule=GetModuleHandle(NULL)))
  292. return FALSE;
  293. //We do not need to do the following any more.
  294. //the oid information are now in the OID database
  295. //now, we are installing the format the extensions :
  296. //BASICCONTRAINTS2
  297. if (NULL == (hFormatFuncSet = CryptInitOIDFunctionSet(
  298. CRYPT_OID_FORMAT_OBJECT_FUNC,
  299. 0))) // dwFlags
  300. {
  301. IDSwprintf(hModule, IDS_ERR_INIT_OID_SET);
  302. return FALSE;
  303. }
  304. //install the default formatting routine
  305. if (!CryptInstallOIDFunctionAddress(
  306. NULL, // hModule
  307. g_dwCertEncodingType,
  308. CRYPT_OID_FORMAT_OBJECT_FUNC,
  309. g_dwFormatCount,
  310. g_FormatTable,
  311. 0)) // dwFlags
  312. {
  313. IDSwprintf(hModule, IDS_ERR_INSTALL_OID);
  314. return FALSE;
  315. }
  316. //secondly, we install the OID information
  317. //init OIDInfo
  318. /* memset(&OIDInfo, 0, sizeof(CRYPT_OID_INFO));
  319. OIDInfo.cbSize=sizeof(CRYPT_OID_INFO);
  320. OIDInfo.dwGroupId=CRYPT_EXT_OR_ATTR_OID_GROUP_ID;
  321. for(dwIndex=0; dwIndex < g_dwOIDInfo; dwIndex++)
  322. {
  323. if(!LoadStringU(hModule, g_rgOIDInfo[dwIndex].idsOIDName,
  324. wszOIDName, MAX_STRING_RSC_SIZE))
  325. return FALSE;
  326. OIDInfo.pszOID=g_rgOIDInfo[dwIndex].pszOID;
  327. OIDInfo.pwszName=wszOIDName;
  328. CryptRegisterOIDInfo(&OIDInfo,0);
  329. } */
  330. return TRUE;
  331. }
  332. //---------------------------------------------------------------------------
  333. // Usage
  334. //
  335. //---------------------------------------------------------------------------
  336. void Usage(void)
  337. {
  338. IDSwprintf(hModule,IDS_SYNTAX);
  339. IDSwprintf(hModule,IDS_SYNTAX1);
  340. IDSwprintf(hModule,IDS_OPTIONS);
  341. IDSwprintf(hModule,IDS_OPTION_ADD_DESC);
  342. IDSwprintf(hModule,IDS_OPTION_DEL_DESC);
  343. IDSwprintf(hModule,IDS_OPTION_DEL_DESC1);
  344. IDSwprintf(hModule,IDS_OPTION_PUT_DESC);
  345. IDSwprintf(hModule,IDS_OPTION_PUT_DESC1);
  346. IDSwprintf(hModule,IDS_OPTION_PUT_DESC2);
  347. IDSwprintf(hModule,IDS_OPTION_S_DESC);
  348. IDSwprintf(hModule,IDS_OPTION_R_DESC);
  349. IDS_IDS_IDS_IDSwprintf(hModule,IDS_OPTION_MORE_VALUE,IDS_R_CU,IDS_R_LM,IDS_R_CU);
  350. IDSwprintf(hModule,IDS_OPTION_C_DESC);
  351. IDSwprintf(hModule,IDS_OPTION_CRL_DESC);
  352. IDSwprintf(hModule,IDS_OPTION_CTL_DESC);
  353. IDSwprintf(hModule,IDS_OPTION_V_DESC);
  354. IDSwprintf(hModule,IDS_OPTION_ALL_DESC);
  355. IDSwprintf(hModule,IDS_OPTION_N_DESC);
  356. IDSwprintf(hModule,IDS_OPTION_SHA1_DESC);
  357. IDSwprintf(hModule,IDS_OPTION_7_DESC);
  358. IDSwprintf(hModule,IDS_OPTION_E_DESC);
  359. IDSwprintf(hModule,IDS_OPTION_E_DESC1);
  360. IDSwprintf(hModule,IDS_OPTION_F_DESC);
  361. IDSwprintf(hModule,IDS_OPTION_Y_DESC);
  362. }
  363. //---------------------------------------------------------------------------
  364. //
  365. // Usage
  366. //
  367. //---------------------------------------------------------------------------
  368. void UndocumentedUsage()
  369. {
  370. IDSwprintf(hModule, IDS_SYNTAX);
  371. IDSwprintf(hModule, IDS_OPTIONS);
  372. IDSwprintf(hModule, IDS_OPTION_EKU_DESC);
  373. IDSwprintf(hModule, IDS_OPTION_NAME_DESC);
  374. IDSwprintf(hModule, IDS_OPTION_MULTI_DESC);
  375. }
  376. //--------------------------------------------------------------------------------
  377. // Parse arguements
  378. //--------------------------------------------------------------------------------
  379. BOOL
  380. ParseSwitch (int *pArgc,
  381. WCHAR **pArgv[])
  382. {
  383. WCHAR* param = **pArgv;
  384. //move pass '/' or '-'
  385. param++;
  386. if (IDSwcsicmp(hModule, param, IDS_OPTION_ADD)==0) {
  387. g_dwAction |= ACTION_ADD;
  388. return TRUE;
  389. }
  390. else if(IDSwcsicmp(hModule, param, IDS_OPTION_DEL)==0) {
  391. g_dwAction |= ACTION_DELETE;
  392. return TRUE;
  393. }
  394. else if(IDSwcsicmp(hModule, param, IDS_OPTION_PUT)==0) {
  395. g_dwAction |= ACTION_PUT;
  396. return TRUE;
  397. }
  398. else if(IDSwcsicmp(hModule,param, IDS_OPTION_S)==0) {
  399. if(NULL==g_wszSrcStoreName)
  400. g_fSrcSystemStore=TRUE;
  401. else
  402. g_fDesSystemStore=TRUE;
  403. return TRUE;
  404. }
  405. else if(IDSwcsicmp(hModule,param, IDS_OPTION_R)==0) {
  406. if (!--(*pArgc))
  407. return FALSE;
  408. (*pArgv)++;
  409. if(NULL==g_wszSrcStoreName)
  410. return SetParam(&g_wszSrcStoreLocation, **pArgv);
  411. else
  412. return SetParam(&g_wszDesStoreLocation, **pArgv);
  413. }
  414. else if(IDSwcsicmp(hModule,param, IDS_OPTION_C)==0) {
  415. g_dwItem |= ITEM_CERT;
  416. return TRUE;
  417. }
  418. else if(IDSwcsicmp(hModule,param, IDS_OPTION_CRL)==0) {
  419. g_dwItem |= ITEM_CRL;
  420. return TRUE;
  421. }
  422. else if(IDSwcsicmp(hModule,param, IDS_OPTION_CTL)==0) {
  423. g_dwItem |= ITEM_CTL;
  424. return TRUE;
  425. }
  426. else if(IDSwcsicmp(hModule,param, IDS_OPTION_V)==0) {
  427. g_dwItem |= ITEM_VERBOSE;
  428. return TRUE;
  429. }
  430. else if(IDSwcsicmp(hModule,param, IDS_OPTION_ALL)==0) {
  431. g_fAll=TRUE;
  432. return TRUE;
  433. }
  434. else if(IDSwcsicmp(hModule,param, IDS_OPTION_N)==0) {
  435. if (!--(*pArgc))
  436. return FALSE;
  437. (*pArgv)++;
  438. return SetParam(&g_wszCertCN, **pArgv);
  439. }
  440. else if(IDSwcsicmp(hModule,param, IDS_OPTION_SHA1)==0) {
  441. if (!--(*pArgc))
  442. return FALSE;
  443. (*pArgv)++;
  444. return SetParam(&g_wszSha1Hash, **pArgv);
  445. }
  446. else if(IDSwcsicmp(hModule,param, IDS_OPTION_7)==0) {
  447. g_fSaveAs7=TRUE;
  448. return TRUE;
  449. }
  450. else if(IDSwcsicmp(hModule,param, IDS_OPTION_E)==0) {
  451. if (!--(*pArgc))
  452. return FALSE;
  453. (*pArgv)++;
  454. return SetParam(&g_wszCertEncodingType, **pArgv);
  455. }
  456. else if(IDSwcsicmp(hModule,param, IDS_OPTION_Y)==0) {
  457. if (!--(*pArgc))
  458. return FALSE;
  459. (*pArgv)++;
  460. if(NULL==g_wszSrcStoreName)
  461. return SetParam(&g_wszSrcStoreProvider, **pArgv);
  462. else
  463. return SetParam(&g_wszDesStoreProvider, **pArgv);
  464. }
  465. else if(IDSwcsicmp(hModule,param, IDS_OPTION_F)==0) {
  466. if (!--(*pArgc))
  467. return FALSE;
  468. (*pArgv)++;
  469. if(NULL==g_wszSrcStoreName)
  470. return SetParam(&g_wszSrcStoreOpenFlag, **pArgv);
  471. else
  472. return SetParam(&g_wszDesStoreOpenFlag, **pArgv);
  473. }
  474. else if(IDSwcsicmp(hModule, param, IDS_OPTION_EKU)==0) {
  475. if (!--(*pArgc))
  476. return FALSE;
  477. (*pArgv)++;
  478. return SetParam(&g_wszEKU, **pArgv);
  479. }
  480. else if(IDSwcsicmp(hModule, param, IDS_OPTION_NAME)==0) {
  481. if (!--(*pArgc))
  482. return FALSE;
  483. (*pArgv)++;
  484. return SetParam(&g_wszName, **pArgv);
  485. }
  486. else if(IDSwcsicmp(hModule, param, IDS_OPTION_MULTI)==0) {
  487. g_fMulti=TRUE;
  488. return TRUE;
  489. }
  490. else if(IDSwcsicmp(hModule, param, IDS_OPTION_TEST)==0) {
  491. g_fUndocumented=TRUE;
  492. return FALSE;
  493. }
  494. return FALSE;
  495. }
  496. //-----------------------------------------------------------------------------
  497. // Check the parameters
  498. //
  499. //-----------------------------------------------------------------------------
  500. BOOL CheckParameter()
  501. {
  502. DWORD dwItemCount=0;
  503. //check actions
  504. if((g_dwAction & ACTION_ADD) && (g_dwAction & ACTION_DELETE))
  505. {
  506. IDSwprintf(hModule, IDS_ERR_SINGLE_ACTION);
  507. return FALSE;
  508. }
  509. if((g_dwAction & ACTION_ADD) && (g_dwAction & ACTION_PUT))
  510. {
  511. IDSwprintf(hModule, IDS_ERR_SINGLE_ACTION);
  512. return FALSE;
  513. }
  514. if((g_dwAction & ACTION_PUT) && (g_dwAction & ACTION_DELETE))
  515. {
  516. IDSwprintf(hModule, IDS_ERR_SINGLE_ACTION);
  517. return FALSE;
  518. }
  519. if(0==g_dwAction)
  520. g_dwAction |= ACTION_DISPLAY;
  521. //-7 and -CTL can not be set at the same time for add or put
  522. if(TRUE==g_fSaveAs7)
  523. {
  524. if(g_dwItem & ITEM_CTL)
  525. {
  526. if((g_dwAction & ACTION_ADD) || (g_dwAction & ACTION_PUT))
  527. {
  528. IDSwprintf(hModule, IDS_ERR_7_CTL);
  529. IDSwprintf(hModule, IDS_ERR_7_CTL1);
  530. return FALSE;
  531. }
  532. }
  533. }
  534. //-n and -sha1 can not be set at the same time
  535. if(g_wszCertCN && g_wszSha1Hash)
  536. {
  537. IDSwprintf(hModule, IDS_ERR_N_SHA1);
  538. return FALSE;
  539. }
  540. //-all can not be set with -n and -sha1 option
  541. if(TRUE==g_fAll)
  542. {
  543. if(g_wszCertCN || g_wszSha1Hash)
  544. {
  545. IDSwprintf(hModule, IDS_ERR_ALL_N_SHA1);
  546. return FALSE;
  547. }
  548. }
  549. //-y, -f can not be set with -s and -r for source
  550. if(g_wszSrcStoreProvider || g_wszSrcStoreOpenFlag)
  551. {
  552. if((TRUE==g_fSrcSystemStore)||(g_wszSrcStoreLocation))
  553. {
  554. IDSwprintf(hModule, IDS_ERR_PROVIDER_SYSTEM);
  555. return FALSE;
  556. }
  557. }
  558. //-y, -f can not be set with -s and -r for desitnation
  559. if(g_wszDesStoreProvider || g_wszDesStoreOpenFlag)
  560. {
  561. if((TRUE==g_fDesSystemStore)||(g_wszDesStoreLocation))
  562. {
  563. IDSwprintf(hModule, IDS_ERR_PROVIDER_SYSTEM);
  564. return FALSE;
  565. }
  566. }
  567. //source store has to be set
  568. if(NULL==g_wszSrcStoreName)
  569. {
  570. IDSwprintf(hModule, IDS_ERR_SOURCE_STORE);
  571. return FALSE;
  572. }
  573. //get the source store Provider
  574. if(g_wszSrcStoreProvider)
  575. {
  576. if(S_OK != WSZtoSZ(g_wszSrcStoreProvider, &g_szSrcStoreProvider))
  577. {
  578. IDSwprintf(hModule, IDS_ERR_STORE_PROVIDER);
  579. return FALSE;
  580. }
  581. }
  582. //get the source store open flag
  583. if(g_wszSrcStoreOpenFlag)
  584. {
  585. g_dwSrcStoreOpenFlag = _wtol(g_wszSrcStoreOpenFlag);
  586. }
  587. //get the destination store Provider
  588. if(g_wszDesStoreProvider)
  589. {
  590. if(S_OK != WSZtoSZ(g_wszDesStoreProvider, &g_szDesStoreProvider))
  591. {
  592. IDSwprintf(hModule, IDS_ERR_STORE_PROVIDER);
  593. return FALSE;
  594. }
  595. }
  596. //get the destination store open flag
  597. if(g_wszDesStoreOpenFlag)
  598. {
  599. g_dwDesStoreOpenFlag = _wtol(g_wszDesStoreOpenFlag);
  600. }
  601. //get the encoding type
  602. if(g_wszCertEncodingType)
  603. {
  604. g_dwCertEncodingType = _wtol(g_wszCertEncodingType);
  605. }
  606. g_dwMsgAndCertEncodingType |= g_dwCertEncodingType;
  607. //get the source store location
  608. if(g_wszSrcStoreLocation)
  609. {
  610. if(IDSwcsicmp(hModule,g_wszSrcStoreLocation, IDS_R_CU) == 0)
  611. g_dwSrcStoreFlag = CERT_SYSTEM_STORE_CURRENT_USER;
  612. else
  613. {
  614. if(IDSwcsicmp(hModule,g_wszSrcStoreLocation, IDS_R_LM) == 0)
  615. g_dwSrcStoreFlag = CERT_SYSTEM_STORE_LOCAL_MACHINE;
  616. else
  617. {
  618. IDSwprintf(hModule,IDS_ERR_NO_REG);
  619. return FALSE;
  620. }
  621. }
  622. }
  623. //get the destincation store location
  624. if(g_wszDesStoreLocation)
  625. {
  626. if(IDSwcsicmp(hModule,g_wszDesStoreLocation, IDS_R_CU) == 0)
  627. g_dwDesStoreFlag = CERT_SYSTEM_STORE_CURRENT_USER;
  628. else
  629. {
  630. if(IDSwcsicmp(hModule,g_wszDesStoreLocation, IDS_R_LM) == 0)
  631. g_dwDesStoreFlag = CERT_SYSTEM_STORE_LOCAL_MACHINE;
  632. else
  633. {
  634. IDSwprintf(hModule,IDS_ERR_NO_REG);
  635. return FALSE;
  636. }
  637. }
  638. }
  639. //get the hash
  640. if(g_wszSha1Hash)
  641. {
  642. if(S_OK != WSZtoBLOB(g_wszSha1Hash, &g_pbHash, &g_cbHash))
  643. {
  644. //sha1 hash is invalid
  645. IDSwprintf(hModule, IDS_ERR_SHA1_HASH);
  646. return FALSE;
  647. }
  648. }
  649. //check the item
  650. if(g_dwAction & ACTION_DISPLAY)
  651. {
  652. if(0==g_dwItem || ITEM_VERBOSE==g_dwItem)
  653. g_dwItem = g_dwItem | ITEM_CERT | ITEM_CTL | ITEM_CRL;
  654. //can not set destination source
  655. if((g_wszDesStoreLocation) || (g_fDesSystemStore==TRUE) ||
  656. (g_wszCertCN) || (g_wszSha1Hash) || (g_fSaveAs7==TRUE) ||
  657. (g_wszDesStoreName) ||(g_wszDesStoreProvider) ||(g_wszDesStoreOpenFlag))
  658. {
  659. IDSwprintf(hModule,IDS_ERR_DISPLAY_TOO_MANY);
  660. return FALSE;
  661. }
  662. }
  663. //-eku can not be set for DISPLAY or PUT
  664. if((g_dwAction & ACTION_DISPLAY) || (g_dwAction & ACTION_PUT))
  665. {
  666. //can not set -eku option
  667. if(g_wszEKU || g_wszName)
  668. {
  669. IDSwprintf(hModule, IDS_ERR_DISPLAY_EKU);
  670. return FALSE;
  671. }
  672. }
  673. if(g_dwAction & ACTION_PUT)
  674. {
  675. //g_fAll can not be set,
  676. if(TRUE==g_fAll)
  677. {
  678. IDSwprintf(hModule, IDS_ERR_ALL_PUT);
  679. return FALSE;
  680. }
  681. //only one item can not set
  682. dwItemCount=0;
  683. if(g_dwItem & ITEM_CERT)
  684. dwItemCount++;
  685. if(g_dwItem & ITEM_CTL)
  686. dwItemCount++;
  687. if(g_dwItem & ITEM_CRL)
  688. dwItemCount++;
  689. if(1!=dwItemCount)
  690. {
  691. IDSwprintf(hModule, IDS_ERR_PUT_ITEM);
  692. return FALSE;
  693. }
  694. //check the destination store
  695. if(NULL == g_wszDesStoreName)
  696. {
  697. IDSwprintf(hModule,IDS_ERR_DES_STORE);
  698. return FALSE;
  699. }
  700. //can not set -s, -y, -f, or -r for the destination store
  701. if((g_fDesSystemStore==TRUE) || (g_wszDesStoreLocation) ||
  702. (g_wszDesStoreProvider) || (g_wszDesStoreOpenFlag))
  703. {
  704. IDSwprintf(hModule,IDS_TOO_MANY_DES_STORE);
  705. return FALSE;
  706. }
  707. }
  708. if((g_dwAction & ACTION_ADD) ||
  709. (g_dwAction & ACTION_DELETE))
  710. {
  711. //if g_fAll is set, OK
  712. if(TRUE==g_fAll)
  713. {
  714. if(g_dwItem==0 || ITEM_VERBOSE==g_dwItem )
  715. g_dwItem = g_dwItem | ITEM_CERT | ITEM_CTL | ITEM_CRL;
  716. }
  717. //check the destination store
  718. if(NULL == g_wszDesStoreName)
  719. {
  720. if(g_dwAction & ACTION_ADD)
  721. {
  722. IDSwprintf(hModule,IDS_ERR_DES_STORE);
  723. return FALSE;
  724. }
  725. g_fSameSrcDes=TRUE;
  726. //can not have set -s, -y, -f or -r if the store name is not set
  727. if((g_fDesSystemStore==TRUE) || (g_wszDesStoreLocation) ||
  728. (g_wszDesStoreProvider) || (g_wszDesStoreOpenFlag))
  729. {
  730. IDSwprintf(hModule,IDS_ERR_DES_STORE);
  731. return FALSE;
  732. }
  733. g_wszDesStoreName=g_wszSrcStoreName;
  734. g_dwDesStoreFlag=g_dwSrcStoreFlag;
  735. g_fDesSystemStore=g_fSrcSystemStore;
  736. g_szDesStoreProvider=g_szSrcStoreProvider;
  737. g_dwDesStoreOpenFlag=g_dwSrcStoreOpenFlag;
  738. }
  739. //if -7 is set, can not save to a system store
  740. if(TRUE==g_fSaveAs7)
  741. {
  742. if(TRUE==g_fDesSystemStore)
  743. {
  744. IDSwprintf(hModule,IDS_ERR_SOURCE_SYSTEM_7);
  745. return FALSE;
  746. }
  747. }
  748. }
  749. return TRUE;
  750. }
  751. //------------------------------------------------------------------------------------
  752. //
  753. // Open a store. The order of trying is following:
  754. //
  755. // Using predefined store provider
  756. // SystemStore
  757. // CTL
  758. // CRL
  759. // Serialized Store, PKCS#7, Encoded Cert
  760. // PKCS7 via sip
  761. // Base64 encoded, then go throught the whole thing again
  762. //
  763. //
  764. //------------------------------------------------------------------------------------
  765. BOOL OpenGenericStore(LPWSTR wszStoreName,
  766. BOOL fSystemStore,
  767. DWORD dwStoreFlag,
  768. LPSTR szStoreProvider,
  769. DWORD dwStoreOpenFlag,
  770. BOOL fCheckExist,
  771. HCERTSTORE *phCertStore)
  772. {
  773. HCERTSTORE hStore=NULL;
  774. BYTE *pbByte=NULL;
  775. DWORD cbByte=0;
  776. CRYPT_DATA_BLOB Blob;
  777. if(!wszStoreName || !phCertStore)
  778. return FALSE;
  779. //open the store using supplied store provider
  780. if(szStoreProvider)
  781. {
  782. hStore=CertOpenStore(szStoreProvider,
  783. g_dwMsgAndCertEncodingType,
  784. NULL,
  785. dwStoreOpenFlag,
  786. wszStoreName);
  787. //one shot and we are done
  788. goto CLEANUP;
  789. }
  790. //open the system store
  791. if(fSystemStore)
  792. {
  793. if(TRUE==fCheckExist)
  794. {
  795. //open Read Only stores
  796. hStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
  797. g_dwMsgAndCertEncodingType,
  798. NULL,
  799. dwStoreFlag |CERT_STORE_READONLY_FLAG,
  800. wszStoreName);
  801. //we need to open the store as non-readonly if the store exists
  802. //and we the source store is the same as destination store
  803. if(NULL!=hStore)
  804. {
  805. if(TRUE==g_fSameSrcDes)
  806. {
  807. CertCloseStore(hStore, 0);
  808. hStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
  809. g_dwMsgAndCertEncodingType,
  810. NULL,
  811. dwStoreFlag,
  812. wszStoreName);
  813. }
  814. }
  815. }
  816. else
  817. {
  818. hStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
  819. g_dwMsgAndCertEncodingType,
  820. NULL,
  821. dwStoreFlag,
  822. wszStoreName);
  823. }
  824. //one shot and we are done
  825. goto CLEANUP;
  826. }
  827. //open an encoded CTL
  828. hStore=OpenEncodedCTL(wszStoreName);
  829. if(hStore)
  830. {
  831. //mark this is a CTL
  832. if((0==g_dwItem) || (ITEM_VERBOSE==g_dwItem))
  833. g_dwItem |= ITEM_CTL;
  834. goto CLEANUP;
  835. }
  836. //open an encoded CRL
  837. hStore=OpenEncodedCRL(wszStoreName);
  838. if(hStore)
  839. {
  840. //mark this is a CRL
  841. if((0==g_dwItem) || (ITEM_VERBOSE==g_dwItem))
  842. g_dwItem |= ITEM_CRL;
  843. goto CLEANUP;
  844. }
  845. //open an encoded Cert
  846. hStore=OpenEncodedCert(wszStoreName);
  847. if(hStore)
  848. {
  849. //mark this is a CERT
  850. if((0==g_dwItem) || (ITEM_VERBOSE==g_dwItem))
  851. g_dwItem |= ITEM_CERT;
  852. goto CLEANUP;
  853. }
  854. //Serialized Store, PKCS#7, Encoded Cert
  855. hStore=CertOpenStore(CERT_STORE_PROV_FILENAME_W,
  856. g_dwMsgAndCertEncodingType,
  857. NULL,
  858. 0,
  859. wszStoreName);
  860. if(hStore)
  861. goto CLEANUP;
  862. //PKCS7 via SIP
  863. hStore=OpenSipStore(wszStoreName);
  864. if(hStore)
  865. goto CLEANUP;
  866. //base64 encoded
  867. if(!GetBase64Decoded(wszStoreName, &pbByte,&cbByte))
  868. goto CLEANUP;
  869. Blob.cbData=cbByte;
  870. Blob.pbData=pbByte;
  871. //open a temporary memory store
  872. hStore=CertOpenStore(CERT_STORE_PROV_MEMORY,
  873. g_dwMsgAndCertEncodingType,
  874. NULL,
  875. 0,
  876. NULL);
  877. if(!hStore)
  878. goto CLEANUP;
  879. //try as encodedCTL
  880. if(CertAddEncodedCTLToStore(hStore,
  881. g_dwMsgAndCertEncodingType,
  882. pbByte,
  883. cbByte,
  884. CERT_STORE_ADD_ALWAYS,
  885. NULL))
  886. goto CLEANUP;
  887. //try as encodedCRL
  888. if(CertAddEncodedCRLToStore(hStore,
  889. g_dwMsgAndCertEncodingType,
  890. pbByte,
  891. cbByte,
  892. CERT_STORE_ADD_ALWAYS,
  893. NULL))
  894. goto CLEANUP;
  895. //try as encodedCert
  896. if(CertAddEncodedCertificateToStore(hStore,
  897. g_dwMsgAndCertEncodingType,
  898. pbByte,
  899. cbByte,
  900. CERT_STORE_ADD_ALWAYS,
  901. NULL))
  902. goto CLEANUP;
  903. //close the temporary store
  904. CertCloseStore(hStore, 0);
  905. hStore=NULL;
  906. //try as an 7
  907. hStore=CertOpenStore(CERT_STORE_PROV_PKCS7,
  908. g_dwMsgAndCertEncodingType,
  909. NULL,
  910. 0,
  911. &Blob);
  912. if(hStore)
  913. goto CLEANUP;
  914. //try as a serialized store
  915. hStore=CertOpenStore(CERT_STORE_PROV_SERIALIZED,
  916. g_dwMsgAndCertEncodingType,
  917. NULL,
  918. 0,
  919. &Blob);
  920. //now we give up
  921. CLEANUP:
  922. //free memory
  923. if(pbByte)
  924. ToolUtlFree(pbByte);
  925. if(hStore)
  926. {
  927. *phCertStore=hStore;
  928. return TRUE;
  929. }
  930. return FALSE;
  931. }
  932. //-------------------------------------------------------------------------
  933. //
  934. // Add certs/CTLs/CRLs from the source store to the destination store
  935. //
  936. //-------------------------------------------------------------------------
  937. BOOL AddCertStore(HCERTSTORE hCertStore)
  938. {
  939. BOOL fResult=FALSE;
  940. HCERTSTORE hAddStore=NULL;
  941. int idsErr=0;
  942. CRYPT_HASH_BLOB Blob;
  943. DWORD dwIndex=0;
  944. PCCERT_CONTEXT pCertContext=NULL;
  945. DWORD dwCertCount=0;
  946. PCCERT_CONTEXT *rgpCertContext=NULL;
  947. PCCRL_CONTEXT pCRLContext=NULL;
  948. DWORD dwCRLCount=0;
  949. PCCRL_CONTEXT *rgpCRLContext=NULL;
  950. PCCTL_CONTEXT pCTLContext=NULL;
  951. DWORD dwCTLCount=0;
  952. PCCTL_CONTEXT *rgpCTLContext=NULL;
  953. //User has to specify the item to delete
  954. if(g_dwItem==0 || ITEM_VERBOSE==g_dwItem)
  955. {
  956. IDSwprintf(hModule,IDS_ERR_C_CTL_CTL_ALL);
  957. return FALSE;
  958. }
  959. //create a temporaray memory store
  960. hAddStore=CertOpenStore(CERT_STORE_PROV_MEMORY,
  961. g_dwMsgAndCertEncodingType,
  962. NULL,
  963. 0,
  964. NULL);
  965. if(!hAddStore)
  966. {
  967. idsErr=IDS_ERR_TMP_STORE;
  968. goto CLEANUP;
  969. }
  970. //add certs
  971. if(g_dwItem & ITEM_CERT)
  972. {
  973. //add all
  974. if(g_fAll)
  975. {
  976. if(!MoveItem(hCertStore, hAddStore,ITEM_CERT))
  977. {
  978. idsErr=IDS_ERR_ADD_CERT_ALL;
  979. goto CLEANUP;
  980. }
  981. }
  982. else
  983. {
  984. //add based on Hash
  985. if(g_pbHash)
  986. {
  987. Blob.cbData=g_cbHash;
  988. Blob.pbData=g_pbHash;
  989. //search for the certificate
  990. pCertContext=CertFindCertificateInStore(
  991. hCertStore,
  992. g_dwCertEncodingType,
  993. 0,
  994. CERT_FIND_SHA1_HASH,
  995. &Blob,
  996. NULL);
  997. if(!pCertContext)
  998. {
  999. idsErr=IDS_ERR_NO_CERT_HASH;
  1000. goto CLEANUP;
  1001. }
  1002. //add certificate to the hash
  1003. if(!CertAddCertificateContextToStore(hAddStore,
  1004. pCertContext,
  1005. CERT_STORE_ADD_REPLACE_EXISTING,
  1006. NULL))
  1007. {
  1008. idsErr=IDS_ERR_ADD_CERT;
  1009. goto CLEANUP;
  1010. }
  1011. //free the pCertContext
  1012. CertFreeCertificateContext(pCertContext);
  1013. pCertContext=NULL;
  1014. }
  1015. else
  1016. {
  1017. if(g_wszCertCN)
  1018. {
  1019. //search for the certificate
  1020. if(!BuildCertList(hCertStore, g_wszCertCN,
  1021. &rgpCertContext, &dwCertCount))
  1022. {
  1023. idsErr=IDS_ERR_CERT_FIND;
  1024. goto CLEANUP;
  1025. }
  1026. }
  1027. else
  1028. {
  1029. //search for the certificate
  1030. if(!BuildCertList(hCertStore, NULL,
  1031. &rgpCertContext, &dwCertCount))
  1032. {
  1033. idsErr=IDS_ERR_CERT_FIND;
  1034. goto CLEANUP;
  1035. }
  1036. }
  1037. //check if there is no certs
  1038. if(0==dwCertCount && g_wszCertCN)
  1039. {
  1040. idsErr=IDS_ERR_ADD_NO_CERT;
  1041. goto CLEANUP;
  1042. }
  1043. //check if there is only one cert
  1044. if(1==dwCertCount)
  1045. {
  1046. //add certificate
  1047. if(!CertAddCertificateContextToStore(hAddStore,
  1048. rgpCertContext[0],
  1049. CERT_STORE_ADD_REPLACE_EXISTING,
  1050. NULL))
  1051. {
  1052. idsErr=IDS_ERR_ADD_CERT;
  1053. goto CLEANUP;
  1054. }
  1055. }
  1056. else
  1057. {
  1058. if(dwCertCount>1)
  1059. {
  1060. //promt user for the index number to add
  1061. if(!DisplayCertAndPrompt(rgpCertContext, dwCertCount, &dwIndex))
  1062. {
  1063. idsErr=IDS_ERR_ADD_CERT;
  1064. goto CLEANUP;
  1065. }
  1066. //add certificate
  1067. if(!CertAddCertificateContextToStore(hAddStore,
  1068. rgpCertContext[dwIndex],
  1069. CERT_STORE_ADD_REPLACE_EXISTING,
  1070. NULL))
  1071. {
  1072. idsErr=IDS_ERR_ADD_CERT;
  1073. goto CLEANUP;
  1074. }
  1075. }
  1076. }
  1077. }
  1078. }
  1079. }
  1080. //add CRLs
  1081. if(g_dwItem & ITEM_CRL)
  1082. {
  1083. //add all
  1084. if(g_fAll)
  1085. {
  1086. if(!MoveItem(hCertStore, hAddStore,ITEM_CRL))
  1087. {
  1088. idsErr=IDS_ERR_ADD_CRL_ALL;
  1089. goto CLEANUP;
  1090. }
  1091. }
  1092. else
  1093. {
  1094. //add based on Hash
  1095. if(g_pbHash)
  1096. {
  1097. Blob.cbData=g_cbHash;
  1098. Blob.pbData=g_pbHash;
  1099. pCRLContext=FindCRLInStore(
  1100. hCertStore,
  1101. &Blob);
  1102. if(!pCRLContext)
  1103. {
  1104. idsErr=IDS_ERR_NO_CRL_HASH;
  1105. goto CLEANUP;
  1106. }
  1107. //add CRL to the hash
  1108. if(!CertAddCRLContextToStore(hAddStore,
  1109. pCRLContext,
  1110. CERT_STORE_ADD_REPLACE_EXISTING,
  1111. NULL))
  1112. {
  1113. idsErr=IDS_ERR_ADD_CRL;
  1114. goto CLEANUP;
  1115. }
  1116. //free the pCRLContext
  1117. CertFreeCRLContext(pCRLContext);
  1118. pCRLContext=NULL;
  1119. }
  1120. else
  1121. {
  1122. //search for the CRL
  1123. if(!BuildCRLList(hCertStore, &rgpCRLContext, &dwCRLCount))
  1124. {
  1125. idsErr=IDS_ERR_CRL_FIND;
  1126. goto CLEANUP;
  1127. }
  1128. //check if there is only one CRL
  1129. if(1==dwCRLCount)
  1130. {
  1131. //add CRL
  1132. if(!CertAddCRLContextToStore(hAddStore,
  1133. rgpCRLContext[0],
  1134. CERT_STORE_ADD_REPLACE_EXISTING,
  1135. NULL))
  1136. {
  1137. idsErr=IDS_ERR_ADD_CRL;
  1138. goto CLEANUP;
  1139. }
  1140. }
  1141. else
  1142. {
  1143. if(dwCRLCount>1)
  1144. {
  1145. //promt user for the index number to add
  1146. if(!DisplayCRLAndPrompt(rgpCRLContext, dwCRLCount, &dwIndex))
  1147. {
  1148. idsErr=IDS_ERR_ADD_CRL;
  1149. goto CLEANUP;
  1150. }
  1151. //add certificate
  1152. if(!CertAddCRLContextToStore(hAddStore,
  1153. rgpCRLContext[dwIndex],
  1154. CERT_STORE_ADD_REPLACE_EXISTING,
  1155. NULL))
  1156. {
  1157. idsErr=IDS_ERR_ADD_CRL;
  1158. goto CLEANUP;
  1159. }
  1160. }
  1161. }
  1162. }
  1163. }
  1164. }
  1165. //add CTLs
  1166. if(g_dwItem & ITEM_CTL)
  1167. {
  1168. //add all
  1169. if(g_fAll)
  1170. {
  1171. if(!MoveItem(hCertStore, hAddStore,ITEM_CTL))
  1172. {
  1173. idsErr=IDS_ERR_ADD_CTL_ALL;
  1174. goto CLEANUP;
  1175. }
  1176. }
  1177. else
  1178. {
  1179. //add based on Hash
  1180. if(g_pbHash)
  1181. {
  1182. Blob.cbData=g_cbHash;
  1183. Blob.pbData=g_pbHash;
  1184. pCTLContext=CertFindCTLInStore(
  1185. hCertStore,
  1186. g_dwMsgAndCertEncodingType,
  1187. 0,
  1188. CTL_FIND_SHA1_HASH,
  1189. &Blob,
  1190. NULL);
  1191. if(!pCTLContext)
  1192. {
  1193. idsErr=IDS_ERR_NO_CTL_HASH;
  1194. goto CLEANUP;
  1195. }
  1196. //add CTL to the hash
  1197. if(!CertAddCTLContextToStore(hAddStore,
  1198. pCTLContext,
  1199. CERT_STORE_ADD_REPLACE_EXISTING,
  1200. NULL))
  1201. {
  1202. idsErr=IDS_ERR_ADD_CTL;
  1203. goto CLEANUP;
  1204. }
  1205. //free the pCRLContext
  1206. CertFreeCTLContext(pCTLContext);
  1207. pCTLContext=NULL;
  1208. }
  1209. else
  1210. {
  1211. //search for the certificate
  1212. if(!BuildCTLList(hCertStore,&rgpCTLContext, &dwCTLCount))
  1213. {
  1214. idsErr=IDS_ERR_CTL_FIND;
  1215. goto CLEANUP;
  1216. }
  1217. //check if there is only one item
  1218. if(1==dwCTLCount)
  1219. {
  1220. //add CRL
  1221. if(!CertAddCTLContextToStore(hAddStore,
  1222. rgpCTLContext[0],
  1223. CERT_STORE_ADD_REPLACE_EXISTING,
  1224. NULL))
  1225. {
  1226. idsErr=IDS_ERR_ADD_CTL;
  1227. goto CLEANUP;
  1228. }
  1229. }
  1230. else
  1231. {
  1232. if(dwCTLCount>1)
  1233. {
  1234. //promt user for the index number to add
  1235. if(!DisplayCTLAndPrompt(rgpCTLContext, dwCTLCount, &dwIndex))
  1236. {
  1237. idsErr=IDS_ERR_ADD_CTL;
  1238. goto CLEANUP;
  1239. }
  1240. //add certificate
  1241. if(!CertAddCTLContextToStore(hAddStore,
  1242. rgpCTLContext[dwIndex],
  1243. CERT_STORE_ADD_REPLACE_EXISTING,
  1244. NULL))
  1245. {
  1246. idsErr=IDS_ERR_ADD_CTL;
  1247. goto CLEANUP;
  1248. }
  1249. }
  1250. }
  1251. }
  1252. }
  1253. }
  1254. //save the properties to the certificates in the store
  1255. if(g_wszEKU)
  1256. {
  1257. if(!SetEKUProperty(hAddStore))
  1258. {
  1259. idsErr=IDS_ERR_SET_EKU;
  1260. goto CLEANUP;
  1261. }
  1262. }
  1263. //save the properties to the certificates in the store
  1264. if(g_wszName)
  1265. {
  1266. if(!SetNameProperty(hAddStore))
  1267. {
  1268. idsErr=IDS_ERR_SET_NAME;
  1269. goto CLEANUP;
  1270. }
  1271. }
  1272. //save the hAddStore to the destination store
  1273. if(!SaveStore(hAddStore))
  1274. goto CLEANUP;
  1275. fResult=TRUE;
  1276. CLEANUP:
  1277. if(pCertContext)
  1278. CertFreeCertificateContext(pCertContext);
  1279. if(pCRLContext)
  1280. CertFreeCRLContext(pCRLContext);
  1281. if(pCTLContext)
  1282. CertFreeCTLContext(pCTLContext);
  1283. if(rgpCertContext)
  1284. {
  1285. for(dwIndex=0; dwIndex<dwCertCount; dwIndex++)
  1286. CertFreeCertificateContext(rgpCertContext[dwIndex]);
  1287. free(rgpCertContext);
  1288. }
  1289. if(rgpCRLContext)
  1290. {
  1291. for(dwIndex=0; dwIndex<dwCRLCount; dwIndex++)
  1292. CertFreeCRLContext(rgpCRLContext[dwIndex]);
  1293. free(rgpCRLContext);
  1294. }
  1295. if(rgpCTLContext)
  1296. {
  1297. for(dwIndex=0; dwIndex<dwCTLCount; dwIndex++)
  1298. CertFreeCTLContext(rgpCTLContext[dwIndex]);
  1299. free(rgpCTLContext);
  1300. }
  1301. if(hAddStore)
  1302. CertCloseStore(hAddStore, 0);
  1303. if(FALSE==fResult)
  1304. {
  1305. //output the error message
  1306. IDSwprintf(hModule,idsErr);
  1307. }
  1308. return fResult;
  1309. }
  1310. //-------------------------------------------------------------------------
  1311. //
  1312. // Put certs/CTLs/CRLs from the source store to the destination store
  1313. //
  1314. //-------------------------------------------------------------------------
  1315. BOOL PutCertStore(HCERTSTORE hCertStore)
  1316. {
  1317. BOOL fResult=FALSE;
  1318. HCERTSTORE hPutStore=NULL;
  1319. int idsErr=0;
  1320. CRYPT_HASH_BLOB Blob;
  1321. DWORD dwIndex=0;
  1322. PCCERT_CONTEXT pCertContext=NULL;
  1323. PCCERT_CONTEXT pCertPut=NULL;
  1324. DWORD dwCertCount=0;
  1325. PCCERT_CONTEXT *rgpCertContext=NULL;
  1326. PCCRL_CONTEXT pCRLContext=NULL;
  1327. PCCRL_CONTEXT pCRLPut=NULL;
  1328. DWORD dwCRLCount=0;
  1329. PCCRL_CONTEXT *rgpCRLContext=NULL;
  1330. PCCTL_CONTEXT pCTLContext=NULL;
  1331. PCCTL_CONTEXT pCTLPut=NULL;
  1332. DWORD dwCTLCount=0;
  1333. PCCTL_CONTEXT *rgpCTLContext=NULL;
  1334. BYTE *pByte=NULL;
  1335. DWORD cbByte=0;
  1336. DWORD dwCRLFlag=0;
  1337. //User has to specify the item to delete
  1338. if(g_dwItem==0 || ITEM_VERBOSE==g_dwItem)
  1339. {
  1340. IDSwprintf(hModule,IDS_ERR_PUT_ITEM);
  1341. return FALSE;
  1342. }
  1343. //create a temporaray memory store
  1344. hPutStore=CertOpenStore(CERT_STORE_PROV_MEMORY,
  1345. g_dwMsgAndCertEncodingType,
  1346. NULL,
  1347. 0,
  1348. NULL);
  1349. if(!hPutStore)
  1350. {
  1351. idsErr=IDS_ERR_TMP_STORE;
  1352. goto CLEANUP;
  1353. }
  1354. //put certs
  1355. if(g_dwItem & ITEM_CERT)
  1356. {
  1357. //add based on Hash
  1358. if(g_pbHash)
  1359. {
  1360. Blob.cbData=g_cbHash;
  1361. Blob.pbData=g_pbHash;
  1362. //search for the certificate
  1363. pCertContext=CertFindCertificateInStore(
  1364. hCertStore,
  1365. g_dwCertEncodingType,
  1366. 0,
  1367. CERT_FIND_SHA1_HASH,
  1368. &Blob,
  1369. NULL);
  1370. if(!pCertContext)
  1371. {
  1372. idsErr=IDS_ERR_NO_CERT_HASH;
  1373. goto CLEANUP;
  1374. }
  1375. //add certificate to the hash
  1376. if(!CertAddCertificateContextToStore(hPutStore,
  1377. pCertContext,
  1378. CERT_STORE_ADD_REPLACE_EXISTING,
  1379. NULL))
  1380. {
  1381. idsErr=IDS_ERR_PUT_CERT;
  1382. goto CLEANUP;
  1383. }
  1384. //free the pCertContext
  1385. CertFreeCertificateContext(pCertContext);
  1386. pCertContext=NULL;
  1387. }
  1388. else
  1389. {
  1390. if(g_wszCertCN)
  1391. {
  1392. //search for the certificate
  1393. if(!BuildCertList(hCertStore, g_wszCertCN,
  1394. &rgpCertContext, &dwCertCount))
  1395. {
  1396. idsErr=IDS_ERR_CERT_FIND;
  1397. goto CLEANUP;
  1398. }
  1399. }
  1400. else
  1401. {
  1402. //search for the certificate
  1403. if(!BuildCertList(hCertStore, NULL,
  1404. &rgpCertContext, &dwCertCount))
  1405. {
  1406. idsErr=IDS_ERR_PUT_NO_CERT;
  1407. goto CLEANUP;
  1408. }
  1409. }
  1410. //check if there is no certs
  1411. if(0==dwCertCount)
  1412. {
  1413. idsErr=IDS_ERR_CERT_FIND;
  1414. goto CLEANUP;
  1415. }
  1416. //check if there is only one cert
  1417. if(1==dwCertCount)
  1418. {
  1419. //add certificate
  1420. if(!CertAddCertificateContextToStore(hPutStore,
  1421. rgpCertContext[0],
  1422. CERT_STORE_ADD_REPLACE_EXISTING,
  1423. NULL))
  1424. {
  1425. idsErr=IDS_ERR_PUT_CERT;
  1426. goto CLEANUP;
  1427. }
  1428. }
  1429. else
  1430. {
  1431. if(dwCertCount>1)
  1432. {
  1433. //promt user for the index number to add
  1434. if(!DisplayCertAndPrompt(rgpCertContext, dwCertCount, &dwIndex))
  1435. {
  1436. idsErr=IDS_ERR_PUT_CERT;
  1437. goto CLEANUP;
  1438. }
  1439. //add certificate
  1440. if(!CertAddCertificateContextToStore(hPutStore,
  1441. rgpCertContext[dwIndex],
  1442. CERT_STORE_ADD_REPLACE_EXISTING,
  1443. NULL))
  1444. {
  1445. idsErr=IDS_ERR_PUT_CERT;
  1446. goto CLEANUP;
  1447. }
  1448. }
  1449. }
  1450. }
  1451. }
  1452. //add CRLs
  1453. if(g_dwItem & ITEM_CRL)
  1454. {
  1455. //add based on Hash
  1456. if(g_pbHash)
  1457. {
  1458. Blob.cbData=g_cbHash;
  1459. Blob.pbData=g_pbHash;
  1460. pCRLContext=FindCRLInStore(
  1461. hCertStore,
  1462. &Blob);
  1463. if(!pCRLContext)
  1464. {
  1465. idsErr=IDS_ERR_NO_CRL_HASH;
  1466. goto CLEANUP;
  1467. }
  1468. //add CRL to the hash
  1469. if(!CertAddCRLContextToStore(hPutStore,
  1470. pCRLContext,
  1471. CERT_STORE_ADD_REPLACE_EXISTING,
  1472. NULL))
  1473. {
  1474. idsErr=IDS_ERR_PUT_CRL;
  1475. goto CLEANUP;
  1476. }
  1477. //free the pCRLContext
  1478. CertFreeCRLContext(pCRLContext);
  1479. pCRLContext=NULL;
  1480. }
  1481. else
  1482. {
  1483. //search for the CRL
  1484. if(!BuildCRLList(hCertStore, &rgpCRLContext, &dwCRLCount))
  1485. {
  1486. idsErr=IDS_ERR_PUT_CRL_FIND;
  1487. goto CLEANUP;
  1488. }
  1489. //check if there is no certs
  1490. if(0==dwCRLCount)
  1491. {
  1492. idsErr=IDS_ERR_PUT_CRL_FIND;
  1493. goto CLEANUP;
  1494. }
  1495. //check if there is only one CRL
  1496. if(1==dwCRLCount)
  1497. {
  1498. //add CRL
  1499. if(!CertAddCRLContextToStore(hPutStore,
  1500. rgpCRLContext[0],
  1501. CERT_STORE_ADD_REPLACE_EXISTING,
  1502. NULL))
  1503. {
  1504. idsErr=IDS_ERR_PUT_CRL;
  1505. goto CLEANUP;
  1506. }
  1507. }
  1508. else
  1509. {
  1510. if(dwCRLCount>1)
  1511. {
  1512. //promt user for the index number to add
  1513. if(!DisplayCRLAndPrompt(rgpCRLContext, dwCRLCount, &dwIndex))
  1514. {
  1515. idsErr=IDS_ERR_PUT_CRL;
  1516. goto CLEANUP;
  1517. }
  1518. //add certificate
  1519. if(!CertAddCRLContextToStore(hPutStore,
  1520. rgpCRLContext[dwIndex],
  1521. CERT_STORE_ADD_REPLACE_EXISTING,
  1522. NULL))
  1523. {
  1524. idsErr=IDS_ERR_PUT_CRL;
  1525. goto CLEANUP;
  1526. }
  1527. }
  1528. }
  1529. }
  1530. }
  1531. //add CTLs
  1532. if(g_dwItem & ITEM_CTL)
  1533. {
  1534. //add based on Hash
  1535. if(g_pbHash)
  1536. {
  1537. Blob.cbData=g_cbHash;
  1538. Blob.pbData=g_pbHash;
  1539. pCTLContext=CertFindCTLInStore(
  1540. hCertStore,
  1541. g_dwMsgAndCertEncodingType,
  1542. 0,
  1543. CTL_FIND_SHA1_HASH,
  1544. &Blob,
  1545. NULL);
  1546. if(!pCTLContext)
  1547. {
  1548. idsErr=IDS_ERR_NO_CTL_HASH;
  1549. goto CLEANUP;
  1550. }
  1551. //add CTL to the hash
  1552. if(!CertAddCTLContextToStore(hPutStore,
  1553. pCTLContext,
  1554. CERT_STORE_ADD_REPLACE_EXISTING,
  1555. NULL))
  1556. {
  1557. idsErr=IDS_ERR_PUT_CTL;
  1558. goto CLEANUP;
  1559. }
  1560. //free the pCRLContext
  1561. CertFreeCTLContext(pCTLContext);
  1562. pCTLContext=NULL;
  1563. }
  1564. else
  1565. {
  1566. //search for the certificate
  1567. if(!BuildCTLList(hCertStore,&rgpCTLContext, &dwCTLCount))
  1568. {
  1569. idsErr=IDS_ERR_PUT_CTL_FIND;
  1570. goto CLEANUP;
  1571. }
  1572. //check if there is no certs
  1573. if(0==dwCTLCount)
  1574. {
  1575. idsErr=IDS_ERR_PUT_CTL_FIND;
  1576. goto CLEANUP;
  1577. }
  1578. //check if there is only one item
  1579. if(1==dwCTLCount)
  1580. {
  1581. //add CRL
  1582. if(!CertAddCTLContextToStore(hPutStore,
  1583. rgpCTLContext[0],
  1584. CERT_STORE_ADD_REPLACE_EXISTING,
  1585. NULL))
  1586. {
  1587. idsErr=IDS_ERR_PUT_CTL;
  1588. goto CLEANUP;
  1589. }
  1590. }
  1591. else
  1592. {
  1593. if(dwCTLCount>1)
  1594. {
  1595. //promt user for the index number to add
  1596. if(!DisplayCTLAndPrompt(rgpCTLContext, dwCTLCount, &dwIndex))
  1597. {
  1598. idsErr=IDS_ERR_PUT_CTL;
  1599. goto CLEANUP;
  1600. }
  1601. //add certificate
  1602. if(!CertAddCTLContextToStore(hPutStore,
  1603. rgpCTLContext[dwIndex],
  1604. CERT_STORE_ADD_REPLACE_EXISTING,
  1605. NULL))
  1606. {
  1607. idsErr=IDS_ERR_PUT_CTL;
  1608. goto CLEANUP;
  1609. }
  1610. }
  1611. }
  1612. }
  1613. }
  1614. //save the hPutStore to the destination store
  1615. //save as 7 is required
  1616. if(g_fSaveAs7==TRUE)
  1617. {
  1618. if(!CertSaveStore(hPutStore,
  1619. g_dwMsgAndCertEncodingType,
  1620. CERT_STORE_SAVE_AS_PKCS7,
  1621. CERT_STORE_SAVE_TO_FILENAME_W,
  1622. g_wszDesStoreName,
  1623. 0))
  1624. {
  1625. IDSwprintf(hModule,IDS_ERR_SAVE_DES_STORE);
  1626. goto CLEANUP;
  1627. }
  1628. }
  1629. else
  1630. {
  1631. //get the BLOB to save to a file in X509 format
  1632. if(g_dwItem & ITEM_CERT)
  1633. {
  1634. if(NULL==(pCertPut=CertEnumCertificatesInStore(hPutStore, NULL)))
  1635. {
  1636. IDSwprintf(hModule,IDS_ERR_SAVE_DES_STORE);
  1637. goto CLEANUP;
  1638. }
  1639. pByte=pCertPut->pbCertEncoded;
  1640. cbByte=pCertPut->cbCertEncoded;
  1641. }
  1642. if(g_dwItem & ITEM_CRL)
  1643. {
  1644. if(NULL==(pCRLPut=CertGetCRLFromStore(hPutStore,
  1645. NULL,
  1646. NULL,
  1647. &dwCRLFlag)))
  1648. {
  1649. IDSwprintf(hModule,IDS_ERR_SAVE_DES_STORE);
  1650. goto CLEANUP;
  1651. }
  1652. pByte=pCRLPut->pbCrlEncoded;
  1653. cbByte=pCRLPut->cbCrlEncoded;
  1654. }
  1655. if(g_dwItem & ITEM_CTL)
  1656. {
  1657. if(NULL==(pCTLPut=CertEnumCTLsInStore(hPutStore, NULL)))
  1658. {
  1659. IDSwprintf(hModule,IDS_ERR_SAVE_DES_STORE);
  1660. goto CLEANUP;
  1661. }
  1662. pByte=pCTLPut->pbCtlEncoded;
  1663. cbByte=pCTLPut->cbCtlEncoded;
  1664. }
  1665. if(S_OK !=OpenAndWriteToFile(g_wszDesStoreName,pByte, cbByte))
  1666. {
  1667. IDSwprintf(hModule,IDS_ERR_SAVE_DES_STORE);
  1668. goto CLEANUP;
  1669. }
  1670. }
  1671. fResult=TRUE;
  1672. CLEANUP:
  1673. if(pCertContext)
  1674. CertFreeCertificateContext(pCertContext);
  1675. if(pCRLContext)
  1676. CertFreeCRLContext(pCRLContext);
  1677. if(pCTLContext)
  1678. CertFreeCTLContext(pCTLContext);
  1679. if(pCertPut)
  1680. CertFreeCertificateContext(pCertPut);
  1681. if(pCRLPut)
  1682. CertFreeCRLContext(pCRLPut);
  1683. if(pCTLPut)
  1684. CertFreeCTLContext(pCTLPut);
  1685. if(rgpCertContext)
  1686. {
  1687. for(dwIndex=0; dwIndex<dwCertCount; dwIndex++)
  1688. CertFreeCertificateContext(rgpCertContext[dwIndex]);
  1689. free(rgpCertContext);
  1690. }
  1691. if(rgpCRLContext)
  1692. {
  1693. for(dwIndex=0; dwIndex<dwCRLCount; dwIndex++)
  1694. CertFreeCRLContext(rgpCRLContext[dwIndex]);
  1695. free(rgpCRLContext);
  1696. }
  1697. if(rgpCTLContext)
  1698. {
  1699. for(dwIndex=0; dwIndex<dwCTLCount; dwIndex++)
  1700. CertFreeCTLContext(rgpCTLContext[dwIndex]);
  1701. free(rgpCTLContext);
  1702. }
  1703. if(hPutStore)
  1704. CertCloseStore(hPutStore, 0);
  1705. if(FALSE==fResult)
  1706. {
  1707. //output the error message
  1708. IDSwprintf(hModule,idsErr);
  1709. }
  1710. return fResult;
  1711. }
  1712. //-------------------------------------------------------------------------
  1713. //
  1714. // Delete certs/CTLs/CRLs from the source store to the destination store
  1715. //
  1716. //-------------------------------------------------------------------------
  1717. BOOL DeleteCertStore(HCERTSTORE hCertStore)
  1718. {
  1719. BOOL fResult=FALSE;
  1720. HCERTSTORE hDeleteStore=NULL;
  1721. BOOL fDuplicated=FALSE;
  1722. int idsErr=0;
  1723. CRYPT_HASH_BLOB Blob;
  1724. DWORD dwIndex=0;
  1725. PCCERT_CONTEXT pCertContext=NULL;
  1726. DWORD dwCertCount=0;
  1727. PCCERT_CONTEXT *rgpCertContext=NULL;
  1728. PCCRL_CONTEXT pCRLContext=NULL;
  1729. DWORD dwCRLCount=0;
  1730. PCCRL_CONTEXT *rgpCRLContext=NULL;
  1731. PCCTL_CONTEXT pCTLContext=NULL;
  1732. DWORD dwCTLCount=0;
  1733. PCCTL_CONTEXT *rgpCTLContext=NULL;
  1734. //User has to specify the item to delete
  1735. if(g_dwItem==0 || ITEM_VERBOSE==g_dwItem)
  1736. {
  1737. IDSwprintf(hModule,IDS_ERR_C_CTL_CTL_ALL);
  1738. return FALSE;
  1739. }
  1740. //first of all, create a certificate from which the certs will be deleted
  1741. //if the source store is a fileStore, or a system store saved to its self,
  1742. //we do not need to duplicate the source store since the deletion is not persistent;
  1743. //otherwise, we need to duplicate the source store so that the deletion
  1744. //will not show up at the source store
  1745. if( ((NULL != g_szSrcStoreProvider) &&(FALSE==g_fSameSrcDes) ) ||
  1746. ((FALSE==g_fSameSrcDes) &&(TRUE==g_fSrcSystemStore)))
  1747. {
  1748. //open a temporary store
  1749. hDeleteStore=CertOpenStore(CERT_STORE_PROV_MEMORY,
  1750. g_dwMsgAndCertEncodingType,
  1751. NULL,
  1752. 0,
  1753. NULL);
  1754. if(!hDeleteStore)
  1755. {
  1756. idsErr=IDS_ERR_TMP_STORE;
  1757. goto CLEANUP;
  1758. }
  1759. fDuplicated=TRUE;
  1760. //need to copy from the source to the delete store
  1761. if(!MoveItem(hCertStore, hDeleteStore, ITEM_CERT | ITEM_CTL | ITEM_CRL))
  1762. {
  1763. idsErr=IDS_ERR_COPY_FROM_SRC;
  1764. goto CLEANUP;
  1765. }
  1766. }
  1767. else
  1768. hDeleteStore=hCertStore;
  1769. //now, we delete CERTs, CTLs, and CRLs
  1770. //delete certs
  1771. if(g_dwItem & ITEM_CERT)
  1772. {
  1773. //delete all
  1774. if(g_fAll)
  1775. {
  1776. if(!DeleteItem(hDeleteStore,ITEM_CERT))
  1777. {
  1778. idsErr=IDS_ERR_DELETE_CERT_ALL;
  1779. goto CLEANUP;
  1780. }
  1781. }
  1782. else
  1783. {
  1784. //delete based on Hash
  1785. if(g_pbHash)
  1786. {
  1787. Blob.cbData=g_cbHash;
  1788. Blob.pbData=g_pbHash;
  1789. //search for the certificate
  1790. pCertContext=CertFindCertificateInStore(
  1791. hDeleteStore,
  1792. g_dwCertEncodingType,
  1793. 0,
  1794. CERT_FIND_SHA1_HASH,
  1795. &Blob,
  1796. NULL);
  1797. if(!pCertContext)
  1798. {
  1799. idsErr=IDS_ERR_NO_CERT_HASH;
  1800. goto CLEANUP;
  1801. }
  1802. //delete certificate to the hash
  1803. if(!CertDeleteCertificateFromStore(pCertContext))
  1804. {
  1805. idsErr=IDS_ERR_DELETE_CERT;
  1806. goto CLEANUP;
  1807. }
  1808. //free the pCertContext
  1809. //CertFreeCertificateContext(pCertContext);
  1810. pCertContext=NULL;
  1811. }
  1812. else
  1813. {
  1814. if(g_wszCertCN)
  1815. {
  1816. //search for the certificate
  1817. if(!BuildCertList(hDeleteStore, g_wszCertCN,
  1818. &rgpCertContext, &dwCertCount))
  1819. {
  1820. idsErr=IDS_ERR_CERT_FIND;
  1821. goto CLEANUP;
  1822. }
  1823. }
  1824. else
  1825. {
  1826. //search for the certificate
  1827. if(!BuildCertList(hDeleteStore, NULL,
  1828. &rgpCertContext, &dwCertCount))
  1829. {
  1830. idsErr=IDS_ERR_CERT_FIND;
  1831. goto CLEANUP;
  1832. }
  1833. }
  1834. //check if there is no certs
  1835. if(0==dwCertCount && g_wszCertCN)
  1836. {
  1837. idsErr=IDS_ERR_DELETE_NO_CERT;
  1838. goto CLEANUP;
  1839. }
  1840. //check if there is only one cert
  1841. if(1==dwCertCount)
  1842. {
  1843. //delete certificate
  1844. CertDuplicateCertificateContext(rgpCertContext[0]);
  1845. if(!CertDeleteCertificateFromStore(rgpCertContext[0]))
  1846. {
  1847. idsErr=IDS_ERR_DELETE_CERT;
  1848. goto CLEANUP;
  1849. }
  1850. }
  1851. else
  1852. {
  1853. if(dwCertCount>1)
  1854. {
  1855. //promt user for the index number to delete
  1856. if(!DisplayCertAndPrompt(rgpCertContext, dwCertCount, &dwIndex))
  1857. {
  1858. idsErr=IDS_ERR_DELETE_CERT;
  1859. goto CLEANUP;
  1860. }
  1861. //delete certificate
  1862. CertDuplicateCertificateContext(rgpCertContext[dwIndex]);
  1863. if(!CertDeleteCertificateFromStore(rgpCertContext[dwIndex]))
  1864. {
  1865. idsErr=IDS_ERR_DELETE_CERT;
  1866. goto CLEANUP;
  1867. }
  1868. }
  1869. }
  1870. }
  1871. }
  1872. }
  1873. //delete CRLs
  1874. if(g_dwItem & ITEM_CRL)
  1875. {
  1876. //delete all
  1877. if(g_fAll)
  1878. {
  1879. if(!DeleteItem(hDeleteStore, ITEM_CRL))
  1880. {
  1881. idsErr=IDS_ERR_DELETE_CRL_ALL;
  1882. goto CLEANUP;
  1883. }
  1884. }
  1885. else
  1886. {
  1887. //delete based on Hash
  1888. if(g_pbHash)
  1889. {
  1890. Blob.cbData=g_cbHash;
  1891. Blob.pbData=g_pbHash;
  1892. pCRLContext=FindCRLInStore(
  1893. hDeleteStore,
  1894. &Blob);
  1895. if(!pCRLContext)
  1896. {
  1897. idsErr=IDS_ERR_NO_CRL_HASH;
  1898. goto CLEANUP;
  1899. }
  1900. //delete CRL to the hash
  1901. if(!CertDeleteCRLFromStore(pCRLContext))
  1902. {
  1903. idsErr=IDS_ERR_DELETE_CRL;
  1904. goto CLEANUP;
  1905. }
  1906. //free the pCRLContext
  1907. //CertFreeCRLContext(pCRLContext);
  1908. pCRLContext=NULL;
  1909. }
  1910. else
  1911. {
  1912. //search for the CRL
  1913. if(!BuildCRLList(hDeleteStore, &rgpCRLContext, &dwCRLCount))
  1914. {
  1915. idsErr=IDS_ERR_CRL_FIND;
  1916. goto CLEANUP;
  1917. }
  1918. //check if there is only one CRL
  1919. if(1==dwCRLCount)
  1920. {
  1921. //delete CRL
  1922. CertDuplicateCRLContext(rgpCRLContext[0]);
  1923. if(!CertDeleteCRLFromStore(rgpCRLContext[0]))
  1924. {
  1925. idsErr=IDS_ERR_DELETE_CRL;
  1926. goto CLEANUP;
  1927. }
  1928. }
  1929. else
  1930. {
  1931. if(dwCRLCount>1)
  1932. {
  1933. //promt user for the index number to delete
  1934. if(!DisplayCRLAndPrompt(rgpCRLContext, dwCRLCount, &dwIndex))
  1935. {
  1936. idsErr=IDS_ERR_DELETE_CRL;
  1937. goto CLEANUP;
  1938. }
  1939. //delete certificate
  1940. CertDuplicateCRLContext(rgpCRLContext[dwIndex]);
  1941. if(!CertDeleteCRLFromStore(rgpCRLContext[dwIndex]))
  1942. {
  1943. idsErr=IDS_ERR_DELETE_CRL;
  1944. goto CLEANUP;
  1945. }
  1946. }
  1947. }
  1948. }
  1949. }
  1950. }
  1951. //delete CTLs
  1952. if(g_dwItem & ITEM_CTL)
  1953. {
  1954. //delete all
  1955. if(g_fAll)
  1956. {
  1957. if(!DeleteItem(hDeleteStore, ITEM_CTL))
  1958. {
  1959. idsErr=IDS_ERR_DELETE_CTL_ALL;
  1960. goto CLEANUP;
  1961. }
  1962. }
  1963. else
  1964. {
  1965. //delete based on Hash
  1966. if(g_pbHash)
  1967. {
  1968. Blob.cbData=g_cbHash;
  1969. Blob.pbData=g_pbHash;
  1970. pCTLContext=CertFindCTLInStore(
  1971. hDeleteStore,
  1972. g_dwMsgAndCertEncodingType,
  1973. 0,
  1974. CTL_FIND_SHA1_HASH,
  1975. &Blob,
  1976. NULL);
  1977. if(!pCTLContext)
  1978. {
  1979. idsErr=IDS_ERR_NO_CTL_HASH;
  1980. goto CLEANUP;
  1981. }
  1982. //delete CTL to the hash
  1983. if(!CertDeleteCTLFromStore(pCTLContext))
  1984. {
  1985. idsErr=IDS_ERR_DELETE_CTL;
  1986. goto CLEANUP;
  1987. }
  1988. //free the pCRLContext
  1989. //CertFreeCTLContext(pCTLContext);
  1990. pCTLContext=NULL;
  1991. }
  1992. else
  1993. {
  1994. //search for the CTLs
  1995. if(!BuildCTLList(hDeleteStore,&rgpCTLContext, &dwCTLCount))
  1996. {
  1997. idsErr=IDS_ERR_CTL_FIND;
  1998. goto CLEANUP;
  1999. }
  2000. //check if there is only one item
  2001. if(1==dwCTLCount)
  2002. {
  2003. //delete CRL
  2004. CertDuplicateCTLContext(rgpCTLContext[0]);
  2005. if(!CertDeleteCTLFromStore(rgpCTLContext[0]))
  2006. {
  2007. idsErr=IDS_ERR_DELETE_CTL;
  2008. goto CLEANUP;
  2009. }
  2010. }
  2011. else
  2012. {
  2013. if(dwCTLCount>1)
  2014. {
  2015. //promt user for the index number to delete
  2016. if(!DisplayCTLAndPrompt(rgpCTLContext, dwCTLCount, &dwIndex))
  2017. {
  2018. idsErr=IDS_ERR_DELETE_CTL;
  2019. goto CLEANUP;
  2020. }
  2021. //delete CTL
  2022. CertDuplicateCTLContext(rgpCTLContext[dwIndex]);
  2023. if(!CertDeleteCTLFromStore(rgpCTLContext[dwIndex]))
  2024. {
  2025. idsErr=IDS_ERR_DELETE_CTL;
  2026. goto CLEANUP;
  2027. }
  2028. }
  2029. }
  2030. }
  2031. }
  2032. }
  2033. //save the properties to the certificates in the store
  2034. if(g_wszEKU)
  2035. {
  2036. if(!SetEKUProperty(hDeleteStore))
  2037. {
  2038. idsErr=IDS_ERR_SET_EKU;
  2039. goto CLEANUP;
  2040. }
  2041. }
  2042. //save the properties to the certificates in the store
  2043. if(g_wszName)
  2044. {
  2045. if(!SetNameProperty(hDeleteStore))
  2046. {
  2047. idsErr=IDS_ERR_SET_NAME;
  2048. goto CLEANUP;
  2049. }
  2050. }
  2051. //at last, we save the content for hDeleteStore to the desination store
  2052. //we do not need to do any thing if the source is a system store and
  2053. //it is saved to its self
  2054. if(((TRUE==g_fSameSrcDes) && (TRUE==g_fDesSystemStore))||
  2055. ((TRUE==g_fSameSrcDes)&& (NULL!=g_szDesStoreProvider)))
  2056. {
  2057. fResult=TRUE;
  2058. goto CLEANUP;
  2059. }
  2060. if(!SaveStore(hDeleteStore))
  2061. goto CLEANUP;
  2062. fResult=TRUE;
  2063. CLEANUP:
  2064. if(pCertContext)
  2065. CertFreeCertificateContext(pCertContext);
  2066. if(pCRLContext)
  2067. CertFreeCRLContext(pCRLContext);
  2068. if(pCTLContext)
  2069. CertFreeCTLContext(pCTLContext);
  2070. if(rgpCertContext)
  2071. {
  2072. for(dwIndex=0; dwIndex<dwCertCount; dwIndex++)
  2073. CertFreeCertificateContext(rgpCertContext[dwIndex]);
  2074. free(rgpCertContext);
  2075. }
  2076. if(rgpCRLContext)
  2077. {
  2078. for(dwIndex=0; dwIndex<dwCRLCount; dwIndex++)
  2079. CertFreeCRLContext(rgpCRLContext[dwIndex]);
  2080. free(rgpCRLContext);
  2081. }
  2082. if(rgpCTLContext)
  2083. {
  2084. for(dwIndex=0; dwIndex<dwCTLCount; dwIndex++)
  2085. CertFreeCTLContext(rgpCTLContext[dwIndex]);
  2086. free(rgpCTLContext);
  2087. }
  2088. if((hDeleteStore) &&(TRUE==fDuplicated) )
  2089. CertCloseStore(hDeleteStore, 0);
  2090. if(FALSE==fResult)
  2091. //output the error message
  2092. IDSwprintf(hModule,idsErr);
  2093. return fResult;
  2094. }
  2095. //---------------------------------------------------------------------------
  2096. //
  2097. // Save the store to the destination
  2098. //--------------------------------------------------------------------------
  2099. BOOL SaveStore(HCERTSTORE hSrcStore)
  2100. {
  2101. BOOL fResult=FALSE;
  2102. HCERTSTORE hDesStore=NULL;
  2103. DWORD dwSaveAs=0;
  2104. if(!hSrcStore)
  2105. {
  2106. IDSwprintf(hModule,IDS_ERR_SAVE_DES_STORE);
  2107. return FALSE;
  2108. }
  2109. //now, we need to distinguish between save to a file, or to a system store
  2110. if(g_fDesSystemStore || g_szDesStoreProvider)
  2111. {
  2112. if(NULL==g_szDesStoreProvider)
  2113. {
  2114. hDesStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
  2115. g_dwMsgAndCertEncodingType,
  2116. NULL,
  2117. g_dwDesStoreFlag,
  2118. g_wszDesStoreName);
  2119. }
  2120. else
  2121. {
  2122. hDesStore=CertOpenStore(g_szDesStoreProvider,
  2123. g_dwMsgAndCertEncodingType,
  2124. NULL,
  2125. g_dwDesStoreOpenFlag,
  2126. g_wszDesStoreName);
  2127. }
  2128. if(!hDesStore)
  2129. {
  2130. IDSwprintf(hModule,IDS_ERR_OPEN_DES_STORE);
  2131. goto CLEANUP;
  2132. }
  2133. if(!MoveItem(hSrcStore, hDesStore,ITEM_CERT | ITEM_CRL |ITEM_CTL))
  2134. {
  2135. IDSwprintf(hModule,IDS_ERR_SAVE_DES_STORE);
  2136. goto CLEANUP;
  2137. }
  2138. }
  2139. else
  2140. {
  2141. //now, try to open the desitnation store so that the content of the destination
  2142. //store will not be overwritten
  2143. //we should try to do so, except when we are doing deleting,
  2144. //and the file is saved to its self
  2145. if(!((g_dwAction & ACTION_DELETE) && (g_fSameSrcDes==TRUE) &&
  2146. (FALSE==g_fDesSystemStore)))
  2147. {
  2148. if(OpenGenericStore(g_wszDesStoreName,
  2149. g_fDesSystemStore,
  2150. g_dwDesStoreFlag,
  2151. g_szDesStoreProvider,
  2152. g_dwDesStoreOpenFlag,
  2153. FALSE,
  2154. &hDesStore))
  2155. {
  2156. //if open succeeded, just move the items
  2157. if(!MoveItem(hSrcStore, hDesStore,ITEM_CERT | ITEM_CRL |ITEM_CTL))
  2158. {
  2159. IDSwprintf(hModule,IDS_ERR_OPEN_DES_STORE);
  2160. goto CLEANUP;
  2161. }
  2162. //now the items are moved, we need to persist them to a file. Go on.
  2163. }
  2164. //if we can not open the generic store, then the desination store
  2165. //does not exist. Go on
  2166. }
  2167. //now, we have the right store to save from
  2168. if(g_fSaveAs7==TRUE)
  2169. dwSaveAs=CERT_STORE_SAVE_AS_PKCS7;
  2170. else
  2171. dwSaveAs=CERT_STORE_SAVE_AS_STORE;
  2172. if(!CertSaveStore(hDesStore ? hDesStore : hSrcStore,
  2173. g_dwMsgAndCertEncodingType,
  2174. dwSaveAs,
  2175. CERT_STORE_SAVE_TO_FILENAME_W,
  2176. g_wszDesStoreName,
  2177. 0))
  2178. {
  2179. IDSwprintf(hModule,IDS_ERR_SAVE_DES_STORE);
  2180. goto CLEANUP;
  2181. }
  2182. }
  2183. fResult=TRUE;
  2184. CLEANUP:
  2185. if(hDesStore)
  2186. CertCloseStore(hDesStore, 0);
  2187. return fResult;
  2188. }
  2189. //-------------------------------------------------------------------------
  2190. //
  2191. // Set EKU property to all the certificate in the store
  2192. //
  2193. //-------------------------------------------------------------------------
  2194. BOOL SetEKUProperty( HCERTSTORE hSrcStore)
  2195. {
  2196. BOOL fResult=FALSE;
  2197. BYTE *pbEncoded =NULL;
  2198. DWORD cbEncoded =0;
  2199. DWORD cCount;
  2200. LPSTR psz=NULL;
  2201. LPSTR pszTok=NULL;
  2202. DWORD cTok = 0;
  2203. PCERT_ENHKEY_USAGE pUsage =NULL;
  2204. CRYPT_DATA_BLOB Blob;
  2205. PCCERT_CONTEXT pCertContext=NULL;
  2206. PCCERT_CONTEXT pCertPre=NULL;
  2207. if(S_OK != WSZtoSZ(g_wszEKU, &psz))
  2208. return FALSE;
  2209. // Count the number of OIDs as well as converting from comma delimited
  2210. // to NULL character delimited
  2211. pszTok = strtok(psz, ",");
  2212. while ( pszTok != NULL )
  2213. {
  2214. cTok++;
  2215. pszTok = strtok(NULL, ",");
  2216. }
  2217. //if cTok is 0, make sure user has passed in the correct format
  2218. if(0==cTok)
  2219. {
  2220. if(0!=strcmp(psz, ","))
  2221. goto CLEANUP;
  2222. }
  2223. // Allocate a cert enhanced key usage structure and fill it in with
  2224. // the string tokens
  2225. if(0!=cTok)
  2226. {
  2227. pUsage = (PCERT_ENHKEY_USAGE)ToolUtlAlloc(sizeof(CERT_ENHKEY_USAGE));
  2228. if(NULL==pUsage)
  2229. goto CLEANUP;
  2230. pUsage->cUsageIdentifier = cTok;
  2231. pUsage->rgpszUsageIdentifier = (LPSTR *)ToolUtlAlloc(sizeof(LPSTR)*cTok);
  2232. if(NULL==pUsage->rgpszUsageIdentifier)
  2233. goto CLEANUP;
  2234. //set up the OID array
  2235. pszTok = psz;
  2236. for ( cCount = 0; cCount < cTok; cCount++ )
  2237. {
  2238. pUsage->rgpszUsageIdentifier[cCount] = pszTok;
  2239. pszTok = pszTok+strlen(pszTok)+1;
  2240. }
  2241. // Encode the usage
  2242. if(!CryptEncodeObject(
  2243. X509_ASN_ENCODING,
  2244. szOID_ENHANCED_KEY_USAGE,
  2245. pUsage,
  2246. NULL,
  2247. &cbEncoded
  2248. ))
  2249. goto CLEANUP;
  2250. pbEncoded = (BYTE *)ToolUtlAlloc(cbEncoded);
  2251. if ( NULL == pbEncoded)
  2252. goto CLEANUP;
  2253. if(!CryptEncodeObject(X509_ASN_ENCODING,
  2254. szOID_ENHANCED_KEY_USAGE,
  2255. pUsage,
  2256. pbEncoded,
  2257. &cbEncoded
  2258. ))
  2259. goto CLEANUP;
  2260. }
  2261. //now, set the EKU for each certificate in the store
  2262. while(pCertContext=CertEnumCertificatesInStore(hSrcStore, pCertPre))
  2263. {
  2264. //1st, delete the original property
  2265. if(!CertSetCertificateContextProperty(pCertContext,
  2266. CERT_ENHKEY_USAGE_PROP_ID,
  2267. 0,
  2268. NULL))
  2269. goto CLEANUP;
  2270. //2nd, set the new property if required
  2271. if(0!=cTok)
  2272. {
  2273. Blob.cbData=cbEncoded;
  2274. Blob.pbData=pbEncoded;
  2275. if(!CertSetCertificateContextProperty(pCertContext,
  2276. CERT_ENHKEY_USAGE_PROP_ID,
  2277. 0,
  2278. &Blob))
  2279. goto CLEANUP;
  2280. }
  2281. pCertPre=pCertContext;
  2282. }
  2283. fResult=TRUE;
  2284. CLEANUP:
  2285. if(psz)
  2286. ToolUtlFree(psz);
  2287. if(pUsage)
  2288. {
  2289. if(pUsage->rgpszUsageIdentifier)
  2290. ToolUtlFree(pUsage->rgpszUsageIdentifier);
  2291. ToolUtlFree(pUsage);
  2292. }
  2293. if(pbEncoded)
  2294. ToolUtlFree(pbEncoded);
  2295. if(pCertContext)
  2296. CertFreeCertificateContext(pCertContext);
  2297. return fResult;
  2298. }
  2299. //-------------------------------------------------------------------------
  2300. //
  2301. // Set name property to all the certificate in the store
  2302. //
  2303. //-------------------------------------------------------------------------
  2304. BOOL SetNameProperty( HCERTSTORE hSrcStore)
  2305. {
  2306. BOOL fResult=FALSE;
  2307. CRYPT_DATA_BLOB Blob;
  2308. PCCERT_CONTEXT pCertContext=NULL;
  2309. PCCERT_CONTEXT pCertPre=NULL;
  2310. //init the name property
  2311. Blob.cbData=(wcslen(g_wszName)+1)*sizeof(WCHAR);
  2312. Blob.pbData=(BYTE*)g_wszName;
  2313. //now, set the NAME for each certificate in the store
  2314. while(pCertContext=CertEnumCertificatesInStore(hSrcStore, pCertPre))
  2315. {
  2316. //1st, delete the original property
  2317. if(!CertSetCertificateContextProperty(pCertContext,
  2318. CERT_FRIENDLY_NAME_PROP_ID,
  2319. 0,
  2320. NULL))
  2321. goto CLEANUP;
  2322. //2nd, set the new property if required
  2323. if(!CertSetCertificateContextProperty(pCertContext,
  2324. CERT_FRIENDLY_NAME_PROP_ID,
  2325. 0,
  2326. &Blob))
  2327. goto CLEANUP;
  2328. pCertPre=pCertContext;
  2329. }
  2330. fResult=TRUE;
  2331. CLEANUP:
  2332. if(pCertContext)
  2333. CertFreeCertificateContext(pCertContext);
  2334. return fResult;
  2335. }
  2336. //-------------------------------------------------------------------------
  2337. //
  2338. // Find a CRL based on SHA1 hash
  2339. //
  2340. //-------------------------------------------------------------------------
  2341. PCCRL_CONTEXT FindCRLInStore(HCERTSTORE hCertStore,
  2342. CRYPT_HASH_BLOB *pBlob)
  2343. {
  2344. BYTE *pbData=NULL;
  2345. DWORD cbData=0;
  2346. BOOL fResult=FALSE;
  2347. DWORD dwCRLFlag=0;
  2348. PCCRL_CONTEXT pCRLContext=NULL;
  2349. PCCRL_CONTEXT pCRLPre=NULL;
  2350. if(!pBlob)
  2351. return NULL;
  2352. if(!(pBlob->pbData))
  2353. return NULL;
  2354. //enum the CRLS
  2355. while(pCRLContext=CertGetCRLFromStore(hCertStore,
  2356. NULL,
  2357. pCRLPre,
  2358. &dwCRLFlag))
  2359. {
  2360. //get the hash
  2361. if(!CertGetCRLContextProperty(pCRLContext,
  2362. CERT_SHA1_HASH_PROP_ID,
  2363. NULL,
  2364. &cbData))
  2365. goto CLEANUP;
  2366. pbData=(BYTE *)ToolUtlAlloc(cbData);
  2367. if(!pbData)
  2368. goto CLEANUP;
  2369. if(!CertGetCRLContextProperty(pCRLContext,
  2370. CERT_SHA1_HASH_PROP_ID,
  2371. pbData,
  2372. &cbData))
  2373. goto CLEANUP;
  2374. //Compare
  2375. if(cbData==pBlob->cbData)
  2376. {
  2377. if(memcmp(pbData, pBlob->pbData, cbData)==0)
  2378. {
  2379. fResult=TRUE;
  2380. break;
  2381. }
  2382. }
  2383. pCRLPre=pCRLContext;
  2384. }
  2385. CLEANUP:
  2386. if(pbData)
  2387. ToolUtlFree(pbData);
  2388. if(FALSE==fResult)
  2389. {
  2390. if(pCRLContext)
  2391. {
  2392. CertFreeCRLContext(pCRLContext);
  2393. pCRLContext=NULL;
  2394. }
  2395. }
  2396. return pCRLContext;
  2397. }
  2398. //-------------------------------------------------------------------------
  2399. //
  2400. // Move Certs/CRls/CTLs from the source store to the destination
  2401. //
  2402. //-------------------------------------------------------------------------
  2403. BOOL MoveItem(HCERTSTORE hSrcStore,
  2404. HCERTSTORE hDesStore,
  2405. DWORD dwItem)
  2406. {
  2407. BOOL fResult=FALSE;
  2408. DWORD dwCRLFlag=0;
  2409. PCCERT_CONTEXT pCertContext=NULL;
  2410. PCCERT_CONTEXT pCertPre=NULL;
  2411. PCCRL_CONTEXT pCRLContext=NULL;
  2412. PCCRL_CONTEXT pCRLPre=NULL;
  2413. PCCTL_CONTEXT pCTLContext=NULL;
  2414. PCCTL_CONTEXT pCTLPre=NULL;
  2415. //add the certs
  2416. if(dwItem & ITEM_CERT)
  2417. {
  2418. while(pCertContext=CertEnumCertificatesInStore(hSrcStore, pCertPre))
  2419. {
  2420. if(!CertAddCertificateContextToStore(hDesStore,
  2421. pCertContext,
  2422. CERT_STORE_ADD_REPLACE_EXISTING,
  2423. NULL))
  2424. goto CLEANUP;
  2425. pCertPre=pCertContext;
  2426. }
  2427. }
  2428. //add the CTLs
  2429. if(dwItem & ITEM_CTL)
  2430. {
  2431. while(pCTLContext=CertEnumCTLsInStore(hSrcStore, pCTLPre))
  2432. {
  2433. if(!CertAddCTLContextToStore(hDesStore,
  2434. pCTLContext,
  2435. CERT_STORE_ADD_REPLACE_EXISTING,
  2436. NULL))
  2437. goto CLEANUP;
  2438. pCTLPre=pCTLContext;
  2439. }
  2440. }
  2441. //add the CRLs
  2442. if(dwItem & ITEM_CRL)
  2443. {
  2444. while(pCRLContext=CertGetCRLFromStore(hSrcStore,
  2445. NULL,
  2446. pCRLPre,
  2447. &dwCRLFlag))
  2448. {
  2449. if(!CertAddCRLContextToStore(hDesStore,
  2450. pCRLContext,
  2451. CERT_STORE_ADD_REPLACE_EXISTING,
  2452. NULL))
  2453. goto CLEANUP;
  2454. pCRLPre=pCRLContext;
  2455. }
  2456. }
  2457. fResult=TRUE;
  2458. CLEANUP:
  2459. if(pCertContext)
  2460. CertFreeCertificateContext(pCertContext);
  2461. if(pCTLContext)
  2462. CertFreeCTLContext(pCTLContext);
  2463. if(pCRLContext)
  2464. CertFreeCRLContext(pCRLContext);
  2465. return fResult;
  2466. }
  2467. //-------------------------------------------------------------------------
  2468. //
  2469. // Delete Certs/CRls/CTLs from the source store
  2470. //
  2471. //-------------------------------------------------------------------------
  2472. BOOL DeleteItem(HCERTSTORE hSrcStore,
  2473. DWORD dwItem)
  2474. {
  2475. BOOL fResult=FALSE;
  2476. DWORD dwCRLFlag=0;
  2477. PCCERT_CONTEXT pCertContext=NULL;
  2478. PCCERT_CONTEXT pCertPre=NULL;
  2479. PCCRL_CONTEXT pCRLContext=NULL;
  2480. PCCRL_CONTEXT pCRLPre=NULL;
  2481. PCCTL_CONTEXT pCTLContext=NULL;
  2482. PCCTL_CONTEXT pCTLPre=NULL;
  2483. //add the certs
  2484. if(dwItem & ITEM_CERT)
  2485. {
  2486. while(pCertContext=CertEnumCertificatesInStore(hSrcStore, pCertPre))
  2487. {
  2488. pCertPre=pCertContext;
  2489. if(!CertDeleteCertificateFromStore(CertDuplicateCertificateContext(pCertContext)))
  2490. goto CLEANUP;
  2491. }
  2492. }
  2493. //add the CTLs
  2494. if(dwItem & ITEM_CTL)
  2495. {
  2496. while(pCTLContext=CertEnumCTLsInStore(hSrcStore, pCTLPre))
  2497. {
  2498. pCTLPre=pCTLContext;
  2499. if(!CertDeleteCTLFromStore(CertDuplicateCTLContext(pCTLContext)))
  2500. goto CLEANUP;
  2501. }
  2502. }
  2503. //add the CRLs
  2504. if(dwItem & ITEM_CRL)
  2505. {
  2506. while(pCRLContext=CertGetCRLFromStore(hSrcStore,
  2507. NULL,
  2508. pCRLPre,
  2509. &dwCRLFlag))
  2510. {
  2511. pCRLPre=pCRLContext;
  2512. if(!CertDeleteCRLFromStore(CertDuplicateCRLContext(pCRLContext)))
  2513. goto CLEANUP;
  2514. }
  2515. }
  2516. fResult=TRUE;
  2517. CLEANUP:
  2518. if(pCertContext)
  2519. CertFreeCertificateContext(pCertContext);
  2520. if(pCTLContext)
  2521. CertFreeCTLContext(pCTLContext);
  2522. if(pCRLContext)
  2523. CertFreeCRLContext(pCRLContext);
  2524. return fResult;
  2525. }
  2526. //-------------------------------------------------------------------------
  2527. //
  2528. // Display all the certificates and prompt user for the index
  2529. //
  2530. //-------------------------------------------------------------------------
  2531. BOOL DisplayCertAndPrompt(PCCERT_CONTEXT *rgpCertContext,
  2532. DWORD dwCertCount,
  2533. DWORD *pdwIndex)
  2534. {
  2535. DWORD dwIndex=0;
  2536. if(!pdwIndex)
  2537. return FALSE;
  2538. //the count has to be more than 1
  2539. if(dwCertCount<2)
  2540. return FALSE;
  2541. //Display all the certs
  2542. for(dwIndex=0; dwIndex<dwCertCount; dwIndex++)
  2543. {
  2544. IDSwprintf(hModule,IDS_CERT_INDEX, dwIndex+1);
  2545. if(!DisplayCert(rgpCertContext[dwIndex], 0))
  2546. {
  2547. IDSwprintf(hModule,IDS_ERR_DISPLAY);
  2548. return FALSE;
  2549. }
  2550. }
  2551. //promot user for an index
  2552. //tell them starting from 1
  2553. if(g_dwAction & ACTION_ADD)
  2554. IDSwprintf(hModule,IDS_ENTER_ADD_INDEX_CERT);
  2555. else
  2556. {
  2557. if(g_dwAction & ACTION_DELETE)
  2558. IDSwprintf(hModule, IDS_ENTER_DELETE_INDEX_CERT);
  2559. else
  2560. {
  2561. IDSwprintf(hModule, IDS_ENTER_PUT_INDEX_CERT);
  2562. }
  2563. }
  2564. if (0 == scanf("%d",pdwIndex))
  2565. {
  2566. return FALSE;
  2567. }
  2568. if((*pdwIndex>=1) && (*pdwIndex<=dwCertCount))
  2569. {
  2570. //return the index
  2571. *pdwIndex=*pdwIndex-1;
  2572. return TRUE;
  2573. }
  2574. IDSwprintf(hModule, IDS_ERR_INVALID_INDEX);
  2575. return FALSE;
  2576. }
  2577. //-------------------------------------------------------------------------
  2578. //
  2579. // Display all the CRLs and prompt user for the index
  2580. //
  2581. //-------------------------------------------------------------------------
  2582. BOOL DisplayCRLAndPrompt(PCCRL_CONTEXT *rgpCRLContext,
  2583. DWORD dwCRLCount,
  2584. DWORD *pdwIndex)
  2585. {
  2586. DWORD dwIndex=0;
  2587. if(!pdwIndex)
  2588. return FALSE;
  2589. //the count has to be more than 1
  2590. if(dwCRLCount<2)
  2591. return FALSE;
  2592. //Display all the CRLs
  2593. for(dwIndex=0; dwIndex<dwCRLCount; dwIndex++)
  2594. {
  2595. IDSwprintf(hModule,IDS_CRL_INDEX, dwIndex+1);
  2596. if(!DisplayCRL(rgpCRLContext[dwIndex], 0))
  2597. {
  2598. IDSwprintf(hModule,IDS_ERR_DISPLAY);
  2599. return FALSE;
  2600. }
  2601. }
  2602. //promot user for an index
  2603. //tell them starting from 1
  2604. if(g_dwAction & ACTION_ADD)
  2605. IDSwprintf(hModule,IDS_ENTER_ADD_INDEX_CRL);
  2606. else
  2607. {
  2608. if(g_dwAction & ACTION_DELETE)
  2609. IDSwprintf(hModule, IDS_ENTER_DELETE_INDEX_CRL);
  2610. else
  2611. {
  2612. IDSwprintf(hModule, IDS_ENTER_PUT_INDEX_CRL);
  2613. }
  2614. }
  2615. if (0 == scanf("%d",pdwIndex))
  2616. {
  2617. return FALSE;
  2618. }
  2619. if((*pdwIndex>=1) && (*pdwIndex<=dwCRLCount))
  2620. {
  2621. //return the index
  2622. *pdwIndex=*pdwIndex-1;
  2623. return TRUE;
  2624. }
  2625. IDSwprintf(hModule,IDS_ERR_INVALID_INDEX);
  2626. return FALSE;
  2627. }
  2628. //-------------------------------------------------------------------------
  2629. //
  2630. // Display all the CTLs and prompt user for the index
  2631. //
  2632. //-------------------------------------------------------------------------
  2633. BOOL DisplayCTLAndPrompt(PCCTL_CONTEXT *rgpCTLContext,
  2634. DWORD dwCTLCount,
  2635. DWORD *pdwIndex)
  2636. {
  2637. DWORD dwIndex=0;
  2638. if(!pdwIndex)
  2639. return FALSE;
  2640. //the count has to be more than 1
  2641. if(dwCTLCount<2)
  2642. return FALSE;
  2643. //Display all the CTLs
  2644. for(dwIndex=0; dwIndex<dwCTLCount; dwIndex++)
  2645. {
  2646. IDSwprintf(hModule,IDS_CTL_INDEX, dwIndex+1);
  2647. if(!DisplayCTL(rgpCTLContext[dwIndex], 0))
  2648. {
  2649. IDSwprintf(hModule,IDS_ERR_DISPLAY);
  2650. return FALSE;
  2651. }
  2652. }
  2653. //promot user for an index
  2654. //tell them starting from 1
  2655. if(g_dwAction & ACTION_ADD)
  2656. IDSwprintf(hModule,IDS_ENTER_ADD_INDEX_CTL);
  2657. else
  2658. {
  2659. if(g_dwAction & ACTION_DELETE)
  2660. IDSwprintf(hModule, IDS_ENTER_DELETE_INDEX_CTL);
  2661. else
  2662. {
  2663. IDSwprintf(hModule, IDS_ENTER_PUT_INDEX_CTL);
  2664. }
  2665. }
  2666. if (0 == scanf("%d",pdwIndex))
  2667. {
  2668. return FALSE;
  2669. }
  2670. if((*pdwIndex>=1) && (*pdwIndex<=dwCTLCount))
  2671. {
  2672. //return the index
  2673. *pdwIndex=*pdwIndex-1;
  2674. return TRUE;
  2675. }
  2676. IDSwprintf(hModule,IDS_ERR_INVALID_INDEX);
  2677. return FALSE;
  2678. }
  2679. //-------------------------------------------------------------------------
  2680. //
  2681. // Build a list of certificates for people to choose from
  2682. //
  2683. //-------------------------------------------------------------------------
  2684. BOOL BuildCertList(HCERTSTORE hCertStore,
  2685. LPWSTR wszCertCN,
  2686. PCCERT_CONTEXT **prgpCertContext,
  2687. DWORD *pdwCertCount)
  2688. {
  2689. BOOL fResult=FALSE;
  2690. PCCERT_CONTEXT pCertContext=NULL;
  2691. PCCERT_CONTEXT pCertPre=NULL;
  2692. PCCERT_CONTEXT * rgpCertContext=NULL;
  2693. DWORD dwIndex=0;
  2694. DWORD dwCount=0;
  2695. if(!prgpCertContext || !pdwCertCount)
  2696. return FALSE;
  2697. //init
  2698. *prgpCertContext=NULL;
  2699. *pdwCertCount=0;
  2700. //if wszCertCN is NULL, include every certs in the list
  2701. if(NULL==wszCertCN)
  2702. {
  2703. while(pCertContext=CertEnumCertificatesInStore(hCertStore, pCertPre))
  2704. {
  2705. dwCount++;
  2706. //allocation enough memory
  2707. rgpCertContext=(PCCERT_CONTEXT *)realloc((*prgpCertContext),
  2708. dwCount * sizeof(PCCERT_CONTEXT));
  2709. if(!rgpCertContext)
  2710. goto CLEANUP;
  2711. *prgpCertContext=rgpCertContext;
  2712. //duplicate the certificate context
  2713. (*prgpCertContext)[dwCount-1]=CertDuplicateCertificateContext(pCertContext);
  2714. if(!((*prgpCertContext)[dwCount-1]))
  2715. goto CLEANUP;
  2716. pCertPre=pCertContext;
  2717. }
  2718. }
  2719. else
  2720. {
  2721. //we search for the certificate based on the common name
  2722. while(pCertContext=CertFindCertificateInStore(hCertStore,
  2723. g_dwCertEncodingType,
  2724. 0,
  2725. CERT_FIND_SUBJECT_STR_W,
  2726. wszCertCN,
  2727. pCertPre))
  2728. {
  2729. dwCount++;
  2730. //allocation enough memory
  2731. rgpCertContext=(PCCERT_CONTEXT *)realloc((*prgpCertContext),
  2732. dwCount * sizeof(PCCERT_CONTEXT));
  2733. if(!rgpCertContext)
  2734. goto CLEANUP;
  2735. *prgpCertContext=rgpCertContext;
  2736. //duplicate the certificate context
  2737. (*prgpCertContext)[dwCount-1]=CertDuplicateCertificateContext(pCertContext);
  2738. if(!((*prgpCertContext)[dwCount-1]))
  2739. goto CLEANUP;
  2740. pCertPre=pCertContext;
  2741. }
  2742. }
  2743. fResult=TRUE;
  2744. CLEANUP:
  2745. if(FALSE==fResult)
  2746. {
  2747. if(*prgpCertContext)
  2748. {
  2749. for(dwIndex=0; dwIndex<dwCount; dwIndex++)
  2750. {
  2751. if(((*prgpCertContext)[dwIndex]))
  2752. CertFreeCertificateContext(((*prgpCertContext)[dwIndex]));
  2753. }
  2754. free(*prgpCertContext);
  2755. }
  2756. *prgpCertContext=NULL;
  2757. *pdwCertCount=0;
  2758. }
  2759. else
  2760. {
  2761. *pdwCertCount=dwCount;
  2762. }
  2763. if(pCertContext)
  2764. CertFreeCertificateContext(pCertContext);
  2765. return fResult;
  2766. }
  2767. //-------------------------------------------------------------------------
  2768. //
  2769. // Build a list of CRLs for people to choose from
  2770. //
  2771. //-------------------------------------------------------------------------
  2772. BOOL BuildCRLList( HCERTSTORE hCertStore,
  2773. PCCRL_CONTEXT **prgpCRLContext,
  2774. DWORD *pdwCRLCount)
  2775. {
  2776. BOOL fResult=FALSE;
  2777. PCCRL_CONTEXT pCRLContext=NULL;
  2778. PCCRL_CONTEXT pCRLPre=NULL;
  2779. PCCRL_CONTEXT * rgpCRLContext=NULL;
  2780. DWORD dwCRLFlag=0;
  2781. DWORD dwIndex=0;
  2782. DWORD dwCount=0;
  2783. if(!prgpCRLContext || !pdwCRLCount)
  2784. return FALSE;
  2785. //init
  2786. *prgpCRLContext=NULL;
  2787. *pdwCRLCount=0;
  2788. while(pCRLContext=CertGetCRLFromStore(hCertStore,
  2789. NULL,
  2790. pCRLPre,
  2791. &dwCRLFlag))
  2792. {
  2793. dwCount++;
  2794. //allocation enough memory
  2795. rgpCRLContext=(PCCRL_CONTEXT *)realloc((*prgpCRLContext),
  2796. dwCount * sizeof(PCCRL_CONTEXT));
  2797. if(!rgpCRLContext)
  2798. goto CLEANUP;
  2799. *prgpCRLContext=rgpCRLContext;
  2800. //duplicate the CRL context
  2801. (*prgpCRLContext)[dwCount-1]=CertDuplicateCRLContext(pCRLContext);
  2802. if(!((*prgpCRLContext)[dwCount-1]))
  2803. goto CLEANUP;
  2804. pCRLPre=pCRLContext;
  2805. }
  2806. fResult=TRUE;
  2807. CLEANUP:
  2808. if(FALSE==fResult)
  2809. {
  2810. if(*prgpCRLContext)
  2811. {
  2812. for(dwIndex=0; dwIndex<dwCount; dwIndex++)
  2813. {
  2814. if(((*prgpCRLContext)[dwIndex]))
  2815. CertFreeCRLContext(((*prgpCRLContext)[dwIndex]));
  2816. }
  2817. free(*prgpCRLContext);
  2818. }
  2819. *prgpCRLContext=NULL;
  2820. *pdwCRLCount=0;
  2821. }
  2822. else
  2823. {
  2824. *pdwCRLCount=dwCount;
  2825. }
  2826. if(pCRLContext)
  2827. CertFreeCRLContext(pCRLContext);
  2828. return fResult;
  2829. }
  2830. //-------------------------------------------------------------------------
  2831. //
  2832. // Build a list of CTLs for people to choose from
  2833. //
  2834. //-------------------------------------------------------------------------
  2835. BOOL BuildCTLList( HCERTSTORE hCertStore,
  2836. PCCTL_CONTEXT **prgpCTLContext,
  2837. DWORD *pdwCTLCount)
  2838. {
  2839. BOOL fResult=FALSE;
  2840. PCCTL_CONTEXT pCTLContext=NULL;
  2841. PCCTL_CONTEXT pCTLPre=NULL;
  2842. PCCTL_CONTEXT * rgpCTLContext=NULL;
  2843. DWORD dwIndex=0;
  2844. DWORD dwCount=0;
  2845. if(!prgpCTLContext || !pdwCTLCount)
  2846. return FALSE;
  2847. //init
  2848. *prgpCTLContext=NULL;
  2849. *pdwCTLCount=0;
  2850. while(pCTLContext=CertEnumCTLsInStore(hCertStore,pCTLPre))
  2851. {
  2852. dwCount++;
  2853. //allocation enough memory
  2854. rgpCTLContext=(PCCTL_CONTEXT *)realloc((*prgpCTLContext),
  2855. dwCount * sizeof(PCCTL_CONTEXT));
  2856. if(!rgpCTLContext)
  2857. goto CLEANUP;
  2858. *prgpCTLContext=rgpCTLContext;
  2859. //duplicate the CTL context
  2860. (*prgpCTLContext)[dwCount-1]=CertDuplicateCTLContext(pCTLContext);
  2861. if(!((*prgpCTLContext)[dwCount-1]))
  2862. goto CLEANUP;
  2863. pCTLPre=pCTLContext;
  2864. }
  2865. fResult=TRUE;
  2866. CLEANUP:
  2867. if(FALSE==fResult)
  2868. {
  2869. if(*prgpCTLContext)
  2870. {
  2871. for(dwIndex=0; dwIndex<dwCount; dwIndex++)
  2872. {
  2873. if(((*prgpCTLContext)[dwIndex]))
  2874. CertFreeCTLContext(((*prgpCTLContext)[dwIndex]));
  2875. }
  2876. free(*prgpCTLContext);
  2877. }
  2878. *prgpCTLContext=NULL;
  2879. *pdwCTLCount=0;
  2880. }
  2881. else
  2882. {
  2883. *pdwCTLCount=dwCount;
  2884. }
  2885. if(pCTLContext)
  2886. CertFreeCTLContext(pCTLContext);
  2887. return fResult;
  2888. }
  2889. //-------------------------------------------------------------------------
  2890. //
  2891. // Display everthing in a store
  2892. //
  2893. //-------------------------------------------------------------------------
  2894. BOOL DisplayCertStore(HCERTSTORE hCertStore)
  2895. {
  2896. BOOL fResult=FALSE;
  2897. DWORD dwCount=0;
  2898. DWORD dwCRLFlag=0;
  2899. PCCERT_CONTEXT pCertContext=NULL;
  2900. PCCERT_CONTEXT pCertPre=NULL;
  2901. PCCRL_CONTEXT pCRLContext=NULL;
  2902. PCCRL_CONTEXT pCRLPre=NULL;
  2903. PCCTL_CONTEXT pCTLContext=NULL;
  2904. PCCTL_CONTEXT pCTLPre=NULL;
  2905. //Display the certs
  2906. if(g_dwItem & ITEM_CERT)
  2907. {
  2908. while(pCertContext=CertEnumCertificatesInStore(hCertStore, pCertPre))
  2909. {
  2910. dwCount++;
  2911. IDSwprintf(hModule,IDS_CERT_INDEX, dwCount);
  2912. if(!DisplayCert(pCertContext, g_dwItem))
  2913. {
  2914. IDSwprintf(hModule,IDS_ERR_DISPLAY);
  2915. }
  2916. pCertPre=pCertContext;
  2917. }
  2918. if(0==dwCount)
  2919. IDSwprintf(hModule,IDS_NO_CERT);
  2920. }
  2921. dwCount=0;
  2922. //Display the CTLs
  2923. if(g_dwItem & ITEM_CTL)
  2924. {
  2925. while(pCTLContext=CertEnumCTLsInStore(hCertStore, pCTLPre))
  2926. {
  2927. dwCount++;
  2928. IDSwprintf(hModule,IDS_CTL_INDEX, dwCount);
  2929. if(!DisplayCTL(pCTLContext, g_dwItem))
  2930. {
  2931. IDSwprintf(hModule,IDS_ERR_DISPLAY);
  2932. }
  2933. pCTLPre=pCTLContext;
  2934. }
  2935. if(0==dwCount)
  2936. IDSwprintf(hModule,IDS_NO_CTL);
  2937. }
  2938. dwCount=0;
  2939. //Display the CRLs
  2940. if(g_dwItem & ITEM_CRL)
  2941. {
  2942. while(pCRLContext=CertGetCRLFromStore(hCertStore,
  2943. NULL,
  2944. pCRLPre,
  2945. &dwCRLFlag))
  2946. {
  2947. dwCount++;
  2948. IDSwprintf(hModule,IDS_CRL_INDEX, dwCount);
  2949. if(!DisplayCRL(pCRLContext, g_dwItem))
  2950. {
  2951. IDSwprintf(hModule,IDS_ERR_DISPLAY);
  2952. }
  2953. pCRLPre=pCRLContext;
  2954. }
  2955. if(0==dwCount)
  2956. IDSwprintf(hModule,IDS_NO_CRL);
  2957. }
  2958. fResult=TRUE;
  2959. if(pCertContext)
  2960. CertFreeCertificateContext(pCertContext);
  2961. if(pCTLContext)
  2962. CertFreeCTLContext(pCTLContext);
  2963. if(pCRLContext)
  2964. CertFreeCRLContext(pCRLContext);
  2965. return fResult;
  2966. }
  2967. //+-------------------------------------------------------------------------
  2968. // DisplaySMIMECapabilitiesExtension
  2969. //--------------------------------------------------------------------------
  2970. void DisplayTimeStamp(BYTE *pbEncoded,DWORD cbEncoded,DWORD dwDisplayFlags)
  2971. {
  2972. CMSG_SIGNER_INFO *pSignerInfo=NULL;
  2973. if (NULL == (pSignerInfo = (CMSG_SIGNER_INFO *) TestNoCopyDecodeObject(
  2974. PKCS7_SIGNER_INFO,
  2975. pbEncoded,
  2976. cbEncoded
  2977. ))) goto CommonReturn;
  2978. //display the timestamper's information
  2979. //" Timestamp Version:: %d\n"
  2980. IDSwprintf(hModule, IDS_TS_VERSION, pSignerInfo->dwVersion);
  2981. //"Timestamp server's certificate issuer::\n");
  2982. IDSwprintf(hModule, IDS_TS_ISSUER);
  2983. DecodeName(pSignerInfo->Issuer.pbData,
  2984. pSignerInfo->Issuer.cbData, dwDisplayFlags);
  2985. //"Timestamp server's certificate SerialNumber::\n"
  2986. IDSwprintf(hModule, IDS_TS_SERIAL_NUMBER);
  2987. DisplaySerialNumber(&pSignerInfo->SerialNumber);
  2988. printf("\n");
  2989. //"Timestamp's authenticated attributes::\n"
  2990. IDSwprintf(hModule, IDS_TS_AUTHATTR);
  2991. PrintAttributes(pSignerInfo->AuthAttrs.cAttr, pSignerInfo->AuthAttrs.rgAttr,
  2992. dwDisplayFlags);
  2993. //"Timestamp's unauthenticated attributes::\n"
  2994. if(pSignerInfo->UnauthAttrs.cAttr)
  2995. {
  2996. IDSwprintf(hModule, IDS_TS_UNAUTHATTR);
  2997. PrintAttributes(pSignerInfo->UnauthAttrs.cAttr,
  2998. pSignerInfo->UnauthAttrs.rgAttr,
  2999. dwDisplayFlags);
  3000. }
  3001. CommonReturn:
  3002. if(pSignerInfo)
  3003. ToolUtlFree(pSignerInfo);
  3004. return;
  3005. }
  3006. //-------------------------------------------------------------------------
  3007. //
  3008. // Display a certificate
  3009. //
  3010. //-------------------------------------------------------------------------
  3011. BOOL DisplayCert(PCCERT_CONTEXT pCert, DWORD dwDisplayFlags)
  3012. {
  3013. BOOL fResult=FALSE;
  3014. BYTE rgbHash[MAX_HASH_LEN];
  3015. DWORD cbHash = MAX_HASH_LEN;
  3016. HCRYPTPROV hProv = 0;
  3017. //"Subject::\n");
  3018. IDSwprintf(hModule, IDS_SUBJECT);
  3019. DecodeName(pCert->pCertInfo->Subject.pbData,
  3020. pCert->pCertInfo->Subject.cbData, dwDisplayFlags);
  3021. //"Issuer::\n"
  3022. IDSwprintf(hModule, IDS_ISSUER);
  3023. DecodeName(pCert->pCertInfo->Issuer.pbData,
  3024. pCert->pCertInfo->Issuer.cbData, dwDisplayFlags);
  3025. //"SerialNumber::"
  3026. IDSwprintf(hModule, IDS_SERIAL_NUMBER);
  3027. DisplaySerialNumber(&pCert->pCertInfo->SerialNumber);
  3028. printf("\n");
  3029. CertGetCertificateContextProperty(
  3030. pCert,
  3031. CERT_SHA1_HASH_PROP_ID,
  3032. rgbHash,
  3033. &cbHash
  3034. );
  3035. DisplayThumbprint(g_wszSHA1, rgbHash, cbHash);
  3036. cbHash = MAX_HASH_LEN;
  3037. CertGetCertificateContextProperty(
  3038. pCert,
  3039. CERT_MD5_HASH_PROP_ID,
  3040. rgbHash,
  3041. &cbHash
  3042. );
  3043. DisplayThumbprint(g_wszMD5, rgbHash, cbHash);
  3044. CryptAcquireContext(
  3045. &hProv,
  3046. NULL,
  3047. NULL, // pszProvider
  3048. PROV_RSA_FULL,
  3049. 0 // dwFlags
  3050. );
  3051. if (hProv)
  3052. {
  3053. cbHash = MAX_HASH_LEN;
  3054. CryptHashPublicKeyInfo(
  3055. hProv,
  3056. CALG_MD5,
  3057. 0, // dwFlags
  3058. g_dwCertEncodingType,
  3059. &pCert->pCertInfo->SubjectPublicKeyInfo,
  3060. rgbHash,
  3061. &cbHash
  3062. );
  3063. //"Key "
  3064. IDSwprintf(hModule, IDS_KEY);
  3065. DisplayThumbprint(g_wszMD5, rgbHash, cbHash);
  3066. CryptReleaseContext(hProv, 0);
  3067. }
  3068. //print the Key_Prov_Info_Prop_ID
  3069. {
  3070. PCRYPT_KEY_PROV_INFO pInfo = NULL;
  3071. DWORD cbInfo;
  3072. cbInfo = 0;
  3073. CertGetCertificateContextProperty(
  3074. pCert,
  3075. CERT_KEY_PROV_INFO_PROP_ID,
  3076. NULL, // pvData
  3077. &cbInfo
  3078. );
  3079. if (cbInfo)
  3080. {
  3081. pInfo = (PCRYPT_KEY_PROV_INFO) ToolUtlAlloc(cbInfo);
  3082. if (pInfo)
  3083. {
  3084. if (CertGetCertificateContextProperty(
  3085. pCert,
  3086. CERT_KEY_PROV_INFO_PROP_ID,
  3087. pInfo,
  3088. &cbInfo
  3089. ))
  3090. {
  3091. //"Provider Type:: %d"
  3092. IDSwprintf(hModule, IDS_KEY_PROVIDER, pInfo->dwProvType);
  3093. //" Provider Name:: %s"
  3094. if (pInfo->pwszProvName)
  3095. IDSwprintf(hModule, IDS_PROV_NAME, pInfo->pwszProvName);
  3096. //" Flags: 0x%x"
  3097. if (pInfo->dwFlags)
  3098. IDSwprintf(hModule, IDS_FLAGS, pInfo->dwFlags);
  3099. //" Container: %S"
  3100. if (pInfo->pwszContainerName)
  3101. IDSwprintf(hModule, IDS_CONTAINER, pInfo->pwszContainerName);
  3102. //" Params: %d"
  3103. if (pInfo->cProvParam)
  3104. IDSwprintf(hModule, IDS_PARAM,pInfo->cProvParam);
  3105. //" KeySpec: %d"
  3106. if (pInfo->dwKeySpec)
  3107. IDSwprintf(hModule, IDS_KEY_SPEC, pInfo->dwKeySpec);
  3108. printf("\n");
  3109. }
  3110. ToolUtlFree(pInfo);
  3111. }
  3112. }
  3113. }
  3114. //"NotBefore:: %s\n"
  3115. IDSwprintf(hModule, IDS_NOT_BEFORE, FileTimeText(&pCert->pCertInfo->NotBefore));
  3116. //"NotAfter:: %s\n"
  3117. IDSwprintf(hModule, IDS_NOT_AFTER, FileTimeText(&pCert->pCertInfo->NotAfter));
  3118. //Display the aux properties if verbose
  3119. if(dwDisplayFlags & ITEM_VERBOSE)
  3120. PrintAuxCertProperties(pCert,dwDisplayFlags);
  3121. if (dwDisplayFlags & ITEM_VERBOSE)
  3122. {
  3123. LPSTR pszObjId;
  3124. ALG_ID aiPubKey;
  3125. DWORD dwBitLen;
  3126. //"Version:: %d\n"
  3127. IDSwprintf(hModule, IDS_VERSION, pCert->pCertInfo->dwVersion);
  3128. pszObjId = pCert->pCertInfo->SignatureAlgorithm.pszObjId;
  3129. if (pszObjId == NULL)
  3130. pszObjId = g_szNULL;
  3131. //"SignatureAlgorithm:: "
  3132. IDSwprintf(hModule, IDS_SIG_ALGO);
  3133. printf("%s (%S)\n", pszObjId, GetOIDName(pszObjId, CRYPT_SIGN_ALG_OID_GROUP_ID));
  3134. if (pCert->pCertInfo->SignatureAlgorithm.Parameters.cbData)
  3135. {
  3136. //"SignatureAlgorithm.Parameters::\n"
  3137. IDSwprintf(hModule, IDS_SIG_ALGO_PARAM);
  3138. PrintBytes(L" ",
  3139. pCert->pCertInfo->SignatureAlgorithm.Parameters.pbData,
  3140. pCert->pCertInfo->SignatureAlgorithm.Parameters.cbData);
  3141. }
  3142. //public key algorithm
  3143. pszObjId = pCert->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId;
  3144. if (pszObjId == NULL)
  3145. pszObjId = g_szNULL;
  3146. // "SubjectPublicKeyInfo.Algorithm::
  3147. IDSwprintf(hModule, IDS_SUB_KEY_ALGO);
  3148. printf("%s (%S)\n", pszObjId, GetOIDName(pszObjId, CRYPT_PUBKEY_ALG_OID_GROUP_ID));
  3149. aiPubKey = GetAlgid(pszObjId, CRYPT_PUBKEY_ALG_OID_GROUP_ID);
  3150. if (pCert->pCertInfo->SubjectPublicKeyInfo.Algorithm.Parameters.cbData)
  3151. {
  3152. //"SubjectPublicKeyInfo.Algorithm.Parameters::\n"
  3153. IDSwprintf(hModule, IDS_SUB_KEY_ALGO_PARAM);
  3154. PrintBytes(L" ",
  3155. pCert->pCertInfo->SubjectPublicKeyInfo.Algorithm.Parameters.pbData,
  3156. pCert->pCertInfo->SubjectPublicKeyInfo.Algorithm.Parameters.cbData);
  3157. //display DSS sign key
  3158. if (CALG_DSS_SIGN == aiPubKey)
  3159. {
  3160. PCERT_DSS_PARAMETERS pDssParameters;
  3161. DWORD cbDssParameters;
  3162. if (pDssParameters =
  3163. (PCERT_DSS_PARAMETERS) TestNoCopyDecodeObject(
  3164. X509_DSS_PARAMETERS,
  3165. pCert->pCertInfo->SubjectPublicKeyInfo.Algorithm.Parameters.pbData,
  3166. pCert->pCertInfo->SubjectPublicKeyInfo.Algorithm.Parameters.cbData,
  3167. &cbDssParameters
  3168. ))
  3169. {
  3170. DWORD cbKey = pDssParameters->p.cbData;
  3171. //"DSS Key Length:: %d bytes, %d bits\n"
  3172. IDSwprintf(hModule, IDS_DSS_LENGTH, cbKey, cbKey*8);
  3173. //"DSS P (little endian)::\n"
  3174. IDSwprintf(hModule, IDS_DSS_P);
  3175. PrintBytes(L" ", pDssParameters->p.pbData,
  3176. pDssParameters->p.cbData);
  3177. //"DSS Q (little endian)::\n"
  3178. IDSwprintf(hModule, IDS_DSS_Q);
  3179. PrintBytes(L" ", pDssParameters->q.pbData,
  3180. pDssParameters->q.cbData);
  3181. //"DSS G (little endian)::\n"
  3182. IDSwprintf(hModule, IDS_DSS_G);
  3183. PrintBytes(L" ", pDssParameters->g.pbData,
  3184. pDssParameters->g.cbData);
  3185. ToolUtlFree(pDssParameters);
  3186. }
  3187. }
  3188. }
  3189. //"SubjectPublicKeyInfo.PublicKey"
  3190. IDSwprintf(hModule, IDS_SUB_KEY_INFO);
  3191. if (0 != (dwBitLen = CertGetPublicKeyLength(
  3192. g_dwCertEncodingType,
  3193. &pCert->pCertInfo->SubjectPublicKeyInfo)))
  3194. //" (BitLength: %d)"
  3195. IDSwprintf(hModule, IDS_BIT_LENGTH, dwBitLen);
  3196. if (pCert->pCertInfo->SubjectPublicKeyInfo.PublicKey.cUnusedBits)
  3197. //" (UnusedBits: %d)"
  3198. IDSwprintf(hModule, IDS_UNUSED_BITS,
  3199. pCert->pCertInfo->SubjectPublicKeyInfo.PublicKey.cUnusedBits);
  3200. printf("\n");
  3201. //print public key
  3202. if (pCert->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData)
  3203. {
  3204. PrintBytes(L" ",
  3205. pCert->pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData,
  3206. pCert->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData);
  3207. if (CALG_RSA_SIGN == aiPubKey || CALG_RSA_KEYX == aiPubKey)
  3208. {
  3209. PUBLICKEYSTRUC *pPubKeyStruc=NULL;
  3210. DWORD cbPubKeyStruc;
  3211. //"RSA_CSP_PUBLICKEYBLOB::\n"
  3212. IDSwprintf(hModule, IDS_RSA_CSP);
  3213. if (pPubKeyStruc = (PUBLICKEYSTRUC *) TestNoCopyDecodeObject(
  3214. RSA_CSP_PUBLICKEYBLOB,
  3215. pCert->pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData,
  3216. pCert->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData,
  3217. &cbPubKeyStruc
  3218. ))
  3219. {
  3220. PrintBytes(L" ", (BYTE *) pPubKeyStruc, cbPubKeyStruc);
  3221. ToolUtlFree(pPubKeyStruc);
  3222. }
  3223. }
  3224. else if (CALG_DSS_SIGN == aiPubKey)
  3225. {
  3226. PCRYPT_UINT_BLOB pDssPubKey;
  3227. DWORD cbDssPubKey;
  3228. //"DSS Y (little endian)::\n"
  3229. IDSwprintf(hModule, IDS_DSS_Y);
  3230. if (pDssPubKey = (PCRYPT_UINT_BLOB) TestNoCopyDecodeObject
  3231. (
  3232. X509_DSS_PUBLICKEY,
  3233. pCert->pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData,
  3234. pCert->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData,
  3235. &cbDssPubKey
  3236. ))
  3237. {
  3238. PrintBytes(L" ", pDssPubKey->pbData, pDssPubKey->cbData);
  3239. ToolUtlFree(pDssPubKey);
  3240. }
  3241. }
  3242. }
  3243. else
  3244. //" No public key\n"
  3245. IDSwprintf(hModule, IDS_NO_PUB_KEY);
  3246. DisplaySignature
  3247. (
  3248. pCert->pbCertEncoded,
  3249. pCert->cbCertEncoded,
  3250. dwDisplayFlags);
  3251. //IssuerUniqueId
  3252. if (pCert->pCertInfo->IssuerUniqueId.cbData)
  3253. {
  3254. //"IssuerUniqueId"
  3255. IDSwprintf(hModule, IDS_ISSUER_ID);
  3256. if (pCert->pCertInfo->IssuerUniqueId.cUnusedBits)
  3257. //" (UnusedBits: %d)"
  3258. IDSwprintf(hModule, IDS_UNUSED_BITS,
  3259. pCert->pCertInfo->IssuerUniqueId.cUnusedBits);
  3260. printf("\n");
  3261. PrintBytes(L" ", pCert->pCertInfo->IssuerUniqueId.pbData,
  3262. pCert->pCertInfo->IssuerUniqueId.cbData);
  3263. }
  3264. if (pCert->pCertInfo->SubjectUniqueId.cbData)
  3265. {
  3266. //"SubjectUniqueId"
  3267. IDSwprintf(hModule, IDS_SUBJECT_ID);
  3268. if (pCert->pCertInfo->SubjectUniqueId.cUnusedBits)
  3269. //" (UnusedBits: %d)"
  3270. IDSwprintf(hModule, IDS_UNUSED_BITS,
  3271. pCert->pCertInfo->SubjectUniqueId.cUnusedBits);
  3272. printf("\n");
  3273. PrintBytes(L" ", pCert->pCertInfo->SubjectUniqueId.pbData,
  3274. pCert->pCertInfo->SubjectUniqueId.cbData);
  3275. }
  3276. //extensions
  3277. if (pCert->pCertInfo->cExtension != 0)
  3278. {
  3279. PrintExtensions(pCert->pCertInfo->cExtension,
  3280. pCert->pCertInfo->rgExtension, dwDisplayFlags);
  3281. }
  3282. }//ITEM_VERBOSE
  3283. fResult=TRUE;
  3284. return fResult;
  3285. }
  3286. //-------------------------------------------------------------------------
  3287. //
  3288. // Display a CTL
  3289. //
  3290. //-------------------------------------------------------------------------
  3291. BOOL DisplayCTL(PCCTL_CONTEXT pCtl, DWORD dwDisplayFlags)
  3292. {
  3293. BOOL fResult=FALSE;
  3294. PCTL_INFO pInfo = pCtl->pCtlInfo;
  3295. DWORD cId;
  3296. LPSTR *ppszId = NULL;
  3297. DWORD i;
  3298. BYTE rgbHash[MAX_HASH_LEN];
  3299. DWORD cbHash = MAX_HASH_LEN;
  3300. // "SubjectUsage::\n"
  3301. IDSwprintf(hModule, IDS_SUBJECT_USAGE);
  3302. cId = pInfo->SubjectUsage.cUsageIdentifier;
  3303. ppszId = pInfo->SubjectUsage.rgpszUsageIdentifier;
  3304. if (cId == 0)
  3305. {
  3306. //" No Usage Identifiers\n"
  3307. IDSwprintf(hModule, IDS_NO_USAGE_IDS );
  3308. }
  3309. else
  3310. {
  3311. for (i = 0; i < cId; i++, ppszId++)
  3312. printf(" [%d] %s\n", i, *ppszId);
  3313. }
  3314. //list identifier
  3315. if (pInfo->ListIdentifier.cbData)
  3316. {
  3317. //"ListIdentifier::\n"
  3318. IDSwprintf(hModule, IDS_LIST_DIS);
  3319. PrintBytes(L" ",
  3320. pInfo->ListIdentifier.pbData,
  3321. pInfo->ListIdentifier.cbData);
  3322. }
  3323. if (pInfo->SequenceNumber.cbData)
  3324. {
  3325. //"SequenceNumber::"
  3326. IDSwprintf(hModule, IDS_SEQUENCE);
  3327. DisplaySerialNumber(&pInfo->SequenceNumber);
  3328. printf("\n");
  3329. }
  3330. //update
  3331. //"ThisUpdate:: %s\n"
  3332. IDSwprintf(hModule, IDS_THIS_UPDATE, FileTimeText(&pCtl->pCtlInfo->ThisUpdate));
  3333. //"NextUpdate:: %s\n"
  3334. IDSwprintf(hModule,IDS_NEXT_UPDATE, FileTimeText(&pCtl->pCtlInfo->NextUpdate));
  3335. //check the time validity
  3336. if (!IsTimeValidCtl(pCtl))
  3337. // "****** Time Invalid CTL\n"
  3338. IDSwprintf(hModule, IDS_TIME_INVALID);
  3339. //Display SHA1 thumbprint
  3340. CertGetCTLContextProperty(
  3341. pCtl,
  3342. CERT_SHA1_HASH_PROP_ID,
  3343. rgbHash,
  3344. &cbHash
  3345. );
  3346. DisplayThumbprint(g_wszSHA1, rgbHash, cbHash);
  3347. cbHash=MAX_HASH_LEN;
  3348. CertGetCTLContextProperty(
  3349. pCtl,
  3350. CERT_MD5_HASH_PROP_ID,
  3351. rgbHash,
  3352. &cbHash
  3353. );
  3354. DisplayThumbprint(g_wszMD5, rgbHash, cbHash);
  3355. // PrintAuxCtlProperties(pCtl, dwDisplayFlags);
  3356. //Display SubjectAlgorithm
  3357. if (dwDisplayFlags & ITEM_VERBOSE)
  3358. {
  3359. LPSTR pszObjId;
  3360. //"Version:: %d\n"
  3361. IDSwprintf(hModule, IDS_VERSION, pInfo->dwVersion);
  3362. pszObjId = pInfo->SubjectAlgorithm.pszObjId;
  3363. if (pszObjId == NULL)
  3364. pszObjId = g_szNULL;
  3365. //"SubjectAlgorithm:: "
  3366. IDSwprintf(hModule, IDS_SUB_ALGO);
  3367. printf("%s \n", pszObjId);
  3368. if (pInfo->SubjectAlgorithm.Parameters.cbData)
  3369. {
  3370. //"SubjectAlgorithm.Parameters::\n"
  3371. IDSwprintf(hModule, IDS_SUB_ALGO_PARAM);
  3372. PrintBytes(L" ",
  3373. pInfo->SubjectAlgorithm.Parameters.pbData,
  3374. pInfo->SubjectAlgorithm.Parameters.cbData);
  3375. }
  3376. if (pInfo->cExtension != 0)
  3377. {
  3378. PrintExtensions(pInfo->cExtension, pInfo->rgExtension,
  3379. dwDisplayFlags);
  3380. }
  3381. }
  3382. if (pInfo->cCTLEntry == 0)
  3383. //"----- No Entries -----\n"
  3384. IDSwprintf(hModule, IDS_NO_ENTRIES);
  3385. else
  3386. {
  3387. //"----- Entries -----\n"
  3388. IDSwprintf(hModule, IDS_ENTRIES);
  3389. PrintCtlEntries(pCtl,dwDisplayFlags);
  3390. }
  3391. //print the signer info
  3392. DisplaySignerInfo(pCtl->hCryptMsg, dwDisplayFlags);
  3393. fResult=TRUE;
  3394. return fResult;
  3395. }
  3396. //-------------------------------------------------------------------------
  3397. //
  3398. // Display a CTL entries
  3399. //
  3400. //-------------------------------------------------------------------------
  3401. void PrintCtlEntries(PCCTL_CONTEXT pCtl, DWORD dwDisplayFlags)
  3402. {
  3403. PCTL_INFO pInfo = pCtl->pCtlInfo;
  3404. DWORD cEntry = pInfo->cCTLEntry;
  3405. PCTL_ENTRY pEntry = pInfo->rgCTLEntry;
  3406. DWORD i;
  3407. for (i = 0; i < cEntry; i++, pEntry++)
  3408. {
  3409. //" [%d] SubjectIdentifier::\n"
  3410. IDSwprintf(hModule, IDS_SUB_ID,i);
  3411. PrintBytes(L" ",
  3412. pEntry->SubjectIdentifier.pbData,
  3413. pEntry->SubjectIdentifier.cbData);
  3414. if (dwDisplayFlags & ITEM_VERBOSE)
  3415. {
  3416. if (pEntry->cAttribute)
  3417. {
  3418. //" [%d] Attributes::\n"
  3419. IDSwprintf(hModule, IDS_ATTR, i);
  3420. PrintAttributes(pEntry->cAttribute, pEntry->rgAttribute,
  3421. dwDisplayFlags);
  3422. }
  3423. }
  3424. }
  3425. }
  3426. //-------------------------------------------------------------------------
  3427. //
  3428. // Display a CRL
  3429. //
  3430. //-------------------------------------------------------------------------
  3431. BOOL DisplayCRL(PCCRL_CONTEXT pCrl, DWORD dwDisplayFlags)
  3432. {
  3433. BOOL fResult=FALSE;
  3434. BYTE rgbHash[MAX_HASH_LEN];
  3435. DWORD cbHash = MAX_HASH_LEN;
  3436. //"Issuer::\n"
  3437. IDSwprintf(hModule, IDS_ISSUER);
  3438. DecodeName(pCrl->pCrlInfo->Issuer.pbData,
  3439. pCrl->pCrlInfo->Issuer.cbData, dwDisplayFlags);
  3440. //"ThisUpdate:: %s\n"
  3441. IDSwprintf(hModule, IDS_THIS_UPDATE, FileTimeText(&pCrl->pCrlInfo->ThisUpdate));
  3442. //"NextUpdate:: %s\n"
  3443. IDSwprintf(hModule,IDS_NEXT_UPDATE, FileTimeText(&pCrl->pCrlInfo->NextUpdate));
  3444. CertGetCRLContextProperty(
  3445. pCrl,
  3446. CERT_SHA1_HASH_PROP_ID,
  3447. rgbHash,
  3448. &cbHash
  3449. );
  3450. DisplayThumbprint(g_wszSHA1, rgbHash, cbHash);
  3451. cbHash=MAX_HASH_LEN;
  3452. CertGetCRLContextProperty(
  3453. pCrl,
  3454. CERT_MD5_HASH_PROP_ID,
  3455. rgbHash,
  3456. &cbHash
  3457. );
  3458. DisplayThumbprint(g_wszMD5, rgbHash, cbHash);
  3459. // PrintAuxCrlProperties(pCrl, dwDisplayFlags);
  3460. if (dwDisplayFlags & ITEM_VERBOSE)
  3461. {
  3462. LPSTR pszObjId;
  3463. //"Version:: %d\n"
  3464. IDSwprintf(hModule, IDS_VERSION, pCrl->pCrlInfo->dwVersion);
  3465. pszObjId = pCrl->pCrlInfo->SignatureAlgorithm.pszObjId;
  3466. if (pszObjId == NULL)
  3467. pszObjId = g_szNULL;
  3468. //"SignatureAlgorithm:: "
  3469. IDSwprintf(hModule, IDS_SIG_ALGO);
  3470. printf("%s \n", pszObjId);
  3471. if (pCrl->pCrlInfo->SignatureAlgorithm.Parameters.cbData)
  3472. {
  3473. //"SignatureAlgorithm.Parameters::\n"
  3474. IDSwprintf(hModule, IDS_SIG_ALGO_PARAM);
  3475. PrintBytes(L" ",
  3476. pCrl->pCrlInfo->SignatureAlgorithm.Parameters.pbData,
  3477. pCrl->pCrlInfo->SignatureAlgorithm.Parameters.cbData);
  3478. }
  3479. //extensions
  3480. if (pCrl->pCrlInfo->cExtension != 0)
  3481. {
  3482. PrintExtensions(pCrl->pCrlInfo->cExtension,
  3483. pCrl->pCrlInfo->rgExtension,
  3484. dwDisplayFlags);
  3485. }
  3486. }
  3487. if (pCrl->pCrlInfo->cCRLEntry == 0)
  3488. //"----- No Entries -----\n"
  3489. IDSwprintf(hModule, IDS_NO_ENTRIES);
  3490. else
  3491. {
  3492. //"----- Entries -----\n"
  3493. IDSwprintf(hModule, IDS_ENTRIES);
  3494. PrintCrlEntries(pCrl->pCrlInfo->cCRLEntry,
  3495. pCrl->pCrlInfo->rgCRLEntry, dwDisplayFlags);
  3496. }
  3497. fResult=TRUE;
  3498. return fResult;
  3499. }
  3500. //-------------------------------------------------------------------------
  3501. //
  3502. // PrintCrlEntries
  3503. //
  3504. //-------------------------------------------------------------------------
  3505. void PrintCrlEntries(DWORD cEntry, PCRL_ENTRY pEntry,
  3506. DWORD dwDisplayFlags)
  3507. {
  3508. DWORD i;
  3509. for (i = 0; i < cEntry; i++, pEntry++)
  3510. {
  3511. //" [%d] SerialNumber::"
  3512. IDSwprintf(hModule, IDS_SERIAL_NUM_I, i);
  3513. DisplaySerialNumber(&pEntry->SerialNumber);
  3514. printf("\n");
  3515. if (dwDisplayFlags & ITEM_VERBOSE)
  3516. {
  3517. //" [%d] RevocationDate:: %s\n"
  3518. IDSwprintf(hModule, IDS_REVOC_DATE,
  3519. i,FileTimeText(&pEntry->RevocationDate));
  3520. }
  3521. if (pEntry->cExtension == 0)
  3522. //" [%d] Extensions:: NONE\n"
  3523. IDSwprintf(hModule, IDS_NO_EXTENSION,i);
  3524. else
  3525. {
  3526. //" [%d] Extensions::\n"
  3527. IDSwprintf(hModule, IDS_EXTENSION, i);
  3528. PrintExtensions(pEntry->cExtension, pEntry->rgExtension,
  3529. dwDisplayFlags);
  3530. }
  3531. }
  3532. }
  3533. //-------------------------------------------------------------------------
  3534. //
  3535. // Display a signer info
  3536. //
  3537. //-------------------------------------------------------------------------
  3538. BOOL DisplaySignerInfo(HCRYPTMSG hMsg, DWORD dwItem)
  3539. {
  3540. BOOL fResult=FALSE;
  3541. DWORD dwSignerCount=0;
  3542. DWORD cbData=0;
  3543. DWORD dwSignerIndex=0;
  3544. PCRYPT_ATTRIBUTES pAttrs;
  3545. LPSTR pszObjId=NULL;
  3546. if(!hMsg)
  3547. return FALSE;
  3548. //decide the number of signers
  3549. cbData=sizeof(dwSignerCount);
  3550. if(!CryptMsgGetParam(hMsg,
  3551. CMSG_SIGNER_COUNT_PARAM,
  3552. 0,
  3553. &dwSignerCount,
  3554. &cbData) )
  3555. {
  3556. IDSwprintf(hModule, IDS_ERR_GET_SINGER_COUNT);
  3557. return FALSE;
  3558. }
  3559. if(dwSignerCount==0)
  3560. {
  3561. IDSwprintf(hModule, IDS_DIS_NO_SIGNER);
  3562. return TRUE;
  3563. }
  3564. for(dwSignerIndex=0; dwSignerIndex < dwSignerCount; dwSignerIndex++)
  3565. {
  3566. PCCERT_CONTEXT pSigner;
  3567. PCMSG_SIGNER_INFO pSignerInfo;
  3568. //"----- Signer [%d] -----\n");
  3569. IDSwprintf(hModule, IDS_SIGNER_INDEX, dwSignerIndex+1);
  3570. //get the signerInfo
  3571. if(pSignerInfo=(PCMSG_SIGNER_INFO) AllocAndGetMsgParam(
  3572. hMsg,
  3573. CMSG_SIGNER_INFO_PARAM,
  3574. dwSignerIndex,
  3575. &cbData))
  3576. {
  3577. //Dispaly the hash algorithm
  3578. pszObjId = pSignerInfo->HashAlgorithm.pszObjId;
  3579. if (pszObjId == NULL)
  3580. pszObjId = g_szNULL;
  3581. //"Hash Algorithm:: "
  3582. IDSwprintf(hModule, IDS_HASH_ALGO);
  3583. printf("%s (%S)\n", pszObjId, GetOIDName(pszObjId, CRYPT_HASH_ALG_OID_GROUP_ID));
  3584. if (pSignerInfo->HashAlgorithm.Parameters.cbData)
  3585. {
  3586. //"HashAlgorithm.Parameters::\n"
  3587. IDSwprintf(hModule, IDS_HASH_ALGO_PARAM);
  3588. PrintBytes(L" ",
  3589. pSignerInfo->HashAlgorithm.Parameters.pbData,
  3590. pSignerInfo->HashAlgorithm.Parameters.cbData);
  3591. }
  3592. //Display the encrypt algorithm
  3593. pszObjId = pSignerInfo->HashEncryptionAlgorithm.pszObjId;
  3594. if (pszObjId == NULL)
  3595. pszObjId = g_szNULL;
  3596. //"Encrypt Algorithm:: "
  3597. IDSwprintf(hModule, IDS_ENCRYPT_ALGO);
  3598. printf("%s (%S)\n", pszObjId, GetOIDName(pszObjId, CRYPT_SIGN_ALG_OID_GROUP_ID));
  3599. if (pSignerInfo->HashEncryptionAlgorithm.Parameters.cbData)
  3600. {
  3601. //"Encrypt Algorithm.Parameters::\n"
  3602. IDSwprintf(hModule, IDS_ENCRYPT_ALGO_PARAM);
  3603. PrintBytes(L" ",
  3604. pSignerInfo->HashEncryptionAlgorithm.Parameters.pbData,
  3605. pSignerInfo->HashEncryptionAlgorithm.Parameters.cbData);
  3606. }
  3607. ToolUtlFree(pSignerInfo);
  3608. }
  3609. if (CryptMsgGetAndVerifySigner(
  3610. hMsg,
  3611. 0, // cSignerStore
  3612. NULL, // rghSignerStore
  3613. CMSG_USE_SIGNER_INDEX_FLAG,
  3614. &pSigner,
  3615. &dwSignerIndex
  3616. ))
  3617. {
  3618. //"----- Signer [%d] Certificate-----\n");
  3619. IDSwprintf(hModule, IDS_SIGNER_INDEX_CERT, dwSignerIndex+1);
  3620. DisplayCert(pSigner, dwItem);
  3621. CertFreeCertificateContext(pSigner);
  3622. }
  3623. else
  3624. {
  3625. IDSwprintf(hModule, IDS_ERR_GET_SIGNER_CERT);
  3626. goto CLEANUP;
  3627. }
  3628. //DisplaySigner information
  3629. if (pAttrs = (PCRYPT_ATTRIBUTES) AllocAndGetMsgParam(
  3630. hMsg,
  3631. CMSG_SIGNER_AUTH_ATTR_PARAM,
  3632. dwSignerIndex,
  3633. &cbData))
  3634. {
  3635. //"----- Signer [%d] AuthenticatedAttributes -----\n"
  3636. IDSwprintf(hModule, IDS_DIS_SIGNER_AUTH_ATTR, dwSignerIndex+1);
  3637. PrintAttributes(pAttrs->cAttr, pAttrs->rgAttr, dwItem);
  3638. ToolUtlFree(pAttrs);
  3639. }
  3640. if (pAttrs = (PCRYPT_ATTRIBUTES) AllocAndGetMsgParam(
  3641. hMsg,
  3642. CMSG_SIGNER_UNAUTH_ATTR_PARAM,
  3643. dwSignerIndex,
  3644. &cbData))
  3645. {
  3646. //"----- Signer [%d] UnauthenticatedAttributes -----\n",
  3647. IDSwprintf(hModule, IDS_DIS_SIGNER_UNAUTH_ATTR, dwSignerIndex+1);
  3648. PrintAttributes(pAttrs->cAttr, pAttrs->rgAttr, dwItem);
  3649. ToolUtlFree(pAttrs);
  3650. }
  3651. }
  3652. fResult=TRUE;
  3653. CLEANUP:
  3654. return fResult;
  3655. }
  3656. //-------------------------------------------------------------------------
  3657. //
  3658. // Open a store file using sip functions
  3659. //
  3660. //-------------------------------------------------------------------------
  3661. HCERTSTORE OpenSipStore(LPWSTR pwszStoreFilename)
  3662. {
  3663. HCERTSTORE hStore = NULL;
  3664. CRYPT_DATA_BLOB SignedData;
  3665. memset(&SignedData, 0, sizeof(SignedData));
  3666. DWORD dwGetEncodingType;
  3667. DWORD dwMsgType=0;
  3668. GUID gSubject;
  3669. SIP_DISPATCH_INFO SipDispatch;
  3670. SIP_SUBJECTINFO SubjectInfo;
  3671. if (!CryptSIPRetrieveSubjectGuid(
  3672. pwszStoreFilename,
  3673. NULL, // hFile
  3674. &gSubject)) goto CommonReturn;
  3675. memset(&SipDispatch, 0, sizeof(SipDispatch));
  3676. SipDispatch.cbSize = sizeof(SipDispatch);
  3677. if (!CryptSIPLoad(
  3678. &gSubject,
  3679. 0, // dwFlags
  3680. &SipDispatch)) goto CommonReturn;
  3681. memset(&SubjectInfo, 0, sizeof(SubjectInfo));
  3682. SubjectInfo.cbSize = sizeof(SubjectInfo);
  3683. SubjectInfo.pgSubjectType = (GUID*) &gSubject;
  3684. SubjectInfo.hFile = INVALID_HANDLE_VALUE;
  3685. SubjectInfo.pwsFileName = pwszStoreFilename;
  3686. // SubjectInfo.pwsDisplayName =
  3687. // SubjectInfo.lpSIPInfo =
  3688. // SubjectInfo.dwReserved =
  3689. // SubjectInfo.hProv =
  3690. // SubjectInfo.DigestAlgorithm =
  3691. // SubjectInfo.dwFlags =
  3692. SubjectInfo.dwEncodingType = g_dwMsgAndCertEncodingType;
  3693. // SubjectInfo.lpAddInfo =
  3694. if (!SipDispatch.pfGet(
  3695. &SubjectInfo,
  3696. &dwGetEncodingType,
  3697. 0, // dwIndex
  3698. &SignedData.cbData,
  3699. NULL // pbSignedData
  3700. ) || 0 == SignedData.cbData)
  3701. goto CommonReturn;
  3702. if (NULL == (SignedData.pbData = (BYTE *) ToolUtlAlloc(SignedData.cbData)))
  3703. goto CommonReturn;
  3704. if (!SipDispatch.pfGet(
  3705. &SubjectInfo,
  3706. &dwGetEncodingType,
  3707. 0, // dwIndex
  3708. &SignedData.cbData,
  3709. SignedData.pbData
  3710. ))
  3711. goto CommonReturn;
  3712. hStore = CertOpenStore(
  3713. CERT_STORE_PROV_PKCS7,
  3714. g_dwMsgAndCertEncodingType,
  3715. 0, // hCryptProv
  3716. 0, // dwFlags
  3717. (const void *) &SignedData
  3718. );
  3719. if(!hStore)
  3720. goto CommonReturn;
  3721. //now, we want to update the g_hMsg to hold the signer info
  3722. if(SignNoContentWrap(SignedData.pbData, SignedData.cbData))
  3723. dwMsgType = CMSG_SIGNED;
  3724. if (!(g_hMsg = CryptMsgOpenToDecode(g_dwMsgAndCertEncodingType,
  3725. 0, // dwFlags
  3726. dwMsgType,
  3727. NULL,
  3728. NULL, // pRecipientInfo
  3729. NULL)))
  3730. {
  3731. CertCloseStore(hStore, 0);
  3732. hStore=NULL;
  3733. goto CommonReturn;
  3734. }
  3735. if (!CryptMsgUpdate(g_hMsg,
  3736. SignedData.pbData,
  3737. SignedData.cbData,
  3738. TRUE)) // fFinal
  3739. {
  3740. CertCloseStore(hStore, 0);
  3741. hStore=NULL;
  3742. CryptMsgClose(g_hMsg);
  3743. g_hMsg=NULL;
  3744. }
  3745. CommonReturn:
  3746. if(SignedData.pbData)
  3747. ToolUtlFree(SignedData.pbData);
  3748. return hStore;
  3749. }
  3750. //-------------------------------------------------------------------------
  3751. //
  3752. // BytesToBase64: ascii:
  3753. // conver base64 bstr to bytes
  3754. //
  3755. //-------------------------------------------------------------------------
  3756. HRESULT Base64ToBytes(CHAR *pEncode, DWORD cbEncode, BYTE **ppb, DWORD *pcb)
  3757. {
  3758. DWORD dwErr;
  3759. BYTE *pb;
  3760. DWORD cb;
  3761. *ppb = NULL;
  3762. *pcb = 0;
  3763. cb = 0;
  3764. if (!CryptStringToBinaryA(
  3765. pEncode,
  3766. cbEncode,
  3767. CRYPT_STRING_ANY,
  3768. NULL,
  3769. &cb,
  3770. NULL,
  3771. NULL
  3772. ))
  3773. return HRESULT_FROM_WIN32(GetLastError());
  3774. if (cb == 0)
  3775. return S_OK;
  3776. if (NULL == (pb = (BYTE *) ToolUtlAlloc(cb)))
  3777. return E_OUTOFMEMORY;
  3778. if (!CryptStringToBinaryA(
  3779. pEncode,
  3780. cbEncode,
  3781. CRYPT_STRING_ANY,
  3782. pb,
  3783. &cb,
  3784. NULL,
  3785. NULL
  3786. )) {
  3787. ToolUtlFree(pb);
  3788. return HRESULT_FROM_WIN32(GetLastError());
  3789. } else {
  3790. *ppb = pb;
  3791. *pcb = cb;
  3792. return S_OK;
  3793. }
  3794. }
  3795. //-------------------------------------------------------------------------
  3796. //
  3797. // BytesToBase64 wchar version:
  3798. // conver base64 bstr to bytes
  3799. //
  3800. //-------------------------------------------------------------------------
  3801. HRESULT Base64ToBytesW(WCHAR *pEncode, DWORD cbEncode, BYTE **ppb, DWORD *pcb)
  3802. {
  3803. DWORD dwErr;
  3804. BYTE *pb;
  3805. DWORD cb;
  3806. *ppb = NULL;
  3807. *pcb = 0;
  3808. cb = 0;
  3809. if (!CryptStringToBinaryW(
  3810. pEncode,
  3811. cbEncode,
  3812. CRYPT_STRING_ANY,
  3813. NULL,
  3814. &cb,
  3815. NULL,
  3816. NULL
  3817. ))
  3818. return HRESULT_FROM_WIN32(GetLastError());
  3819. if (cb == 0)
  3820. return S_OK;
  3821. if (NULL == (pb = (BYTE *) ToolUtlAlloc(cb)))
  3822. return E_OUTOFMEMORY;
  3823. if (!CryptStringToBinaryW(
  3824. pEncode,
  3825. cbEncode,
  3826. CRYPT_STRING_ANY,
  3827. pb,
  3828. &cb,
  3829. NULL,
  3830. NULL
  3831. )) {
  3832. ToolUtlFree(pb);
  3833. return HRESULT_FROM_WIN32(GetLastError());
  3834. } else {
  3835. *ppb = pb;
  3836. *pcb = cb;
  3837. return S_OK;
  3838. }
  3839. }
  3840. //------------------------------------------------------------------------------------
  3841. //
  3842. // Base64 decode the file
  3843. //
  3844. //------------------------------------------------------------------------------------
  3845. BOOL GetBase64Decoded(LPWSTR wszStoreName,
  3846. BYTE **ppbByte,
  3847. DWORD *pcbByte)
  3848. {
  3849. BOOL fResult=FALSE;
  3850. BYTE *pbEncoded=NULL;
  3851. DWORD cbEncoded=0;
  3852. //get the blob
  3853. if (S_OK != RetrieveBLOBFromFile(wszStoreName,&cbEncoded, &pbEncoded))
  3854. return FALSE;
  3855. //base64 decode. ascii version
  3856. if(S_OK != Base64ToBytes((CHAR *)pbEncoded, cbEncoded,
  3857. ppbByte, pcbByte))
  3858. {
  3859. //WCHAR version
  3860. if(cbEncoded %2 == 0)
  3861. {
  3862. if(S_OK !=Base64ToBytesW((WCHAR *)pbEncoded, cbEncoded/2,
  3863. ppbByte, pcbByte))
  3864. goto CLEANUP;
  3865. }
  3866. else
  3867. {
  3868. goto CLEANUP;
  3869. }
  3870. }
  3871. fResult=TRUE;
  3872. CLEANUP:
  3873. if(pbEncoded)
  3874. UnmapViewOfFile(pbEncoded);
  3875. return fResult;
  3876. }
  3877. //------------------------------------------------------------------------------------
  3878. //
  3879. // Attempt to read as a file containing an encoded CRL.
  3880. //
  3881. //------------------------------------------------------------------------------------
  3882. HCERTSTORE OpenEncodedCRL(LPWSTR pwszStoreFilename)
  3883. {
  3884. HCERTSTORE hStore=NULL;
  3885. BYTE *pbEncoded;
  3886. DWORD cbEncoded;
  3887. if (S_OK != RetrieveBLOBFromFile(pwszStoreFilename, &cbEncoded,&pbEncoded))
  3888. return NULL;
  3889. if (NULL == (hStore = CertOpenStore(
  3890. CERT_STORE_PROV_MEMORY,
  3891. 0, // dwEncodingType
  3892. 0, // hCryptProv
  3893. 0, // dwFlags
  3894. NULL // pvPara
  3895. )))
  3896. goto CommonReturn;
  3897. if (!CertAddEncodedCRLToStore(
  3898. hStore,
  3899. g_dwCertEncodingType,
  3900. pbEncoded,
  3901. cbEncoded,
  3902. CERT_STORE_ADD_ALWAYS,
  3903. NULL // ppCrlContext
  3904. ))
  3905. {
  3906. CertCloseStore(hStore, 0);
  3907. hStore = NULL;
  3908. }
  3909. CommonReturn:
  3910. if(pbEncoded)
  3911. UnmapViewOfFile(pbEncoded);
  3912. return hStore;
  3913. }
  3914. //------------------------------------------------------------------------------------
  3915. //
  3916. // Attempt to read as a file containing an encoded CER.
  3917. //
  3918. //------------------------------------------------------------------------------------
  3919. HCERTSTORE OpenEncodedCert (LPWSTR pwszStoreFilename)
  3920. {
  3921. HCERTSTORE hStore;
  3922. BYTE *pbEncoded;
  3923. DWORD cbEncoded;
  3924. if (S_OK != RetrieveBLOBFromFile(pwszStoreFilename, &cbEncoded, &pbEncoded))
  3925. return NULL;
  3926. if (NULL == (hStore = CertOpenStore(
  3927. CERT_STORE_PROV_MEMORY,
  3928. 0, // dwEncodingType
  3929. 0, // hCryptProv
  3930. 0, // dwFlags
  3931. NULL // pvPara
  3932. )))
  3933. goto CommonReturn;
  3934. if (!CertAddEncodedCertificateToStore(
  3935. hStore,
  3936. g_dwMsgAndCertEncodingType,
  3937. pbEncoded,
  3938. cbEncoded,
  3939. CERT_STORE_ADD_ALWAYS,
  3940. NULL // ppCtlContext
  3941. ))
  3942. {
  3943. CertCloseStore(hStore, 0);
  3944. hStore = NULL;
  3945. }
  3946. CommonReturn:
  3947. if(pbEncoded)
  3948. UnmapViewOfFile(pbEncoded);
  3949. return hStore;
  3950. }
  3951. //------------------------------------------------------------------------------------
  3952. //
  3953. // Attempt to read as a file containing an encoded CTL.
  3954. //
  3955. //------------------------------------------------------------------------------------
  3956. HCERTSTORE OpenEncodedCTL (LPWSTR pwszStoreFilename)
  3957. {
  3958. HCERTSTORE hStore;
  3959. BYTE *pbEncoded;
  3960. DWORD cbEncoded;
  3961. if (S_OK != RetrieveBLOBFromFile(pwszStoreFilename, &cbEncoded, &pbEncoded))
  3962. return NULL;
  3963. if (NULL == (hStore = CertOpenStore(
  3964. CERT_STORE_PROV_MEMORY,
  3965. 0, // dwEncodingType
  3966. 0, // hCryptProv
  3967. 0, // dwFlags
  3968. NULL // pvPara
  3969. )))
  3970. goto CommonReturn;
  3971. if (!CertAddEncodedCTLToStore(
  3972. hStore,
  3973. g_dwMsgAndCertEncodingType,
  3974. pbEncoded,
  3975. cbEncoded,
  3976. CERT_STORE_ADD_ALWAYS,
  3977. NULL // ppCtlContext
  3978. ))
  3979. {
  3980. CertCloseStore(hStore, 0);
  3981. hStore = NULL;
  3982. }
  3983. CommonReturn:
  3984. if(pbEncoded)
  3985. UnmapViewOfFile(pbEncoded);
  3986. return hStore;
  3987. }
  3988. //--------------------------------------------------------------------------------
  3989. // Set the parameters. They can only be set once
  3990. //--------------------------------------------------------------------------------
  3991. BOOL SetParam(WCHAR **ppwszParam, WCHAR *pwszValue)
  3992. {
  3993. if(*ppwszParam!=NULL)
  3994. {
  3995. IDSwprintf(hModule,IDS_ERR_TOO_MANY_PARAM);
  3996. return FALSE;
  3997. }
  3998. *ppwszParam=pwszValue;
  3999. return TRUE;
  4000. }
  4001. //--------------------------------------------------------------------------------
  4002. // Convert an array of wchars to a BLOB
  4003. //--------------------------------------------------------------------------------
  4004. HRESULT WSZtoBLOB(LPWSTR pwsz, BYTE **ppbByte, DWORD *pcbByte)
  4005. {
  4006. HRESULT hr=E_FAIL;
  4007. DWORD dwIndex=0;
  4008. ULONG ulHalfByte=0;
  4009. DWORD dw1st=0;
  4010. DWORD dw2nd=0;
  4011. if((!pwsz) || (!ppbByte) || (!pcbByte))
  4012. return E_INVALIDARG;
  4013. *ppbByte=NULL;
  4014. *pcbByte=0;
  4015. //make sure the pwsz consists of 20 characters
  4016. if(wcslen(pwsz)!= 2*SHA1_LENGTH)
  4017. return E_FAIL;
  4018. //memory allocation
  4019. *ppbByte=(BYTE *)ToolUtlAlloc(SHA1_LENGTH);
  4020. if(NULL==(*ppbByte))
  4021. return E_INVALIDARG;
  4022. memset(*ppbByte, 0, SHA1_LENGTH);
  4023. //go through two characters (one byte) at a time
  4024. for(dwIndex=0; dwIndex<SHA1_LENGTH; dwIndex++)
  4025. {
  4026. dw1st=dwIndex * 2;
  4027. dw2nd=dwIndex * 2 +1;
  4028. //1st character
  4029. if(((int)(pwsz[dw1st])-(int)(L'0')) <=9 &&
  4030. ((int)(pwsz[dw1st])-(int)(L'0')) >=0)
  4031. {
  4032. ulHalfByte=(ULONG)((ULONG)(pwsz[dw1st])-(ULONG)(L'0'));
  4033. }
  4034. else
  4035. {
  4036. if(((int)(towupper(pwsz[dw1st]))-(int)(L'A')) >=0 &&
  4037. ((int)(towupper(pwsz[dw1st]))-(int)(L'A')) <=5 )
  4038. ulHalfByte=10+(ULONG)((ULONG)(towupper(pwsz[dw1st]))-(ULONG)(L'A'));
  4039. else
  4040. {
  4041. hr=E_INVALIDARG;
  4042. goto CLEANUP;
  4043. }
  4044. }
  4045. //copy the 1st character
  4046. (*ppbByte)[dwIndex]=(BYTE)ulHalfByte;
  4047. //left shift 4 bits
  4048. (*ppbByte)[dwIndex]= (*ppbByte)[dwIndex] <<4;
  4049. //2nd character
  4050. if(((int)(pwsz[dw2nd])-(int)(L'0')) <=9 &&
  4051. ((int)(pwsz[dw2nd])-(int)(L'0')) >=0)
  4052. {
  4053. ulHalfByte=(ULONG)((ULONG)(pwsz[dw2nd])-(ULONG)(L'0'));
  4054. }
  4055. else
  4056. {
  4057. if(((int)(towupper(pwsz[dw2nd]))-(int)(L'A')) >=0 &&
  4058. ((int)(towupper(pwsz[dw2nd]))-(int)(L'A')) <=5 )
  4059. ulHalfByte=10+(ULONG)((ULONG)(towupper(pwsz[dw2nd]))-(ULONG)(L'A'));
  4060. else
  4061. {
  4062. hr=E_INVALIDARG;
  4063. goto CLEANUP;
  4064. }
  4065. }
  4066. //ORed the second character
  4067. (*ppbByte)[dwIndex]=(*ppbByte)[dwIndex] | ((BYTE)ulHalfByte);
  4068. }
  4069. hr=S_OK;
  4070. CLEANUP:
  4071. if(hr!=S_OK)
  4072. {
  4073. if(*ppbByte)
  4074. ToolUtlFree(*ppbByte);
  4075. *ppbByte=NULL;
  4076. }
  4077. else
  4078. *pcbByte=SHA1_LENGTH;
  4079. return hr;
  4080. }
  4081. //+-------------------------------------------------------------------------
  4082. // Skip over the identifier and length octets in an ASN encoded blob.
  4083. // Returns the number of bytes skipped.
  4084. //
  4085. // For an invalid identifier or length octet returns 0.
  4086. //--------------------------------------------------------------------------
  4087. DWORD SkipOverIdentifierAndLengthOctets(
  4088. IN const BYTE *pbDER,
  4089. IN DWORD cbDER
  4090. )
  4091. {
  4092. #define TAG_MASK 0x1f
  4093. DWORD cb;
  4094. DWORD cbLength;
  4095. const BYTE *pb = pbDER;
  4096. // Need minimum of 2 bytes
  4097. if (cbDER < 2)
  4098. return 0;
  4099. // Skip over the identifier octet(s)
  4100. if (TAG_MASK == (*pb++ & TAG_MASK)) {
  4101. // high-tag-number form
  4102. for (cb=2; *pb++ & 0x80; cb++) {
  4103. if (cb >= cbDER)
  4104. return 0;
  4105. }
  4106. } else
  4107. // low-tag-number form
  4108. cb = 1;
  4109. // need at least one more byte for length
  4110. if (cb >= cbDER)
  4111. return 0;
  4112. if (0x80 == *pb)
  4113. // Indefinite
  4114. cb++;
  4115. else if ((cbLength = *pb) & 0x80) {
  4116. cbLength &= ~0x80; // low 7 bits have number of bytes
  4117. cb += cbLength + 1;
  4118. if (cb > cbDER)
  4119. return 0;
  4120. } else
  4121. cb++;
  4122. return cb;
  4123. }
  4124. //--------------------------------------------------------------------------
  4125. //
  4126. // Skip over the tag and length
  4127. //----------------------------------------------------------------------------
  4128. BOOL SignNoContentWrap(IN const BYTE *pbDER, IN DWORD cbDER)
  4129. {
  4130. DWORD cb;
  4131. cb = SkipOverIdentifierAndLengthOctets(pbDER, cbDER);
  4132. if (cb > 0 && cb < cbDER && pbDER[cb] == 0x02)
  4133. return TRUE;
  4134. else
  4135. return FALSE;
  4136. }
  4137. //--------------------------------------------------------------------------
  4138. //
  4139. // Print out bytes
  4140. //--------------------------------------------------------------------------
  4141. #define CROW 16
  4142. void PrintBytes(LPWSTR pwszHdr, BYTE *pb, DWORD cbSize)
  4143. {
  4144. ULONG cb, i;
  4145. if (cbSize == 0)
  4146. {
  4147. //"%s NO Value Bytes\n"
  4148. IDSwprintf(hModule, IDS_NO_BYTE,pwszHdr);
  4149. return;
  4150. }
  4151. while (cbSize > 0)
  4152. {
  4153. wprintf(L"%s", pwszHdr);
  4154. cb = min(CROW, cbSize);
  4155. cbSize -= cb;
  4156. for (i = 0; i<cb; i++)
  4157. wprintf(L" %02X", pb[i]);
  4158. for (i = cb; i<CROW; i++)
  4159. wprintf(L" ");
  4160. wprintf(L" '");
  4161. for (i = 0; i<cb; i++)
  4162. if (pb[i] >= 0x20 && pb[i] <= 0x7f)
  4163. wprintf(L"%c", pb[i]);
  4164. else
  4165. wprintf(L".");
  4166. pb += cb;
  4167. wprintf(L"'\n");
  4168. }
  4169. }
  4170. //+-------------------------------------------------------------------------
  4171. // Allocates and returns the specified cryptographic message parameter.
  4172. //--------------------------------------------------------------------------
  4173. void PrintAttributes(DWORD cAttr, PCRYPT_ATTRIBUTE pAttr,
  4174. DWORD dwItem)
  4175. {
  4176. DWORD i;
  4177. DWORD j;
  4178. LPWSTR pwszObjId=NULL;
  4179. for (i = 0; i < cAttr; i++, pAttr++)
  4180. {
  4181. DWORD cValue = pAttr->cValue;
  4182. PCRYPT_ATTR_BLOB pValue = pAttr->rgValue;
  4183. LPSTR pszObjId = pAttr->pszObjId;
  4184. if (pszObjId == NULL)
  4185. pszObjId = g_szNULL;
  4186. if (cValue)
  4187. {
  4188. for (j = 0; j < cValue; j++, pValue++)
  4189. {
  4190. printf(" [%d,%d] %s\n", i, j, pszObjId);
  4191. if (pValue->cbData)
  4192. {
  4193. if(dwItem & ITEM_VERBOSE)
  4194. PrintBytes(L" ", pValue->pbData, pValue->cbData);
  4195. if (strcmp(pszObjId, szOID_NEXT_UPDATE_LOCATION) == 0)
  4196. {
  4197. //" NextUpdateLocation::\n"
  4198. IDSwprintf(hModule, IDS_NEXT_UPDATE_LOCATION);
  4199. DecodeAndDisplayAltName(pValue->pbData, pValue->cbData,
  4200. dwItem);
  4201. }
  4202. //Display the timestamp attriute
  4203. if(strcmp(pszObjId, szOID_RSA_counterSign)==0)
  4204. {
  4205. //" Timestamp:: \n"
  4206. IDSwprintf(hModule, IDS_TIMESTMAP);
  4207. DisplayTimeStamp(pValue->pbData,
  4208. pValue->cbData,
  4209. dwItem);
  4210. }
  4211. //Display the signing time
  4212. if(strcmp(pszObjId, szOID_RSA_signingTime)==0)
  4213. {
  4214. FILETIME *pSigningTime=NULL;
  4215. if(pSigningTime=(FILETIME *)TestNoCopyDecodeObject(
  4216. PKCS_UTC_TIME,
  4217. pValue->pbData,
  4218. pValue->cbData))
  4219. {
  4220. //" Signing Time:: \n %s\n"
  4221. IDSwprintf(hModule, IDS_SIGNING_TIME,
  4222. FileTimeText(pSigningTime));
  4223. ToolUtlFree(pSigningTime);
  4224. }
  4225. }
  4226. }
  4227. else
  4228. //" NO Value Bytes\n"
  4229. IDSwprintf(hModule, IDS_NO_VALUE_BYTES);
  4230. }
  4231. }
  4232. else
  4233. {
  4234. if(S_OK==SZtoWSZ(pszObjId, &pwszObjId))
  4235. //" [%d] %s :: No Values\n"
  4236. IDSwprintf(hModule, IDS_I_ID_NO_VALUE, i, pwszObjId);
  4237. }
  4238. }
  4239. if(pwszObjId)
  4240. ToolUtlFree(pwszObjId);
  4241. }
  4242. //+-------------------------------------------------------------------------
  4243. // DecodeAndDisplayAltName
  4244. //--------------------------------------------------------------------------
  4245. void DecodeAndDisplayAltName(
  4246. BYTE *pbEncoded,
  4247. DWORD cbEncoded,
  4248. DWORD dwDisplayFlags)
  4249. {
  4250. PCERT_ALT_NAME_INFO pInfo = NULL;
  4251. if (NULL == (pInfo = (PCERT_ALT_NAME_INFO) TestNoCopyDecodeObject(
  4252. X509_ALTERNATE_NAME,
  4253. pbEncoded,
  4254. cbEncoded
  4255. ))) goto CommonReturn;
  4256. DisplayAltName(pInfo, dwDisplayFlags);
  4257. CommonReturn:
  4258. if (pInfo)
  4259. ToolUtlFree(pInfo);
  4260. }
  4261. //+-------------------------------------------------------------------------
  4262. // Display AltName
  4263. //--------------------------------------------------------------------------
  4264. void DisplayAltName(
  4265. PCERT_ALT_NAME_INFO pInfo,
  4266. DWORD dwDisplayFlags)
  4267. {
  4268. DWORD i;
  4269. PCERT_ALT_NAME_ENTRY pEntry = pInfo->rgAltEntry;
  4270. DWORD cEntry = pInfo->cAltEntry;
  4271. for (i = 0; i < cEntry; i++, pEntry++) {
  4272. wprintf(L" [%d] ", i);
  4273. DisplayAltNameEntry(pEntry, dwDisplayFlags);
  4274. }
  4275. }
  4276. //+-------------------------------------------------------------------------
  4277. // Display an alternative name entry
  4278. //--------------------------------------------------------------------------
  4279. void DisplayAltNameEntry(
  4280. PCERT_ALT_NAME_ENTRY pEntry,
  4281. DWORD dwDisplayFlags)
  4282. {
  4283. switch (pEntry->dwAltNameChoice) {
  4284. case CERT_ALT_NAME_OTHER_NAME:
  4285. //"OtherName:\n"
  4286. IDSwprintf(hModule, IDS_OTHER_NAME);
  4287. break;
  4288. case CERT_ALT_NAME_X400_ADDRESS:
  4289. //"X400Address:\n");
  4290. IDSwprintf(hModule, IDS_X400);
  4291. break;
  4292. case CERT_ALT_NAME_DIRECTORY_NAME:
  4293. //("DirectoryName:\n");
  4294. IDSwprintf(hModule, IDS_DIRECTORY_NAME);
  4295. DecodeName(pEntry->DirectoryName.pbData,
  4296. pEntry->DirectoryName.cbData, dwDisplayFlags);
  4297. break;
  4298. case CERT_ALT_NAME_EDI_PARTY_NAME:
  4299. //"EdiPartyName:\n"
  4300. IDSwprintf(hModule, IDS_EDI_PARTY);
  4301. break;
  4302. case CERT_ALT_NAME_RFC822_NAME:
  4303. //"RFC822: %s\n"
  4304. IDSwprintf(hModule, IDS_RFC,pEntry->pwszRfc822Name );
  4305. break;
  4306. case CERT_ALT_NAME_DNS_NAME:
  4307. //"DNS: %s\n",
  4308. IDSwprintf(hModule, IDS_DNS, pEntry->pwszDNSName);
  4309. break;
  4310. case CERT_ALT_NAME_URL:
  4311. //"URL: %s\n"
  4312. IDSwprintf(hModule, IDS_ALT_NAME_URL,pEntry->pwszURL);
  4313. break;
  4314. case CERT_ALT_NAME_IP_ADDRESS:
  4315. //"IPAddress:\n"
  4316. IDSwprintf(hModule, IDS_IP);
  4317. PrintBytes(L" ", pEntry->IPAddress.pbData, pEntry->IPAddress.cbData);
  4318. break;
  4319. case CERT_ALT_NAME_REGISTERED_ID:
  4320. //"RegisteredID:",
  4321. IDSwprintf(hModule, IDS_REG_ID);
  4322. printf("%s\n", pEntry->pszRegisteredID);
  4323. break;
  4324. default:
  4325. //"Unknown choice: %d\n"
  4326. IDSwprintf(hModule, IDS_UNKNOWN_ALT_NAME,pEntry->dwAltNameChoice);
  4327. }
  4328. }
  4329. //+-------------------------------------------------------------------------
  4330. // Display an alternative name entry
  4331. //--------------------------------------------------------------------------
  4332. void DisplayThumbprint(
  4333. LPWSTR pwszHash,
  4334. BYTE *pbHash,
  4335. DWORD cbHash
  4336. )
  4337. {
  4338. //"%s Thumbprint:: "
  4339. IDSwprintf(hModule, IDS_Thumbprint, pwszHash);
  4340. if (cbHash == 0)
  4341. printf("%s", g_szNULL);
  4342. else
  4343. {
  4344. ULONG cb;
  4345. while (cbHash > 0) {
  4346. cb = min(4, cbHash);
  4347. cbHash -= cb;
  4348. for (; cb > 0; cb--, pbHash++)
  4349. printf("%02X", *pbHash);
  4350. printf(" ");
  4351. }
  4352. }
  4353. printf("\n");
  4354. }
  4355. //+-------------------------------------------------------------------------
  4356. // Print out the FileTime
  4357. //--------------------------------------------------------------------------
  4358. LPWSTR FileTimeText(FILETIME *pft)
  4359. {
  4360. static WCHAR wszbuf[100];
  4361. FILETIME ftLocal;
  4362. struct tm ctm;
  4363. SYSTEMTIME st;
  4364. WCHAR wszFileTime[50];
  4365. WCHAR wszMilliSecond[50];
  4366. //init
  4367. wszbuf[0]=L'\0';
  4368. //check if the time is available
  4369. if((pft->dwLowDateTime==0) &&
  4370. (pft->dwHighDateTime==0))
  4371. {
  4372. LoadStringU(hModule, IDS_NOT_AVAILABLE, wszbuf, 100);
  4373. return wszbuf;
  4374. }
  4375. //load the string we need
  4376. //" <milliseconds:: %03d>"
  4377. //"<FILETIME %08lX:%08lX>"
  4378. if(!LoadStringU(hModule, IDS_FILE_TIME, wszFileTime, 50) ||
  4379. !LoadStringU(hModule, IDS_MILLI_SECOND, wszMilliSecond, 50))
  4380. return wszbuf;
  4381. FileTimeToLocalFileTime(pft, &ftLocal);
  4382. if (FileTimeToSystemTime(&ftLocal, &st))
  4383. {
  4384. ctm.tm_sec = st.wSecond;
  4385. ctm.tm_min = st.wMinute;
  4386. ctm.tm_hour = st.wHour;
  4387. ctm.tm_mday = st.wDay;
  4388. ctm.tm_mon = st.wMonth-1;
  4389. ctm.tm_year = st.wYear-1900;
  4390. ctm.tm_wday = st.wDayOfWeek;
  4391. ctm.tm_yday = 0;
  4392. ctm.tm_isdst = 0;
  4393. wcscpy(wszbuf, _wasctime(&ctm));
  4394. wszbuf[wcslen(wszbuf)-1] = 0;
  4395. if (st.wMilliseconds)
  4396. {
  4397. WCHAR *pwch = wszbuf + wcslen(wszbuf);
  4398. swprintf(pwch, wszMilliSecond, st.wMilliseconds);
  4399. }
  4400. }
  4401. else
  4402. swprintf(wszbuf, wszFileTime, pft->dwHighDateTime, pft->dwLowDateTime);
  4403. return wszbuf;
  4404. }
  4405. //+-------------------------------------------------------------------------
  4406. // Print other cer properies
  4407. //--------------------------------------------------------------------------
  4408. void PrintAuxCertProperties(PCCERT_CONTEXT pCert, DWORD dwDisplayFlags)
  4409. {
  4410. DWORD dwPropId = 0;
  4411. while (dwPropId = CertEnumCertificateContextProperties(pCert, dwPropId))
  4412. {
  4413. switch (dwPropId)
  4414. {
  4415. case CERT_KEY_PROV_INFO_PROP_ID:
  4416. case CERT_SHA1_HASH_PROP_ID:
  4417. case CERT_MD5_HASH_PROP_ID:
  4418. case CERT_KEY_CONTEXT_PROP_ID:
  4419. // Formatted elsewhere
  4420. break;
  4421. default:
  4422. {
  4423. BYTE *pbData;
  4424. DWORD cbData;
  4425. //"Aux PropId %d (0x%x) ::\n"
  4426. IDSwprintf(hModule, IDS_AUX_PROP_ID, dwPropId, dwPropId);
  4427. CertGetCertificateContextProperty(
  4428. pCert,
  4429. dwPropId,
  4430. NULL, // pvData
  4431. &cbData
  4432. );
  4433. if (cbData)
  4434. {
  4435. if (pbData = (BYTE *) ToolUtlAlloc(cbData))
  4436. {
  4437. if (CertGetCertificateContextProperty(
  4438. pCert,
  4439. dwPropId,
  4440. pbData,
  4441. &cbData
  4442. ))
  4443. {
  4444. PrintBytes(L" ", pbData, cbData);
  4445. if (CERT_CTL_USAGE_PROP_ID == dwPropId)
  4446. {
  4447. // " EnhancedKeyUsage::\n"
  4448. IDSwprintf(hModule, IDS_ENHANCED_KEY_USAGE);
  4449. DecodeAndDisplayCtlUsage(pbData, cbData,
  4450. dwDisplayFlags);
  4451. }
  4452. }
  4453. ToolUtlFree(pbData);
  4454. }
  4455. }
  4456. else
  4457. //" NO Property Bytes\n"
  4458. IDSwprintf(hModule, IDS_NO_PROP_BYTES);
  4459. }
  4460. break;
  4461. }
  4462. }
  4463. }
  4464. //+-------------------------------------------------------------------------
  4465. // DecodeAndDisplayCtlUsage
  4466. //--------------------------------------------------------------------------
  4467. void DecodeAndDisplayCtlUsage(
  4468. BYTE *pbEncoded,
  4469. DWORD cbEncoded,
  4470. DWORD dwDisplayFlags)
  4471. {
  4472. PCTL_USAGE pInfo;
  4473. DWORD cId;
  4474. LPSTR *ppszId;
  4475. DWORD i;
  4476. if (NULL == (pInfo =
  4477. (PCTL_USAGE) TestNoCopyDecodeObject(
  4478. X509_ENHANCED_KEY_USAGE,
  4479. pbEncoded,
  4480. cbEncoded
  4481. ))) goto CLEANUP;
  4482. cId = pInfo->cUsageIdentifier;
  4483. ppszId = pInfo->rgpszUsageIdentifier;
  4484. if (cId == 0)
  4485. //" No Usage Identifiers\n"
  4486. IDSwprintf(hModule, IDS_NO_USAGE_ID);
  4487. for (i = 0; i < cId; i++, ppszId++)
  4488. printf(" [%d] %s\n", i, *ppszId);
  4489. CLEANUP:
  4490. if (pInfo)
  4491. ToolUtlFree(pInfo);
  4492. }
  4493. //+-------------------------------------------------------------------------
  4494. // DisplaySignature
  4495. //--------------------------------------------------------------------------
  4496. void DisplaySignature(
  4497. BYTE *pbEncoded,
  4498. DWORD cbEncoded,
  4499. DWORD dwDisplayFlags
  4500. )
  4501. {
  4502. PCERT_SIGNED_CONTENT_INFO pSignedContent;
  4503. if (pSignedContent = (PCERT_SIGNED_CONTENT_INFO) TestNoCopyDecodeObject(
  4504. X509_CERT,
  4505. pbEncoded,
  4506. cbEncoded
  4507. ))
  4508. {
  4509. LPSTR pszObjId;
  4510. pszObjId = pSignedContent->SignatureAlgorithm.pszObjId;
  4511. if (pszObjId == NULL)
  4512. pszObjId = g_szNULL;
  4513. //"Content SignatureAlgorithm::
  4514. IDSwprintf(hModule, IDS_CONTENT_SIG_ALGO);
  4515. printf("%s (%S)\n",
  4516. pszObjId, GetOIDName(pszObjId, CRYPT_SIGN_ALG_OID_GROUP_ID));
  4517. if (pSignedContent->SignatureAlgorithm.Parameters.cbData)
  4518. {
  4519. //"Content SignatureAlgorithm.Parameters::\n"
  4520. IDSwprintf(hModule, IDS_CONTENT_SIG_ALGO_PARAM);
  4521. PrintBytes(L" ",
  4522. pSignedContent->SignatureAlgorithm.Parameters.pbData,
  4523. pSignedContent->SignatureAlgorithm.Parameters.cbData);
  4524. }
  4525. if (pSignedContent->Signature.cbData)
  4526. {
  4527. ALG_ID aiHash;
  4528. ALG_ID aiPubKey;
  4529. //"Content Signature (little endian)::\n"
  4530. IDSwprintf(hModule, IDS_CONTEXT_SIG);
  4531. PrintBytes(L" ", pSignedContent->Signature.pbData,
  4532. pSignedContent->Signature.cbData);
  4533. GetSignAlgids(pszObjId, &aiHash, &aiPubKey);
  4534. if (CALG_SHA == aiHash && CALG_DSS_SIGN == aiPubKey)
  4535. {
  4536. BYTE *pbDssSignature;
  4537. DWORD cbDssSignature;
  4538. ReverseBytes(pSignedContent->Signature.pbData,
  4539. pSignedContent->Signature.cbData);
  4540. if (pbDssSignature =
  4541. (BYTE *) TestNoCopyDecodeObject(
  4542. X509_DSS_SIGNATURE,
  4543. pSignedContent->Signature.pbData,
  4544. pSignedContent->Signature.cbData,
  4545. &cbDssSignature
  4546. )) {
  4547. if (CERT_DSS_SIGNATURE_LEN == cbDssSignature)
  4548. {
  4549. //"DSS R (little endian)::\n"
  4550. IDSwprintf(hModule, IDS_DSS_R);
  4551. PrintBytes(L" ", pbDssSignature, CERT_DSS_R_LEN);
  4552. //"DSS S (little endian)::\n"
  4553. IDSwprintf(hModule, IDS_DSS_S);
  4554. PrintBytes(L" ", pbDssSignature + CERT_DSS_R_LEN,
  4555. CERT_DSS_S_LEN);
  4556. }
  4557. else
  4558. {
  4559. //"DSS Signature (unexpected length, little endian)::\n"
  4560. IDSwprintf(hModule, IDS_DSS_INFO);
  4561. PrintBytes(L" ", pbDssSignature, cbDssSignature);
  4562. }
  4563. ToolUtlFree(pbDssSignature);
  4564. }
  4565. }
  4566. } else
  4567. //"Content Signature:: NONE\n"
  4568. IDSwprintf(hModule, IDS_CONTENT_SIG_NONE);
  4569. ToolUtlFree(pSignedContent);
  4570. }
  4571. }
  4572. //+-------------------------------------------------------------------------
  4573. // Decode an X509 Name
  4574. //--------------------------------------------------------------------------
  4575. BOOL DecodeName(BYTE *pbEncoded, DWORD cbEncoded, DWORD dwDisplayFlags)
  4576. {
  4577. BOOL fResult;
  4578. PCERT_NAME_INFO pInfo = NULL;
  4579. DWORD i,j;
  4580. PCERT_RDN pRDN;
  4581. PCERT_RDN_ATTR pAttr;
  4582. if (NULL == (pInfo = (PCERT_NAME_INFO) TestNoCopyDecodeObject
  4583. (
  4584. X509_NAME,
  4585. pbEncoded,
  4586. cbEncoded
  4587. ))) goto ErrorReturn;
  4588. for (i = 0, pRDN = pInfo->rgRDN; i < pInfo->cRDN; i++, pRDN++)
  4589. {
  4590. for (j = 0, pAttr = pRDN->rgRDNAttr; j < pRDN->cRDNAttr; j++, pAttr++)
  4591. {
  4592. LPSTR pszObjId = pAttr->pszObjId;
  4593. if (pszObjId == NULL)
  4594. pszObjId = g_szNULL;
  4595. if ((dwDisplayFlags & ITEM_VERBOSE) ||
  4596. (pAttr->dwValueType == CERT_RDN_ENCODED_BLOB) ||
  4597. (pAttr->dwValueType == CERT_RDN_OCTET_STRING))
  4598. {
  4599. printf(" [%d,%d] %s (%S) ", i, j, pszObjId, GetOIDName(pszObjId));
  4600. //ValueType: %d\n"
  4601. IDSwprintf(hModule, IDS_VALUE_TYPE, pAttr->dwValueType);
  4602. PrintBytes(L" ", pAttr->Value.pbData, pAttr->Value.cbData);
  4603. } else if (pAttr->dwValueType == CERT_RDN_UNIVERSAL_STRING)
  4604. {
  4605. printf(" [%d,%d] %s (%S)",
  4606. i, j, pszObjId, GetOIDName(pszObjId));
  4607. DWORD cdw = pAttr->Value.cbData / 4;
  4608. DWORD *pdw = (DWORD *) pAttr->Value.pbData;
  4609. for ( ; cdw > 0; cdw--, pdw++)
  4610. printf(" 0x%08X", *pdw);
  4611. printf("\n");
  4612. DWORD csz;
  4613. csz = CertRDNValueToStrA(
  4614. pAttr->dwValueType,
  4615. &pAttr->Value,
  4616. NULL, // psz
  4617. 0 // csz
  4618. );
  4619. if (csz > 1)
  4620. {
  4621. LPSTR psz = (LPSTR) ToolUtlAlloc(csz);
  4622. if (psz)
  4623. {
  4624. CertRDNValueToStrA(
  4625. pAttr->dwValueType,
  4626. &pAttr->Value,
  4627. psz,
  4628. csz
  4629. );
  4630. //" Str: "
  4631. IDSwprintf(hModule, IDS_STR);
  4632. printf("%s\n", psz);
  4633. ToolUtlFree(psz);
  4634. }
  4635. }
  4636. DWORD cwsz;
  4637. cwsz = CertRDNValueToStrW(
  4638. pAttr->dwValueType,
  4639. &pAttr->Value,
  4640. NULL, // pwsz
  4641. 0 // cwsz
  4642. );
  4643. if (cwsz > 1)
  4644. {
  4645. LPWSTR pwsz =
  4646. (LPWSTR) ToolUtlAlloc(cwsz * sizeof(WCHAR));
  4647. if (pwsz)
  4648. {
  4649. CertRDNValueToStrW(
  4650. pAttr->dwValueType,
  4651. &pAttr->Value,
  4652. pwsz,
  4653. cwsz
  4654. );
  4655. //" WStr: %S\n"
  4656. IDSwprintf(hModule, IDS_WSTR, pwsz);
  4657. ToolUtlFree(pwsz);
  4658. }
  4659. }
  4660. } else if (pAttr->dwValueType == CERT_RDN_BMP_STRING)
  4661. {
  4662. printf(" [%d,%d] %s (%S) %S\n",
  4663. i, j, pszObjId, GetOIDName(pszObjId), (LPWSTR) pAttr->Value.pbData);
  4664. } else
  4665. printf(" [%d,%d] %s (%S) %s\n",
  4666. i, j, pszObjId, GetOIDName(pszObjId), pAttr->Value.pbData);
  4667. }
  4668. }
  4669. fResult = TRUE;
  4670. goto CommonReturn;
  4671. ErrorReturn:
  4672. fResult = FALSE;
  4673. CommonReturn:
  4674. if (pInfo)
  4675. ToolUtlFree(pInfo);
  4676. return fResult;
  4677. }
  4678. //+-------------------------------------------------------------------------
  4679. // PrintExtensions
  4680. //--------------------------------------------------------------------------
  4681. void PrintExtensions(DWORD cExt, PCERT_EXTENSION pExt, DWORD dwDisplayFlags)
  4682. {
  4683. DWORD i;
  4684. for (i = 0; i < cExt; i++, pExt++)
  4685. {
  4686. LPSTR pszObjId = pExt->pszObjId;
  4687. if (pszObjId == NULL)
  4688. pszObjId = g_szNULL;
  4689. int idsCritical = pExt->fCritical ? IDS_TRUE : IDS_FALSE;
  4690. //print the end of line
  4691. printf("\n");
  4692. //"Extension[%d] "
  4693. IDSwprintf(hModule, IDS_EXTENSION_INDEX, i);
  4694. printf("%s", pszObjId);
  4695. //(%s) Critical: ",
  4696. IDSwprintf(hModule, IDS_NAME_CRITICAL, GetOIDName(pszObjId));
  4697. //"%s::\n"
  4698. IDS_IDSwprintf(hModule, IDS_STRING, idsCritical);
  4699. //print bytes on verbose options
  4700. if(dwDisplayFlags & ITEM_VERBOSE)
  4701. PrintBytes(L" ", pExt->Value.pbData, pExt->Value.cbData);
  4702. //try the installed formatting routine 1st
  4703. if(TRUE==InstalledFormat(pszObjId, pExt->Value.pbData, pExt->Value.cbData))
  4704. continue;
  4705. if (strcmp(pszObjId, szOID_AUTHORITY_KEY_IDENTIFIER) == 0)
  4706. DisplayAuthorityKeyIdExtension(
  4707. pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
  4708. else if (strcmp(pszObjId, szOID_AUTHORITY_KEY_IDENTIFIER2) == 0)
  4709. DisplayAuthorityKeyId2Extension(
  4710. pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
  4711. // Will add back after PKIX stabilizes on the definition of this extension
  4712. // else if (strcmp(pszObjId, szOID_AUTHORITY_INFO_ACCESS) == 0)
  4713. // DisplayAuthorityInfoAccessExtension(
  4714. // pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
  4715. else if (strcmp(pszObjId, szOID_CRL_DIST_POINTS) == 0)
  4716. DisplayCrlDistPointsExtension(
  4717. pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
  4718. else if (strcmp(pszObjId, szOID_SUBJECT_KEY_IDENTIFIER) == 0)
  4719. //" <SubjectKeyIdentifer> \n"
  4720. DisplayOctetString(IDS_SUB_KEY_ID,
  4721. pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
  4722. else if (strcmp(pszObjId, szOID_KEY_ATTRIBUTES) == 0)
  4723. DisplayKeyAttrExtension(
  4724. pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
  4725. else if (strcmp(pszObjId, szOID_SUBJECT_ALT_NAME) == 0)
  4726. //" <Subject AltName> \n"
  4727. DisplayAltNameExtension(IDS_SUB_ALT,
  4728. pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
  4729. else if (strcmp(pszObjId, szOID_ISSUER_ALT_NAME) == 0)
  4730. //" <Issuer AltName> \n"
  4731. DisplayAltNameExtension(IDS_ISS_ALT,
  4732. pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
  4733. else if (strcmp(pszObjId, szOID_SUBJECT_ALT_NAME2) == 0)
  4734. //" <Subject AltName #2> \n"
  4735. DisplayAltNameExtension(IDS_SUB_ALT2,
  4736. pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
  4737. else if (strcmp(pszObjId, szOID_ISSUER_ALT_NAME2) == 0)
  4738. //" <Issuer AltName #2> \n"
  4739. DisplayAltNameExtension(IDS_ISS_ALT2,
  4740. pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
  4741. else if (strcmp(pszObjId, szOID_NEXT_UPDATE_LOCATION) == 0)
  4742. //" <NextUpdateLocation> \n"
  4743. DisplayAltNameExtension(IDS_NEXT_UPDATE_LOC,
  4744. pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
  4745. else if (strcmp(pszObjId, szOID_KEY_USAGE_RESTRICTION) == 0)
  4746. DisplayKeyUsageRestrictionExtension(
  4747. pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
  4748. else if (strcmp(pszObjId, szOID_BASIC_CONSTRAINTS) == 0)
  4749. DisplayBasicConstraintsExtension(
  4750. pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
  4751. else if (strcmp(pszObjId, szOID_KEY_USAGE) == 0)
  4752. DisplayKeyUsageExtension(
  4753. pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
  4754. else if (strcmp(pszObjId, szOID_BASIC_CONSTRAINTS2) == 0)
  4755. DisplayBasicConstraints2Extension(
  4756. pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
  4757. else if (strcmp(pszObjId, szOID_CERT_POLICIES) == 0)
  4758. //" <Certificate Policies> \n"
  4759. DisplayPoliciesExtension(IDS_CERT_POLICIES,
  4760. pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
  4761. else if (strcmp(pszObjId, SPC_SP_AGENCY_INFO_OBJID) == 0)
  4762. DisplaySpcSpAgencyExtension(
  4763. pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
  4764. else if (strcmp(pszObjId, SPC_FINANCIAL_CRITERIA_OBJID) == 0)
  4765. DisplaySpcFinancialCriteriaExtension(
  4766. pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
  4767. else if (strcmp(pszObjId, SPC_MINIMAL_CRITERIA_OBJID) == 0)
  4768. DisplaySpcMinimalCriteriaExtension(
  4769. pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
  4770. else if (strcmp(pszObjId, szOID_COMMON_NAME) == 0)
  4771. DisplayCommonNameExtension(
  4772. pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
  4773. else if (strcmp(pszObjId, szOID_ENHANCED_KEY_USAGE) == 0)
  4774. DisplayEnhancedKeyUsageExtension(
  4775. pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
  4776. else if (strcmp(pszObjId, szOID_RSA_SMIMECapabilities) == 0)
  4777. DisplaySMIMECapabilitiesExtension(
  4778. pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
  4779. // CRL extensions
  4780. else if (strcmp(pszObjId, szOID_CRL_REASON_CODE) == 0)
  4781. DisplayCRLReason(
  4782. pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
  4783. // Netscape extensions
  4784. else if (strcmp(pszObjId, szOID_NETSCAPE_CERT_TYPE) == 0)
  4785. //" <NetscapeCertType> \n"
  4786. DisplayBits(IDS_NSCP_CERT,
  4787. pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
  4788. else if (strcmp(pszObjId, szOID_NETSCAPE_BASE_URL) == 0)
  4789. //" <NetscapeBaseURL> \n"
  4790. DisplayAnyString(IDS_NSCP_BASE,
  4791. pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
  4792. else if (strcmp(pszObjId, szOID_NETSCAPE_REVOCATION_URL) == 0)
  4793. //" <NetscapeRevocationURL> \n"
  4794. DisplayAnyString(IDS_NSCP_REV,
  4795. pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
  4796. else if (strcmp(pszObjId, szOID_NETSCAPE_CA_REVOCATION_URL) == 0)
  4797. //" <NetscapeCARevocationURL> \n"
  4798. DisplayAnyString(IDS_NSCP_CA_REV,
  4799. pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
  4800. else if (strcmp(pszObjId, szOID_NETSCAPE_CERT_RENEWAL_URL) == 0)
  4801. //" <NetscapeCertRenewalURL> \n"
  4802. DisplayAnyString(IDS_NSCP_RENEW,
  4803. pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
  4804. else if (strcmp(pszObjId, szOID_NETSCAPE_CA_POLICY_URL) == 0)
  4805. //" <NetscapeCAPolicyURL> \n"
  4806. DisplayAnyString(IDS_NSCP_CA_URL,
  4807. pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
  4808. else if (strcmp(pszObjId, szOID_NETSCAPE_SSL_SERVER_NAME) == 0)
  4809. //" <NetscapeSSLServerName> \n"
  4810. DisplayAnyString(IDS_NSCP_SSL,
  4811. pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
  4812. else if (strcmp(pszObjId, szOID_NETSCAPE_COMMENT) == 0)
  4813. //" <NetscapeComment> \n"
  4814. DisplayAnyString(IDS_NSCP_COM,
  4815. pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
  4816. else if(0==(dwDisplayFlags & ITEM_VERBOSE))
  4817. PrintBytes(L" ", pExt->Value.pbData, pExt->Value.cbData);
  4818. }
  4819. }
  4820. //+-------------------------------------------------------------------------
  4821. // DisplaySMIMECapabilitiesExtension
  4822. //--------------------------------------------------------------------------
  4823. void DisplaySMIMECapabilitiesExtension(
  4824. BYTE *pbEncoded,
  4825. DWORD cbEncoded,
  4826. DWORD dwDisplayFlags)
  4827. {
  4828. PCRYPT_SMIME_CAPABILITIES pInfo;
  4829. DWORD cCap;
  4830. PCRYPT_SMIME_CAPABILITY pCap;
  4831. DWORD i;
  4832. if (NULL == (pInfo =
  4833. (PCRYPT_SMIME_CAPABILITIES) TestNoCopyDecodeObject(
  4834. PKCS_SMIME_CAPABILITIES,
  4835. pbEncoded,
  4836. cbEncoded
  4837. ))) goto ErrorReturn;
  4838. cCap = pInfo->cCapability;
  4839. pCap = pInfo->rgCapability;
  4840. //" <SMIME Capabilties>\n"
  4841. IDSwprintf(hModule, IDS_SMIME);
  4842. if (cCap == 0)
  4843. IDSwprintf(hModule, IDS_NONE);
  4844. for (i = 0; i < cCap; i++, pCap++)
  4845. {
  4846. LPSTR pszObjId = pCap->pszObjId;
  4847. printf(" [%d] %s (%S)", i, pszObjId, GetOIDName(pszObjId));
  4848. if (pCap->Parameters.cbData)
  4849. {
  4850. //" Parameters::\n"
  4851. IDSwprintf(hModule, IDS_PARAMS);
  4852. PrintBytes(L" ",
  4853. pCap->Parameters.pbData,
  4854. pCap->Parameters.cbData);
  4855. } else
  4856. printf("\n");
  4857. }
  4858. ErrorReturn:
  4859. if (pInfo)
  4860. ToolUtlFree(pInfo);
  4861. }
  4862. //+-------------------------------------------------------------------------
  4863. // DisplayEnhancedKeyUsageExtension
  4864. //--------------------------------------------------------------------------
  4865. void DisplayEnhancedKeyUsageExtension(
  4866. BYTE *pbEncoded,
  4867. DWORD cbEncoded,
  4868. DWORD dwDisplayFlags)
  4869. {
  4870. //" <EnhancedKeyUsage> \n");
  4871. IDSwprintf(hModule, IDS_ENH_KEY_USAGE);
  4872. DecodeAndDisplayCtlUsage(pbEncoded, cbEncoded, dwDisplayFlags);
  4873. }
  4874. //+-------------------------------------------------------------------------
  4875. // DisplaySpcFinancialCriteriaExtension
  4876. //--------------------------------------------------------------------------
  4877. void DisplayCommonNameExtension(
  4878. BYTE *pbEncoded,
  4879. DWORD cbEncoded,
  4880. DWORD dwDisplayFlags)
  4881. {
  4882. PCERT_NAME_VALUE pInfo = NULL;
  4883. LPWSTR pwsz = NULL;
  4884. DWORD cwsz;
  4885. if (NULL == (pInfo = (PCERT_NAME_VALUE) TestNoCopyDecodeObject(
  4886. X509_NAME_VALUE,
  4887. pbEncoded,
  4888. cbEncoded
  4889. ))) goto ErrorReturn;
  4890. //" <Common Name> \n"
  4891. IDSwprintf(hModule, IDS_COMMON_NAME);
  4892. cwsz = CertRDNValueToStrW(
  4893. pInfo->dwValueType,
  4894. &pInfo->Value,
  4895. NULL, // pwsz
  4896. 0 // cwsz
  4897. );
  4898. if (cwsz > 1)
  4899. {
  4900. pwsz = (LPWSTR)ToolUtlAlloc(cwsz * sizeof(WCHAR));
  4901. if (pwsz)
  4902. CertRDNValueToStrW(
  4903. pInfo->dwValueType,
  4904. &pInfo->Value,
  4905. pwsz,
  4906. cwsz
  4907. );
  4908. }
  4909. //" ValueType: %d String: ",
  4910. IDSwprintf(hModule, IDS_VALUE_STRING, pInfo->dwValueType);
  4911. if (pwsz)
  4912. wprintf(L"%s", pwsz);
  4913. else
  4914. IDSwprintf(hModule, IDS_NULL);
  4915. printf("\n");
  4916. goto CommonReturn;
  4917. ErrorReturn:
  4918. CommonReturn:
  4919. if (pInfo)
  4920. ToolUtlFree(pInfo);
  4921. if (pwsz)
  4922. ToolUtlFree(pwsz);
  4923. }
  4924. //+-------------------------------------------------------------------------
  4925. // DisplaySpcFinancialCriteriaExtension
  4926. //--------------------------------------------------------------------------
  4927. void DisplaySpcFinancialCriteriaExtension(
  4928. BYTE *pbEncoded,
  4929. DWORD cbEncoded,
  4930. DWORD dwDisplayFlags)
  4931. {
  4932. SPC_FINANCIAL_CRITERIA FinancialCriteria;
  4933. DWORD cbInfo = sizeof(FinancialCriteria);
  4934. if (!CryptDecodeObject(
  4935. g_dwCertEncodingType,
  4936. SPC_FINANCIAL_CRITERIA_OBJID,
  4937. pbEncoded,
  4938. cbEncoded,
  4939. 0, // dwFlags
  4940. &FinancialCriteria,
  4941. &cbInfo
  4942. )) {
  4943. return;
  4944. }
  4945. //" <FinancialCriteria> \n "
  4946. IDSwprintf(hModule, IDS_FIN_CRI);
  4947. if (FinancialCriteria.fFinancialInfoAvailable)
  4948. //"Financial Info Available.");
  4949. IDSwprintf(hModule, IDS_FIN_AVAI);
  4950. else
  4951. IDSwprintf(hModule, IDS_NONE);
  4952. if (FinancialCriteria.fMeetsCriteria)
  4953. //" Meets Criteria."
  4954. IDSwprintf(hModule, IDS_MEET_CRI);
  4955. else
  4956. //" Doesn't Meets Criteria."
  4957. IDSwprintf(hModule, IDS_NO_MEET_CRI);
  4958. printf("\n");
  4959. }
  4960. //+-------------------------------------------------------------------------
  4961. // DisplaySpcMinimalCriteriaExtension
  4962. //--------------------------------------------------------------------------
  4963. void DisplaySpcMinimalCriteriaExtension(
  4964. BYTE *pbEncoded,
  4965. DWORD cbEncoded,
  4966. DWORD dwDisplayFlags)
  4967. {
  4968. BOOL fMinimalCriteria;
  4969. DWORD cbInfo = sizeof(fMinimalCriteria);
  4970. if (!CryptDecodeObject(
  4971. g_dwCertEncodingType,
  4972. SPC_MINIMAL_CRITERIA_OBJID,
  4973. pbEncoded,
  4974. cbEncoded,
  4975. 0, // dwFlags
  4976. &fMinimalCriteria,
  4977. &cbInfo)) {
  4978. return;
  4979. }
  4980. //" <MinimalCriteria> \n ");
  4981. IDSwprintf(hModule, IDS_MIN_CRI);
  4982. if (fMinimalCriteria)
  4983. //"Meets Minimal Criteria."
  4984. IDSwprintf(hModule, IDS_MEET_MIN);
  4985. else
  4986. //"Doesn't Meet Minimal Criteria."
  4987. IDSwprintf(hModule, IDS_NO_MEET_MIN);
  4988. printf("\n");
  4989. }
  4990. //+-------------------------------------------------------------------------
  4991. // DisplaySpcLink
  4992. //--------------------------------------------------------------------------
  4993. void DisplaySpcLink(PSPC_LINK pSpcLink)
  4994. {
  4995. switch (pSpcLink->dwLinkChoice)
  4996. {
  4997. case SPC_URL_LINK_CHOICE:
  4998. //"URL=> %S\n", );
  4999. IDSwprintf(hModule, IDS_SPC_URL, pSpcLink->pwszUrl);
  5000. break;
  5001. case SPC_MONIKER_LINK_CHOICE:
  5002. wprintf(L"%s\n", GuidText((GUID *) pSpcLink->Moniker.ClassId));
  5003. if (pSpcLink->Moniker.SerializedData.cbData)
  5004. {
  5005. //" SerializedData::\n");
  5006. IDSwprintf(hModule, IDS_SERIAL_DATA);
  5007. PrintBytes(L" ", pSpcLink->Moniker.SerializedData.pbData,
  5008. pSpcLink->Moniker.SerializedData.cbData);
  5009. }
  5010. break;
  5011. case SPC_FILE_LINK_CHOICE:
  5012. //"FILE=> %S\n",
  5013. IDSwprintf(hModule, IDS_SPC_FILE,pSpcLink->pwszFile);
  5014. break;
  5015. default:
  5016. //"Unknown SPC Link Choice:: %d\n",
  5017. IDSwprintf(hModule, IDS_UNKNOWN_SPC, pSpcLink->dwLinkChoice);
  5018. }
  5019. }
  5020. //+-------------------------------------------------------------------------
  5021. // DisplaySpcSpAgencyExtension
  5022. //--------------------------------------------------------------------------
  5023. void DisplaySpcSpAgencyExtension(
  5024. BYTE *pbEncoded,
  5025. DWORD cbEncoded,
  5026. DWORD dwDisplayFlags)
  5027. {
  5028. PSPC_SP_AGENCY_INFO pInfo;
  5029. if (NULL == (pInfo = (PSPC_SP_AGENCY_INFO) TestNoCopyDecodeObject(
  5030. SPC_SP_AGENCY_INFO_OBJID,
  5031. pbEncoded,
  5032. cbEncoded
  5033. ))) goto ErrorReturn;
  5034. //" <SpcSpAgencyInfo> \n");
  5035. IDSwprintf(hModule, IDS_SPC_AGENCY);
  5036. if (pInfo->pPolicyInformation)
  5037. {
  5038. //" PolicyInformation: "
  5039. IDSwprintf(hModule, IDS_POL_INFO);
  5040. DisplaySpcLink(pInfo->pPolicyInformation);
  5041. }
  5042. if (pInfo->pwszPolicyDisplayText)
  5043. {
  5044. //" PolicyDisplayText: %s\n",
  5045. IDSwprintf(hModule, IDS_POL_DIS, pInfo->pwszPolicyDisplayText);
  5046. }
  5047. if (pInfo->pLogoImage)
  5048. {
  5049. PSPC_IMAGE pImage = pInfo->pLogoImage;
  5050. if (pImage->pImageLink)
  5051. {
  5052. //" ImageLink: ");
  5053. IDSwprintf(hModule, IDS_IMG_LINK);
  5054. DisplaySpcLink(pImage->pImageLink);
  5055. }
  5056. if (pImage->Bitmap.cbData)
  5057. {
  5058. //" Bitmap:\n");
  5059. IDSwprintf(hModule, IDS_BITMAP);
  5060. PrintBytes(L" ", pImage->Bitmap.pbData, pImage->Bitmap.cbData);
  5061. }
  5062. if (pImage->Metafile.cbData)
  5063. {
  5064. //" Metafile:\n");
  5065. IDSwprintf(hModule, IDS_META_FILE);
  5066. PrintBytes(L" ", pImage->Metafile.pbData,
  5067. pImage->Metafile.cbData);
  5068. }
  5069. if (pImage->EnhancedMetafile.cbData)
  5070. {
  5071. //" EnhancedMetafile:\n");
  5072. IDSwprintf(hModule, IDS_ENH_META);
  5073. PrintBytes(L" ", pImage->EnhancedMetafile.pbData,
  5074. pImage->EnhancedMetafile.cbData);
  5075. }
  5076. if (pImage->GifFile.cbData)
  5077. {
  5078. //" GifFile:\n"
  5079. IDSwprintf(hModule, IDS_GIF_FILE);
  5080. PrintBytes(L" ", pImage->GifFile.pbData,
  5081. pImage->GifFile.cbData);
  5082. }
  5083. }
  5084. if (pInfo->pLogoLink)
  5085. {
  5086. //" LogoLink: ");
  5087. IDSwprintf(hModule, IDS_LOGO_LINK);
  5088. DisplaySpcLink(pInfo->pLogoLink);
  5089. }
  5090. goto CommonReturn;
  5091. ErrorReturn:
  5092. CommonReturn:
  5093. if (pInfo)
  5094. ToolUtlFree(pInfo);
  5095. }
  5096. //+-------------------------------------------------------------------------
  5097. // DisplayPoliciesExtension
  5098. //--------------------------------------------------------------------------
  5099. void DisplayPoliciesExtension(
  5100. int idsIDS,
  5101. BYTE *pbEncoded,
  5102. DWORD cbEncoded,
  5103. DWORD dwDisplayFlags)
  5104. {
  5105. PCERT_POLICIES_INFO pInfo;
  5106. DWORD cPolicy;
  5107. PCERT_POLICY_INFO pPolicy;
  5108. DWORD i;
  5109. if (NULL == (pInfo =
  5110. (PCERT_POLICIES_INFO) TestNoCopyDecodeObject(
  5111. X509_CERT_POLICIES,
  5112. pbEncoded,
  5113. cbEncoded
  5114. ))) goto ErrorReturn;
  5115. cPolicy = pInfo->cPolicyInfo;
  5116. pPolicy = pInfo->rgPolicyInfo;
  5117. //Display the name of the extension
  5118. IDSwprintf(hModule, idsIDS);
  5119. if (cPolicy == 0)
  5120. IDSwprintf(hModule, IDS_NONE);
  5121. for (i = 0; i < cPolicy; i++, pPolicy++)
  5122. {
  5123. DWORD cQualifier = pPolicy->cPolicyQualifier;
  5124. PCERT_POLICY_QUALIFIER_INFO pQualifier;
  5125. DWORD j;
  5126. printf(" [%d] %s", i, pPolicy->pszPolicyIdentifier);
  5127. if (cQualifier)
  5128. //" Qualifiers:: \n"
  5129. IDSwprintf(hModule, IDS_QUALI);
  5130. pQualifier = pPolicy->rgPolicyQualifier;
  5131. for (j = 0; j < cQualifier; j++, pQualifier++)
  5132. {
  5133. printf(" [%d] %s", j, pQualifier->pszPolicyQualifierId);
  5134. if (pQualifier->Qualifier.cbData)
  5135. {
  5136. //" Encoded Data::\n"
  5137. IDSwprintf(hModule, IDS_ENCODED_DATA);
  5138. PrintBytes(L" ",
  5139. pQualifier->Qualifier.pbData, pQualifier->Qualifier.cbData);
  5140. } else
  5141. printf("\n");
  5142. }
  5143. }
  5144. ErrorReturn:
  5145. if (pInfo)
  5146. ToolUtlFree(pInfo);
  5147. }
  5148. //+-------------------------------------------------------------------------
  5149. // DisplayKeyUsageExtension
  5150. //--------------------------------------------------------------------------
  5151. void DisplayKeyUsageExtension(
  5152. BYTE *pbEncoded,
  5153. DWORD cbEncoded,
  5154. DWORD dwDisplayFlags)
  5155. {
  5156. PCRYPT_BIT_BLOB pInfo;
  5157. BYTE bFlags;
  5158. if (NULL == (pInfo =
  5159. (PCRYPT_BIT_BLOB) TestNoCopyDecodeObject(
  5160. X509_KEY_USAGE,
  5161. pbEncoded,
  5162. cbEncoded
  5163. ))) goto ErrorReturn;
  5164. //" <KeyUsage> \n"
  5165. IDSwprintf(hModule, IDS_KEY_USAGE);
  5166. if (pInfo->cbData)
  5167. bFlags = *pInfo->pbData;
  5168. else
  5169. bFlags = 0;
  5170. DisplayKeyUsage(bFlags);
  5171. ErrorReturn:
  5172. if (pInfo)
  5173. ToolUtlFree(pInfo);
  5174. }
  5175. //+-------------------------------------------------------------------------
  5176. // DisplayBasicConstraints2Extension
  5177. //--------------------------------------------------------------------------
  5178. void DisplayBasicConstraints2Extension(
  5179. BYTE *pbEncoded,
  5180. DWORD cbEncoded,
  5181. DWORD dwDisplayFlags)
  5182. {
  5183. PCERT_BASIC_CONSTRAINTS2_INFO pInfo;
  5184. if (NULL == (pInfo = (PCERT_BASIC_CONSTRAINTS2_INFO) TestNoCopyDecodeObject(
  5185. X509_BASIC_CONSTRAINTS2,
  5186. pbEncoded,
  5187. cbEncoded
  5188. ))) goto ErrorReturn;
  5189. //" <Basic Constraints2> \n"
  5190. IDSwprintf(hModule, IDS_BASIC_CON2);
  5191. if (pInfo->fCA)
  5192. IDSwprintf(hModule, IDS_SUB_CA);
  5193. else
  5194. IDSwprintf(hModule, IDS_SUB_EE);
  5195. printf("\n");
  5196. //" PathLenConstraint:: "
  5197. IDSwprintf(hModule, IDS_PATH_LEN);
  5198. if (pInfo->fPathLenConstraint)
  5199. printf("%d", pInfo->dwPathLenConstraint);
  5200. else
  5201. IDSwprintf(hModule, IDS_NONE);
  5202. printf("\n");
  5203. ErrorReturn:
  5204. if (pInfo)
  5205. ToolUtlFree(pInfo);
  5206. }
  5207. //+-------------------------------------------------------------------------
  5208. // DisplayBasicConstraintsExtension
  5209. //--------------------------------------------------------------------------
  5210. void DisplayBasicConstraintsExtension(
  5211. BYTE *pbEncoded,
  5212. DWORD cbEncoded,
  5213. DWORD dwDisplayFlags)
  5214. {
  5215. PCERT_BASIC_CONSTRAINTS_INFO pInfo;
  5216. if (NULL == (pInfo = (PCERT_BASIC_CONSTRAINTS_INFO) TestNoCopyDecodeObject(
  5217. X509_BASIC_CONSTRAINTS,
  5218. pbEncoded,
  5219. cbEncoded
  5220. ))) goto ErrorReturn;
  5221. //" <Basic Constraints> \n"
  5222. IDSwprintf(hModule, IDS_BASIC_CON);
  5223. //" SubjectType:: ";
  5224. IDSwprintf(hModule, IDS_SUB_TYPE);
  5225. if (pInfo->SubjectType.cbData == 0)
  5226. IDSwprintf(hModule, IDS_NONE);
  5227. else
  5228. {
  5229. BYTE bSubjectType = *pInfo->SubjectType.pbData;
  5230. if (bSubjectType == 0)
  5231. IDSwprintf(hModule, IDS_NONE);
  5232. if (bSubjectType & CERT_CA_SUBJECT_FLAG)
  5233. //" CA ");
  5234. IDSwprintf(hModule, IDS_SUB_CA);
  5235. if (bSubjectType & CERT_END_ENTITY_SUBJECT_FLAG)
  5236. //" END_ENTITY ")
  5237. IDSwprintf(hModule, IDS_SUB_EE);
  5238. }
  5239. printf("\n");
  5240. //" PathLenConstraint:: "
  5241. IDSwprintf(hModule, IDS_PATH_LEN);
  5242. if (pInfo->fPathLenConstraint)
  5243. printf("%d", pInfo->dwPathLenConstraint);
  5244. else
  5245. IDSwprintf(hModule, IDS_NONE_NOELN);
  5246. printf("\n");
  5247. if (pInfo->cSubtreesConstraint)
  5248. {
  5249. DWORD i;
  5250. PCERT_NAME_BLOB pSubtrees = pInfo->rgSubtreesConstraint;
  5251. for (i = 0; i < pInfo->cSubtreesConstraint; i++, pSubtrees++)
  5252. {
  5253. //" SubtreesConstraint[%d]::\n"
  5254. IDSwprintf(hModule, IDS_SUB_CON, i);
  5255. DecodeName(pSubtrees->pbData, pSubtrees->cbData, dwDisplayFlags);
  5256. }
  5257. }
  5258. goto CommonReturn;
  5259. ErrorReturn:
  5260. CommonReturn:
  5261. if (pInfo)
  5262. ToolUtlFree(pInfo);
  5263. }
  5264. //+-------------------------------------------------------------------------
  5265. // DisplayKeyUsageRestrictionExtension
  5266. //--------------------------------------------------------------------------
  5267. void DisplayKeyUsage(BYTE bFlags)
  5268. {
  5269. if (bFlags == 0)
  5270. IDSwprintf(hModule, IDS_NONE);
  5271. if (bFlags & CERT_DIGITAL_SIGNATURE_KEY_USAGE)
  5272. //"DIGITAL_SIGNATURE "
  5273. IDSwprintf(hModule, IDS_DIG_SIG);
  5274. if (bFlags & CERT_NON_REPUDIATION_KEY_USAGE)
  5275. //"NON_REPUDIATION "
  5276. IDSwprintf(hModule, IDS_NON_REP);
  5277. if (bFlags & CERT_KEY_ENCIPHERMENT_KEY_USAGE)
  5278. //"KEY_ENCIPHERMENT "
  5279. IDSwprintf(hModule, IDS_KEY_ENCI);
  5280. if (bFlags & CERT_DATA_ENCIPHERMENT_KEY_USAGE)
  5281. //"DATA_ENCIPHERMENT ");
  5282. IDSwprintf(hModule, IDS_DATA_ENCI);
  5283. if (bFlags & CERT_KEY_AGREEMENT_KEY_USAGE)
  5284. //"KEY_AGREEMENT ");
  5285. IDSwprintf(hModule, IDS_KEY_AGRE);
  5286. if (bFlags & CERT_KEY_CERT_SIGN_KEY_USAGE)
  5287. //"KEY_CERT_SIGN "
  5288. IDSwprintf(hModule, IDS_CERT_SIGN);
  5289. if (bFlags & CERT_OFFLINE_CRL_SIGN_KEY_USAGE)
  5290. //"OFFLINE_CRL_SIGN "
  5291. IDSwprintf(hModule, IDS_OFFLINE_CRL);
  5292. printf("\n");
  5293. }
  5294. //+-------------------------------------------------------------------------
  5295. // DisplayKeyUsageRestrictionExtension
  5296. //--------------------------------------------------------------------------
  5297. void DisplayKeyUsageRestrictionExtension(
  5298. BYTE *pbEncoded,
  5299. DWORD cbEncoded,
  5300. DWORD dwDisplayFlags)
  5301. {
  5302. PCERT_KEY_USAGE_RESTRICTION_INFO pInfo;
  5303. if (NULL == (pInfo =
  5304. (PCERT_KEY_USAGE_RESTRICTION_INFO) TestNoCopyDecodeObject(
  5305. X509_KEY_USAGE_RESTRICTION,
  5306. pbEncoded,
  5307. cbEncoded
  5308. ))) goto ErrorReturn;
  5309. //Display the name of the certificate
  5310. //" <KeyUsageRestriction> \n "
  5311. IDSwprintf(hModule, IDS_KEY_RESTRIC);
  5312. if (pInfo->cCertPolicyId)
  5313. {
  5314. DWORD i, j;
  5315. //" CertPolicySet::\n"
  5316. IDSwprintf(hModule, IDS_CERT_POLICY);
  5317. PCERT_POLICY_ID pPolicyId = pInfo->rgCertPolicyId;
  5318. for (i = 0; i < pInfo->cCertPolicyId; i++, pPolicyId++)
  5319. {
  5320. if (pPolicyId->cCertPolicyElementId == 0)
  5321. printf(" [%d,*] %s\n", i, g_szNULL);
  5322. LPSTR *ppszObjId = pPolicyId->rgpszCertPolicyElementId;
  5323. for (j = 0; j < pPolicyId->cCertPolicyElementId; j++, ppszObjId++)
  5324. {
  5325. LPSTR pszObjId = *ppszObjId;
  5326. if (pszObjId == NULL)
  5327. pszObjId = g_szNULL;
  5328. printf(" [%d,%d] %s\n", i, j, pszObjId);
  5329. }
  5330. }
  5331. }
  5332. if (pInfo->RestrictedKeyUsage.cbData)
  5333. {
  5334. BYTE bFlags = *pInfo->RestrictedKeyUsage.pbData;
  5335. //" RestrictedKeyUsage:: "
  5336. IDSwprintf(hModule, IDS_RESTRIC_KEY);
  5337. DisplayKeyUsage(bFlags);
  5338. }
  5339. goto CommonReturn;
  5340. ErrorReturn:
  5341. CommonReturn:
  5342. if (pInfo)
  5343. ToolUtlFree(pInfo);
  5344. }
  5345. //+-------------------------------------------------------------------------
  5346. // DisplayCRLReason
  5347. //--------------------------------------------------------------------------
  5348. void DisplayCRLReason(
  5349. BYTE *pbEncoded,
  5350. DWORD cbEncoded,
  5351. DWORD dwDisplayFlags)
  5352. {
  5353. DWORD cbInfo;
  5354. int CRLReason;
  5355. cbInfo = sizeof(CRLReason);
  5356. if (!CryptDecodeObject(
  5357. g_dwCertEncodingType,
  5358. szOID_CRL_REASON_CODE,
  5359. pbEncoded,
  5360. cbEncoded,
  5361. 0, // dwFlags
  5362. &CRLReason,
  5363. &cbInfo
  5364. ))
  5365. {
  5366. return;
  5367. }
  5368. //" <CRL Reason> \n");
  5369. IDSwprintf(hModule, IDS_CRL_REASON);
  5370. switch (CRLReason)
  5371. {
  5372. case CRL_REASON_UNSPECIFIED:
  5373. //"REASON_UNSPECIFIED"
  5374. IDSwprintf(hModule, IDS_CRL_UNSPECIFIED);
  5375. break;
  5376. case CRL_REASON_KEY_COMPROMISE:
  5377. //"KEY_COMPROMISE"
  5378. IDSwprintf(hModule, IDS_KEY_COMP);
  5379. break;
  5380. case CRL_REASON_CA_COMPROMISE:
  5381. //"CA_COMPROMISE"
  5382. IDSwprintf(hModule, IDS_CA_COMP);
  5383. break;
  5384. case CRL_REASON_AFFILIATION_CHANGED:
  5385. //"AFFILIATION_CHANGED"
  5386. IDSwprintf(hModule, IDS_AFFI_CHANGED);
  5387. break;
  5388. case CRL_REASON_SUPERSEDED:
  5389. //"SUPERSEDED"
  5390. IDSwprintf(hModule, IDS_SUPERSEDED);
  5391. break;
  5392. case CRL_REASON_CESSATION_OF_OPERATION:
  5393. //"CESSATION_OF_OPERATION"
  5394. IDSwprintf(hModule, IDS_CESS_OPER);
  5395. break;
  5396. case CRL_REASON_CERTIFICATE_HOLD:
  5397. //"CERTIFICATE_HOLD"
  5398. IDSwprintf(hModule, IDS_CERT_HOLD);
  5399. break;
  5400. case CRL_REASON_REMOVE_FROM_CRL:
  5401. //REMOVE_FROM_CRL);
  5402. IDSwprintf(hModule, IDS_REMOVE_CRL);
  5403. break;
  5404. default:
  5405. printf("%d", CRLReason);
  5406. break;
  5407. }
  5408. printf("\n");
  5409. }
  5410. //+-------------------------------------------------------------------------
  5411. // DisplayAltNameExtension
  5412. //--------------------------------------------------------------------------
  5413. void DisplayAltNameExtension(
  5414. int idsIDS,
  5415. BYTE *pbEncoded,
  5416. DWORD cbEncoded,
  5417. DWORD dwDisplayFlags)
  5418. {
  5419. IDSwprintf(hModule, idsIDS);
  5420. DecodeAndDisplayAltName(pbEncoded, cbEncoded, dwDisplayFlags);
  5421. }
  5422. //+-------------------------------------------------------------------------
  5423. // DisplayKeyAttrExtension
  5424. //--------------------------------------------------------------------------
  5425. void DisplayKeyAttrExtension(
  5426. BYTE *pbEncoded,
  5427. DWORD cbEncoded,
  5428. DWORD dwDisplayFlags)
  5429. {
  5430. PCERT_KEY_ATTRIBUTES_INFO pInfo;
  5431. if (NULL == (pInfo = (PCERT_KEY_ATTRIBUTES_INFO) TestNoCopyDecodeObject(
  5432. X509_KEY_ATTRIBUTES,
  5433. pbEncoded,
  5434. cbEncoded
  5435. ))) goto CommonReturn;
  5436. //" <KeyAttributes>\n"
  5437. IDSwprintf(hModule ,IDS_KEY_ATTR);
  5438. if (pInfo->KeyId.cbData)
  5439. {
  5440. //" KeyId::\n"
  5441. IDSwprintf(hModule, IDS_KEY_ID);
  5442. PrintBytes(L" ", pInfo->KeyId.pbData, pInfo->KeyId.cbData);
  5443. }
  5444. if (pInfo->IntendedKeyUsage.cbData)
  5445. {
  5446. BYTE bFlags = *pInfo->IntendedKeyUsage.pbData;
  5447. //" IntendedKeyUsage:: "
  5448. IDSwprintf(hModule, IDS_INTEND_KEY_USAGE);
  5449. if (bFlags == 0)
  5450. IDSwprintf(hModule, IDS_NONE);
  5451. if (bFlags & CERT_DIGITAL_SIGNATURE_KEY_USAGE)
  5452. //"DIGITAL_SIGNATURE "
  5453. IDSwprintf(hModule, IDS_DIG_SIG);
  5454. if (bFlags & CERT_NON_REPUDIATION_KEY_USAGE)
  5455. //"NON_REPUDIATION "
  5456. IDSwprintf(hModule, IDS_NON_REP);
  5457. if (bFlags & CERT_KEY_ENCIPHERMENT_KEY_USAGE)
  5458. //"KEY_ENCIPHERMENT "
  5459. IDSwprintf(hModule, IDS_KEY_ENCI);
  5460. if (bFlags & CERT_DATA_ENCIPHERMENT_KEY_USAGE)
  5461. //"DATA_ENCIPHERMENT ");
  5462. IDSwprintf(hModule, IDS_DATA_ENCI);
  5463. if (bFlags & CERT_KEY_AGREEMENT_KEY_USAGE)
  5464. //"KEY_AGREEMENT ");
  5465. IDSwprintf(hModule, IDS_KEY_AGRE);
  5466. if (bFlags & CERT_KEY_CERT_SIGN_KEY_USAGE)
  5467. //"KEY_CERT_SIGN "
  5468. IDSwprintf(hModule, IDS_CERT_SIGN);
  5469. if (bFlags & CERT_OFFLINE_CRL_SIGN_KEY_USAGE)
  5470. //"OFFLINE_CRL_SIGN "
  5471. IDSwprintf(hModule, IDS_OFFLINE_CRL);
  5472. printf("\n");
  5473. }
  5474. if (pInfo->pPrivateKeyUsagePeriod)
  5475. {
  5476. PCERT_PRIVATE_KEY_VALIDITY p = pInfo->pPrivateKeyUsagePeriod;
  5477. //"NotBefore:: %s\n"
  5478. IDSwprintf(hModule, IDS_NOT_BEFORE, FileTimeText(&p->NotBefore));
  5479. IDSwprintf(hModule, IDS_NOT_AFTER, FileTimeText(&p->NotAfter));
  5480. }
  5481. CommonReturn:
  5482. if (pInfo)
  5483. ToolUtlFree(pInfo);
  5484. }
  5485. //+-------------------------------------------------------------------------
  5486. // DisplayCrlDistPointsExtension
  5487. //--------------------------------------------------------------------------
  5488. void DisplayCrlDistPointsExtension(
  5489. BYTE *pbEncoded,
  5490. DWORD cbEncoded,
  5491. DWORD dwDisplayFlags)
  5492. {
  5493. PCRL_DIST_POINTS_INFO pInfo = NULL;
  5494. DWORD i;
  5495. if (NULL == (pInfo = (PCRL_DIST_POINTS_INFO) TestNoCopyDecodeObject(
  5496. X509_CRL_DIST_POINTS,
  5497. pbEncoded,
  5498. cbEncoded
  5499. ))) goto CommonReturn;
  5500. if (0 == pInfo->cDistPoint)
  5501. //" NO CRL Distribution Points\n"
  5502. IDSwprintf(hModule, IDS_NO_CRL_DIS);
  5503. else
  5504. {
  5505. DWORD cPoint = pInfo->cDistPoint;
  5506. PCRL_DIST_POINT pPoint = pInfo->rgDistPoint;
  5507. for (i = 0; i < cPoint; i++, pPoint++)
  5508. {
  5509. //" CRL Distribution Point[%d]\n"
  5510. IDSwprintf(hModule,IDS_CRL_IDS_I, i);
  5511. DWORD dwNameChoice = pPoint->DistPointName.dwDistPointNameChoice;
  5512. switch (dwNameChoice)
  5513. {
  5514. case CRL_DIST_POINT_NO_NAME:
  5515. break;
  5516. case CRL_DIST_POINT_FULL_NAME:
  5517. //" FullName:\n"
  5518. IDSwprintf(hModule, IDS_CRL_DIS_FULL_NAME);
  5519. DisplayAltName(&pPoint->DistPointName.FullName,
  5520. dwDisplayFlags);
  5521. break;
  5522. case CRL_DIST_POINT_ISSUER_RDN_NAME:
  5523. //printf(" IssuerRDN: (Not Implemented)\n");
  5524. IDSwprintf(hModule, IDS_CRL_RDN);
  5525. break;
  5526. default:
  5527. //" Unknown name choice: %d\n", dwNameChoice);
  5528. IDSwprintf(hModule, IDS_CRL_UNKNOWN, dwNameChoice);
  5529. break;
  5530. }
  5531. if (pPoint->ReasonFlags.cbData)
  5532. {
  5533. BYTE bFlags;
  5534. //" ReasonFlags: "
  5535. IDSwprintf(hModule, IDS_REASON_FLAG);
  5536. bFlags = *pPoint->ReasonFlags.pbData;
  5537. if (bFlags == 0)
  5538. //"<NONE> \n"
  5539. IDSwprintf(hModule, IDS_NONE);
  5540. if (bFlags & CRL_REASON_UNUSED_FLAG)
  5541. //"UNUSED "
  5542. IDSwprintf(hModule, IDS_REASON_UNUSED);
  5543. if (bFlags & CRL_REASON_KEY_COMPROMISE_FLAG)
  5544. //"KEY_COMPROMISE "
  5545. IDSwprintf(hModule, IDS_KEY_COMP);
  5546. if (bFlags & CRL_REASON_CA_COMPROMISE_FLAG)
  5547. //"CA_COMPROMISE "
  5548. IDSwprintf(hModule, IDS_CA_COMP);
  5549. if (bFlags & CRL_REASON_AFFILIATION_CHANGED_FLAG)
  5550. //"AFFILIATION_CHANGED "
  5551. IDSwprintf(hModule, IDS_AFFI_CHANGED);
  5552. if (bFlags & CRL_REASON_SUPERSEDED_FLAG)
  5553. //"SUPERSEDED "
  5554. IDSwprintf(hModule, IDS_SUPERSEDED);
  5555. if (bFlags & CRL_REASON_CESSATION_OF_OPERATION_FLAG)
  5556. //"CESSATION_OF_OPERATION "
  5557. IDSwprintf(hModule, IDS_CESS_OPER);
  5558. if (bFlags & CRL_REASON_CERTIFICATE_HOLD_FLAG)
  5559. //"CERTIFICATE_HOLD "
  5560. IDSwprintf(hModule, IDS_CERT_HOLD);
  5561. printf("\n");
  5562. }
  5563. if (pPoint->CRLIssuer.cAltEntry)
  5564. {
  5565. //" ISSUER::\n"
  5566. IDSwprintf(hModule, IDS_CRL_ISSUER);
  5567. DisplayAltName(&pPoint->CRLIssuer, dwDisplayFlags);
  5568. }
  5569. }
  5570. }
  5571. CommonReturn:
  5572. if (pInfo)
  5573. ToolUtlFree(pInfo);
  5574. }
  5575. //+-------------------------------------------------------------------------
  5576. // DisplayAuthorityKeyIdExtension
  5577. //--------------------------------------------------------------------------
  5578. void DisplayAuthorityKeyIdExtension(
  5579. BYTE *pbEncoded,
  5580. DWORD cbEncoded,
  5581. DWORD dwDisplayFlags)
  5582. {
  5583. PCERT_AUTHORITY_KEY_ID_INFO pInfo;
  5584. //" <AuthorityKeyId>\n"
  5585. IDSwprintf(hModule, IDS_AUTH_KEY_ID);
  5586. if (NULL == (pInfo = (PCERT_AUTHORITY_KEY_ID_INFO) TestNoCopyDecodeObject(
  5587. X509_AUTHORITY_KEY_ID,
  5588. pbEncoded,
  5589. cbEncoded
  5590. ))) goto CommonReturn;
  5591. if (pInfo->KeyId.cbData)
  5592. {
  5593. //" KeyId::\n"
  5594. IDSwprintf(hModule, IDS_KEY_ID);
  5595. PrintBytes(L" ", pInfo->KeyId.pbData, pInfo->KeyId.cbData);
  5596. }
  5597. if (pInfo->CertIssuer.cbData)
  5598. {
  5599. //" AuthorityCertIssuer::\n"
  5600. IDSwprintf(hModule, IDS_AUTH_CERT_ISSUER);
  5601. DecodeName(pInfo->CertIssuer.pbData, pInfo->CertIssuer.cbData,
  5602. dwDisplayFlags);
  5603. }
  5604. if (pInfo->CertSerialNumber.cbData)
  5605. {
  5606. //" CertSerialNumber::"
  5607. IDSwprintf(hModule, IDS_AUTH_CERT_ISSUER_SERIAL_NUMBER);
  5608. DisplaySerialNumber(&pInfo->CertSerialNumber);
  5609. printf("\n");
  5610. }
  5611. CommonReturn:
  5612. if (pInfo)
  5613. ToolUtlFree(pInfo);
  5614. }
  5615. //+-------------------------------------------------------------------------
  5616. // Get the name of an OID
  5617. //--------------------------------------------------------------------------
  5618. void DisplayAuthorityKeyId2Extension(
  5619. BYTE *pbEncoded,
  5620. DWORD cbEncoded,
  5621. DWORD dwDisplayFlags)
  5622. {
  5623. PCERT_AUTHORITY_KEY_ID2_INFO pInfo;
  5624. //" <AuthorityKeyId #2>\n"
  5625. IDSwprintf(hModule, IDS_AUTH_KEY_ID2);
  5626. if (NULL == (pInfo = (PCERT_AUTHORITY_KEY_ID2_INFO) TestNoCopyDecodeObject(
  5627. X509_AUTHORITY_KEY_ID2,
  5628. pbEncoded,
  5629. cbEncoded
  5630. ))) goto CommonReturn;
  5631. if (pInfo->KeyId.cbData)
  5632. {
  5633. //" KeyId::\n"
  5634. IDSwprintf(hModule, IDS_KEY_ID);
  5635. PrintBytes(L" ", pInfo->KeyId.pbData, pInfo->KeyId.cbData);
  5636. }
  5637. if (pInfo->AuthorityCertIssuer.cAltEntry)
  5638. {
  5639. //" AuthorityCertIssuer::\n"
  5640. IDSwprintf(hModule, IDS_AUTH_CERT_ISSUER);
  5641. DisplayAltName(&pInfo->AuthorityCertIssuer, dwDisplayFlags);
  5642. }
  5643. if (pInfo->AuthorityCertSerialNumber.cbData)
  5644. {
  5645. //" AuthorityCertSerialNumber::"
  5646. IDSwprintf(hModule, IDS_AUTH_CERT_ISSUER_SERIAL_NUMBER);
  5647. DisplaySerialNumber(&pInfo->AuthorityCertSerialNumber);
  5648. printf("\n");
  5649. }
  5650. CommonReturn:
  5651. if (pInfo)
  5652. ToolUtlFree(pInfo);
  5653. }
  5654. //+-------------------------------------------------------------------------
  5655. // DisplayAnyString
  5656. //--------------------------------------------------------------------------
  5657. void DisplayAnyString(
  5658. int idsIDS,
  5659. BYTE *pbEncoded,
  5660. DWORD cbEncoded,
  5661. DWORD dwDisplayFlags
  5662. )
  5663. {
  5664. PCERT_NAME_VALUE pInfo = NULL;
  5665. if (NULL == (pInfo = (PCERT_NAME_VALUE) TestNoCopyDecodeObject(
  5666. X509_UNICODE_ANY_STRING,
  5667. pbEncoded,
  5668. cbEncoded
  5669. ))) goto CommonReturn;
  5670. //print the pre-fix
  5671. IDSwprintf(hModule, idsIDS);
  5672. if (pInfo->dwValueType == CERT_RDN_ENCODED_BLOB ||
  5673. pInfo->dwValueType == CERT_RDN_OCTET_STRING)
  5674. {
  5675. //"ValueType: %d\n"
  5676. IDSwprintf(hModule, IDS_VALUE_TYPE, pInfo->dwValueType);
  5677. PrintBytes(L" ", pInfo->Value.pbData, pInfo->Value.cbData);
  5678. } else
  5679. //"ValueType: %d String: %s\n"
  5680. IDSwprintf(hModule, IDS_VALUE_STRING_S,
  5681. pInfo->dwValueType, pInfo->Value.pbData);
  5682. CommonReturn:
  5683. if (pInfo)
  5684. ToolUtlFree(pInfo);
  5685. }
  5686. //+-------------------------------------------------------------------------
  5687. // DisplayBits
  5688. //--------------------------------------------------------------------------
  5689. void DisplayBits(
  5690. int idsIDS,
  5691. BYTE *pbEncoded,
  5692. DWORD cbEncoded,
  5693. DWORD dwDisplayFlags)
  5694. {
  5695. PCRYPT_BIT_BLOB pInfo = NULL;
  5696. if (NULL == (pInfo = (PCRYPT_BIT_BLOB) TestNoCopyDecodeObject(
  5697. X509_BITS,
  5698. pbEncoded,
  5699. cbEncoded
  5700. ))) goto CommonReturn;
  5701. IDSwprintf(hModule, idsIDS);
  5702. if (1 == pInfo->cbData)
  5703. {
  5704. printf(" %02X", *pInfo->pbData);
  5705. if (pInfo->cUnusedBits)
  5706. {
  5707. //" (UnusedBits: %d)"
  5708. IDSwprintf(hModule, IDS_UNUSED_BITS, pInfo->cUnusedBits);
  5709. }
  5710. printf("\n");
  5711. }
  5712. else
  5713. {
  5714. if (pInfo->cbData)
  5715. {
  5716. printf("\n");
  5717. PrintBytes(L" ", pInfo->pbData, pInfo->cbData);
  5718. IDSwprintf(hModule, IDS_UNUSED_BITS, pInfo->cUnusedBits);
  5719. printf("\n");
  5720. }
  5721. else
  5722. IDSwprintf(hModule, IDS_NONE);
  5723. }
  5724. CommonReturn:
  5725. if (pInfo)
  5726. ToolUtlFree(pInfo);
  5727. }
  5728. //+-------------------------------------------------------------------------
  5729. // DisplayOctetString
  5730. //--------------------------------------------------------------------------
  5731. void DisplayOctetString(
  5732. int idsIDS,
  5733. BYTE *pbEncoded,
  5734. DWORD cbEncoded,
  5735. DWORD dwDisplayFlags)
  5736. {
  5737. PCRYPT_DATA_BLOB pInfo = NULL;
  5738. if (NULL == (pInfo = (PCRYPT_DATA_BLOB) TestNoCopyDecodeObject(
  5739. X509_OCTET_STRING,
  5740. pbEncoded,
  5741. cbEncoded
  5742. ))) goto CommonReturn;
  5743. IDSwprintf(hModule, idsIDS);
  5744. PrintBytes(L" ", pInfo->pbData, pInfo->cbData);
  5745. CommonReturn:
  5746. if (pInfo)
  5747. ToolUtlFree(pInfo);
  5748. }
  5749. //+-------------------------------------------------------------------------
  5750. // Get the name of an OID
  5751. //--------------------------------------------------------------------------
  5752. LPCWSTR GetOIDName(LPCSTR pszOID, DWORD dwGroupId)
  5753. {
  5754. PCCRYPT_OID_INFO pInfo;
  5755. if (pInfo = CryptFindOIDInfo
  5756. (
  5757. CRYPT_OID_INFO_OID_KEY,
  5758. (void *) pszOID,
  5759. dwGroupId
  5760. ))
  5761. {
  5762. if (L'\0' != pInfo->pwszName[0])
  5763. return pInfo->pwszName;
  5764. }
  5765. return g_wszUnKnown;
  5766. }
  5767. //--------------------------------------------------------------------------
  5768. //
  5769. // FormatBasicConstraints2
  5770. //--------------------------------------------------------------------------
  5771. BOOL
  5772. WINAPI
  5773. FormatBasicConstraints2(
  5774. DWORD dwCertEncodingType,
  5775. DWORD dwFormatType,
  5776. DWORD dwFormatStrType,
  5777. void *pFormatStruct,
  5778. LPCSTR lpszStructType,
  5779. const BYTE *pbEncoded,
  5780. DWORD cbEncoded,
  5781. void *pbFormat,
  5782. DWORD *pcbFormat)
  5783. {
  5784. WCHAR wszFormat[100]=L"\0";
  5785. WCHAR wszLength[15];
  5786. PCERT_BASIC_CONSTRAINTS2_INFO pInfo=NULL;
  5787. DWORD cbNeeded=0;
  5788. //check for input parameters
  5789. if(( pbEncoded!=NULL && cbEncoded==0)
  5790. ||(pbEncoded==NULL && cbEncoded!=0)
  5791. || (pcbFormat==NULL))
  5792. {
  5793. SetLastError(E_INVALIDARG);
  5794. return FALSE;
  5795. }
  5796. //check for simple case. No work needed
  5797. if(pbEncoded==NULL && cbEncoded==0)
  5798. {
  5799. *pcbFormat=0;
  5800. return TRUE;
  5801. }
  5802. if (NULL == (pInfo = (PCERT_BASIC_CONSTRAINTS2_INFO) TestNoCopyDecodeObject(
  5803. X509_BASIC_CONSTRAINTS2,
  5804. pbEncoded,
  5805. cbEncoded
  5806. )))
  5807. return FALSE;
  5808. //" <Basic Constraints2> \n"
  5809. IDSwcscat(hModule, wszFormat, IDS_BASIC_CON2);
  5810. if (pInfo->fCA)
  5811. //" CA ");
  5812. IDSwcscat(hModule,wszFormat,IDS_SUB_CA);
  5813. else
  5814. //" End-Entity"
  5815. IDSwcscat(hModule,wszFormat, IDS_SUB_EE);
  5816. //"\n"
  5817. IDSwcscat(hModule, wszFormat, IDS_ELN);
  5818. //" PathLenConstraint:: "
  5819. IDSwcscat(hModule, wszFormat, IDS_PATH_LEN);
  5820. if (pInfo->fPathLenConstraint)
  5821. {
  5822. swprintf(wszLength, L"%d",pInfo->dwPathLenConstraint);
  5823. wcscat(wszFormat, wszLength);
  5824. }
  5825. else
  5826. IDSwcscat(hModule, wszFormat, IDS_NONE_NOELN);
  5827. if (pInfo)
  5828. ToolUtlFree(pInfo);
  5829. cbNeeded=sizeof(WCHAR)*(wcslen(wszFormat)+1);
  5830. //length only calculation
  5831. if(NULL==pbFormat)
  5832. {
  5833. *pcbFormat=cbNeeded;
  5834. return TRUE;
  5835. }
  5836. if((*pcbFormat)<cbNeeded)
  5837. {
  5838. SetLastError(ERROR_MORE_DATA);
  5839. return FALSE;
  5840. }
  5841. //copy the data
  5842. memcpy(pbFormat, wszFormat, cbNeeded);
  5843. //copy the size
  5844. *pcbFormat=cbNeeded;
  5845. return TRUE;
  5846. }
  5847. //+-------------------------------------------------------------------------
  5848. // Get the name of an OID
  5849. //--------------------------------------------------------------------------
  5850. BOOL InstalledFormat(LPSTR szStructType, BYTE *pbEncoded, DWORD cbEncoded)
  5851. {
  5852. BOOL fResult=FALSE;
  5853. void *pvFuncAddr=NULL;
  5854. HCRYPTOIDFUNCADDR hFuncAddr=NULL;
  5855. DWORD cbFormat=0;
  5856. LPWSTR wszFormat=NULL;
  5857. DWORD dwFormatStrType=0;
  5858. if(TRUE==g_fMulti)
  5859. dwFormatStrType |=CRYPT_FORMAT_STR_MULTI_LINE;
  5860. if(NULL==pbEncoded || 0==cbEncoded)
  5861. return FALSE;
  5862. //load the formatting functions
  5863. if (!CryptGetOIDFunctionAddress(
  5864. hFormatFuncSet,
  5865. g_dwCertEncodingType,
  5866. szStructType,
  5867. 0, // dwFlags
  5868. &pvFuncAddr,
  5869. &hFuncAddr))
  5870. goto CLEANUP;
  5871. //call the functions
  5872. if(!((PFN_FORMAT_FUNC) pvFuncAddr)(
  5873. g_dwCertEncodingType,
  5874. 0,
  5875. dwFormatStrType,
  5876. NULL,
  5877. szStructType,
  5878. pbEncoded,
  5879. cbEncoded,
  5880. NULL,
  5881. &cbFormat
  5882. ))
  5883. goto CLEANUP;
  5884. //allocate
  5885. wszFormat=(LPWSTR)ToolUtlAlloc(cbFormat * sizeof(WCHAR));
  5886. if(!wszFormat)
  5887. goto CLEANUP;
  5888. if(!((PFN_FORMAT_FUNC) pvFuncAddr)(
  5889. g_dwCertEncodingType,
  5890. 0,
  5891. dwFormatStrType,
  5892. NULL,
  5893. szStructType,
  5894. pbEncoded,
  5895. cbEncoded,
  5896. wszFormat,
  5897. &cbFormat
  5898. ))
  5899. goto CLEANUP;
  5900. //print
  5901. wprintf(L"%s\n", wszFormat);
  5902. fResult=TRUE;
  5903. CLEANUP:
  5904. if(wszFormat)
  5905. ToolUtlFree(wszFormat);
  5906. if(hFuncAddr)
  5907. CryptFreeOIDFunctionAddress(hFuncAddr, 0);
  5908. return fResult;
  5909. }
  5910. #pragma pack(1)
  5911. struct SplitGuid
  5912. {
  5913. DWORD dw1;
  5914. WORD w1;
  5915. WORD w2;
  5916. BYTE b[8];
  5917. };
  5918. #pragma pack()
  5919. WCHAR *GuidText(GUID *pguid)
  5920. {
  5921. static WCHAR buf[39];
  5922. SplitGuid *psg = (SplitGuid *)pguid;
  5923. swprintf(buf, L"{%08lX-%04hX-%04hX-%02X%02X-%02X%02X%02X%02X%02X%02X}",
  5924. psg->dw1, psg->w1, psg->w2, psg->b[0], psg->b[1], psg->b[2],
  5925. psg->b[3], psg->b[4], psg->b[5], psg->b[6], psg->b[7]);
  5926. return buf;
  5927. }