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.

772 lines
24 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows NT Security
  4. // Copyright (C) Microsoft Corporation, 1997 - 1998
  5. //
  6. // File: tcrobu.cpp
  7. //
  8. // Contents: CryptRetrieveObjectByUrl tests
  9. //
  10. // History: 27-May-97 kirtd Created
  11. //
  12. //----------------------------------------------------------------------------
  13. #include <windows.h>
  14. #include <assert.h>
  15. #include "wincrypt.h"
  16. #include "certtest.h"
  17. #include <stdlib.h>
  18. #include <stdio.h>
  19. #include <string.h>
  20. #include <memory.h>
  21. #include <time.h>
  22. #include <wininet.h>
  23. #include <md5.h>
  24. #include <cryptnet.h>
  25. typedef BYTE CRYPT_ORIGIN_IDENTIFIER[MD5DIGESTLEN];
  26. BYTE Foo[300];
  27. BYTE Bar[300];
  28. DWORD g_dwCount = 0;
  29. //+---------------------------------------------------------------------------
  30. //
  31. // Function: Usage
  32. //
  33. // Synopsis: prints the usage statement
  34. //
  35. //----------------------------------------------------------------------------
  36. static void Usage(void)
  37. {
  38. printf("Usage: tcrobu URL [ObjectOid] [-m] [-c] [-s] [-w] [-l]\n");
  39. printf(" URL, locator to retrieve from\n");
  40. printf(" ObjectOid, a cert, crl, or ctl, if omitted, retrieve bits\n");
  41. printf(" -m, retrieve multiple objects\n");
  42. printf(" -c, cache only retrieval\n");
  43. printf(" -d, do not cache the result\n");
  44. printf(" -w, wire only retrieval\n");
  45. printf(" -u, CryptGetObjectUrl on the result context\n");
  46. printf(" -l, logon user credentials <user> <password>\n");
  47. printf(" -t, timeout\n");
  48. printf(" -f, install cancel function\n");
  49. printf(" -n, install and uninstall cancel function\n");
  50. printf(" -r, the # of times the cancel function should be called\n");
  51. printf(" -v, verbose display\n");
  52. printf(" -q, quiet display\n");
  53. printf(" -s, save to serialized store file\n");
  54. printf(" -7, save to PKCS7 store file\n");
  55. printf(" -a, get AuxInfo\n");
  56. printf(" -p, sticky persist\n");
  57. printf(" -e, prepend LDAP entry and attribute\n");
  58. printf(" -k, Kerberos Signing for LDAP\n");
  59. printf(" -i, inhibit authentication\n");
  60. printf(" -Error, expected error\n");
  61. printf(" -Flags, retrieval flags to be OR'ed\n");
  62. printf(" -Size, maximum retrieval byte count\n");
  63. }
  64. //+---------------------------------------------------------------------------
  65. //
  66. // Function: CertGetOriginIdentifier
  67. //
  68. // Synopsis: get the origin identifier for a certificate
  69. //
  70. //----------------------------------------------------------------------------
  71. BOOL WINAPI CertGetOriginIdentifier (
  72. IN PCCERT_CONTEXT pCertContext,
  73. IN PCCERT_CONTEXT pIssuer,
  74. IN DWORD dwFlags,
  75. OUT CRYPT_ORIGIN_IDENTIFIER OriginIdentifier
  76. )
  77. {
  78. MD5_CTX md5ctx;
  79. PCERT_INFO pCertInfo = pCertContext->pCertInfo;
  80. PCERT_INFO pIssuerCertInfo = pIssuer->pCertInfo;
  81. MD5Init( &md5ctx );
  82. MD5Update( &md5ctx, pCertInfo->Issuer.pbData, pCertInfo->Issuer.cbData );
  83. MD5Update( &md5ctx, pCertInfo->Subject.pbData, pCertInfo->Subject.cbData );
  84. MD5Update(
  85. &md5ctx,
  86. (LPBYTE)pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId,
  87. strlen( pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId )
  88. );
  89. MD5Update(
  90. &md5ctx,
  91. pCertInfo->SubjectPublicKeyInfo.Algorithm.Parameters.pbData,
  92. pCertInfo->SubjectPublicKeyInfo.Algorithm.Parameters.cbData
  93. );
  94. // We assume that the unused public key bits are zero
  95. MD5Update(
  96. &md5ctx,
  97. pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData,
  98. pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData
  99. );
  100. MD5Update(
  101. &md5ctx,
  102. pIssuerCertInfo->SubjectPublicKeyInfo.PublicKey.pbData,
  103. pIssuerCertInfo->SubjectPublicKeyInfo.PublicKey.cbData
  104. );
  105. MD5Final( &md5ctx );
  106. memcpy( OriginIdentifier, md5ctx.digest, MD5DIGESTLEN );
  107. return( TRUE );
  108. }
  109. //+---------------------------------------------------------------------------
  110. //
  111. // Function: MyCancelFunction
  112. //
  113. // Synopsis: The call back function to cancel the object retrieval.
  114. // The cancellation happens when it is called for the 3rd time.
  115. //
  116. //----------------------------------------------------------------------------
  117. BOOL WINAPI MyCancelFunction(DWORD dwFlags, void *pvArg)
  118. {
  119. DWORD *pCount=NULL;
  120. pCount=(DWORD *)pvArg;
  121. if(*pCount == g_dwCount)
  122. return TRUE;
  123. (*pCount)++;
  124. return FALSE;
  125. }
  126. //+---------------------------------------------------------------------------
  127. //
  128. // Function: main
  129. //
  130. // Synopsis: main program entry point
  131. //
  132. //----------------------------------------------------------------------------
  133. int _cdecl main(int argc, char * argv[])
  134. {
  135. #if 0
  136. BOOL fResult;
  137. HINTERNET hInetSession;
  138. hInetSession = InternetOpen(
  139. "foo",
  140. INTERNET_OPEN_TYPE_PRECONFIG,
  141. NULL,
  142. NULL,
  143. 0
  144. );
  145. if ( hInetSession == NULL )
  146. {
  147. printf("Error opening internet session %lx\n", GetLastError());
  148. return( 1 );
  149. }
  150. fResult = InternetSetOption(
  151. hInetSession,
  152. INTERNET_OPTION_USERNAME,
  153. "foo",
  154. strlen( "foo" ) + 1
  155. );
  156. if ( fResult == TRUE )
  157. {
  158. fResult = InternetSetOption(
  159. hInetSession,
  160. INTERNET_OPTION_PROXY_USERNAME,
  161. "bar",
  162. strlen( "bar" ) + 1
  163. );
  164. }
  165. if ( fResult == TRUE )
  166. {
  167. fResult = InternetSetOption(
  168. hInetSession,
  169. INTERNET_OPTION_PASSWORD,
  170. "gamma",
  171. strlen( "gamma" ) + 1
  172. );
  173. if ( fResult == TRUE )
  174. {
  175. fResult = InternetSetOption(
  176. hInetSession,
  177. INTERNET_OPTION_PROXY_PASSWORD,
  178. "beta",
  179. strlen( "beta" ) + 1
  180. );
  181. }
  182. }
  183. InternetCloseHandle( hInetSession );
  184. return( 0 );
  185. #endif
  186. #if 0
  187. LPWSTR pwszUrl = NULL;
  188. if ( I_CryptNetGetUserDsStoreUrl( L"X509Certificate", &pwszUrl ) == TRUE )
  189. {
  190. wprintf(L"User DS Store URL = <%s>\n", pwszUrl);
  191. CryptMemFree( pwszUrl );
  192. }
  193. else
  194. {
  195. printf("I_CryptNetGetUserDsStoreUrl failed <%lx>\n", GetLastError());
  196. }
  197. return( 0 );
  198. #endif
  199. #if 1
  200. ULONG cCount;
  201. PCRYPT_BLOB_ARRAY pcba;
  202. LPVOID pv;
  203. LPSTR pszObjectOid = NULL;
  204. LPSTR pszUrl = NULL;
  205. LPSTR pszUsername = NULL;
  206. LPSTR pszPassword = NULL;
  207. DWORD dwRetrievalFlags = 0;
  208. BOOL fGetObjectUrl = FALSE;
  209. PCRYPT_CREDENTIALS pCredentials = NULL;
  210. CRYPT_CREDENTIALS Credentials;
  211. CRYPT_PASSWORD_CREDENTIALSA PasswordCredentials;
  212. CRYPT_PASSWORD_CREDENTIALSW UnicodePasswordCredentials;
  213. BOOL fUnicodeCredentials = FALSE;
  214. LPWSTR pwszUsername = NULL;
  215. LPWSTR pwszPassword = NULL;
  216. DWORD dwTimeout = 0;
  217. BOOL fCancel = FALSE;
  218. BOOL fUninstall = FALSE;
  219. DWORD dwCount = 0;
  220. BOOL fQuiet = FALSE;
  221. DWORD dwDisplayFlags = 0;
  222. BOOL fSave = FALSE;
  223. BOOL fPKCS7Save = FALSE;
  224. LPSTR pszSaveFilename = NULL;
  225. DWORD dwExpectedError = 0;
  226. PCRYPT_RETRIEVE_AUX_INFO pAuxInfo = NULL;
  227. FILETIME LastSyncTime = { 0, 0 };
  228. CRYPT_RETRIEVE_AUX_INFO AuxInfo;
  229. memset(&AuxInfo, 0, sizeof(AuxInfo));
  230. AuxInfo.cbSize = sizeof(AuxInfo);
  231. if ( argc < 2 )
  232. {
  233. Usage();
  234. return( 1 );
  235. }
  236. argv++;
  237. argc--;
  238. printf( "command line: %s\n", GetCommandLineA() );
  239. pszUrl = argv[0];
  240. while ( --argc > 0 )
  241. {
  242. if (**++argv == '-')
  243. {
  244. if (0 == _stricmp(argv[0]+1, "Error")) {
  245. if ( argc < 2 )
  246. {
  247. Usage();
  248. return( 1 );
  249. }
  250. dwExpectedError = (DWORD) strtoul(argv[1], NULL, 0);
  251. argc -= 1;
  252. argv++;
  253. } else if (0 == _stricmp(argv[0]+1, "Flags")) {
  254. if ( argc < 2 )
  255. {
  256. Usage();
  257. return( 1 );
  258. }
  259. dwRetrievalFlags |= (DWORD) strtoul(argv[1], NULL, 0);
  260. argc -= 1;
  261. argv++;
  262. } else if (0 == _stricmp(argv[0]+1, "Size")) {
  263. if ( argc < 2 )
  264. {
  265. Usage();
  266. return( 1 );
  267. }
  268. pAuxInfo = &AuxInfo;
  269. AuxInfo.dwMaxUrlRetrievalByteCount =
  270. (DWORD) strtoul(argv[1], NULL, 0);
  271. argc -= 1;
  272. argv++;
  273. } else {
  274. switch(argv[0][1])
  275. {
  276. case 'm':
  277. case 'M':
  278. dwRetrievalFlags |= CRYPT_RETRIEVE_MULTIPLE_OBJECTS;
  279. break;
  280. case 'c':
  281. case 'C':
  282. dwRetrievalFlags |= CRYPT_CACHE_ONLY_RETRIEVAL;
  283. break;
  284. case 'w':
  285. case 'W':
  286. dwRetrievalFlags |= CRYPT_WIRE_ONLY_RETRIEVAL;
  287. break;
  288. case 'f':
  289. case 'F':
  290. fCancel = TRUE;
  291. break;
  292. case 'n':
  293. case 'N':
  294. fUninstall = TRUE;
  295. break;
  296. case 'd':
  297. case 'D':
  298. dwRetrievalFlags |= CRYPT_DONT_CACHE_RESULT;
  299. break;
  300. case 'u':
  301. case 'U':
  302. fGetObjectUrl = TRUE;
  303. break;
  304. case 't':
  305. case 'T':
  306. if ( argc < 2 )
  307. {
  308. Usage();
  309. return( 1 );
  310. }
  311. dwTimeout = atol( argv[1] );
  312. argc -= 1;
  313. argv++;
  314. break;
  315. case 'r':
  316. case 'R':
  317. if ( argc < 2 )
  318. {
  319. Usage();
  320. return( 1 );
  321. }
  322. g_dwCount = atol( argv[1] );
  323. argc -= 1;
  324. argv++;
  325. break;
  326. case 'L':
  327. fUnicodeCredentials = TRUE;
  328. case 'l':
  329. if ( argc < 2 )
  330. {
  331. Usage();
  332. return( 1 );
  333. }
  334. pszUsername = argv[1];
  335. if ( argc > 2 )
  336. {
  337. pszPassword = argv[2];
  338. argc--;
  339. argv++;
  340. }
  341. argc -= 1;
  342. argv++;
  343. break;
  344. case 'q':
  345. case 'Q':
  346. fQuiet = TRUE;
  347. break;
  348. case 'v':
  349. case 'V':
  350. dwDisplayFlags |= DISPLAY_VERBOSE_FLAG;
  351. break;
  352. case '7':
  353. fPKCS7Save = TRUE;
  354. case 's':
  355. case 'S':
  356. fSave = TRUE;
  357. if ( argc < 2 )
  358. {
  359. Usage();
  360. return( 1 );
  361. }
  362. pszSaveFilename = argv[1];
  363. argc -= 1;
  364. argv++;
  365. break;
  366. case 'a':
  367. case 'A':
  368. pAuxInfo = &AuxInfo;
  369. AuxInfo.pLastSyncTime = &LastSyncTime;
  370. break;
  371. case 'p':
  372. case 'P':
  373. dwRetrievalFlags |= CRYPT_STICKY_CACHE_RETRIEVAL;
  374. break;
  375. case 'e':
  376. case 'E':
  377. dwRetrievalFlags |= CRYPT_LDAP_INSERT_ENTRY_ATTRIBUTE;
  378. break;
  379. case 'k':
  380. case 'K':
  381. dwRetrievalFlags |= CRYPT_LDAP_SIGN_RETRIEVAL;
  382. break;
  383. case 'i':
  384. case 'I':
  385. dwRetrievalFlags |= CRYPT_NO_AUTH_RETRIEVAL;
  386. break;
  387. default:
  388. Usage();
  389. return -1;
  390. }
  391. }
  392. }
  393. else
  394. {
  395. if ( _stricmp( argv[0], "cert" ) == 0 )
  396. {
  397. pszObjectOid = (LPSTR)CONTEXT_OID_CERTIFICATE;
  398. }
  399. else if ( _stricmp( argv[0], "ctl" ) == 0 )
  400. {
  401. pszObjectOid = (LPSTR)CONTEXT_OID_CTL;
  402. }
  403. else if ( _stricmp( argv[0], "crl" ) == 0 )
  404. {
  405. pszObjectOid = (LPSTR)CONTEXT_OID_CRL;
  406. }
  407. else if ( _stricmp( argv[0], "pkcs7" ) == 0 )
  408. {
  409. pszObjectOid = (LPSTR)CONTEXT_OID_PKCS7;
  410. }
  411. else if ( _stricmp( argv[0], "any" ) == 0 )
  412. {
  413. pszObjectOid = (LPSTR)CONTEXT_OID_CAPI2_ANY;
  414. }
  415. else
  416. {
  417. Usage();
  418. return( -1 );
  419. }
  420. }
  421. }
  422. if ( pszUsername != NULL )
  423. {
  424. if (fUnicodeCredentials)
  425. {
  426. pwszUsername = AllocAndSzToWsz(pszUsername);
  427. if ( pszPassword != NULL )
  428. {
  429. pwszPassword = AllocAndSzToWsz(pszPassword);
  430. }
  431. UnicodePasswordCredentials.cbSize =
  432. sizeof( UnicodePasswordCredentials );
  433. UnicodePasswordCredentials.pszUsername = pwszUsername;
  434. UnicodePasswordCredentials.pszPassword = pwszPassword;
  435. Credentials.cbSize = sizeof( Credentials );
  436. Credentials.pszCredentialsOid =
  437. CREDENTIAL_OID_PASSWORD_CREDENTIALS_W;
  438. Credentials.pvCredentials = (LPVOID)&UnicodePasswordCredentials;
  439. pCredentials = &Credentials;
  440. printf("Using Unicode credentials %S <%S>\n",
  441. pwszUsername, pwszPassword);
  442. }
  443. else
  444. {
  445. PasswordCredentials.cbSize = sizeof( PasswordCredentials );
  446. PasswordCredentials.pszUsername = pszUsername;
  447. PasswordCredentials.pszPassword = pszPassword;
  448. Credentials.cbSize = sizeof( Credentials );
  449. Credentials.pszCredentialsOid = CREDENTIAL_OID_PASSWORD_CREDENTIALS_A;
  450. Credentials.pvCredentials = (LPVOID)&PasswordCredentials;
  451. pCredentials = &Credentials;
  452. printf("Using credentials %s <%s>\n", pszUsername, pszPassword);
  453. }
  454. }
  455. if(fCancel)
  456. {
  457. if(!CryptInstallCancelRetrieval(
  458. MyCancelFunction,
  459. &dwCount,
  460. 0,
  461. NULL))
  462. printf("Install cancel function failed!\n");
  463. if(fUninstall)
  464. {
  465. if(!CryptUninstallCancelRetrieval(
  466. 0,
  467. NULL))
  468. printf("Uninstall cancel function failed!\n");
  469. }
  470. }
  471. if ( CryptRetrieveObjectByUrlA(
  472. pszUrl,
  473. pszObjectOid,
  474. dwRetrievalFlags,
  475. dwTimeout,
  476. &pv,
  477. NULL,
  478. pCredentials,
  479. NULL,
  480. pAuxInfo
  481. ) == FALSE )
  482. {
  483. DWORD dwLastErr = GetLastError();
  484. if (0 == dwExpectedError)
  485. printf( "CryptRetrieveObjectByUrl FAILED! <0x%x %d>\n", dwLastErr, dwLastErr );
  486. else if (dwLastErr != dwExpectedError)
  487. printf( "CryptRetrieveObjectByUrl FAILED! Expected: 0x%x Actual: <0x%x %d>\n", dwExpectedError, dwLastErr, dwLastErr );
  488. else
  489. printf( "CryptRetrieveObjectByUrl SUCCEEDED! Got Expected: <0x%x %d>\n", dwLastErr, dwLastErr );
  490. if(fCancel)
  491. {
  492. if(!fUninstall)
  493. {
  494. if(!CryptUninstallCancelRetrieval(
  495. 0,
  496. NULL))
  497. printf("Uninstall cancel function failed!\n");
  498. }
  499. }
  500. if (pwszUsername)
  501. TestFree(pwszUsername);
  502. if (pwszPassword)
  503. TestFree(pwszPassword);
  504. return( -1 );
  505. }
  506. if (0 == dwExpectedError)
  507. printf( "CryptRetrieveObjectByUrl SUCCEEDED!\n" );
  508. else
  509. printf( "CryptRetrieveObjectByUrl FAILED! Expected: 0x%x Actual: 0x0\n", dwExpectedError );
  510. if (pAuxInfo)
  511. {
  512. printf(" LastSyncTime:: %s\n",
  513. FileTimeText(&LastSyncTime));
  514. }
  515. if(fCancel)
  516. {
  517. if(!fUninstall)
  518. {
  519. if(!CryptUninstallCancelRetrieval(
  520. 0,
  521. NULL))
  522. printf("Uninstall cancel function failed!\n");
  523. }
  524. }
  525. if ( pszObjectOid == NULL )
  526. {
  527. pcba = (PCRYPT_BLOB_ARRAY)pv;
  528. for ( cCount = 0; cCount < pcba->cBlob; cCount++ )
  529. {
  530. PBYTE pb = pcba->rgBlob[cCount].pbData;
  531. DWORD cb = pcba->rgBlob[cCount].cbData;
  532. printf( "\nObject#%d ", cCount+1);
  533. if (dwRetrievalFlags & CRYPT_LDAP_INSERT_ENTRY_ATTRIBUTE)
  534. {
  535. DWORD cbPrefix;
  536. LPCSTR pszIndex;
  537. LPCSTR pszAttr;
  538. pszIndex = (LPCSTR) pb;
  539. cbPrefix = strlen(pszIndex) + 1;
  540. pb += cbPrefix;
  541. cb -= cbPrefix;
  542. pszAttr = (LPCSTR) pb;
  543. cbPrefix = strlen(pszAttr) + 1;
  544. pb += cbPrefix;
  545. cb -= cbPrefix;
  546. printf("[%s, %s] ", pszIndex, pszAttr);
  547. }
  548. printf( "- Length=0x%lx\n", cb );
  549. PrintBytes(
  550. "",
  551. pb,
  552. cb
  553. );
  554. }
  555. CryptMemFree( pv );
  556. }
  557. else if ( pszObjectOid == CONTEXT_OID_CERTIFICATE )
  558. {
  559. if ( !( dwRetrievalFlags & CRYPT_RETRIEVE_MULTIPLE_OBJECTS ) )
  560. {
  561. DisplayCert( (PCCERT_CONTEXT)pv, dwDisplayFlags );
  562. if ( fGetObjectUrl == TRUE )
  563. {
  564. #if 1
  565. DWORD cbUrlArray;
  566. if ( CryptGetObjectUrl(
  567. URL_OID_CERTIFICATE_CRL_DIST_POINT,
  568. pv,
  569. 0,
  570. NULL,
  571. &cbUrlArray,
  572. NULL,
  573. NULL,
  574. NULL
  575. ) == FALSE )
  576. {
  577. printf("GetObjectUrl failed %lx\n", GetLastError());
  578. }
  579. else
  580. {
  581. printf("cbUrlArray = %ld\n", cbUrlArray);
  582. }
  583. #else
  584. DWORD cCount;
  585. LARGE_INTEGER TickCount1;
  586. LARGE_INTEGER TickCount2;
  587. LARGE_INTEGER TickCount;
  588. CRYPT_ORIGIN_IDENTIFIER OriginIdentifier;
  589. #define NUM_ITER 1000000
  590. GetSystemTimeAsFileTime( (LPFILETIME)&TickCount1 );
  591. for ( cCount = 0; cCount < NUM_ITER; cCount++ )
  592. {
  593. if ( memcmp( Foo, Bar, 100 ) != 0 )
  594. {
  595. Foo[0] = 1;
  596. Bar[0] = 1;
  597. }
  598. if ( memcmp( Foo, Bar, 200 ) != 0 )
  599. {
  600. Foo[0] = 1;
  601. Bar[0] = 1;
  602. }
  603. if ( memcmp( Foo, Bar, 64 ) != 0 )
  604. {
  605. Foo[0] = 1;
  606. Bar[0] = 1;
  607. }
  608. if ( memcmp( Foo, Bar, 128 ) != 0 )
  609. {
  610. Foo[0] = 1;
  611. Bar[0] = 1;
  612. }
  613. //CertGetOriginIdentifier(
  614. // (PCCERT_CONTEXT)pv,
  615. // (PCCERT_CONTEXT)pv,
  616. // 0,
  617. // OriginIdentifier
  618. // );
  619. }
  620. GetSystemTimeAsFileTime( (LPFILETIME)&TickCount2 );
  621. TickCount.QuadPart = ( TickCount2.QuadPart - TickCount1.QuadPart );
  622. printf("PerIter = %ld ns. Total = %ld s.\n", (((LPFILETIME)&TickCount)->dwLowDateTime / NUM_ITER) * 100, ((LPFILETIME)&TickCount)->dwLowDateTime / 10000000);
  623. #endif
  624. }
  625. CertFreeCertificateContext( (PCCERT_CONTEXT)pv );
  626. }
  627. else
  628. {
  629. if (!fQuiet)
  630. DisplayStore( (HCERTSTORE)pv, dwDisplayFlags );
  631. if (fSave && pszSaveFilename)
  632. SaveStoreEx( (HCERTSTORE)pv, fPKCS7Save, pszSaveFilename);
  633. CertCloseStore( (HCERTSTORE)pv, 0 );
  634. }
  635. }
  636. else if ( pszObjectOid == CONTEXT_OID_CTL )
  637. {
  638. if ( !( dwRetrievalFlags & CRYPT_RETRIEVE_MULTIPLE_OBJECTS ) )
  639. {
  640. DisplayCtl( (PCCTL_CONTEXT)pv, dwDisplayFlags );
  641. CertFreeCTLContext( (PCCTL_CONTEXT)pv );
  642. }
  643. else
  644. {
  645. if (!fQuiet)
  646. DisplayStore( (HCERTSTORE)pv, dwDisplayFlags );
  647. if (fSave && pszSaveFilename)
  648. SaveStoreEx( (HCERTSTORE)pv, fPKCS7Save, pszSaveFilename);
  649. CertCloseStore( (HCERTSTORE)pv, 0 );
  650. }
  651. }
  652. else if ( pszObjectOid == CONTEXT_OID_CRL )
  653. {
  654. if ( !( dwRetrievalFlags & CRYPT_RETRIEVE_MULTIPLE_OBJECTS ) )
  655. {
  656. DisplayCrl( (PCCRL_CONTEXT)pv, dwDisplayFlags );
  657. CertFreeCRLContext( (PCCRL_CONTEXT)pv );
  658. }
  659. else
  660. {
  661. if (!fQuiet)
  662. DisplayStore( (HCERTSTORE)pv, dwDisplayFlags );
  663. if (fSave && pszSaveFilename)
  664. SaveStoreEx( (HCERTSTORE)pv, fPKCS7Save, pszSaveFilename);
  665. CertCloseStore( (HCERTSTORE)pv, 0 );
  666. }
  667. }
  668. else if ( ( pszObjectOid == CONTEXT_OID_CAPI2_ANY ) ||
  669. ( pszObjectOid == CONTEXT_OID_PKCS7 ) )
  670. {
  671. if (!fQuiet)
  672. DisplayStore( (HCERTSTORE)pv, dwDisplayFlags );
  673. if (fSave && pszSaveFilename)
  674. SaveStoreEx( (HCERTSTORE)pv, fPKCS7Save, pszSaveFilename);
  675. CertCloseStore( (HCERTSTORE)pv, 0 );
  676. }
  677. if (pwszUsername)
  678. TestFree(pwszUsername);
  679. if (pwszPassword)
  680. TestFree(pwszPassword);
  681. return( 0 );
  682. #endif
  683. }