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.

775 lines
28 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997-2002.
  5. //
  6. // File: StoreGPE.cpp
  7. //
  8. // Contents: Implementation of CCertStoreGPE
  9. //
  10. //----------------------------------------------------------------------------
  11. #include "stdafx.h"
  12. #include <gpedit.h>
  13. #include "cookie.h"
  14. #include "storegpe.h"
  15. #include "certifct.h"
  16. USE_HANDLE_MACROS("CERTMGR(storegpe.cpp)")
  17. #ifdef _DEBUG
  18. #ifndef ALPHA
  19. #define new DEBUG_NEW
  20. #endif
  21. #undef THIS_FILE
  22. static char THIS_FILE[] = __FILE__;
  23. #endif
  24. GUID g_guidExtension = { 0xb1be8d72, 0x6eac, 0x11d2, {0xa4, 0xea, 0x00, 0xc0, 0x4f, 0x79, 0xf8, 0x3a }};
  25. GUID g_guidRegExt = REGISTRY_EXTENSION_GUID;
  26. GUID g_guidSnapin = CLSID_CertificateManager;
  27. ///////////////////////////////////////////////////////////////////////////////
  28. ///////////////////////////////////////////////////////////////////////////////
  29. HRESULT CCertStoreGPE::Commit ()
  30. {
  31. _TRACE (1, L"Entering CCertStoreGPE::Commit - %s\n",
  32. (LPCWSTR) m_pcszStoreName);
  33. ASSERT (CERTMGR_LOG_STORE_GPE == m_objecttype);
  34. HRESULT hr = S_OK;
  35. if ( GetStoreType () == EFS_STORE && !m_fIsNullEFSPolicy )
  36. {
  37. if ( SUCCEEDED (hr) )
  38. hr = WriteEFSBlobToRegistry ();
  39. }
  40. if ( SUCCEEDED (hr) && m_bDirty )
  41. {
  42. hr = CCertStore::Commit ();
  43. ASSERT (SUCCEEDED (hr));
  44. ASSERT (m_pGPEInformation);
  45. if ( SUCCEEDED (hr) && m_pGPEInformation )
  46. {
  47. hr = m_pGPEInformation->PolicyChanged (
  48. m_fIsComputerType ? TRUE : FALSE,
  49. m_bAddInCallToPolicyChanged, &g_guidExtension, &g_guidSnapin );
  50. hr = m_pGPEInformation->PolicyChanged (
  51. m_fIsComputerType ? TRUE : FALSE,
  52. m_bAddInCallToPolicyChanged, &g_guidRegExt, &g_guidSnapin );
  53. ASSERT (SUCCEEDED (hr));
  54. }
  55. }
  56. _TRACE (-1, L"Leaving CCertStoreGPE::Commit - %s\n",
  57. (LPCWSTR) m_pcszStoreName);
  58. return hr;
  59. }
  60. CCertStoreGPE::CCertStoreGPE (
  61. DWORD dwFlags,
  62. LPCWSTR lpcszMachineName,
  63. LPCWSTR objectName,
  64. const CString & pcszLogStoreName,
  65. const CString & pcszPhysStoreName,
  66. IGPEInformation * pGPTInformation,
  67. const GUID& compDataGUID,
  68. IConsole* pConsole)
  69. : CCertStore (CERTMGR_LOG_STORE_GPE,
  70. CERT_STORE_PROV_SYSTEM, dwFlags, lpcszMachineName, objectName,
  71. pcszLogStoreName, pcszPhysStoreName,
  72. StoreNameToType (pcszLogStoreName),
  73. 0,
  74. pConsole),
  75. m_pGPEInformation (pGPTInformation),
  76. m_fIsNullEFSPolicy (true), // assume NULL policy until proven otherwise
  77. m_hGroupPolicyKey (0),
  78. m_bAddInCallToPolicyChanged (TRUE)
  79. {
  80. _TRACE (1, L"Entering CCertStoreGPE::CCertStoreGPE - %s\n",
  81. (LPCWSTR) pcszLogStoreName);
  82. ASSERT (CERTMGR_LOG_STORE_GPE == m_objecttype);
  83. ASSERT (m_pGPEInformation);
  84. if ( m_pGPEInformation )
  85. {
  86. m_pGPEInformation->AddRef ();
  87. if ( ::IsEqualGUID (compDataGUID, NODEID_User) )
  88. {
  89. m_fIsComputerType = false;
  90. m_dwFlags |= CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY;
  91. }
  92. else if ( ::IsEqualGUID (compDataGUID, NODEID_Machine) )
  93. {
  94. m_fIsComputerType = true;
  95. m_dwFlags |= CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY;
  96. }
  97. else
  98. ASSERT (0);
  99. }
  100. _TRACE (-1, L"Leaving CCertStoreGPE::CCertStoreGPE - %s\n",
  101. (LPCWSTR) pcszLogStoreName);
  102. }
  103. CCertStoreGPE::~CCertStoreGPE ()
  104. {
  105. _TRACE (1, L"Entering CCertStoreGPE::~CCertStoreGPE - %s\n",
  106. (LPCWSTR) m_pcszStoreName);;
  107. ASSERT (CERTMGR_LOG_STORE_GPE == m_objecttype);
  108. if ( m_hGroupPolicyKey )
  109. RegCloseKey (m_hGroupPolicyKey);
  110. if ( m_pGPEInformation )
  111. {
  112. m_pGPEInformation->Release ();
  113. m_pGPEInformation = 0;
  114. }
  115. CERT_CONTEXT_PSID_STRUCT* pCert = 0;
  116. while (!m_EFSCertList.IsEmpty () )
  117. {
  118. pCert = m_EFSCertList.RemoveHead ();
  119. ASSERT (pCert);
  120. if ( pCert )
  121. delete pCert;
  122. }
  123. _TRACE (-1, L"Leaving CCertStoreGPE::~CCertStoreGPE - %s\n",
  124. (LPCWSTR) m_pcszStoreName);
  125. }
  126. HCERTSTORE CCertStoreGPE::GetStoreHandle (BOOL bSilent /*= FALSE*/, HRESULT* phr /* = 0*/)
  127. {
  128. _TRACE (1, L"Entering CCertStoreGPE::GetStoreHandle - %s\n",
  129. (LPCWSTR) m_pcszStoreName);
  130. ASSERT (CERTMGR_LOG_STORE_GPE == m_objecttype);
  131. CERT_SYSTEM_STORE_RELOCATE_PARA RelocatePara;
  132. void* pvPara = 0;
  133. if ( !m_hCertStore )
  134. {
  135. DWORD dwErr = 0;
  136. if ( EFS_STORE == GetStoreType () && m_fIsNullEFSPolicy )
  137. {
  138. // Test to see if EFS key exists, if not, flag this as
  139. // having no EFS policy and return.
  140. HKEY hEFSKey = 0;
  141. // security review 2/27/2002 BryanWal ok
  142. LONG lResult = ::RegOpenKeyEx (GetGroupPolicyKey (), CERT_EFSBLOB_REGPATH, 0,
  143. KEY_READ, &hEFSKey);
  144. if ( ERROR_SUCCESS == lResult )
  145. {
  146. m_fIsNullEFSPolicy = false;
  147. ::RegCloseKey (hEFSKey);
  148. }
  149. else
  150. return 0;
  151. }
  152. RelocatePara.hKeyBase = GetGroupPolicyKey ();
  153. RelocatePara.pwszSystemStore = (LPCWSTR) m_pcszStoreName;
  154. pvPara = (void*) &RelocatePara;
  155. m_hCertStore = ::CertOpenStore (m_storeProvider,
  156. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, NULL,
  157. m_dwFlags | CERT_STORE_SET_LOCALIZED_NAME_FLAG | CERT_STORE_MAXIMUM_ALLOWED_FLAG,
  158. pvPara);
  159. if ( !m_hCertStore )
  160. {
  161. dwErr = GetLastError ();
  162. if ( phr )
  163. *phr = HRESULT_FROM_WIN32 (dwErr);
  164. m_hCertStore = ::CertOpenStore (m_storeProvider,
  165. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, NULL,
  166. m_dwFlags | CERT_STORE_READONLY_FLAG | CERT_STORE_SET_LOCALIZED_NAME_FLAG,
  167. pvPara);
  168. if ( m_hCertStore )
  169. m_bReadOnly = true;
  170. else
  171. {
  172. dwErr = GetLastError ();
  173. if ( phr )
  174. *phr = HRESULT_FROM_WIN32 (dwErr);
  175. _TRACE (0, L"CertOpenStore (%s) failed: 0x%x\n",
  176. (PCWSTR) m_pcszStoreName, dwErr);
  177. }
  178. }
  179. if ( !m_hCertStore && !m_bUnableToOpenMsgDisplayed && !bSilent &&
  180. (USERDS_STORE != GetStoreType ()) )
  181. {
  182. m_bUnableToOpenMsgDisplayed = true;
  183. CString caption;
  184. CString text;
  185. int iRetVal = 0;
  186. VERIFY (caption.LoadString (IDS_CERTIFICATE_MANAGER));
  187. text.FormatMessage (IDS_UNABLE_TO_OPEN_STORE, GetStoreName (),
  188. GetSystemMessage (dwErr));
  189. if ( m_pConsole )
  190. m_pConsole->MessageBox (text, caption, MB_OK | MB_ICONINFORMATION, &iRetVal);
  191. }
  192. }
  193. _TRACE (-1, L"Leaving CCertStoreGPE::GetStoreHandle - %s\n",
  194. (LPCWSTR) m_pcszStoreName);
  195. return m_hCertStore;
  196. }
  197. bool CCertStoreGPE::CanContain(CertificateManagerObjectType nodeType)
  198. {
  199. _TRACE (1, L"Entering CCertStoreGPE::CanContain - %s\n",
  200. (LPCWSTR) m_pcszStoreName);
  201. ASSERT (CERTMGR_LOG_STORE_GPE == m_objecttype);
  202. bool bCanContain = false;
  203. switch (nodeType)
  204. {
  205. case CERTMGR_CERTIFICATE:
  206. if ( ROOT_STORE == GetStoreType () ||
  207. EFS_STORE == GetStoreType () )
  208. {
  209. bCanContain = true;
  210. }
  211. break;
  212. case CERTMGR_CTL:
  213. if ( TRUST_STORE == GetStoreType () )
  214. {
  215. bCanContain = true;
  216. }
  217. break;
  218. default:
  219. break;
  220. }
  221. _TRACE (-1, L"Leaving CCertStoreGPE::CanContain - %s\n",
  222. (LPCWSTR) m_pcszStoreName);
  223. return bCanContain;
  224. }
  225. bool CCertStoreGPE::IsMachineStore()
  226. {
  227. _TRACE (0, L"Entering and leaving CCertStoreGPE::IsMachineStore - %s\n",
  228. (LPCWSTR) m_pcszStoreName);
  229. ASSERT (CERTMGR_LOG_STORE_GPE == m_objecttype);
  230. if (m_dwFlags & CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY)
  231. return true;
  232. else
  233. return false;
  234. }
  235. HKEY CCertStoreGPE::GetGroupPolicyKey()
  236. {
  237. _TRACE (1, L"Entering CCertStoreGPE::GetGroupPolicyKey - %s\n",
  238. (LPCWSTR) m_pcszStoreName);
  239. ASSERT (CERTMGR_LOG_STORE_GPE == m_objecttype);
  240. if ( !m_hGroupPolicyKey )
  241. {
  242. if ( m_fIsComputerType )
  243. {
  244. HRESULT hr = m_pGPEInformation->GetRegistryKey (GPO_SECTION_MACHINE,
  245. &m_hGroupPolicyKey);
  246. ASSERT (SUCCEEDED (hr));
  247. }
  248. else
  249. {
  250. HRESULT hr = m_pGPEInformation->GetRegistryKey (GPO_SECTION_USER,
  251. &m_hGroupPolicyKey);
  252. ASSERT (SUCCEEDED (hr));
  253. }
  254. }
  255. _TRACE (-1, L"Leaving CCertStoreGPE::GetGroupPolicyKey - %s\n",
  256. (LPCWSTR) m_pcszStoreName);
  257. return m_hGroupPolicyKey;
  258. }
  259. IGPEInformation * CCertStoreGPE::GetGPEInformation() const
  260. {
  261. _TRACE (0, L"Entering and leaving CCertStoreGPE::GetGPEInformation - %s\n",
  262. (LPCWSTR) m_pcszStoreName);
  263. ASSERT (CERTMGR_LOG_STORE_GPE == m_objecttype);
  264. return m_pGPEInformation;
  265. }
  266. HRESULT CCertStoreGPE::WriteEFSBlobToRegistry()
  267. {
  268. _TRACE (1, L"Entering CCertStoreGPE::WriteEFSBlobToRegistry - %s\n",
  269. (LPCWSTR) m_pcszStoreName);
  270. ASSERT (CERTMGR_LOG_STORE_GPE == m_objecttype);
  271. HRESULT hr = S_OK;
  272. if ( !m_fIsNullEFSPolicy )
  273. {
  274. HKEY hGroupPolicyKey = GetGroupPolicyKey ();
  275. if ( hGroupPolicyKey )
  276. {
  277. DWORD dwDisposition = 0;
  278. HKEY hKeyEFSBlob = 0;
  279. int nCertCnt = GetCertCount ();
  280. // security review 2/27/2002 BryanWal ok - reduce privilege requested
  281. LONG lResult = ::RegCreateKeyEx (hGroupPolicyKey, // handle of an open key
  282. CERT_EFSBLOB_REGPATH, // address of subkey name
  283. 0, // reserved
  284. L"", // address of class string
  285. REG_OPTION_NON_VOLATILE, // special options flag
  286. KEY_SET_VALUE, // desired security access
  287. NULL, // address of key security structure
  288. &hKeyEFSBlob, // address of buffer for opened handle
  289. &dwDisposition); // address of disposition value buffer
  290. ASSERT (lResult == ERROR_SUCCESS);
  291. if ( lResult == ERROR_SUCCESS )
  292. {
  293. try {
  294. PEFS_PUBLIC_KEY_INFO* pEFSPKI = new PEFS_PUBLIC_KEY_INFO[nCertCnt];
  295. DWORD* cbPKI = new DWORD[nCertCnt];
  296. PRECOVERY_KEY_1_1* pRecoveryKey = new PRECOVERY_KEY_1_1[nCertCnt];
  297. DWORD* cbRecoveryKey = new DWORD[nCertCnt];
  298. PRECOVERY_POLICY_1_1 pRecoveryPolicy = 0;
  299. DWORD cbRecoveryPolicy = 0;
  300. BYTE* pData = 0;
  301. DWORD cbData = 0;
  302. int nActualCertCnt = 0;
  303. PCCERT_CONTEXT pCertContext = 0;
  304. if ( !pEFSPKI || ! cbPKI || ! pRecoveryKey || !cbRecoveryKey )
  305. {
  306. ::RegCloseKey (hKeyEFSBlob);
  307. hr = E_OUTOFMEMORY;
  308. }
  309. else
  310. {
  311. // security review 2/27/2002 BryanWal ok
  312. ::ZeroMemory (pEFSPKI, nCertCnt*sizeof (PEFS_PUBLIC_KEY_INFO));
  313. ::ZeroMemory (cbPKI, nCertCnt*sizeof (DWORD));
  314. ::ZeroMemory (pRecoveryKey, nCertCnt*sizeof (PRECOVERY_KEY_1_1));
  315. ::ZeroMemory (cbRecoveryKey, nCertCnt*sizeof (DWORD));
  316. while ( 1 )
  317. {
  318. // Subsequent calls to CertEnumCertificatesInStore () free pCertContext. If
  319. // we must break prematurely out of this loop, we must CertFreeCertificateContext ()
  320. // explicitly on the last pCertContext
  321. pCertContext = EnumCertificates (pCertContext);
  322. if ( pCertContext )
  323. {
  324. hr = CreatePublicKeyInformationCertificate (
  325. GetPSIDFromCert (pCertContext),
  326. pCertContext->pbCertEncoded,
  327. pCertContext->cbCertEncoded,
  328. &pEFSPKI[nActualCertCnt],
  329. &cbPKI[nActualCertCnt]);
  330. if ( SUCCEEDED (hr) )
  331. {
  332. cbRecoveryKey[nActualCertCnt] = sizeof (ULONG) + cbPKI[nActualCertCnt];
  333. pRecoveryKey[nActualCertCnt] = (PRECOVERY_KEY_1_1)
  334. ::LocalAlloc (LPTR, cbRecoveryKey[nActualCertCnt]);
  335. if ( pRecoveryKey[nActualCertCnt] )
  336. {
  337. pRecoveryKey[nActualCertCnt]->TotalLength = cbRecoveryKey[nActualCertCnt];
  338. // security review 2/27/2002 BryanWal ok
  339. memcpy (&(pRecoveryKey[nActualCertCnt]->PublicKeyInfo),
  340. pEFSPKI[nActualCertCnt],
  341. cbPKI[nActualCertCnt]);
  342. }
  343. else
  344. {
  345. hr = E_OUTOFMEMORY;
  346. ::CertFreeCertificateContext (pCertContext);
  347. break;
  348. }
  349. }
  350. nActualCertCnt++;
  351. if ( nActualCertCnt > nCertCnt )
  352. {
  353. ASSERT (0);
  354. ::CertFreeCertificateContext (pCertContext);
  355. break;
  356. }
  357. }
  358. else
  359. break;
  360. }
  361. Close ();
  362. ASSERT (nActualCertCnt == nCertCnt);
  363. if ( SUCCEEDED (hr) )
  364. {
  365. cbRecoveryPolicy = sizeof (RECOVERY_POLICY_HEADER);
  366. for (int nIndex = 0; nIndex < nActualCertCnt; nIndex++)
  367. cbRecoveryPolicy += cbRecoveryKey[nIndex];
  368. pRecoveryPolicy = (PRECOVERY_POLICY_1_1) ::LocalAlloc (LPTR, cbRecoveryPolicy);
  369. if ( pRecoveryPolicy )
  370. {
  371. pRecoveryPolicy->RecoveryPolicyHeader.MajorRevision = EFS_RECOVERY_POLICY_MAJOR_REVISION_1;
  372. pRecoveryPolicy->RecoveryPolicyHeader.MinorRevision = EFS_RECOVERY_POLICY_MINOR_REVISION_1;
  373. pRecoveryPolicy->RecoveryPolicyHeader.RecoveryKeyCount = nActualCertCnt;
  374. // Build array of variable size recovery keys.
  375. BYTE* ptr = (BYTE*) pRecoveryPolicy->RecoveryKeyList;
  376. for (int nIndex = 0; nIndex < nActualCertCnt; nIndex++)
  377. {
  378. // security review 2/27/2002 BryanWal ok
  379. memcpy (ptr, pRecoveryKey[nIndex], cbRecoveryKey[nIndex]);
  380. ptr += cbRecoveryKey[nIndex];
  381. }
  382. }
  383. else
  384. {
  385. hr = E_OUTOFMEMORY;
  386. }
  387. if ( pRecoveryPolicy ) // otherwise, the value is set to 0
  388. {
  389. pData = (BYTE*) pRecoveryPolicy;
  390. cbData = cbRecoveryPolicy;
  391. }
  392. lResult = ::RegSetValueEx (hKeyEFSBlob, // handle of key to set value for
  393. CERT_EFSBLOB_VALUE_NAME, // address of value to set
  394. 0, // reserved
  395. REG_BINARY, // flag for value type
  396. pData, // address of value data
  397. cbData); // size of value data
  398. if ( lResult == ERROR_SUCCESS )
  399. {
  400. m_bDirty = true;
  401. }
  402. else
  403. DisplaySystemError (NULL, lResult);
  404. }
  405. ::RegCloseKey (hKeyEFSBlob);
  406. hKeyEFSBlob = 0;
  407. // Free all the allocated pointers in the arrays.
  408. for (int nIndex = 0; nIndex < nActualCertCnt; nIndex++)
  409. {
  410. if ( pEFSPKI[nIndex] )
  411. ::LocalFree (pEFSPKI[nIndex]);
  412. if ( pRecoveryKey[nIndex] )
  413. ::LocalFree (pRecoveryKey[nIndex]);
  414. }
  415. // Free the allocated arrays
  416. if ( pEFSPKI )
  417. delete [] pEFSPKI;
  418. if ( cbPKI )
  419. delete [] cbPKI;
  420. if ( cbRecoveryKey )
  421. delete [] cbRecoveryKey;
  422. if ( pRecoveryKey )
  423. delete [] pRecoveryKey;
  424. if ( pRecoveryPolicy )
  425. ::LocalFree (pRecoveryPolicy);
  426. }
  427. }
  428. catch (CMemoryException*)
  429. {
  430. if ( hKeyEFSBlob )
  431. ::RegCloseKey (hKeyEFSBlob);
  432. }
  433. }
  434. else
  435. {
  436. hr = HRESULT_FROM_WIN32 (lResult);
  437. DisplaySystemError (NULL, lResult);
  438. }
  439. if ( SUCCEEDED (hr) )
  440. m_bDirty = true;
  441. }
  442. }
  443. _TRACE (-1, L"Leaving CCertStoreGPE::WriteEFSBlobToRegistry - %s\n",
  444. (LPCWSTR) m_pcszStoreName);
  445. return hr;
  446. }
  447. #define POINTER_TO_OFFSET( Pointer, pBase ) (((PUCHAR)(Pointer)) - ((PUCHAR)(pBase)))
  448. HRESULT CCertStoreGPE::CreatePublicKeyInformationCertificate(
  449. IN PSID pUserSid OPTIONAL,
  450. PBYTE pbCert,
  451. DWORD cbCert,
  452. OUT PEFS_PUBLIC_KEY_INFO * PublicKeyInformation,
  453. DWORD* pcbPublicKeyInfo)
  454. {
  455. _TRACE (1, L"Entering CCertStoreGPE::CreatePublicKeyInformationCertificate - %s\n",
  456. (LPCWSTR) m_pcszStoreName);
  457. ASSERT (CERTMGR_LOG_STORE_GPE == m_objecttype);
  458. ASSERT (PublicKeyInformation && pcbPublicKeyInfo);
  459. ASSERT (pbCert);
  460. if ( !PublicKeyInformation || !pcbPublicKeyInfo || !pbCert)
  461. return E_POINTER;
  462. DWORD userSidLength = 0;
  463. PBYTE pBase = 0;
  464. if (pUserSid != NULL)
  465. {
  466. userSidLength = GetLengthSid (pUserSid);
  467. }
  468. DWORD publicKeyInformationLength = sizeof( EFS_PUBLIC_KEY_INFO ) + userSidLength + cbCert;
  469. //
  470. // Allocate and fill in the PublicKeyInformation structure
  471. //
  472. *PublicKeyInformation = (PEFS_PUBLIC_KEY_INFO) ::LocalAlloc (LPTR, publicKeyInformationLength);
  473. if ( !(*PublicKeyInformation) )
  474. {
  475. return ERROR_NOT_ENOUGH_MEMORY;
  476. }
  477. (*PublicKeyInformation)->Length = publicKeyInformationLength;
  478. (*PublicKeyInformation)->KeySourceTag = (ULONG)EfsCertificate;
  479. //
  480. // Copy the string and SID data to the end of the structure.
  481. //
  482. pBase = (PBYTE) *PublicKeyInformation;
  483. pBase = (PBYTE) pBase + sizeof (EFS_PUBLIC_KEY_INFO);
  484. if (pUserSid != NULL)
  485. {
  486. (*PublicKeyInformation)->PossibleKeyOwner = (ULONG)POINTER_TO_OFFSET( pBase, *PublicKeyInformation );
  487. // security review 2/27/2002 BryanWal ok
  488. ::CopySid( userSidLength, (PSID)pBase, pUserSid );
  489. }
  490. else
  491. {
  492. (*PublicKeyInformation)->PossibleKeyOwner = (ULONG)NULL;
  493. }
  494. pBase = ((PBYTE)pBase + userSidLength);
  495. (*PublicKeyInformation)->CertificateInfo.CertificateLength = cbCert;
  496. (*PublicKeyInformation)->CertificateInfo.Certificate = (ULONG)POINTER_TO_OFFSET( pBase, *PublicKeyInformation );
  497. // security review 2/27/2002 BryanWal ok
  498. memcpy (pBase, pbCert, cbCert );
  499. *pcbPublicKeyInfo = publicKeyInformationLength;
  500. _TRACE (-1, L"Leaving CCertStoreGPE::CreatePublicKeyInformationCertificate - %s\n",
  501. (LPCWSTR) m_pcszStoreName);
  502. return 0;
  503. }
  504. void CCertStoreGPE::AddCertToList(PCCERT_CONTEXT pCertContext, PSID userPSID)
  505. {
  506. _TRACE (1, L"Entering CCertStoreGPE::AddCertToList - %s\n",
  507. (LPCWSTR) m_pcszStoreName);
  508. ASSERT (CERTMGR_LOG_STORE_GPE == m_objecttype);
  509. if ( pCertContext && userPSID )
  510. {
  511. CERT_CONTEXT_PSID_STRUCT* pCert = new CERT_CONTEXT_PSID_STRUCT (
  512. pCertContext, userPSID);
  513. if ( pCert )
  514. {
  515. m_EFSCertList.AddTail (pCert);
  516. m_bDirty = true;
  517. }
  518. }
  519. _TRACE (-1, L"Leaving CCertStoreGPE::AddCertToList - %s\n",
  520. (LPCWSTR) m_pcszStoreName);
  521. }
  522. PSID CCertStoreGPE::GetPSIDFromCert (PCCERT_CONTEXT pCertContext)
  523. {
  524. _TRACE (1, L"Entering CCertStoreGPE::GetPSIDFromCert - %s\n",
  525. (LPCWSTR) m_pcszStoreName);
  526. ASSERT (CERTMGR_LOG_STORE_GPE == m_objecttype);
  527. PSID pSID = 0;
  528. CERT_CONTEXT_PSID_STRUCT* pCert = 0;
  529. POSITION curPos = 0;
  530. for (POSITION nextPos = m_EFSCertList.GetHeadPosition (); nextPos; )
  531. {
  532. curPos = nextPos;
  533. pCert = m_EFSCertList.GetNext (nextPos);
  534. if ( CertCompareCertificate (
  535. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  536. pCert->m_pCertContext->pCertInfo,
  537. pCertContext->pCertInfo) )
  538. {
  539. pSID = pCert->m_psid;
  540. break;
  541. }
  542. }
  543. _TRACE (-1, L"Leaving CCertStoreGPE::GetPSIDFromCert - %s\n",
  544. (LPCWSTR) m_pcszStoreName);
  545. return pSID;
  546. }
  547. void CCertStoreGPE::FinalCommit()
  548. {
  549. _TRACE (1, L"Entering CCertStoreGPE::FinalCommit - %s\n",
  550. (LPCWSTR) m_pcszStoreName);
  551. ASSERT (CERTMGR_LOG_STORE_GPE == m_objecttype);
  552. // Called only from destructor
  553. // Cannot commit here for GPT: GPT has already freed all pertinent data
  554. _TRACE (-1, L"Leaving CCertStoreGPE::FinalCommit - %s\n",
  555. (LPCWSTR) m_pcszStoreName);
  556. }
  557. bool CCertStoreGPE::IsNullEFSPolicy()
  558. {
  559. _TRACE (1, L"Entering CCertStoreGPE::IsNullEFSPolicy - %s\n",
  560. (LPCWSTR) m_pcszStoreName);
  561. GetStoreHandle (); // to initialize
  562. Close ();
  563. _TRACE (-1, L"Leaving CCertStoreGPE::IsNullEFSPolicy - %s\n",
  564. (LPCWSTR) m_pcszStoreName);
  565. return m_fIsNullEFSPolicy;
  566. }
  567. void CCertStoreGPE::AllowEmptyEFSPolicy()
  568. {
  569. _TRACE (1, L"Entering CCertStoreGPE::AllowEmptyEFSPolicy - %s\n",
  570. (LPCWSTR) m_pcszStoreName);
  571. m_fIsNullEFSPolicy = false;
  572. _TRACE (-1, L"Leaving CCertStoreGPE::AllowEmptyEFSPolicy - %s\n",
  573. (LPCWSTR) m_pcszStoreName);
  574. }
  575. HRESULT CCertStoreGPE::AddCertificateContext(PCCERT_CONTEXT pContext, LPCONSOLE pConsole, bool bDeletePrivateKey)
  576. {
  577. _TRACE (1, L"Entering CCertStoreGPE::AddCertificateContext - %s\n",
  578. (LPCWSTR) m_pcszStoreName);
  579. HRESULT hr = S_OK;
  580. AllowEmptyEFSPolicy ();
  581. hr = CCertStore::AddCertificateContext (pContext, pConsole, bDeletePrivateKey);
  582. _TRACE (-1, L"Leaving CCertStoreGPE::AddCertificateContext - %s\n",
  583. (LPCWSTR) m_pcszStoreName);
  584. return hr;
  585. }
  586. HRESULT CCertStoreGPE::DeleteEFSPolicy(bool bCommitChanges)
  587. {
  588. _TRACE (1, L"Entering CCertStoreGPE::DeleteEFSPolicy - %s\n",
  589. (LPCWSTR) m_pcszStoreName);
  590. ASSERT (EFS_STORE == GetStoreType ());
  591. if ( EFS_STORE == GetStoreType () )
  592. {
  593. // If the store is open, close it first
  594. if ( m_hCertStore )
  595. {
  596. CERT_CONTEXT_PSID_STRUCT* pCert = 0;
  597. while (!m_EFSCertList.IsEmpty () )
  598. {
  599. pCert = m_EFSCertList.RemoveHead ();
  600. ASSERT (pCert);
  601. if ( pCert )
  602. delete pCert;
  603. }
  604. VERIFY (::CertCloseStore (m_hCertStore, CERT_CLOSE_STORE_FORCE_FLAG)); //CERT_CLOSE_STORE_CHECK_FLAG);
  605. m_hCertStore = 0;
  606. }
  607. LRESULT lResult = ::RegDelnode (GetGroupPolicyKey (), CERT_EFSBLOB_REGPATH);
  608. if ( ERROR_SUCCESS == lResult )
  609. {
  610. m_fIsNullEFSPolicy = true;
  611. m_bDirty = true;
  612. if ( bCommitChanges )
  613. {
  614. m_bAddInCallToPolicyChanged = FALSE; // delete policy
  615. Commit ();
  616. m_bAddInCallToPolicyChanged = TRUE;
  617. }
  618. }
  619. else
  620. DisplaySystemError (NULL, (DWORD)lResult);
  621. }
  622. _TRACE (-1, L"Leaving CCertStoreGPE::DeleteEFSPolicy - %s\n",
  623. (LPCWSTR) m_pcszStoreName);
  624. return S_OK;
  625. }
  626. HRESULT CCertStoreGPE::PolicyChanged()
  627. {
  628. _TRACE (1, L"Entering CCertStoreGPE::PolicyChanged - %s\n",
  629. (LPCWSTR) m_pcszStoreName);
  630. HRESULT hr = E_FAIL;
  631. if ( m_pGPEInformation )
  632. {
  633. hr = m_pGPEInformation->PolicyChanged (
  634. m_fIsComputerType ? TRUE : FALSE,
  635. m_bAddInCallToPolicyChanged, &g_guidExtension, &g_guidSnapin);
  636. hr = m_pGPEInformation->PolicyChanged (
  637. m_fIsComputerType ? TRUE : FALSE,
  638. m_bAddInCallToPolicyChanged, &g_guidRegExt, &g_guidSnapin);
  639. }
  640. _TRACE (-1, L"Leaving CCertStoreGPE::PolicyChanged - %s\n",
  641. (LPCWSTR) m_pcszStoreName);
  642. return hr;
  643. }
  644. PCCERT_CONTEXT CCertStoreGPE::EnumCertificates (PCCERT_CONTEXT pPrevCertContext)
  645. {
  646. PCCERT_CONTEXT pCertContext = CCertStore::EnumCertificates (pPrevCertContext);
  647. if ( pCertContext )
  648. m_fIsNullEFSPolicy = false;
  649. return pCertContext;
  650. }
  651. CERT_CONTEXT_PSID_STRUCT::CERT_CONTEXT_PSID_STRUCT (PCCERT_CONTEXT pCertContext, PSID psid) :
  652. m_pCertContext (0),
  653. m_psid (0)
  654. {
  655. if ( pCertContext && psid )
  656. {
  657. m_pCertContext = CertDuplicateCertificateContext (pCertContext);
  658. DWORD dwSidSize = ::GetLengthSid (psid);
  659. if ( dwSidSize > 0 )
  660. {
  661. m_psid = new BYTE[dwSidSize];
  662. if ( m_psid )
  663. {
  664. // security review 2/27/2002 BryanWal ok
  665. ::ZeroMemory (m_psid, dwSidSize);
  666. if ( !::CopySid (dwSidSize, m_psid, psid) )
  667. {
  668. ASSERT (0);
  669. delete [] m_psid;
  670. m_psid = 0;
  671. }
  672. }
  673. }
  674. }
  675. }
  676. CERT_CONTEXT_PSID_STRUCT::~CERT_CONTEXT_PSID_STRUCT ()
  677. {
  678. if ( m_pCertContext )
  679. ::CertFreeCertificateContext (m_pCertContext);
  680. if ( m_psid )
  681. delete [] m_psid;
  682. }