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.

910 lines
24 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1996 - 1999
  6. //
  7. // File: mscatctl.cpp
  8. //
  9. // Contents: Microsoft Internet Security Catalog Utilities
  10. // implements the Certificate Trust List & persistent storage
  11. //
  12. // Functions: CatalogLoadFileData
  13. // CatalogSaveP7UData
  14. // CatalogSaveP7SData
  15. // IsCatalogFile
  16. //
  17. // *** local functions ***
  18. // CatalogLoadData
  19. // CatalogFillCatStore
  20. // CatalogFillCTL
  21. // CatalogFillCTLAttr
  22. // CatalogFreeCTL
  23. // CatalogFreeCTLAttr
  24. // CatalogFillCatMember
  25. // CatalogFillMemAttr
  26. // CatalogFillCatAttr
  27. // CatalogFillCatLevelAttr
  28. //
  29. // History: 05-May-1997 pberkman created
  30. //
  31. //--------------------------------------------------------------------------
  32. #include "global.hxx"
  33. #include "mscat32.h"
  34. //
  35. // for each member, we have at minimum two authenticated attributes.
  36. // 1 = Indirect Data
  37. // 2 = Subject Guid
  38. //
  39. #define CAT_RESERVE_CTL_ATTR 2
  40. // WARNING: this function allocates pbData -- you must delete!
  41. BOOL CatalogLoadData(WCHAR *pwszCatFile, DWORD *cbData, BYTE **pbData);
  42. BOOL CatalogFillCatStore(CRYPTCATSTORE *pCat, PCTL_INFO pCTLInfo);
  43. BOOL CatalogFreeCTL(CTL_INFO *pCTL);
  44. BOOL CatalogFreeCTLAttr(CRYPT_ATTRIBUTE *pCryptAttr);
  45. BOOL CatalogFillCTL(CRYPTCATSTORE *pCat, CTL_INFO *pCTL);
  46. BOOL CatalogFillCatAttr(CRYPTCATSTORE *pCat, CERT_EXTENSION *pAttr);
  47. BOOL CatalogFillCatLevelAttr(CRYPTCATSTORE *pCatStore, CRYPTCATATTRIBUTE *pAttr,
  48. CERT_EXTENSION *pCertAttr);
  49. BOOL CatalogFillCTLAttr(CRYPTCATSTORE *pCatStore, CRYPTCATATTRIBUTE *pAttr,
  50. PCRYPT_ATTRIBUTE pCryptAttr);
  51. CRYPTCATMEMBER *CatalogFillCatMember(CRYPTCATSTORE *pCat, CTL_ENTRY *pEntry);
  52. BOOL CatalogFillMemAttr(CRYPTCATSTORE *pCat, CRYPTCATMEMBER *pMember, CRYPT_ATTRIBUTE *pAttr);
  53. static const char *pszOID = szOID_CATALOG_LIST;
  54. BOOL CatalogLoadFileData(CRYPTCATSTORE *pCat)
  55. {
  56. BOOL fRet;
  57. DWORD cbData;
  58. BYTE *pbData;
  59. cbData = 0;
  60. pbData = NULL;
  61. if (!(CatalogLoadData(pCat->pwszP7File, &cbData, &pbData)))
  62. {
  63. return(FALSE);
  64. }
  65. if (cbData < 1)
  66. {
  67. if (pbData)
  68. {
  69. UnmapViewOfFile(pbData);
  70. }
  71. //
  72. // not signed and we are probably creating it!
  73. //
  74. return(TRUE);
  75. }
  76. PCCTL_CONTEXT pCTLContext;
  77. pCTLContext = (PCCTL_CONTEXT) CertCreateContext(
  78. CERT_STORE_CTL_CONTEXT,
  79. pCat->dwEncodingType,
  80. pbData,
  81. cbData,
  82. CERT_CREATE_CONTEXT_NOCOPY_FLAG |
  83. CERT_CREATE_CONTEXT_NO_HCRYPTMSG_FLAG,
  84. NULL // pCreatePara
  85. );
  86. if (pCTLContext)
  87. {
  88. //
  89. // got it... fill our arrays!
  90. //
  91. fRet = CatalogFillCatStore(pCat, pCTLContext->pCtlInfo);
  92. CertFreeCTLContext(pCTLContext);
  93. } else
  94. fRet = FALSE;
  95. UnmapViewOfFile(pbData);
  96. return(fRet);
  97. }
  98. BOOL CatalogSaveP7SData(CRYPTCATSTORE *pCat, CTL_CONTEXT *pCTLContext)
  99. {
  100. assert(0); // should never be called!
  101. return(TRUE);
  102. }
  103. BOOL CatalogSaveP7UData(CRYPTCATSTORE *pCat)
  104. {
  105. CMSG_SIGNED_ENCODE_INFO sSignInfo;
  106. CTL_INFO sCTLInfo;
  107. DWORD cbEncoded;
  108. BYTE *pbEncoded;
  109. Stack_ *pStack;
  110. //
  111. // sort the data...
  112. //
  113. if (pCat->hReserved) // member stack_
  114. {
  115. pStack = (Stack_ *)pCat->hReserved;
  116. pStack->Sort(WVT_OFFSETOF(CRYPTCATMEMBER, pwszReferenceTag), sizeof(WCHAR *), STACK_SORTTYPE_PWSZ);
  117. }
  118. memset(&sSignInfo, 0x00, sizeof(CMSG_SIGNED_ENCODE_INFO));
  119. sSignInfo.cbSize = sizeof(CMSG_SIGNED_ENCODE_INFO);
  120. if (CatalogFillCTL(pCat, &sCTLInfo))
  121. {
  122. cbEncoded = 0;
  123. CryptMsgEncodeAndSignCTL( pCat->dwEncodingType,
  124. &sCTLInfo,
  125. &sSignInfo,
  126. 0,
  127. NULL,
  128. &cbEncoded);
  129. if (cbEncoded > 0)
  130. {
  131. BOOL fRet;
  132. if (!(pbEncoded = (BYTE *)CatalogNew(cbEncoded)))
  133. {
  134. CatalogFreeCTL(&sCTLInfo);
  135. return(FALSE);
  136. }
  137. fRet = CryptMsgEncodeAndSignCTL( pCat->dwEncodingType,
  138. &sCTLInfo,
  139. &sSignInfo,
  140. 0,
  141. pbEncoded,
  142. &cbEncoded);
  143. CatalogFreeCTL(&sCTLInfo);
  144. if (fRet)
  145. {
  146. HANDLE hFile;
  147. DWORD lErr;
  148. lErr = GetLastError();
  149. if ((hFile = CreateFileU(pCat->pwszP7File,
  150. GENERIC_WRITE | GENERIC_READ,
  151. 0, // no sharing!!
  152. NULL,
  153. CREATE_ALWAYS,
  154. FILE_ATTRIBUTE_NORMAL,
  155. NULL)) != INVALID_HANDLE_VALUE)
  156. {
  157. DWORD cbWritten;
  158. if (!(WriteFile(hFile, pbEncoded, cbEncoded, &cbWritten, NULL)) ||
  159. (cbEncoded != cbWritten))
  160. {
  161. fRet = FALSE;
  162. }
  163. CloseHandle(hFile);
  164. if (fRet)
  165. {
  166. SetLastError(lErr);
  167. }
  168. }
  169. }
  170. delete pbEncoded;
  171. return(fRet);
  172. }
  173. CatalogFreeCTL(&sCTLInfo);
  174. }
  175. return(FALSE);
  176. }
  177. BOOL CatalogLoadData(WCHAR *pwszCatFile, DWORD *cbData, BYTE **pbData)
  178. {
  179. HANDLE hFile;
  180. *cbData = 0;
  181. if ((hFile = CreateFileU(pwszCatFile,
  182. GENERIC_READ,
  183. FILE_SHARE_READ,
  184. NULL,
  185. OPEN_EXISTING,
  186. FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
  187. NULL)) == INVALID_HANDLE_VALUE)
  188. {
  189. return(FALSE);
  190. }
  191. if ((*cbData = GetFileSize(hFile, NULL)) == 0xffffffff)
  192. {
  193. *cbData = 0;
  194. CloseHandle(hFile);
  195. return(FALSE);
  196. }
  197. if (*cbData < 10)
  198. {
  199. //
  200. // just created file....
  201. //
  202. *cbData = 0;
  203. CloseHandle(hFile);
  204. return(TRUE);
  205. }
  206. HANDLE hMappedFile;
  207. hMappedFile = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
  208. if (!(hMappedFile) || (hMappedFile == INVALID_HANDLE_VALUE))
  209. {
  210. *cbData = 0;
  211. CloseHandle(hFile);
  212. return(FALSE);
  213. }
  214. *pbData = (BYTE *)MapViewOfFile(hMappedFile, FILE_MAP_READ, 0, 0, 0);
  215. CloseHandle(hMappedFile);
  216. CloseHandle(hFile);
  217. if ((*pbData) == NULL)
  218. {
  219. return(FALSE);
  220. }
  221. return(TRUE);
  222. }
  223. BOOL CatalogFillCatStore(CRYPTCATSTORE *pCat, CTL_INFO *pCTL)
  224. {
  225. int iAttr;
  226. if (pCTL->cCTLEntry > 0)
  227. {
  228. for (iAttr = 0; iAttr < (int)pCTL->cExtension; iAttr++)
  229. {
  230. if (!(CatalogFillCatAttr(pCat, &pCTL->rgExtension[iAttr])))
  231. {
  232. return(FALSE);
  233. }
  234. }
  235. CRYPTCATMEMBER *pMember;
  236. for (int iEntry = 0; iEntry < (int)pCTL->cCTLEntry; iEntry++)
  237. {
  238. pMember = CatalogFillCatMember(pCat, &pCTL->rgCTLEntry[iEntry]);
  239. if (!(pMember))
  240. {
  241. return(FALSE);
  242. }
  243. if (pCTL->rgCTLEntry[iEntry].cAttribute > 0)
  244. {
  245. for (iAttr = 0; iAttr < (int)pCTL->rgCTLEntry[iEntry].cAttribute; iAttr++)
  246. {
  247. if (!(CatalogFillMemAttr(pCat, pMember,
  248. &pCTL->rgCTLEntry[iEntry].rgAttribute[iAttr])))
  249. {
  250. return(FALSE);
  251. }
  252. }
  253. }
  254. }
  255. return(TRUE);
  256. }
  257. return(TRUE);
  258. }
  259. CRYPTCATMEMBER *CatalogFillCatMember(CRYPTCATSTORE *pCat, CTL_ENTRY *pEntry)
  260. {
  261. if (!(pEntry))
  262. {
  263. return(NULL);
  264. }
  265. Stack_ *pStack;
  266. CRYPTCATMEMBER *pCatMember;
  267. if (!(pCat->hReserved))
  268. {
  269. pStack = new Stack_(&MSCAT_CriticalSection);
  270. if (!(pStack))
  271. {
  272. assert(0);
  273. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  274. return(NULL);
  275. }
  276. pCat->hReserved = (HANDLE)pStack;
  277. }
  278. pStack = (Stack_ *)pCat->hReserved;
  279. if (!(pCatMember = (CRYPTCATMEMBER *)pStack->Add(sizeof(CRYPTCATMEMBER))))
  280. {
  281. return(NULL);
  282. }
  283. memset(pCatMember, 0x00, sizeof(CRYPTCATMEMBER));
  284. pCatMember->cbStruct = sizeof(CRYPTCATMEMBER);
  285. // pwszFileName
  286. // pwszReferenceTag
  287. if (!(pCatMember->pwszReferenceTag = (LPWSTR)CatalogNew(pEntry->SubjectIdentifier.cbData)))
  288. {
  289. return(NULL);
  290. }
  291. memcpy(pCatMember->pwszReferenceTag, pEntry->SubjectIdentifier.pbData,
  292. pEntry->SubjectIdentifier.cbData);
  293. // pIndirectData (will be filled in while getting attributes!
  294. // gSubjectType (will be filled in while getting attributes!
  295. return(pCatMember);
  296. }
  297. BOOL CatalogFillCatAttr(CRYPTCATSTORE *pCat, CERT_EXTENSION *pAttr)
  298. {
  299. if (!(pAttr))
  300. {
  301. return(FALSE);
  302. }
  303. Stack_ *pStack;
  304. CRYPTCATATTRIBUTE *pCatAttr;
  305. if (!(pCat->hAttrs))
  306. {
  307. pStack = new Stack_(&MSCAT_CriticalSection);
  308. if (!(pStack))
  309. {
  310. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  311. return(FALSE);
  312. }
  313. pCat->hAttrs = (HANDLE)pStack;
  314. }
  315. pStack = (Stack_ *)pCat->hAttrs;
  316. if (!(pCatAttr = (CRYPTCATATTRIBUTE *)pStack->Add(sizeof(CRYPTCATATTRIBUTE))))
  317. {
  318. return(FALSE);
  319. }
  320. memset(pCatAttr, 0x00, sizeof(CRYPTCATATTRIBUTE));
  321. pCatAttr->cbStruct = sizeof(CRYPTCATATTRIBUTE);
  322. CRYPT_ATTRIBUTE sCryptAttr;
  323. CatalogCertExt2CryptAttr(pAttr, &sCryptAttr);
  324. if (!(CatalogDecodeNameValue(pCat, &sCryptAttr, pCatAttr)))
  325. {
  326. return(FALSE);
  327. }
  328. return(TRUE);
  329. }
  330. BOOL CatalogFillMemAttr(CRYPTCATSTORE *pCat, CRYPTCATMEMBER *pMember, CRYPT_ATTRIBUTE *pAttr)
  331. {
  332. if (!(pAttr))
  333. {
  334. return(FALSE);
  335. }
  336. if (strcmp(pAttr->pszObjId, SPC_INDIRECT_DATA_OBJID) == 0)
  337. {
  338. return(CatalogDecodeIndirectData(pCat, pMember, pAttr));
  339. }
  340. if (strcmp(pAttr->pszObjId, CAT_MEMBERINFO_OBJID) == 0)
  341. {
  342. return(CatalogDecodeMemberInfo(pCat, pMember, pAttr));
  343. }
  344. Stack_ *pStack;
  345. CRYPTCATATTRIBUTE *pCatAttr;
  346. if (!(pMember->hReserved))
  347. {
  348. pStack = new Stack_(&MSCAT_CriticalSection);
  349. if (!(pStack))
  350. {
  351. assert(0);
  352. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  353. return(FALSE);
  354. }
  355. pMember->hReserved = (HANDLE)pStack;
  356. }
  357. pStack = (Stack_ *)pMember->hReserved;
  358. if (!(pCatAttr = (CRYPTCATATTRIBUTE *)pStack->Add(sizeof(CRYPTCATATTRIBUTE))))
  359. {
  360. return(FALSE);
  361. }
  362. memset(pCatAttr, 0x00, sizeof(CRYPTCATATTRIBUTE));
  363. pCatAttr->cbStruct = sizeof(CRYPTCATATTRIBUTE);
  364. if (!(CatalogDecodeNameValue(pCat, pAttr, pCatAttr)))
  365. {
  366. return(FALSE);
  367. }
  368. return(TRUE);
  369. }
  370. BOOL CatalogFillCTL(CRYPTCATSTORE *pCat, CTL_INFO *pCTL)
  371. {
  372. typedef HRESULT (WINAPI *pfnCoCreateGuid)(GUID FAR *pguid);
  373. HINSTANCE hOLE;
  374. pfnCoCreateGuid pfnCreateGuid;
  375. memset(pCTL, 0x00, sizeof(CTL_INFO));
  376. // dwVersion
  377. pCTL->dwVersion = CTL_V1;
  378. // SubjectUsage
  379. pCTL->SubjectUsage.cUsageIdentifier = 1;
  380. pCTL->SubjectUsage.rgpszUsageIdentifier = (char **)&pszOID;
  381. // ListIdentifier
  382. if (hOLE = LoadLibraryA("OLE32.DLL"))
  383. {
  384. if (pfnCreateGuid = (pfnCoCreateGuid)GetProcAddress(hOLE, "CoCreateGuid"))
  385. {
  386. if (pCTL->ListIdentifier.pbData = (BYTE *)CatalogNew(sizeof(GUID)))
  387. {
  388. pCTL->ListIdentifier.cbData = sizeof(GUID);
  389. (*pfnCreateGuid)((GUID *)pCTL->ListIdentifier.pbData);
  390. }
  391. }
  392. FreeLibrary(hOLE);
  393. }
  394. // SequenceNumber
  395. // optional!
  396. // ThisUpdate
  397. GetSystemTimeAsFileTime(&pCTL->ThisUpdate);
  398. // NextUpdate
  399. // optional!
  400. // SubjectAlgorithm
  401. pCTL->SubjectAlgorithm.pszObjId = szOID_CATALOG_LIST_MEMBER;
  402. Stack_ *pStackMember;
  403. Stack_ *pStackAttr;
  404. CRYPTCATMEMBER *pMember;
  405. CRYPTCATATTRIBUTE *pAttr;
  406. DWORD dwAttr;
  407. // cCTLEntry & rgCTLEntry
  408. if (pCat->hReserved)
  409. {
  410. pStackMember = (Stack_ *)pCat->hReserved;
  411. // cCTLEntry
  412. pCTL->cCTLEntry = pStackMember->Count();
  413. if (pCTL->cCTLEntry > 0)
  414. {
  415. if (!(pCTL->rgCTLEntry = (PCTL_ENTRY)CatalogNew(sizeof(CTL_ENTRY) *
  416. pStackMember->Count())))
  417. {
  418. return(FALSE);
  419. }
  420. memset(pCTL->rgCTLEntry, 0x00, sizeof(CTL_ENTRY) * pStackMember->Count());
  421. }
  422. DWORD dwMember;
  423. DWORD dwSize;
  424. CTL_ENTRY *pCTLEntry;
  425. //
  426. // copy the members to the ctl_entry
  427. //
  428. dwMember = 0;
  429. while (dwMember < pStackMember->Count())
  430. {
  431. if (!(pMember = (CRYPTCATMEMBER *)pStackMember->Get(dwMember)))
  432. {
  433. return(FALSE);
  434. }
  435. //
  436. // Subject Identifier
  437. //
  438. dwSize = (wcslen(pMember->pwszReferenceTag) + 1) * sizeof(WCHAR);
  439. pCTLEntry = &pCTL->rgCTLEntry[dwMember];
  440. if (!(pCTLEntry->SubjectIdentifier.pbData =
  441. (BYTE *)CatalogNew(dwSize)))
  442. {
  443. return(FALSE);
  444. }
  445. memcpy(pCTLEntry->SubjectIdentifier.pbData,
  446. pMember->pwszReferenceTag,dwSize);
  447. pCTLEntry->SubjectIdentifier.cbData = dwSize;
  448. //
  449. // rgAttribute
  450. // +1 for Indirect Data
  451. // +1 for Subject Guid
  452. //
  453. if (pMember->hReserved)
  454. {
  455. pStackAttr = (Stack_ *)pMember->hReserved;
  456. pCTLEntry->cAttribute = pStackAttr->Count() + CAT_RESERVE_CTL_ATTR;
  457. }
  458. else
  459. {
  460. pCTLEntry->cAttribute = CAT_RESERVE_CTL_ATTR;
  461. }
  462. if (!(pCTLEntry->rgAttribute =
  463. (PCRYPT_ATTRIBUTE)CatalogNew(sizeof(CRYPT_ATTRIBUTE) *
  464. pCTLEntry->cAttribute)))
  465. {
  466. return(FALSE);
  467. }
  468. memset(pCTLEntry->rgAttribute, 0x00,
  469. sizeof(CRYPT_ATTRIBUTE) * pCTLEntry->cAttribute);
  470. //
  471. // put our indirect data in an authenticated attribute
  472. //
  473. if (!(pMember->pIndirectData))
  474. {
  475. CatalogReallyDecodeIndirectData(pCat, pMember, &pMember->sEncodedIndirectData);
  476. }
  477. CatalogEncodeIndirectData(pCat, pMember, &pCTLEntry->rgAttribute[0]);
  478. //
  479. // put our subject guid in an authenticated attribute
  480. //
  481. if ((pMember->gSubjectType.Data1 == 0) &&
  482. (pMember->gSubjectType.Data2 == 0) &&
  483. (pMember->gSubjectType.Data3 == 0))
  484. {
  485. CatalogReallyDecodeMemberInfo(pCat, pMember, &pMember->sEncodedMemberInfo);
  486. }
  487. CatalogEncodeMemberInfo(pCat, pMember, &pCTLEntry->rgAttribute[1]);
  488. if (pMember->hReserved)
  489. {
  490. dwAttr = 0;
  491. while (dwAttr < pStackAttr->Count())
  492. {
  493. pAttr = (CRYPTCATATTRIBUTE *)pStackAttr->Get(dwAttr);
  494. CatalogFillCTLAttr(pCat, pAttr,
  495. &pCTLEntry->rgAttribute[dwAttr + CAT_RESERVE_CTL_ATTR]);
  496. //
  497. // increment our attribute counter!
  498. //
  499. dwAttr++;
  500. }
  501. }
  502. //
  503. // increment our member counter!
  504. //
  505. dwMember++;
  506. }
  507. }
  508. //
  509. // cExtension
  510. // rgExtension
  511. //
  512. if (pCat->hAttrs)
  513. {
  514. pStackAttr = (Stack_ *)pCat->hAttrs;
  515. pCTL->cExtension = pStackAttr->Count();
  516. if (!(pCTL->rgExtension =
  517. (CERT_EXTENSION *)CatalogNew(sizeof(CERT_EXTENSION) * pCTL->cExtension)))
  518. {
  519. return(FALSE);
  520. }
  521. memset(pCTL->rgExtension, 0x00, sizeof(CERT_EXTENSION) * pCTL->cExtension);
  522. dwAttr = 0;
  523. while (dwAttr < pStackAttr->Count())
  524. {
  525. pAttr = (CRYPTCATATTRIBUTE *)pStackAttr->Get(dwAttr);
  526. if (pAttr)
  527. {
  528. CatalogFillCatLevelAttr(pCat, pAttr, &pCTL->rgExtension[dwAttr]);
  529. }
  530. dwAttr++;
  531. }
  532. }
  533. return(TRUE);
  534. }
  535. BOOL CatalogFillCatLevelAttr(CRYPTCATSTORE *pCatStore, CRYPTCATATTRIBUTE *pAttr, CERT_EXTENSION *pCertAttr)
  536. {
  537. CRYPT_ATTR_BLOB sAttrBlob;
  538. CRYPT_ATTRIBUTE sCryptAttr;
  539. memset(&sAttrBlob, 0x00, sizeof(CRYPT_ATTR_BLOB));
  540. memset(&sCryptAttr, 0x00, sizeof(CRYPT_ATTRIBUTE));
  541. sCryptAttr.cValue = 1;
  542. sCryptAttr.rgValue = &sAttrBlob;
  543. if (!(CatalogEncodeNameValue(pCatStore, pAttr, &sCryptAttr)))
  544. {
  545. return(FALSE);
  546. }
  547. CatalogCryptAttr2CertExt(&sCryptAttr, pCertAttr);
  548. return(TRUE);
  549. }
  550. BOOL CatalogFillCTLAttr(CRYPTCATSTORE *pCatStore, CRYPTCATATTRIBUTE *pAttr, PCRYPT_ATTRIBUTE pCryptAttr)
  551. {
  552. if (!(pCryptAttr->rgValue = (PCRYPT_ATTR_BLOB)CatalogNew(sizeof(CRYPT_ATTR_BLOB))))
  553. {
  554. return(FALSE);
  555. }
  556. pCryptAttr->cValue = 1;
  557. memset(pCryptAttr->rgValue, 0x00, sizeof(CRYPT_ATTR_BLOB));
  558. if (!(CatalogEncodeNameValue(pCatStore, pAttr, pCryptAttr)))
  559. {
  560. return(FALSE);
  561. }
  562. return(TRUE);
  563. }
  564. BOOL CatalogFreeCTL(CTL_INFO *pCTL)
  565. {
  566. DWORD dwEntries;
  567. DWORD dwAttributes;
  568. CTL_ENTRY *pCTLEntry;
  569. DELETE_OBJECT(pCTL->ListIdentifier.pbData);
  570. dwEntries = pCTL->cCTLEntry;
  571. while (dwEntries > 0)
  572. {
  573. pCTLEntry = &pCTL->rgCTLEntry[dwEntries - 1];
  574. DELETE_OBJECT(pCTLEntry->SubjectIdentifier.pbData);
  575. dwAttributes = pCTLEntry->cAttribute;
  576. while (dwAttributes > 0)
  577. {
  578. CatalogFreeCTLAttr(&pCTLEntry->rgAttribute[dwAttributes - 1]);
  579. dwAttributes--;
  580. }
  581. DELETE_OBJECT(pCTLEntry->rgAttribute);
  582. dwEntries--;
  583. }
  584. DELETE_OBJECT(pCTL->rgCTLEntry);
  585. for (dwEntries = 0; dwEntries < pCTL->cExtension; dwEntries++)
  586. {
  587. DELETE_OBJECT(pCTL->rgExtension[dwEntries].Value.pbData);
  588. }
  589. DELETE_OBJECT(pCTL->rgExtension);
  590. return(TRUE);
  591. }
  592. BOOL CatalogFreeCTLAttr(CRYPT_ATTRIBUTE *pCryptAttr)
  593. {
  594. if (!(pCryptAttr))
  595. {
  596. return(FALSE);
  597. }
  598. if (pCryptAttr->rgValue)
  599. {
  600. DELETE_OBJECT(pCryptAttr->rgValue->pbData);
  601. DELETE_OBJECT(pCryptAttr->rgValue);
  602. }
  603. return(TRUE);
  604. }
  605. BOOL WINAPI IsCatalogFile(HANDLE hFile, WCHAR *pwszCatalogFile)
  606. {
  607. char *pszCatalogListUsageOID = szOID_CATALOG_LIST;
  608. BOOL fCloseFile;
  609. BOOL fRet;
  610. DWORD cbRead;
  611. DWORD cbFile;
  612. BYTE *pbFile;
  613. PCCTL_CONTEXT pCTLContext;
  614. //
  615. // put a try-except around everything in case there is problems with the
  616. // memory mapped file
  617. //
  618. __try {
  619. pCTLContext = NULL;
  620. pbFile = NULL;
  621. fCloseFile = FALSE;
  622. fRet = FALSE;
  623. if ((hFile == NULL) || (hFile == INVALID_HANDLE_VALUE))
  624. {
  625. if (!(pwszCatalogFile))
  626. {
  627. goto IsCatInvalidParam;
  628. }
  629. if ((hFile = CreateFileU(pwszCatalogFile, GENERIC_READ, FILE_SHARE_READ, NULL,
  630. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
  631. NULL)) == INVALID_HANDLE_VALUE)
  632. {
  633. goto IsCatFileError;
  634. }
  635. fCloseFile = TRUE;
  636. }
  637. HANDLE hMappedFile;
  638. hMappedFile = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
  639. if (!(hMappedFile) || (hMappedFile == INVALID_HANDLE_VALUE))
  640. {
  641. goto CreateFileMapFailed;
  642. }
  643. pbFile = (BYTE *)MapViewOfFile(hMappedFile, FILE_MAP_READ, 0, 0, 0);
  644. CloseHandle(hMappedFile);
  645. if (!(pbFile))
  646. {
  647. goto MapViewFailed;
  648. }
  649. if (((cbFile = GetFileSize(hFile, NULL)) == 0xffffffff) ||
  650. (cbFile < 1))
  651. {
  652. goto FileSizeError;
  653. }
  654. if (pbFile[0] != (BYTE)0x30)
  655. {
  656. goto IsCatNotCatalog;
  657. }
  658. pCTLContext = (PCCTL_CONTEXT) CertCreateContext(
  659. CERT_STORE_CTL_CONTEXT,
  660. PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
  661. pbFile,
  662. cbFile,
  663. CERT_CREATE_CONTEXT_NOCOPY_FLAG |
  664. CERT_CREATE_CONTEXT_NO_HCRYPTMSG_FLAG |
  665. CERT_CREATE_CONTEXT_NO_ENTRY_FLAG,
  666. NULL // pCreatePara
  667. );
  668. if (pCTLContext)
  669. {
  670. if (pCTLContext->pCtlInfo->SubjectUsage.cUsageIdentifier)
  671. {
  672. if (strcmp(pCTLContext->pCtlInfo->SubjectUsage.rgpszUsageIdentifier[0],
  673. pszCatalogListUsageOID) == 0)
  674. {
  675. fRet = TRUE;
  676. goto CommonReturn;
  677. }
  678. }
  679. }
  680. goto IsCatNotCatalog;
  681. } __except(EXCEPTION_EXECUTE_HANDLER) {
  682. SetLastError(GetExceptionCode());
  683. goto ErrorReturn;
  684. }
  685. CommonReturn:
  686. if (pCTLContext)
  687. {
  688. CertFreeCTLContext(pCTLContext);
  689. }
  690. if (pbFile)
  691. {
  692. UnmapViewOfFile(pbFile);
  693. }
  694. if (fCloseFile)
  695. {
  696. CloseHandle(hFile);
  697. }
  698. return(fRet);
  699. ErrorReturn:
  700. fRet = FALSE;
  701. goto CommonReturn;
  702. TRACE_ERROR_EX(DBG_SS, IsCatNotCatalog);
  703. TRACE_ERROR_EX(DBG_SS, IsCatFileError);
  704. TRACE_ERROR_EX(DBG_SS, CreateFileMapFailed);
  705. TRACE_ERROR_EX(DBG_SS, MapViewFailed);
  706. SET_ERROR_VAR_EX(DBG_SS, IsCatInvalidParam, ERROR_INVALID_PARAMETER);
  707. SET_ERROR_VAR_EX(DBG_SS, FileSizeError, ERROR_INVALID_PARAMETER);
  708. }