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.

1217 lines
36 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows NT Security
  4. // Copyright (C) Microsoft Corporation, 1997 - 1999
  5. //
  6. // File: initpki.cpp
  7. //
  8. // Contents: migrates Bob Store to SPC store and adds root certificates
  9. //
  10. // History: 03-Jun-97 kirtd Created
  11. //
  12. //----------------------------------------------------------------------------
  13. #include "global.hxx"
  14. #include "cryptreg.h"
  15. #include "..\mscat32\mscatprv.h"
  16. HMODULE hModule = NULL;
  17. //////////////////////////////////////////////////////////////////
  18. #define INITPKI_HRESULT_FROM_WIN32(a) ((a >= 0x80000000) ? a : HRESULT_FROM_WIN32(a))
  19. #define SHA1_HASH_LENGTH 20
  20. #define wsz_ROOT_STORE L"Root"
  21. #define wsz_TRUST_STORE L"Trust"
  22. #define wsz_CA_STORE L"CA"
  23. #define wsz_TRUST_PUB_STORE L"TrustedPublisher"
  24. #define wsz_DISALLOWED_STORE L"Disallowed"
  25. static LPCWSTR rgpwszPredefinedEnterpriseStore[] = {
  26. wsz_ROOT_STORE,
  27. wsz_TRUST_STORE,
  28. wsz_CA_STORE,
  29. wsz_TRUST_PUB_STORE,
  30. wsz_DISALLOWED_STORE
  31. };
  32. #define NUM_PREDEFINED_ENTERPRISE_STORE \
  33. (sizeof(rgpwszPredefinedEnterpriseStore) / \
  34. sizeof(rgpwszPredefinedEnterpriseStore[0]))
  35. void RegisterEnterpriseStores()
  36. {
  37. DWORD i;
  38. for (i = 0; i < NUM_PREDEFINED_ENTERPRISE_STORE; i++) {
  39. CertRegisterSystemStore(
  40. rgpwszPredefinedEnterpriseStore[i],
  41. CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE,
  42. NULL, // pSystemStoreInfo
  43. NULL // pvReserved
  44. );
  45. }
  46. }
  47. void RemoveCert(HCERTSTORE hStore, BYTE *pThumbPrint)
  48. {
  49. PCERT_CONTEXT pCertContext;
  50. CRYPT_HASH_BLOB CryptHashBlob;
  51. CryptHashBlob.cbData = SHA1_HASH_LENGTH;
  52. CryptHashBlob.pbData = pThumbPrint;
  53. pCertContext = (PCERT_CONTEXT)CertFindCertificateInStore( hStore,
  54. X509_ASN_ENCODING,
  55. 0,
  56. CERT_FIND_SHA1_HASH,
  57. &CryptHashBlob,
  58. NULL);
  59. if (pCertContext)
  60. {
  61. CertDeleteCertificateFromStore(pCertContext);
  62. }
  63. }
  64. //
  65. // if byte 0 is null, make sure to change while loop below!
  66. //
  67. BYTE CertRemoveList[][SHA1_HASH_LENGTH] =
  68. {
  69. { 0x4B, 0x33, 0x8D, 0xCD, 0x50, 0x18, 0x10, 0xB9, 0x36, 0xA0,
  70. 0x63, 0x61, 0x4C, 0x3C, 0xDD, 0x3F, 0xC2, 0xC4, 0x88, 0x55 }, // GTE Glue - '96
  71. { 0x56, 0xB0, 0x65, 0xA7, 0x4B, 0xDC, 0xE3, 0x7C, 0x96, 0xD3,
  72. 0xBA, 0x69, 0x81, 0x08, 0x02, 0xD5, 0x87, 0x03, 0xC0, 0xBD }, // Verisign Comm Glue - '96
  73. { 0x13, 0x39, 0x72, 0xAA, 0x97, 0xD3, 0x65, 0xFB, 0x6A, 0x1D,
  74. 0x47, 0xA5, 0xC7, 0x7A, 0x5C, 0x03, 0x94, 0xBD, 0xB9, 0xED }, // Verisign Indv Glue - '96
  75. { 0x69, 0xD0, 0x4F, 0xFB, 0x62, 0xE1, 0xC9, 0xAE, 0x30, 0x76,
  76. 0x99, 0x2A, 0xE7, 0x46, 0xFD, 0x69, 0x08, 0x3A, 0xBD, 0xE9 }, // MS Root cert - '96
  77. { 0xA7, 0xD7, 0xD5, 0xFD, 0xBB, 0x26, 0xB4, 0x10, 0xC1, 0xD6,
  78. 0x7A, 0xFB, 0xF5, 0xC9, 0x05, 0x39, 0x42, 0xDE, 0xE0, 0xEF }, // MS SGC Root Authority - '99
  79. // { 0xCC, 0x7E, 0xD0, 0x77, 0xF0, 0xF2, 0x92, 0x59, 0x5A, 0x81,
  80. // 0x66, 0xB0, 0x17, 0x09, 0xE2, 0x0C, 0x08, 0x84, 0xA5, 0xF8 }, // verisign "Class1" - '97
  81. //
  82. // { 0xD4, 0x73, 0x5D, 0x8A, 0x9A, 0xE5, 0xBC, 0x4B, 0x0A, 0x0D,
  83. // 0xC2, 0x70, 0xD6, 0xA6, 0x25, 0x38, 0xA5, 0x87, 0xD3, 0x2F }, // verisign "timestamp" - '97
  84. //
  85. // { 0x68, 0x8B, 0x6E, 0xB8, 0x07, 0xE8, 0xED, 0xA5, 0xC7, 0xB1,
  86. // 0x7C, 0x43, 0x93, 0xD0, 0x79, 0x5F, 0x0F, 0xAE, 0x15, 0x5F }, // verisign "commercial" - '97
  87. //
  88. // { 0xB1, 0x9D, 0xD0, 0x96, 0xDC, 0xD4, 0xE3, 0xE0, 0xFD, 0x67,
  89. // 0x68, 0x85, 0x50, 0x5A, 0x67, 0x2C, 0x43, 0x8D, 0x4E, 0x9C }, // verisign "individual" - '97
  90. // Certiposte Classe A Personne
  91. { 0xEB, 0xBC, 0x0E, 0x2D, 0x02, 0x0C, 0xA6, 0x9B, 0x22, 0x2C,
  92. 0x2B, 0xFF, 0xD2, 0x03, 0xCB, 0x8B, 0xF5, 0xA8, 0x27, 0x66 },
  93. // Certiposte Serveur
  94. { 0x28, 0x4F, 0x55, 0xC4, 0x1A, 0x1A, 0x7A, 0x3F, 0x83, 0x28,
  95. 0xD4, 0xC2, 0x62, 0xFB, 0x37, 0x6E, 0xD6, 0x09, 0x6F, 0x24 },
  96. // ViaCode Certification Authority
  97. {0xB5, 0xD3, 0x03, 0xBF, 0x86, 0x82, 0xE1, 0x52, 0x91, 0x9D,
  98. 0x83, 0xF1, 0x84, 0xED, 0x05, 0xF1, 0xDC, 0xE5, 0x37, 0x0C },
  99. // Swisskey Root CA
  100. { 0x13, 0x31, 0xF4, 0x8A, 0x5D, 0xA8, 0xE0, 0x1D, 0xAA, 0xCA,
  101. 0x1B, 0xB0, 0xC1, 0x70, 0x44, 0xAC, 0xFE, 0xF7, 0x55, 0xBB },
  102. // CN=Microsoft Windows Hardware Compatibility,
  103. // OU=Microsoft Corporation,
  104. // OU=Microsoft Windows Hardware Compatibility Intermediate CA,
  105. // OU=Copyright (c) 1997 Microsoft Corp.
  106. //
  107. // The one without a basic constraints extension
  108. { 0xBA, 0x9E, 0x3C, 0x32, 0x56, 0x2A, 0x67, 0x12, 0x8C, 0xAA,
  109. 0xBD, 0x4A, 0xB0, 0xC5, 0x00, 0xBE, 0xE1, 0xD0, 0xC2, 0x56 },
  110. { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  111. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } // term
  112. };
  113. //+---------------------------------------------------------------------------
  114. //
  115. // Function: PurgeExpiringCertsFromStores
  116. //
  117. // Synopsis: blech!
  118. //
  119. //----------------------------------------------------------------------------
  120. HRESULT PurgeExpiringCertsFromStores ()
  121. {
  122. DWORD cRemove;
  123. DWORD cStores;
  124. HCERTSTORE hStore = NULL;
  125. HKEY hKey = NULL;
  126. char *pszStores[] = { "SPC", "ROOT", "CU_ROOT", "AUTHROOT", "CA", NULL };
  127. //
  128. // HACKHACK! no crypt32 UI about the root store.
  129. //
  130. if (RegCreateHKCUKeyExU(HKEY_CURRENT_USER, ROOT_STORE_REGPATH,
  131. 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hKey, NULL) != ERROR_SUCCESS)
  132. {
  133. hKey = NULL;
  134. }
  135. cStores = 0;
  136. while (pszStores[cStores])
  137. {
  138. if (strcmp(pszStores[cStores], "CU_ROOT") == 0)
  139. {
  140. if (hKey)
  141. hStore = CertOpenStore(CERT_STORE_PROV_REG, 0, NULL, 0, (LPVOID)hKey);
  142. else
  143. hStore = NULL;
  144. }
  145. else
  146. {
  147. hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, NULL,
  148. CERT_SYSTEM_STORE_LOCAL_MACHINE |
  149. CERT_STORE_NO_CRYPT_RELEASE_FLAG,
  150. pszStores[cStores]);
  151. }
  152. if (hStore)
  153. {
  154. cRemove = 0;
  155. while (CertRemoveList[cRemove][0] != 0x00)
  156. {
  157. if (hStore)
  158. {
  159. RemoveCert(hStore, &CertRemoveList[cRemove][0]);
  160. }
  161. cRemove++;
  162. }
  163. CertCloseStore(hStore, 0);
  164. }
  165. cStores++;
  166. }
  167. if (hKey)
  168. RegCloseKey(hKey);
  169. return( S_OK );
  170. }
  171. PCCERT_CONTEXT FindCertificateInOtherStore(
  172. IN HCERTSTORE hOtherStore,
  173. IN PCCERT_CONTEXT pCert
  174. )
  175. {
  176. BYTE rgbHash[SHA1_HASH_LENGTH];
  177. CRYPT_DATA_BLOB HashBlob;
  178. HashBlob.pbData = rgbHash;
  179. HashBlob.cbData = SHA1_HASH_LENGTH;
  180. if (!CertGetCertificateContextProperty(
  181. pCert,
  182. CERT_SHA1_HASH_PROP_ID,
  183. rgbHash,
  184. &HashBlob.cbData
  185. ) || SHA1_HASH_LENGTH != HashBlob.cbData)
  186. return NULL;
  187. return CertFindCertificateInStore(
  188. hOtherStore,
  189. 0, // dwCertEncodingType
  190. 0, // dwFindFlags
  191. CERT_FIND_SHA1_HASH,
  192. (const void *) &HashBlob,
  193. NULL //pPrevCertContext
  194. );
  195. }
  196. BOOL IsCertificateInOtherStore(
  197. IN HCERTSTORE hOtherStore,
  198. IN PCCERT_CONTEXT pCert
  199. )
  200. {
  201. PCCERT_CONTEXT pOtherCert;
  202. if (pOtherCert = FindCertificateInOtherStore(hOtherStore, pCert)) {
  203. CertFreeCertificateContext(pOtherCert);
  204. return TRUE;
  205. } else
  206. return FALSE;
  207. }
  208. void DeleteCertificateFromOtherStore(
  209. IN HCERTSTORE hOtherStore,
  210. IN PCCERT_CONTEXT pCert
  211. )
  212. {
  213. PCCERT_CONTEXT pOtherCert;
  214. if (pOtherCert = FindCertificateInOtherStore(hOtherStore, pCert))
  215. CertDeleteCertificateFromStore(pOtherCert);
  216. }
  217. //+-------------------------------------------------------------------------
  218. // Read a SignedData message consisting of certificates and
  219. // CRLs from memory and copy to the specified cert store.
  220. //
  221. // Except for the SPC being loaded from memory, identical to SpcReadSpcFile.
  222. //
  223. // For hLMStore != NULL: if the certificate or CRL already exists in the
  224. // LocalMachine store don't add it. Also if it exists in hCertstore,
  225. // delete it.
  226. //--------------------------------------------------------------------------
  227. HRESULT
  228. SpcReadSpcFromMemory(
  229. IN BYTE *pbData,
  230. IN DWORD cbData,
  231. IN HCERTSTORE hCertStore,
  232. IN DWORD dwMsgAndCertEncodingType,
  233. IN DWORD dwFlags,
  234. IN OPTIONAL HCERTSTORE hLMStore
  235. )
  236. {
  237. HRESULT hr = S_OK;
  238. HCERTSTORE hSpcStore = NULL;
  239. CRYPT_DATA_BLOB sSpcBlob;
  240. HCRYPTPROV hCryptProv = NULL;
  241. PCCERT_CONTEXT pCert = NULL;
  242. PCCRL_CONTEXT pCrl = NULL;
  243. if (!(hCertStore))
  244. {
  245. goto InvalidArg;
  246. }
  247. // Set the blob data.
  248. sSpcBlob.pbData = pbData;
  249. sSpcBlob.cbData = cbData;
  250. // Open up the spc store
  251. hSpcStore = CertOpenStore(CERT_STORE_PROV_SERIALIZED, //CERT_STORE_PROV_PKCS7,
  252. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  253. hCryptProv,
  254. CERT_STORE_NO_CRYPT_RELEASE_FLAG,
  255. &sSpcBlob);
  256. if (!hSpcStore)
  257. {
  258. goto CertStoreError;
  259. }
  260. // Copy in the certificates from the caller.
  261. while (pCert = CertEnumCertificatesInStore(hSpcStore, pCert))
  262. {
  263. if (hLMStore && IsCertificateInOtherStore(hLMStore, pCert))
  264. // Certificate exists in LocalMachine. Delete it from
  265. // CurrentUser if it already exists there.
  266. DeleteCertificateFromOtherStore(hCertStore, pCert);
  267. else
  268. CertAddCertificateContextToStore(hCertStore,
  269. pCert,
  270. CERT_STORE_ADD_REPLACE_EXISTING,
  271. NULL);
  272. }
  273. while (pCrl = CertEnumCRLsInStore(hSpcStore, pCrl))
  274. {
  275. CertAddCRLContextToStore(hCertStore,
  276. pCrl,
  277. CERT_STORE_ADD_NEWER,
  278. NULL);
  279. if (hLMStore) {
  280. // Check if newer or same CRL exists in the hLMStore
  281. PCCRL_CONTEXT pLMCrl;
  282. pLMCrl = CertFindCRLInStore(
  283. hLMStore,
  284. pCrl->dwCertEncodingType,
  285. 0, // dwFindFlags
  286. CRL_FIND_EXISTING,
  287. (const void *) pCrl,
  288. NULL // pPrevCrlContext
  289. );
  290. if (NULL != pLMCrl) {
  291. PCCRL_CONTEXT pCUCrl;
  292. pCUCrl = CertFindCRLInStore(
  293. hCertStore,
  294. pCrl->dwCertEncodingType,
  295. 0, // dwFindFlags
  296. CRL_FIND_EXISTING,
  297. (const void *) pCrl,
  298. NULL // pPrevCrlContext
  299. );
  300. if (NULL != pCUCrl) {
  301. if (0 <= CompareFileTime(
  302. &pLMCrl->pCrlInfo->ThisUpdate,
  303. &pCUCrl->pCrlInfo->ThisUpdate
  304. ))
  305. CertDeleteCRLFromStore(pCUCrl);
  306. else
  307. CertFreeCRLContext(pCUCrl);
  308. }
  309. CertFreeCRLContext(pLMCrl);
  310. }
  311. }
  312. }
  313. CommonReturn:
  314. if (hSpcStore)
  315. {
  316. CertCloseStore(hSpcStore, 0);
  317. }
  318. return(hr);
  319. ErrorReturn:
  320. SetLastError((DWORD)hr);
  321. goto CommonReturn;
  322. SET_HRESULT_EX(DBG_SS, InvalidArg, E_INVALIDARG);
  323. SET_HRESULT_EX(DBG_SS, CertStoreError, GetLastError());
  324. }
  325. // For nonNULL pszLMStoreName, doesn't add certificates if already in
  326. // pszLMStoreName store.
  327. HRESULT AddCertificates2(
  328. IN LPCSTR pszStoreName,
  329. IN OPTIONAL LPCSTR pszLMStoreName,
  330. IN DWORD dwOpenStoreFlags,
  331. IN LPCSTR pszResourceName,
  332. IN LPCSTR pszResourceType
  333. )
  334. {
  335. HRESULT hr = S_OK;
  336. HCERTSTORE hCertStore = NULL;
  337. HCERTSTORE hLMStore = NULL;
  338. LPBYTE pb = NULL;
  339. DWORD cb;
  340. HRSRC hrsrc;
  341. hCertStore = CertOpenStore(
  342. CERT_STORE_PROV_SYSTEM_REGISTRY_A,
  343. 0, // dwEncodingType
  344. NULL, // hCryptProv
  345. dwOpenStoreFlags |
  346. CERT_SYSTEM_STORE_UNPROTECTED_FLAG,
  347. (const void *) pszStoreName
  348. );
  349. if (!(hCertStore))
  350. {
  351. return(GetLastError());
  352. }
  353. if (NULL != pszLMStoreName)
  354. {
  355. hLMStore = CertOpenStore(
  356. CERT_STORE_PROV_SYSTEM_REGISTRY_A,
  357. 0, // dwEncodingType
  358. NULL, // hCryptProv
  359. CERT_SYSTEM_STORE_LOCAL_MACHINE |
  360. CERT_STORE_READONLY_FLAG |
  361. CERT_SYSTEM_STORE_UNPROTECTED_FLAG,
  362. (const void *) pszLMStoreName
  363. );
  364. }
  365. hrsrc = FindResourceA(hModule, pszResourceName, pszResourceType);
  366. if ( hrsrc != NULL )
  367. {
  368. HGLOBAL hglobRes;
  369. hglobRes = LoadResource(hModule, hrsrc);
  370. if ( hglobRes != NULL )
  371. {
  372. ULONG cbRes;
  373. BYTE* pbRes;
  374. cbRes = SizeofResource(hModule, hrsrc);
  375. pbRes = (BYTE *)LockResource(hglobRes);
  376. hr = SpcReadSpcFromMemory( pbRes,
  377. cbRes,
  378. hCertStore,
  379. PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
  380. 0,
  381. hLMStore);
  382. UnlockResource(hglobRes);
  383. FreeResource(hglobRes);
  384. }
  385. else
  386. {
  387. hr = HRESULT_FROM_WIN32(GetLastError());
  388. }
  389. }
  390. else
  391. {
  392. hr = HRESULT_FROM_WIN32(GetLastError());
  393. }
  394. if ( hCertStore != NULL )
  395. {
  396. CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
  397. }
  398. if ( hLMStore != NULL )
  399. {
  400. CertCloseStore(hLMStore, CERT_CLOSE_STORE_FORCE_FLAG);
  401. }
  402. return( hr );
  403. }
  404. // For non-LocalMachine store, doesn't add certificates if already in
  405. // corresponding LocalMachine store.
  406. HRESULT AddCertificates(
  407. IN LPCSTR pszStoreName,
  408. IN DWORD dwOpenStoreFlags,
  409. IN LPCSTR pszResourceName,
  410. IN LPCSTR pszResourceType
  411. )
  412. {
  413. LPCSTR pszLMStoreName;
  414. if (CERT_SYSTEM_STORE_LOCAL_MACHINE !=
  415. (dwOpenStoreFlags & CERT_SYSTEM_STORE_LOCATION_MASK))
  416. pszLMStoreName = pszStoreName;
  417. else
  418. pszLMStoreName = NULL;
  419. return AddCertificates2(
  420. pszStoreName,
  421. pszLMStoreName,
  422. dwOpenStoreFlags,
  423. pszResourceName,
  424. pszResourceType
  425. );
  426. }
  427. HRESULT AddCurrentUserCACertificates()
  428. {
  429. return AddCertificates(
  430. "CA",
  431. CERT_SYSTEM_STORE_CURRENT_USER,
  432. MAKEINTRESOURCE(IDR_CAS),
  433. "CAS"
  434. );
  435. }
  436. HRESULT AddLocalMachineCACertificates()
  437. {
  438. return AddCertificates(
  439. "CA",
  440. CERT_SYSTEM_STORE_LOCAL_MACHINE,
  441. MAKEINTRESOURCE(IDR_CAS),
  442. "CAS"
  443. );
  444. }
  445. HRESULT AddCurrentUserDisallowedCertificates()
  446. {
  447. return AddCertificates(
  448. "Disallowed",
  449. CERT_SYSTEM_STORE_CURRENT_USER,
  450. MAKEINTRESOURCE(IDR_DISALLOW),
  451. "DISALLOW"
  452. );
  453. }
  454. HRESULT AddLocalMachineDisallowedCertificates()
  455. {
  456. return AddCertificates(
  457. "Disallowed",
  458. CERT_SYSTEM_STORE_LOCAL_MACHINE,
  459. MAKEINTRESOURCE(IDR_DISALLOW),
  460. "DISALLOW"
  461. );
  462. }
  463. HRESULT AddCurrentUserRootCertificates()
  464. {
  465. HRESULT hr;
  466. HRESULT hr2;
  467. hr = AddCertificates(
  468. "Root",
  469. CERT_SYSTEM_STORE_CURRENT_USER,
  470. MAKEINTRESOURCE(IDR_ROOTS),
  471. "ROOTS"
  472. );
  473. hr2 = AddCertificates2(
  474. "Root",
  475. "AuthRoot", // check if already in LM AuthRoot store
  476. CERT_SYSTEM_STORE_CURRENT_USER,
  477. MAKEINTRESOURCE(IDR_AUTHROOTS),
  478. "AUTHROOTS"
  479. );
  480. if (hr == ERROR_SUCCESS)
  481. hr = hr2;
  482. return hr;
  483. }
  484. HRESULT AddLocalMachineRootCertificates()
  485. {
  486. HRESULT hr;
  487. HRESULT hr2;
  488. HRESULT hr3;
  489. HRESULT hr4;
  490. hr = AddCertificates(
  491. "AuthRoot",
  492. CERT_SYSTEM_STORE_LOCAL_MACHINE,
  493. MAKEINTRESOURCE(IDR_AUTHROOTS),
  494. "AUTHROOTS"
  495. );
  496. // Remove all the AuthRoots from the "Root" store
  497. hr2 = AddCertificates2(
  498. "Root",
  499. "AuthRoot", // check if already in LM AuthRoot store
  500. CERT_SYSTEM_STORE_LOCAL_MACHINE,
  501. MAKEINTRESOURCE(IDR_AUTHROOTS),
  502. "AUTHROOTS"
  503. );
  504. hr3 = AddCertificates(
  505. "Root",
  506. CERT_SYSTEM_STORE_LOCAL_MACHINE,
  507. MAKEINTRESOURCE(IDR_ROOTS),
  508. "ROOTS"
  509. );
  510. // Remove all the Roots from the "AuthRoot" store
  511. hr4 = AddCertificates2(
  512. "AuthRoot",
  513. "Root", // check if already in LM Root store
  514. CERT_SYSTEM_STORE_LOCAL_MACHINE,
  515. MAKEINTRESOURCE(IDR_ROOTS),
  516. "ROOTS"
  517. );
  518. if (hr == ERROR_SUCCESS)
  519. hr = hr2;
  520. if (hr == ERROR_SUCCESS)
  521. hr = hr3;
  522. if (hr == ERROR_SUCCESS)
  523. hr = hr4;
  524. return hr;
  525. }
  526. void CreateKey(
  527. IN HKEY hKey,
  528. IN LPCWSTR pwszSubKey
  529. )
  530. {
  531. LONG err;
  532. DWORD dwDisposition;
  533. HKEY hSubKey;
  534. if (ERROR_SUCCESS != (err = RegCreateKeyExU(
  535. hKey,
  536. pwszSubKey,
  537. 0, // dwReserved
  538. NULL, // lpClass
  539. REG_OPTION_NON_VOLATILE,
  540. MAXIMUM_ALLOWED,
  541. NULL, // lpSecurityAttributes
  542. &hSubKey,
  543. &dwDisposition))) {
  544. #if DBG
  545. DbgPrintf(DBG_SS_CRYPT32,
  546. "RegCreateKeyEx(%S) returned error: %d 0x%x\n",
  547. pwszSubKey, err, err);
  548. #endif
  549. } else {
  550. RegCloseKey(hSubKey);
  551. }
  552. }
  553. // Loop through the certificates in the "My" store and get their
  554. // KeyIdentifier property. If the certificate also has a KEY_PROV_INFO,
  555. // then, this will cause its KeyIdentifier to be created.
  556. void UpdateMyKeyIdentifiers(
  557. IN DWORD dwOpenStoreFlags
  558. )
  559. {
  560. HCERTSTORE hStore;
  561. if (hStore = CertOpenStore(
  562. CERT_STORE_PROV_SYSTEM_A,
  563. 0, // dwEncodingType
  564. NULL, // hCryptProv
  565. dwOpenStoreFlags | CERT_STORE_ENUM_ARCHIVED_FLAG,
  566. (const void *) "My"
  567. )) {
  568. PCCERT_CONTEXT pCert = NULL;
  569. while (pCert = CertEnumCertificatesInStore(hStore, pCert)) {
  570. DWORD cbData = 0;
  571. // Dummy get to force the KeyIdentifer property to be created
  572. // if it doesn't already exist.
  573. CertGetCertificateContextProperty(
  574. pCert,
  575. CERT_KEY_IDENTIFIER_PROP_ID,
  576. NULL, // pvData
  577. &cbData
  578. );
  579. }
  580. CertCloseStore(hStore, 0);
  581. }
  582. }
  583. //---------------------------------------------------------------------------
  584. // Set Software Publisher State Key Value
  585. //
  586. //---------------------------------------------------------------------------
  587. BOOL SetSoftPubKey(DWORD dwMask, BOOL fOn)
  588. {
  589. DWORD dwState=0;
  590. DWORD dwDisposition=0;
  591. DWORD dwType=0;
  592. DWORD cbData=0;
  593. LPWSTR wszState=REGNAME_WINTRUST_POLICY_FLAGS;
  594. BOOL fResult=FALSE;
  595. HKEY hKey=NULL;
  596. // Set the State in the registry
  597. if (ERROR_SUCCESS != RegCreateKeyExU(
  598. HKEY_CURRENT_USER,
  599. REGPATH_WINTRUST_POLICY_FLAGS,
  600. 0, // dwReserved
  601. NULL, // lpszClass
  602. REG_OPTION_NON_VOLATILE,
  603. KEY_ALL_ACCESS,
  604. NULL, // lpSecurityAttributes
  605. &hKey,
  606. &dwDisposition))
  607. goto RegErr;
  608. dwState = 0;
  609. cbData = sizeof(dwState);
  610. if(ERROR_SUCCESS != RegQueryValueExU
  611. ( hKey,
  612. wszState,
  613. NULL, // lpReserved
  614. &dwType,
  615. (BYTE *) &dwState,
  616. &cbData
  617. ))
  618. goto RegErr;
  619. if ((dwType != REG_DWORD) && (dwType != REG_BINARY))
  620. goto UnexpectedErr;
  621. switch(dwMask)
  622. {
  623. case WTPF_IGNOREREVOCATIONONTS:
  624. case WTPF_IGNOREREVOKATION:
  625. case WTPF_IGNOREEXPIRATION:
  626. // Revocation and expiration are a double negative so the bit set
  627. // means revocation and expriation checking is off.
  628. fOn = !fOn;
  629. break;
  630. default:
  631. break;
  632. };
  633. if (fOn)
  634. dwState |= dwMask;
  635. else
  636. dwState &= ~dwMask;
  637. if(ERROR_SUCCESS != RegSetValueExU(
  638. hKey,
  639. wszState,
  640. 0, // dwReserved
  641. REG_DWORD,
  642. (BYTE *) &dwState,
  643. sizeof(dwState)
  644. ))
  645. goto SetValueErr;
  646. fResult=TRUE;
  647. CommonReturn:
  648. if(hKey)
  649. RegCloseKey(hKey);
  650. return fResult;
  651. ErrorReturn:
  652. goto CommonReturn;
  653. TRACE_ERROR(RegErr);
  654. SET_ERROR(UnexpectedErr, E_UNEXPECTED);
  655. TRACE_ERROR(SetValueErr);
  656. }
  657. //+---------------------------------------------------------------------------
  658. //
  659. // Function: GetNextRegToken
  660. //
  661. // Synopsis:
  662. // Find the next token with space as the deliminator
  663. //----------------------------------------------------------------------------
  664. LPWSTR GetNextRegToken(LPWSTR pwsz, LPWSTR pwszPreToken, BOOL *pfEnd)
  665. {
  666. LPWSTR pwszStart=NULL;
  667. LPWSTR pwszSearch=NULL;
  668. if(NULL == pwsz)
  669. return NULL;
  670. if(TRUE == (*pfEnd))
  671. return NULL;
  672. pwszStart=pwsz;
  673. if(pwszPreToken)
  674. pwszStart=pwszPreToken + wcslen(pwszPreToken) + 1;
  675. //skip the spaces
  676. while((*pwszStart)==L' ')
  677. pwszStart++;
  678. //check for NULL
  679. if(*pwszStart==L'\0')
  680. return NULL;
  681. pwszSearch=pwszStart;
  682. while(((*pwszSearch) != L'\0') && ((*pwszSearch) !=L' ') )
  683. pwszSearch++;
  684. if(*pwszSearch == L'\0')
  685. {
  686. *pfEnd=TRUE;
  687. return pwszStart;
  688. }
  689. *pwszSearch=L'\0';
  690. *pfEnd=FALSE;
  691. return pwszStart;
  692. }
  693. //+---------------------------------------------------------------------------
  694. //
  695. // Function: InitRegistryValue
  696. //
  697. // Synopsis: This function replace SetReg.exe. The expected
  698. // command line would be: 1 TRUE 3 FALSE 9 TRUE 4 FALSE ....
  699. //
  700. //----------------------------------------------------------------------------
  701. HRESULT InitRegistryValue(LPWSTR pwszCommand)
  702. {
  703. HRESULT hr= E_FAIL;
  704. DWORD SoftPubFlags[] =
  705. {
  706. WTPF_TRUSTTEST | WTPF_TESTCANBEVALID,
  707. WTPF_IGNOREEXPIRATION,
  708. WTPF_IGNOREREVOKATION,
  709. WTPF_OFFLINEOK_IND,
  710. WTPF_OFFLINEOK_COM,
  711. WTPF_OFFLINEOKNBU_IND,
  712. WTPF_OFFLINEOKNBU_COM,
  713. WTPF_VERIFY_V1_OFF,
  714. WTPF_IGNOREREVOCATIONONTS,
  715. WTPF_ALLOWONLYPERTRUST
  716. };
  717. LPWSTR pwszNextToken=NULL;
  718. int iIndex=-1;
  719. BOOL fOn=FALSE;
  720. int cFlags=sizeof(SoftPubFlags)/sizeof(SoftPubFlags[0]);
  721. DWORD cParam=0;
  722. LPWSTR pwszCopy=NULL;
  723. BOOL fPassThrough=FALSE;
  724. //make a copy of the command line since we will change it
  725. pwszCopy=(LPWSTR)LocalAlloc(LPTR, (1+wcslen(pwszCommand)) * sizeof(WCHAR));
  726. if(NULL== pwszCopy)
  727. goto MemoryErr;
  728. wcscpy(pwszCopy, pwszCommand);
  729. while(pwszNextToken=GetNextRegToken(pwszCopy, pwszNextToken, &fPassThrough))
  730. {
  731. if(-1 == iIndex)
  732. {
  733. iIndex=_wtoi(pwszNextToken);
  734. if((iIndex <= 0) || (iIndex > cFlags))
  735. goto InvalidArgErr;
  736. cParam++;
  737. }
  738. else
  739. {
  740. if(0 == _wcsicmp(pwszNextToken, L"true"))
  741. fOn=TRUE;
  742. else
  743. {
  744. if(0 == _wcsicmp(pwszNextToken, L"false"))
  745. fOn=FALSE;
  746. else
  747. goto InvalidArgErr;
  748. }
  749. cParam++;
  750. //set the registry value
  751. if(!SetSoftPubKey(SoftPubFlags[iIndex-1],
  752. fOn))
  753. {
  754. hr=INITPKI_HRESULT_FROM_WIN32(GetLastError());
  755. goto SetKeyErr;
  756. }
  757. //reset the value for dwIndex
  758. iIndex=-1;
  759. }
  760. }
  761. //we have to have even number of parameters
  762. if( (0 != (cParam %2)) || (0 == cParam))
  763. goto InvalidArgErr;
  764. hr=S_OK;
  765. CommonReturn:
  766. if(pwszCopy)
  767. LocalFree((HLOCAL)pwszCopy);
  768. return hr;
  769. ErrorReturn:
  770. goto CommonReturn;
  771. SET_ERROR(InvalidArgErr, E_INVALIDARG);
  772. SET_ERROR_VAR(SetKeyErr, hr);
  773. SET_ERROR(MemoryErr, E_OUTOFMEMORY);
  774. }
  775. //+---------------------------------------------------------------------------
  776. //
  777. // Function: DllMain
  778. //
  779. // Synopsis:
  780. //
  781. //----------------------------------------------------------------------------
  782. BOOL WINAPI DllMain(HMODULE hInstDLL, DWORD fdwReason, LPVOID lpvReserved)
  783. {
  784. switch ( fdwReason )
  785. {
  786. case DLL_PROCESS_ATTACH:
  787. hModule = hInstDLL;
  788. break;
  789. }
  790. return( TRUE );
  791. }
  792. //+---------------------------------------------------------------------------
  793. //
  794. // Function: DllInstall
  795. //
  796. // Synopsis: dll installation entry point
  797. //
  798. //----------------------------------------------------------------------------
  799. STDAPI DllInstall (BOOL fRegister, LPCSTR pszCommand)
  800. {
  801. HRESULT hr = S_OK;
  802. HRESULT hr2;
  803. LPWSTR pwszCommand=NULL;
  804. if ( fRegister == FALSE )
  805. {
  806. return( E_NOTIMPL );
  807. }
  808. switch ( *pszCommand )
  809. {
  810. //letter S stands for setreg input parameters
  811. //the command line should look like following:
  812. //S 1 TRUE 2 FALSE 3 FALSE ...
  813. //pszCommand is ACTUALLY LPWSTR for BOTH
  814. //NT5, NT4 and Win95.
  815. case 'S':
  816. case 's':
  817. pwszCommand=(LPWSTR)pszCommand;
  818. if(wcslen(pwszCommand) <= 2)
  819. {
  820. hr=E_INVALIDARG;
  821. }
  822. else
  823. {
  824. hr=InitRegistryValue((LPWSTR)(&(pwszCommand[1])));
  825. }
  826. break;
  827. case 'M':
  828. case 'm':
  829. PurgeExpiringCertsFromStores();
  830. break;
  831. case 'U':
  832. case 'u':
  833. _AdjustPolicyFlags(psPolicySettings);
  834. PurgeExpiringCertsFromStores();
  835. // Ensure we have a registry entry for the Group Policy
  836. // SystemCertificates. On NT 4.0 or Win98, we emulate NT 5.0 GPT
  837. // notification by doing a RegNotifyChangeKeyValue on this
  838. // registry key.
  839. CreateKey(HKEY_CURRENT_USER, GROUP_POLICY_STORE_REGPATH);
  840. // Before adding to CurrentUser, will check if the root or CA
  841. // already exists in LocalMachine. If it exists in
  842. // LocalMachine and also exists in CurrentUser, will delete it
  843. // from CurrentUser instead of adding.
  844. hr = AddCurrentUserRootCertificates();
  845. hr2 = AddCurrentUserCACertificates();
  846. if (hr == ERROR_SUCCESS)
  847. hr = hr2;
  848. hr2 = AddCurrentUserDisallowedCertificates();
  849. if (hr == ERROR_SUCCESS)
  850. hr = hr2;
  851. // Protect the CurrentUser roots and purge any existing
  852. // protected CurrentUser roots also in LocalMachine
  853. //
  854. // Note, once the roots are protected, all subsequent adds are
  855. // done by a special service executing with System privileges.
  856. // This special service does secure attention sequence (SAS) UI
  857. // before doing the add.
  858. //
  859. // Note, subsequent purges are exempt from UI. ie, this function
  860. // doesn't do any SAS UI.
  861. I_CertProtectFunction(
  862. CERT_PROT_PURGE_LM_ROOTS_FUNC_ID,
  863. 0, // dwFlags
  864. NULL, // pwszIn
  865. NULL, // pbIn
  866. 0, // cbIn
  867. NULL, // ppbOut
  868. NULL // pcbOut
  869. );
  870. UpdateMyKeyIdentifiers(CERT_SYSTEM_STORE_CURRENT_USER);
  871. break;
  872. case 'B':
  873. case 'b':
  874. case 'R':
  875. case 'r':
  876. case 'A':
  877. case 'a':
  878. PurgeExpiringCertsFromStores();
  879. // Ensure we have a registry entry for the Group Policy
  880. // SystemCertificates. On NT 4.0 or Win98, we emulate NT 5.0 GPT
  881. // notification by doing a RegNotifyChangeKeyValue on this
  882. // registry key.
  883. CreateKey(HKEY_LOCAL_MACHINE, GROUP_POLICY_STORE_REGPATH);
  884. CreateKey(HKEY_CURRENT_USER, GROUP_POLICY_STORE_REGPATH);
  885. // Ensure we have existing predefined stores for the LocalMachine
  886. // Enterprise system stores. These stores are periodically updated
  887. // from the DS by a system service. RegNotifyChangeKeyValue is
  888. // used to signal clients about Enterprise store changes.
  889. RegisterEnterpriseStores();
  890. // Our goal is to get the roots and CAs into LocalMachine.
  891. // Note previously, they were only copied to CurrentUser.
  892. AddLocalMachineRootCertificates();
  893. AddLocalMachineCACertificates();
  894. AddLocalMachineDisallowedCertificates();
  895. // If the above adds to LocalMachine failed, then, add
  896. // to CurrentUser.
  897. //
  898. // Before adding to CurrentUser, will check if the root or CA
  899. // already exists in LocalMachine. If it exists in
  900. // LocalMachine and also exists in CurrentUser, will delete it
  901. // from CurrentUser instead of adding.
  902. hr = AddCurrentUserRootCertificates();
  903. hr2 = AddCurrentUserCACertificates();
  904. if (hr == ERROR_SUCCESS)
  905. hr = hr2;
  906. hr2 = AddCurrentUserDisallowedCertificates();
  907. if (hr == ERROR_SUCCESS)
  908. hr = hr2;
  909. // Protect the CurrentUser roots and purge any existing
  910. // protected CurrentUser roots also in LocalMachine
  911. //
  912. // Note, once the roots are protected, all subsequent adds are
  913. // done by a special service executing with System privileges.
  914. // This special service does secure attention sequence (SAS) UI
  915. // before doing the add.
  916. //
  917. // Note, subsequent purges are exempt from UI. ie, this function
  918. // doesn't do any SAS UI.
  919. I_CertProtectFunction(
  920. CERT_PROT_PURGE_LM_ROOTS_FUNC_ID,
  921. 0, // dwFlags
  922. NULL, // pwszIn
  923. NULL, // pbIn
  924. 0, // cbIn
  925. NULL, // ppbOut
  926. NULL // pcbOut
  927. );
  928. UpdateMyKeyIdentifiers(CERT_SYSTEM_STORE_CURRENT_USER);
  929. UpdateMyKeyIdentifiers(CERT_SYSTEM_STORE_LOCAL_MACHINE);
  930. CleanupRegistry();
  931. hr2 = RegisterCryptoDlls(TRUE);
  932. if (hr == ERROR_SUCCESS)
  933. hr = hr2;
  934. if (!I_CryptCatAdminMigrateToNewCatDB())
  935. {
  936. hr2 = HRESULT_FROM_WIN32(GetLastError());
  937. }
  938. else
  939. {
  940. hr2 = ERROR_SUCCESS;
  941. }
  942. if (hr == ERROR_SUCCESS)
  943. hr = hr2;
  944. break;
  945. case 'C':
  946. case 'c':
  947. // Win9x migration post setup cleanup. Remove any migrated
  948. // roots that exist in the AuthRoot store.
  949. AddLocalMachineRootCertificates();
  950. AddCurrentUserRootCertificates();
  951. break;
  952. case 'Z':
  953. case 'z':
  954. //
  955. // This is for componentization install
  956. //
  957. pwszCommand=(LPWSTR)pszCommand;
  958. if (_wcsicmp(pwszCommand, L"z CoreCertificateServices") == 0)
  959. {
  960. AddLocalMachineRootCertificates();
  961. AddLocalMachineCACertificates();
  962. AddLocalMachineDisallowedCertificates();
  963. if (!_LoadAndRegister("wintrust.dll", FALSE) ||
  964. !_LoadAndRegister("mssign32.dll", FALSE) ||
  965. !_LoadAndRegister("xenroll.dll", FALSE) ||
  966. !_AdjustPolicyFlags(psPolicySettings))
  967. {
  968. hr = S_FALSE;
  969. }
  970. RegisterWinlogonExtension("crypt32chain", "crypt32.dll",
  971. "ChainWlxLogoffEvent");
  972. RegisterWinlogonExtension("cryptnet", "cryptnet.dll",
  973. "CryptnetWlxLogoffEvent");
  974. RegisterCrypt32EventSource();
  975. }
  976. else if (_wcsicmp(pwszCommand, L"z CertificateUIServices") == 0)
  977. {
  978. if (!_LoadAndRegister("cryptui.dll", FALSE))
  979. {
  980. hr = S_FALSE;
  981. }
  982. }
  983. else if (_wcsicmp(pwszCommand, L"z CryptographicNetworkServices") == 0)
  984. {
  985. if (!_LoadAndRegister("cryptnet.dll", FALSE))
  986. {
  987. hr = S_FALSE;
  988. }
  989. }
  990. else if (_wcsicmp(pwszCommand, L"z CertificateUIExtensions") == 0)
  991. {
  992. if (!_LoadAndRegister("cryptext.dll", FALSE))
  993. {
  994. hr = S_FALSE;
  995. }
  996. }
  997. else
  998. {
  999. hr = E_INVALIDARG;
  1000. }
  1001. break;
  1002. default:
  1003. hr = E_INVALIDARG;
  1004. }
  1005. return( hr );
  1006. }
  1007. STDAPI DllRegisterServer(void)
  1008. {
  1009. return(DllInstall(TRUE, "A"));
  1010. }
  1011. STDAPI DllUnregisterServer(void)
  1012. {
  1013. return(UnregisterCryptoDlls());
  1014. }
  1015. BOOL WINAPI InitializePKI(void)
  1016. {
  1017. if (RegisterCryptoDlls(TRUE) != S_OK)
  1018. {
  1019. return(FALSE);
  1020. }
  1021. return(TRUE);
  1022. }