Source code of Windows XP (NT5)
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.

1789 lines
36 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 2001
  5. //
  6. // File: cainfo.cpp
  7. //
  8. // Contents:
  9. //
  10. //---------------------------------------------------------------------------
  11. #include "pch.cpp"
  12. #pragma hdrstop
  13. #include <certca.h>
  14. #include <cainfop.h>
  15. #include <polreg.h>
  16. #include <cainfoc.h>
  17. #include <certtype.h>
  18. #include <winldap.h>
  19. #define __dwFILE__ __dwFILE_CERTCLIB_CAINFO_CPP__
  20. typedef struct _CA_DEFAULT_PROVIDER {
  21. DWORD dwFlags;
  22. LPWSTR wszName;
  23. } CA_DEFAULT_PROVIDER;
  24. CA_DEFAULT_PROVIDER g_DefaultProviders[] =
  25. {
  26. {0, MS_DEF_PROV_W},
  27. {0, MS_ENHANCED_PROV_W},
  28. {0, MS_DEF_RSA_SIG_PROV_W},
  29. {0, MS_DEF_RSA_SCHANNEL_PROV_W},
  30. {0, MS_DEF_DSS_PROV_W},
  31. {0, MS_DEF_DSS_DH_PROV_W},
  32. {0, MS_ENH_DSS_DH_PROV_W},
  33. {0, MS_DEF_DH_SCHANNEL_PROV_W},
  34. {0, MS_SCARD_PROV_W}
  35. };
  36. DWORD g_cDefaultProviders = sizeof(g_DefaultProviders)/sizeof(g_DefaultProviders[0]);
  37. LPCWSTR
  38. CAGetDN(
  39. IN HCAINFO hCAInfo
  40. )
  41. {
  42. CSASSERT(hCAInfo);
  43. return ((CCAInfo*)hCAInfo)->GetDN();
  44. }
  45. HRESULT
  46. CAFindByName(
  47. IN LPCWSTR wszCAName,
  48. IN LPCWSTR wszScope,
  49. IN DWORD fFlags,
  50. OUT HCAINFO * phCAInfo
  51. )
  52. {
  53. HRESULT hr = S_OK;
  54. DWORD err;
  55. WCHAR *wszQueryBase = L"(cn=";
  56. WCHAR *wszQuery = NULL;
  57. DWORD cQuery;
  58. if((wszCAName == NULL) || (phCAInfo == NULL))
  59. {
  60. return E_POINTER;
  61. }
  62. // Generate Query
  63. cQuery = wcslen(wszQueryBase) + wcslen(wszCAName) + 2; // 2 for ending paren and null
  64. wszQuery = (WCHAR *)LocalAlloc(LMEM_FIXED, sizeof(WCHAR)*cQuery);
  65. if(wszQuery == NULL)
  66. {
  67. hr = E_OUTOFMEMORY;
  68. goto error;
  69. }
  70. wcscpy(wszQuery, wszQueryBase);
  71. wcscat(wszQuery, wszCAName);
  72. wcscat(wszQuery, L")");
  73. if(fFlags & CA_FLAG_SCOPE_DNS)
  74. {
  75. hr = CCAInfo::FindDnsDomain(wszQuery, wszScope, fFlags, (CCAInfo **)phCAInfo);
  76. }
  77. else
  78. {
  79. hr = CCAInfo::Find(wszQuery, wszScope, fFlags, (CCAInfo **)phCAInfo);
  80. }
  81. if((hr == S_OK) &&
  82. (*phCAInfo == NULL))
  83. {
  84. hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
  85. }
  86. error:
  87. if(wszQuery)
  88. {
  89. LocalFree(wszQuery);
  90. }
  91. return hr;
  92. }
  93. HRESULT
  94. CAFindByCertType(
  95. IN LPCWSTR wszCertType,
  96. IN LPCWSTR wszScope,
  97. IN DWORD fFlags,
  98. OUT HCAINFO * phCAInfo
  99. )
  100. {
  101. HRESULT hr = S_OK;
  102. DWORD err;
  103. WCHAR *wszQueryBase = L"(" CA_PROP_CERT_TYPES L"=";
  104. WCHAR *wszQuery = NULL;
  105. DWORD cQuery;
  106. if((wszCertType == NULL) || (phCAInfo == NULL))
  107. {
  108. return E_POINTER;
  109. }
  110. // Generate Query
  111. cQuery = wcslen(wszQueryBase) + wcslen(wszCertType) + 2; // 2 for ending paren and null
  112. wszQuery = (WCHAR *)LocalAlloc(LMEM_FIXED, sizeof(WCHAR)*cQuery);
  113. if(wszQuery == NULL)
  114. {
  115. hr = E_OUTOFMEMORY;
  116. goto error;
  117. }
  118. wcscpy(wszQuery, wszQueryBase);
  119. wcscat(wszQuery, wszCertType);
  120. wcscat(wszQuery, L")");
  121. if(fFlags & CA_FLAG_SCOPE_DNS)
  122. {
  123. hr = CCAInfo::FindDnsDomain(wszQuery, wszScope, fFlags, (CCAInfo **)phCAInfo);
  124. }
  125. else
  126. {
  127. hr = CCAInfo::Find(wszQuery, wszScope, fFlags, (CCAInfo **)phCAInfo);
  128. }
  129. if(*phCAInfo == NULL)
  130. {
  131. hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
  132. }
  133. error:
  134. if(wszQuery)
  135. {
  136. LocalFree(wszQuery);
  137. }
  138. return hr;
  139. }
  140. HRESULT
  141. CAFindByIssuerDN(
  142. IN CERT_NAME_BLOB const * pIssuerDN,
  143. IN LPCWSTR wszScope,
  144. IN DWORD fFlags,
  145. OUT HCAINFO * phCAInfo
  146. )
  147. {
  148. HRESULT hr = S_OK;
  149. DWORD err;
  150. WCHAR *wszQueryBase = wszLPAREN L"cACertificateDN=";
  151. WCHAR *wszQuery = NULL;
  152. WCHAR *wszNameStr = NULL;
  153. DWORD cQuery;
  154. if((pIssuerDN == NULL) || (phCAInfo == NULL))
  155. {
  156. return E_POINTER;
  157. }
  158. // Generate Query
  159. // Convert the CAPI2 name to a string
  160. hr = myCertNameToStr(
  161. X509_ASN_ENCODING,
  162. pIssuerDN,
  163. CERT_X500_NAME_STR |
  164. CERT_NAME_STR_REVERSE_FLAG |
  165. CERT_NAME_STR_NO_QUOTING_FLAG,
  166. &wszNameStr);
  167. _JumpIfError(hr, error, "myCertNameToStr");
  168. // Now quote that string with double quotes
  169. // two for ending paren and null, two for the double quotes
  170. cQuery = wcslen(wszQueryBase) + wcslen(wszNameStr) + 4;
  171. wszQuery = (WCHAR *)LocalAlloc(LMEM_FIXED, sizeof(WCHAR)*cQuery);
  172. if(wszQuery == NULL)
  173. {
  174. hr = E_OUTOFMEMORY;
  175. goto error;
  176. }
  177. wcscpy(wszQuery, wszQueryBase);
  178. wcscat(wszQuery, L"\"");
  179. wcscat(wszQuery, wszNameStr);
  180. wcscat(wszQuery, L"\"" wszRPAREN);
  181. CSASSERT(cQuery - 1 == wcslen(wszQuery));
  182. if(fFlags & CA_FLAG_SCOPE_DNS)
  183. {
  184. hr = CCAInfo::FindDnsDomain(wszQuery, wszScope, fFlags, (CCAInfo **)phCAInfo);
  185. }
  186. else
  187. {
  188. hr = CCAInfo::Find(wszQuery, wszScope, fFlags, (CCAInfo **)phCAInfo);
  189. }
  190. error:
  191. if(wszNameStr)
  192. {
  193. LocalFree(wszNameStr);
  194. }
  195. if(wszQuery)
  196. {
  197. LocalFree(wszQuery);
  198. }
  199. return hr;
  200. }
  201. HRESULT
  202. CAEnumFirstCA(
  203. IN LPCWSTR wszScope,
  204. IN DWORD fFlags,
  205. OUT HCAINFO * phCAInfo
  206. )
  207. {
  208. HRESULT hr = S_OK;
  209. if(fFlags & CA_FLAG_SCOPE_DNS)
  210. {
  211. hr = CCAInfo::FindDnsDomain(NULL, wszScope, fFlags, (CCAInfo **)phCAInfo);
  212. }
  213. else
  214. {
  215. hr = CCAInfo::Find(NULL, wszScope, fFlags, (CCAInfo **)phCAInfo);
  216. }
  217. if (S_OK != hr)
  218. {
  219. if (HRESULT_FROM_WIN32(ERROR_NETWORK_UNREACHABLE) != hr &&
  220. HRESULT_FROM_WIN32(ERROR_WRONG_PASSWORD) != hr)
  221. {
  222. _PrintError3(
  223. hr,
  224. "FindDnsDomain/Find",
  225. HRESULT_FROM_WIN32(ERROR_SERVER_DISABLED),
  226. HRESULT_FROM_WIN32(ERROR_NO_SUCH_DOMAIN));
  227. }
  228. goto error;
  229. }
  230. error:
  231. return(hr);
  232. }
  233. HRESULT
  234. CAEnumNextCA(
  235. IN HCAINFO hPrevCA,
  236. OUT HCAINFO * phCAInfo
  237. )
  238. {
  239. CCAInfo *pInfo;
  240. if(hPrevCA == NULL)
  241. {
  242. return E_POINTER;
  243. }
  244. pInfo = (CCAInfo *)hPrevCA;
  245. return pInfo->Next((CCAInfo **)phCAInfo);
  246. }
  247. HRESULT
  248. CACreateNewCA(
  249. IN LPCWSTR wszCAName,
  250. IN LPCWSTR wszScope,
  251. IN DWORD fFlags,
  252. OUT HCAINFO * phCAInfo
  253. )
  254. {
  255. HRESULT hr = S_OK;
  256. DWORD err;
  257. if((wszCAName == NULL) || (phCAInfo == NULL))
  258. {
  259. return E_POINTER;
  260. }
  261. // Generate Query
  262. if(CA_FLAG_SCOPE_DNS & fFlags)
  263. {
  264. hr = CCAInfo::CreateDnsDomain(wszCAName, wszScope, (CCAInfo **)phCAInfo);
  265. }
  266. else
  267. {
  268. hr = CCAInfo::Create(wszCAName, wszScope, (CCAInfo **)phCAInfo);
  269. }
  270. return hr;
  271. }
  272. HRESULT
  273. CAUpdateCA(
  274. IN HCAINFO hCAInfo
  275. )
  276. {
  277. CCAInfo *pInfo;
  278. if(hCAInfo == NULL)
  279. {
  280. return E_POINTER;
  281. }
  282. pInfo = (CCAInfo *)hCAInfo;
  283. return pInfo->Update();
  284. }
  285. HRESULT
  286. CADeleteCA(
  287. IN HCAINFO hCAInfo
  288. )
  289. {
  290. CCAInfo *pInfo;
  291. if(hCAInfo == NULL)
  292. {
  293. return E_POINTER;
  294. }
  295. pInfo = (CCAInfo *)hCAInfo;
  296. return pInfo->Delete();
  297. }
  298. DWORD
  299. CACountCAs(IN HCAINFO hCAInfo)
  300. {
  301. CCAInfo *pInfo;
  302. if(hCAInfo == NULL)
  303. {
  304. return 0;
  305. }
  306. pInfo = (CCAInfo *)hCAInfo;
  307. return pInfo->Count();
  308. }
  309. HRESULT
  310. CACloseCA(IN HCAINFO hCAInfo)
  311. {
  312. CCAInfo *pInfo;
  313. if(hCAInfo == NULL)
  314. {
  315. return E_POINTER;
  316. }
  317. pInfo = (CCAInfo *)hCAInfo;
  318. return pInfo->Release();
  319. }
  320. HRESULT
  321. CAGetCAProperty(
  322. IN HCAINFO hCAInfo,
  323. IN LPCWSTR wszPropertyName,
  324. OUT LPWSTR ** pawszPropertyValue)
  325. {
  326. CCAInfo *pInfo;
  327. if(hCAInfo == NULL)
  328. {
  329. return E_POINTER;
  330. }
  331. pInfo = (CCAInfo *)hCAInfo;
  332. return pInfo->GetProperty(wszPropertyName, pawszPropertyValue);
  333. }
  334. HRESULT
  335. CAFreeCAProperty(
  336. IN HCAINFO hCAInfo,
  337. IN LPWSTR * awszPropertyValue
  338. )
  339. {
  340. CCAInfo *pInfo;
  341. if(hCAInfo == NULL)
  342. {
  343. return E_POINTER;
  344. }
  345. pInfo = (CCAInfo *)hCAInfo;
  346. return pInfo->FreeProperty(awszPropertyValue);
  347. }
  348. HRESULT
  349. CASetCAProperty(
  350. IN HCAINFO hCAInfo,
  351. IN LPCWSTR wszPropertyName,
  352. IN LPWSTR * awszPropertyValue)
  353. {
  354. CCAInfo *pInfo;
  355. if(hCAInfo == NULL)
  356. {
  357. return E_POINTER;
  358. }
  359. pInfo = (CCAInfo *)hCAInfo;
  360. return pInfo->SetProperty(wszPropertyName, awszPropertyValue);
  361. }
  362. HRESULT
  363. CAGetCAFlags(
  364. IN HCAINFO hCAInfo,
  365. OUT DWORD * pdwFlags
  366. )
  367. {
  368. CCAInfo *pInfo;
  369. if(hCAInfo == NULL)
  370. {
  371. return E_POINTER;
  372. }
  373. if(pdwFlags == NULL)
  374. {
  375. return E_POINTER;
  376. }
  377. pInfo = (CCAInfo *)hCAInfo;
  378. *pdwFlags = pInfo->GetFlags();
  379. return S_OK;
  380. }
  381. HRESULT
  382. CASetCAFlags(
  383. IN HCAINFO hCAInfo,
  384. IN DWORD dwFlags
  385. )
  386. {
  387. CCAInfo *pInfo;
  388. if(hCAInfo == NULL)
  389. {
  390. return E_POINTER;
  391. }
  392. pInfo = (CCAInfo *)hCAInfo;
  393. pInfo->SetFlags(dwFlags);
  394. return S_OK;
  395. }
  396. HRESULT
  397. CAGetCACertificate(
  398. IN HCAINFO hCAInfo,
  399. OUT PCCERT_CONTEXT *ppCert)
  400. {
  401. CCAInfo *pInfo;
  402. if(hCAInfo == NULL)
  403. {
  404. return E_POINTER;
  405. }
  406. pInfo = (CCAInfo *)hCAInfo;
  407. return pInfo->GetCertificate(ppCert);
  408. }
  409. HRESULT
  410. CASetCACertificate(
  411. IN HCAINFO hCAInfo,
  412. IN PCCERT_CONTEXT pCert)
  413. {
  414. CCAInfo *pInfo;
  415. if(hCAInfo == NULL)
  416. {
  417. return E_POINTER;
  418. }
  419. pInfo = (CCAInfo *)hCAInfo;
  420. return pInfo->SetCertificate(pCert);
  421. }
  422. HRESULT
  423. CAGetCAExpiration(
  424. HCAINFO hCAInfo,
  425. DWORD * pdwExpiration,
  426. DWORD * pdwUnits
  427. )
  428. {
  429. CCAInfo *pInfo;
  430. if(hCAInfo == NULL)
  431. {
  432. return E_POINTER;
  433. }
  434. pInfo = (CCAInfo *)hCAInfo;
  435. return pInfo->GetExpiration(pdwExpiration, pdwUnits);
  436. }
  437. HRESULT
  438. CASetCAExpiration(
  439. HCAINFO hCAInfo,
  440. DWORD dwExpiration,
  441. DWORD dwUnits
  442. )
  443. {
  444. CCAInfo *pInfo;
  445. if(hCAInfo == NULL)
  446. {
  447. return E_POINTER;
  448. }
  449. pInfo = (CCAInfo *)hCAInfo;
  450. return pInfo->SetExpiration(dwExpiration, dwUnits);
  451. }
  452. HRESULT
  453. CASetCASecurity(
  454. IN HCAINFO hCAInfo,
  455. IN PSECURITY_DESCRIPTOR pSD
  456. )
  457. {
  458. CCAInfo *pInfo;
  459. if(hCAInfo == NULL)
  460. {
  461. return E_POINTER;
  462. }
  463. pInfo = (CCAInfo *)hCAInfo;
  464. return pInfo->SetSecurity( pSD );
  465. }
  466. HRESULT
  467. CAGetCASecurity(
  468. IN HCAINFO hCAInfo,
  469. OUT PSECURITY_DESCRIPTOR * ppSD
  470. )
  471. {
  472. CCAInfo *pInfo;
  473. if(hCAInfo == NULL)
  474. {
  475. return E_POINTER;
  476. }
  477. pInfo = (CCAInfo *)hCAInfo;
  478. return pInfo->GetSecurity( ppSD ) ;
  479. }
  480. CERTCLIAPI
  481. HRESULT
  482. WINAPI
  483. CAAccessCheck(
  484. IN HCAINFO hCAInfo,
  485. IN HANDLE ClientToken
  486. )
  487. {
  488. CCAInfo *pInfo;
  489. if(hCAInfo == NULL)
  490. {
  491. return E_POINTER;
  492. }
  493. pInfo = (CCAInfo *)hCAInfo;
  494. return pInfo->AccessCheck(ClientToken,CERTTYPE_ACCESS_CHECK_ENROLL);
  495. }
  496. CERTCLIAPI
  497. HRESULT
  498. WINAPI
  499. CAAccessCheckEx(
  500. IN HCAINFO hCAInfo,
  501. IN HANDLE ClientToken,
  502. IN DWORD dwOption
  503. )
  504. {
  505. CCAInfo *pInfo;
  506. if(hCAInfo == NULL)
  507. {
  508. return E_POINTER;
  509. }
  510. pInfo = (CCAInfo *)hCAInfo;
  511. return pInfo->AccessCheck(ClientToken,dwOption);
  512. }
  513. HRESULT
  514. CAEnumCertTypesForCAEx(
  515. IN HCAINFO hCAInfo,
  516. IN LPCWSTR wszScope,
  517. IN DWORD dwFlags,
  518. OUT HCERTTYPE * phCertType
  519. )
  520. {
  521. CCAInfo *pInfo;
  522. if(hCAInfo == NULL)
  523. {
  524. return E_POINTER;
  525. }
  526. pInfo = (CCAInfo *)hCAInfo;
  527. if(dwFlags & CA_FLAG_ENUM_ALL_TYPES)
  528. {
  529. return CCertTypeInfo::Enum(wszScope,
  530. dwFlags,
  531. (CCertTypeInfo **)phCertType);
  532. }
  533. return pInfo->EnumSupportedCertTypesEx(wszScope,
  534. dwFlags,
  535. (CCertTypeInfo **)phCertType);
  536. }
  537. HRESULT
  538. CAEnumCertTypesForCA(
  539. IN HCAINFO hCAInfo,
  540. IN DWORD dwFlags,
  541. OUT HCERTTYPE * phCertType
  542. )
  543. {
  544. return CAEnumCertTypesForCAEx(hCAInfo,
  545. NULL,
  546. dwFlags,
  547. phCertType);
  548. }
  549. HRESULT
  550. CAAddCACertificateType(
  551. HCAINFO hCAInfo,
  552. HCERTTYPE hCertType
  553. )
  554. {
  555. CCAInfo *pInfo;
  556. if(hCAInfo == NULL)
  557. {
  558. return E_POINTER;
  559. }
  560. pInfo = (CCAInfo *)hCAInfo;
  561. return pInfo->AddCertType((CCertTypeInfo *)hCertType);
  562. }
  563. HRESULT
  564. CARemoveCACertificateType(
  565. HCAINFO hCAInfo,
  566. HCERTTYPE hCertType
  567. )
  568. {
  569. CCAInfo *pInfo;
  570. if(hCAInfo == NULL)
  571. {
  572. return E_POINTER;
  573. }
  574. pInfo = (CCAInfo *)hCAInfo;
  575. return pInfo->RemoveCertType((CCertTypeInfo *)hCertType);
  576. }
  577. //
  578. // Certificate Type API's
  579. //
  580. HRESULT
  581. CAEnumCertTypes(
  582. IN DWORD dwFlags,
  583. OUT HCERTTYPE * phCertType
  584. )
  585. {
  586. HRESULT hr;
  587. hr = CCertTypeInfo::Enum(NULL,
  588. dwFlags,
  589. (CCertTypeInfo **)phCertType);
  590. return hr;
  591. }
  592. HRESULT
  593. CAEnumCertTypesEx(
  594. IN LPCWSTR wszScope,
  595. IN DWORD dwFlags,
  596. OUT HCERTTYPE * phCertType
  597. )
  598. {
  599. HRESULT hr;
  600. hr = CCertTypeInfo::Enum(wszScope,
  601. dwFlags,
  602. (CCertTypeInfo **)phCertType);
  603. return hr;
  604. }
  605. HRESULT
  606. CAFindCertTypeByName(
  607. IN LPCWSTR wszCertType,
  608. IN HCAINFO hCAInfo,
  609. IN DWORD dwFlags,
  610. OUT HCERTTYPE * phCertType
  611. )
  612. {
  613. HRESULT hr = S_OK;
  614. LPCWSTR awszTypes[2];
  615. if((wszCertType == NULL) || (phCertType == NULL))
  616. {
  617. return E_POINTER;
  618. }
  619. awszTypes[0] = wszCertType;
  620. awszTypes[1] = NULL;
  621. hr = CCertTypeInfo::FindByNames(awszTypes,
  622. ((CT_FLAG_SCOPE_IS_LDAP_HANDLE & dwFlags)?(LPWSTR)hCAInfo:NULL),
  623. dwFlags,
  624. (CCertTypeInfo **)phCertType);
  625. if((hr == S_OK) && (*phCertType == NULL))
  626. {
  627. hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
  628. }
  629. return hr;
  630. }
  631. HRESULT
  632. CACreateCertType(
  633. IN LPCWSTR wszCertType,
  634. IN LPCWSTR wszScope,
  635. IN DWORD fFlags,
  636. OUT HCERTTYPE * phCertType
  637. )
  638. {
  639. HRESULT hr = S_OK;
  640. DWORD err;
  641. if((wszCertType == NULL) || (phCertType == NULL))
  642. {
  643. return E_POINTER;
  644. }
  645. hr = CCertTypeInfo::Create(wszCertType, wszScope, (CCertTypeInfo **)phCertType);
  646. return hr;
  647. }
  648. HRESULT
  649. CAUpdateCertType(
  650. IN HCERTTYPE hCertType
  651. )
  652. {
  653. CCertTypeInfo *pInfo;
  654. if(hCertType == NULL)
  655. {
  656. return E_POINTER;
  657. }
  658. pInfo = (CCertTypeInfo *)hCertType;
  659. return pInfo->Update();
  660. }
  661. HRESULT
  662. CADeleteCertType(
  663. IN HCERTTYPE hCertType
  664. )
  665. {
  666. CCertTypeInfo *pInfo;
  667. if(hCertType == NULL)
  668. {
  669. return E_POINTER;
  670. }
  671. pInfo = (CCertTypeInfo *)hCertType;
  672. return pInfo->Delete();
  673. }
  674. //--------------------------------------------------------------------
  675. //
  676. // CertTypeRetrieveClientToken
  677. //
  678. //--------------------------------------------------------------------
  679. BOOL CertTypeRetrieveClientToken(HANDLE *phToken)
  680. {
  681. HRESULT hr = S_OK;
  682. HANDLE hHandle = NULL;
  683. HANDLE hClientToken = NULL;
  684. hHandle = GetCurrentThread();
  685. if (NULL == hHandle)
  686. {
  687. hr = HRESULT_FROM_WIN32(GetLastError());
  688. }
  689. else
  690. {
  691. if (!OpenThreadToken(hHandle,
  692. TOKEN_QUERY,
  693. TRUE, // open as self
  694. &hClientToken))
  695. {
  696. hr = HRESULT_FROM_WIN32(GetLastError());
  697. CloseHandle(hHandle);
  698. hHandle = NULL;
  699. }
  700. }
  701. if(hr != S_OK)
  702. {
  703. hHandle = GetCurrentProcess();
  704. if (NULL == hHandle)
  705. {
  706. hr = HRESULT_FROM_WIN32(GetLastError());
  707. }
  708. else
  709. {
  710. HANDLE hProcessToken = NULL;
  711. hr = S_OK;
  712. if (!OpenProcessToken(hHandle,
  713. TOKEN_DUPLICATE,
  714. &hProcessToken))
  715. {
  716. hr = HRESULT_FROM_WIN32(GetLastError());
  717. CloseHandle(hHandle);
  718. hHandle = NULL;
  719. }
  720. else
  721. {
  722. if(!DuplicateToken(hProcessToken,
  723. SecurityImpersonation,
  724. &hClientToken))
  725. {
  726. hr = HRESULT_FROM_WIN32(GetLastError());
  727. CloseHandle(hHandle);
  728. hHandle = NULL;
  729. }
  730. CloseHandle(hProcessToken);
  731. }
  732. }
  733. }
  734. if(S_OK == hr)
  735. *phToken = hClientToken;
  736. if(hHandle)
  737. CloseHandle(hHandle);
  738. return (S_OK == hr);
  739. }
  740. HRESULT
  741. CACloneCertType(
  742. IN HCERTTYPE hCertType,
  743. IN LPCWSTR wszCertType,
  744. IN LPCWSTR wszFriendlyName,
  745. IN LPVOID pvldap,
  746. IN DWORD dwFlags,
  747. OUT HCERTTYPE * phCertType
  748. )
  749. {
  750. HRESULT hr=E_INVALIDARG;
  751. DWORD dwFindCT=CT_FLAG_NO_CACHE_LOOKUP | CT_ENUM_MACHINE_TYPES | CT_ENUM_USER_TYPES;
  752. LPWSTR awszProp[2];
  753. DWORD dwEnrollmentFlag=0;
  754. DWORD dwSubjectNameFlag=0;
  755. DWORD dwGeneralFlag=0;
  756. DWORD dwSubjectRequirement=CT_FLAG_SUBJECT_REQUIRE_DIRECTORY_PATH |
  757. CT_FLAG_SUBJECT_REQUIRE_COMMON_NAME |
  758. CT_FLAG_SUBJECT_REQUIRE_EMAIL |
  759. CT_FLAG_SUBJECT_REQUIRE_DNS_AS_CN;
  760. DWORD dwTokenUserSize=0;
  761. DWORD dwAbsSDSize=0;
  762. DWORD dwDaclSize=0;
  763. DWORD dwSaclSize=0;
  764. DWORD dwOwnerSize=0;
  765. DWORD dwPriGrpSize=0;
  766. DWORD dwRelSDSize=0;
  767. HANDLE hToken=NULL;
  768. TOKEN_USER *pTokenUser=NULL;
  769. PSECURITY_DESCRIPTOR pSID=NULL;
  770. PSECURITY_DESCRIPTOR pAbsSD=NULL;
  771. ACL * pAbsDacl=NULL;
  772. ACL * pAbsSacl=NULL;
  773. SID * pAbsOwner=NULL;
  774. SID * pAbsPriGrp=NULL;
  775. PSECURITY_DESCRIPTOR pNewSD=NULL;
  776. LPWSTR * awszCN=NULL;
  777. HCERTTYPE hNewCertType=NULL;
  778. if((NULL==hCertType) || (NULL==wszCertType) || (NULL==phCertType))
  779. goto error;
  780. *phCertType=NULL;
  781. if(pvldap)
  782. dwFindCT |= CT_FLAG_SCOPE_IS_LDAP_HANDLE;
  783. //make sure the new name does not exit
  784. if(S_OK == CAFindCertTypeByName(
  785. wszCertType,
  786. (HCAINFO)pvldap,
  787. dwFindCT,
  788. &hNewCertType))
  789. {
  790. hr=CRYPT_E_EXISTS;
  791. goto error;
  792. }
  793. //get a new cert type handle
  794. if(S_OK != (hr = CAGetCertTypePropertyEx(hCertType,
  795. CERTTYPE_PROP_CN,
  796. &awszCN)))
  797. goto error;
  798. if((NULL==awszCN) || (NULL==awszCN[0]))
  799. {
  800. hr=HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
  801. goto error;
  802. }
  803. if(S_OK != (hr = CAFindCertTypeByName(
  804. (LPCWSTR)awszCN[0],
  805. (HCAINFO)pvldap,
  806. dwFindCT,
  807. &hNewCertType)))
  808. goto error;
  809. if(NULL==hNewCertType)
  810. {
  811. hr=HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
  812. goto error;
  813. }
  814. //clone by setting the CN
  815. awszProp[0]=(LPWSTR)wszCertType;
  816. awszProp[1]=NULL;
  817. if(S_OK != (hr=CASetCertTypePropertyEx(
  818. hNewCertType,
  819. CERTTYPE_PROP_CN,
  820. awszProp)))
  821. goto error;
  822. //set the friendly name
  823. if(wszFriendlyName)
  824. {
  825. awszProp[0]=(LPWSTR)wszFriendlyName;
  826. awszProp[1]=NULL;
  827. if(S_OK != (hr=CASetCertTypePropertyEx(
  828. hNewCertType,
  829. CERTTYPE_PROP_FRIENDLY_NAME,
  830. awszProp)))
  831. goto error;
  832. }
  833. //turn off autoenrollment bit
  834. if(0 == (CT_CLONE_KEEP_AUTOENROLLMENT_SETTING & dwFlags))
  835. {
  836. if(S_OK != (hr=CAGetCertTypeFlagsEx(
  837. hNewCertType,
  838. CERTTYPE_ENROLLMENT_FLAG,
  839. &dwEnrollmentFlag)))
  840. goto error;
  841. dwEnrollmentFlag &= (~CT_FLAG_AUTO_ENROLLMENT);
  842. if(S_OK != (hr=CASetCertTypeFlagsEx(
  843. hNewCertType,
  844. CERTTYPE_ENROLLMENT_FLAG,
  845. dwEnrollmentFlag)))
  846. goto error;
  847. }
  848. //turn off the subject name requirement for machien template
  849. if(0 == (CT_CLONE_KEEP_SUBJECT_NAME_SETTING & dwFlags))
  850. {
  851. if(S_OK != (hr=CAGetCertTypeFlagsEx(
  852. hNewCertType,
  853. CERTTYPE_GENERAL_FLAG,
  854. &dwGeneralFlag)))
  855. goto error;
  856. if(CT_FLAG_MACHINE_TYPE & dwGeneralFlag)
  857. {
  858. if(S_OK != (hr=CAGetCertTypeFlagsEx(
  859. hNewCertType,
  860. CERTTYPE_SUBJECT_NAME_FLAG,
  861. &dwSubjectNameFlag)))
  862. goto error;
  863. dwSubjectNameFlag &= (~dwSubjectRequirement);
  864. if(S_OK != (hr=CASetCertTypeFlagsEx(
  865. hNewCertType,
  866. CERTTYPE_SUBJECT_NAME_FLAG,
  867. dwSubjectNameFlag)))
  868. goto error;
  869. }
  870. }
  871. //get the client token
  872. if(!CertTypeRetrieveClientToken(&hToken))
  873. {
  874. hr = HRESULT_FROM_WIN32(GetLastError());
  875. goto error;
  876. }
  877. //get the client sid
  878. dwTokenUserSize=0;
  879. if(!GetTokenInformation(
  880. hToken, // handle to access token
  881. TokenUser, // token type
  882. NULL, // buffer
  883. 0, // size of buffer
  884. &dwTokenUserSize)) // required buffer size
  885. {
  886. if (ERROR_INSUFFICIENT_BUFFER!=GetLastError())
  887. {
  888. hr=HRESULT_FROM_WIN32(GetLastError());
  889. goto error;
  890. }
  891. }
  892. if(NULL==(pTokenUser=(TOKEN_USER *)LocalAlloc(LPTR, dwTokenUserSize)))
  893. {
  894. hr=E_OUTOFMEMORY;
  895. goto error;
  896. }
  897. if(!GetTokenInformation(
  898. hToken, // handle to access token
  899. TokenUser, // token type
  900. pTokenUser, // buffer
  901. dwTokenUserSize, // size of buffer
  902. &dwTokenUserSize)) // required buffer size
  903. {
  904. hr = HRESULT_FROM_WIN32(GetLastError());
  905. goto error;
  906. }
  907. //update the ACLs of the template to have the caller as the owner
  908. //of the ACL
  909. if(S_OK != (hr=CACertTypeGetSecurity(
  910. hNewCertType,
  911. &pSID)))
  912. goto error;
  913. if(!MakeAbsoluteSD(pSID, NULL, &dwAbsSDSize, NULL, &dwDaclSize, NULL, &dwSaclSize, NULL, &dwOwnerSize, NULL, &dwPriGrpSize))
  914. {
  915. if (ERROR_INSUFFICIENT_BUFFER!=GetLastError())
  916. {
  917. hr=HRESULT_FROM_WIN32(GetLastError());
  918. goto error;
  919. }
  920. }
  921. // allocate memory
  922. if(NULL==(pAbsSD=(PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, dwAbsSDSize)))
  923. {
  924. hr=E_OUTOFMEMORY;
  925. goto error;
  926. }
  927. if(NULL==(pAbsDacl=(ACL * )LocalAlloc(LPTR, dwDaclSize)))
  928. {
  929. hr=E_OUTOFMEMORY;
  930. goto error;
  931. }
  932. if(NULL==(pAbsSacl=(ACL * )LocalAlloc(LPTR, dwSaclSize)))
  933. {
  934. hr=E_OUTOFMEMORY;
  935. goto error;
  936. }
  937. if(NULL==(pAbsOwner=(SID *)LocalAlloc(LPTR, dwOwnerSize)))
  938. {
  939. hr=E_OUTOFMEMORY;
  940. goto error;
  941. }
  942. if(NULL==(pAbsPriGrp=(SID *)LocalAlloc(LPTR, dwPriGrpSize)))
  943. {
  944. hr=E_OUTOFMEMORY;
  945. goto error;
  946. }
  947. // copy the SD to the memory buffers
  948. if(!MakeAbsoluteSD(pSID, pAbsSD, &dwAbsSDSize, pAbsDacl, &dwDaclSize, pAbsSacl, &dwSaclSize, pAbsOwner, &dwOwnerSize, pAbsPriGrp, &dwPriGrpSize))
  949. {
  950. hr=HRESULT_FROM_WIN32(GetLastError());
  951. goto error;
  952. }
  953. if(!SetSecurityDescriptorOwner(
  954. pAbsSD, // SD
  955. (pTokenUser->User).Sid, // SID for owner
  956. FALSE)) // flag for default
  957. {
  958. hr=HRESULT_FROM_WIN32(GetLastError());
  959. goto error;
  960. }
  961. //convert the absolute SD to its relative form
  962. if(!MakeSelfRelativeSD(pAbsSD, NULL, &dwRelSDSize))
  963. {
  964. if (ERROR_INSUFFICIENT_BUFFER!=GetLastError())
  965. {
  966. hr=HRESULT_FROM_WIN32(GetLastError());
  967. goto error;
  968. }
  969. }
  970. // allocate memory
  971. if(NULL==(pNewSD=(PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, dwRelSDSize)))
  972. {
  973. hr=E_OUTOFMEMORY;
  974. goto error;
  975. }
  976. // copy the SD to the new memory buffer
  977. if (!MakeSelfRelativeSD(pAbsSD, pNewSD, &dwRelSDSize))
  978. {
  979. hr=HRESULT_FROM_WIN32(GetLastError());
  980. goto error;
  981. }
  982. //set the relative SID
  983. if(S_OK != (hr=CACertTypeSetSecurity(
  984. hNewCertType,
  985. pNewSD)))
  986. goto error;
  987. //update the template
  988. /* if(S_OK != (hr = CAUpdateCertType(hNewCertType)))
  989. goto error;
  990. //update the local machine cache. No need to check the return value
  991. //because the certificate template has been successfully cloned on the directory
  992. CAEnumCertTypesEx((LPCWSTR)pvldap,
  993. dwFindCT | CT_FIND_LOCAL_SYSTEM,
  994. &hMachineCertType); */
  995. *phCertType=hNewCertType;
  996. hNewCertType=NULL;
  997. hr=S_OK;
  998. error:
  999. if(hToken)
  1000. CloseHandle(hToken);
  1001. if(pTokenUser)
  1002. LocalFree(pTokenUser);
  1003. if(pSID)
  1004. LocalFree(pSID);
  1005. if (NULL!=pAbsSD)
  1006. LocalFree(pAbsSD);
  1007. if (NULL!=pAbsDacl)
  1008. LocalFree(pAbsDacl);
  1009. if (NULL!=pAbsSacl)
  1010. LocalFree(pAbsSacl);
  1011. if (NULL!=pAbsOwner)
  1012. LocalFree(pAbsOwner);
  1013. if (NULL!=pAbsPriGrp)
  1014. LocalFree(pAbsPriGrp);
  1015. if (NULL!=pNewSD)
  1016. LocalFree(pNewSD);
  1017. if(awszCN)
  1018. CAFreeCertTypeProperty(hCertType, awszCN);
  1019. if(hNewCertType)
  1020. CACloseCertType(hNewCertType);
  1021. return hr;
  1022. }
  1023. HRESULT
  1024. CAEnumNextCertType(
  1025. IN HCERTTYPE hPrevCertType,
  1026. OUT HCERTTYPE * phCertTypeInfo
  1027. )
  1028. {
  1029. CCertTypeInfo *pInfo;
  1030. if(hPrevCertType == NULL)
  1031. {
  1032. return E_POINTER;
  1033. }
  1034. pInfo = (CCertTypeInfo *)hPrevCertType;
  1035. return pInfo->Next((CCertTypeInfo **)phCertTypeInfo);
  1036. }
  1037. DWORD
  1038. CACountCertTypes(IN HCERTTYPE hCertType)
  1039. {
  1040. CCertTypeInfo *pInfo;
  1041. if(hCertType == NULL)
  1042. {
  1043. return 0;
  1044. }
  1045. pInfo = (CCertTypeInfo *)hCertType;
  1046. return pInfo->Count();
  1047. }
  1048. HRESULT
  1049. CACloseCertType(IN HCERTTYPE hCertTypeInfo)
  1050. {
  1051. CCertTypeInfo *pInfo;
  1052. if(hCertTypeInfo == NULL)
  1053. {
  1054. return E_POINTER;
  1055. }
  1056. pInfo = (CCertTypeInfo *)hCertTypeInfo;
  1057. return pInfo->Release();
  1058. }
  1059. HRESULT
  1060. CAGetCertTypeProperty(
  1061. IN HCERTTYPE hCertType,
  1062. IN LPCWSTR wszPropertyName,
  1063. OUT LPWSTR ** pawszPropertyValue)
  1064. {
  1065. CCertTypeInfo *pInfo;
  1066. if(hCertType == NULL)
  1067. {
  1068. return E_POINTER;
  1069. }
  1070. pInfo = (CCertTypeInfo *)hCertType;
  1071. return pInfo->GetProperty(wszPropertyName, pawszPropertyValue);
  1072. }
  1073. HRESULT
  1074. CAGetCertTypePropertyEx(
  1075. IN HCERTTYPE hCertType,
  1076. IN LPCWSTR wszPropertyName,
  1077. OUT LPVOID pPropertyValue)
  1078. {
  1079. CCertTypeInfo *pInfo;
  1080. if(hCertType == NULL)
  1081. {
  1082. return E_POINTER;
  1083. }
  1084. pInfo = (CCertTypeInfo *)hCertType;
  1085. return pInfo->GetPropertyEx(wszPropertyName, pPropertyValue);
  1086. }
  1087. HRESULT
  1088. CASetCertTypeProperty(
  1089. IN HCERTTYPE hCertType,
  1090. IN LPCWSTR wszPropertyName,
  1091. IN LPWSTR * awszPropertyValue)
  1092. {
  1093. CCertTypeInfo *pInfo;
  1094. if(hCertType == NULL)
  1095. {
  1096. return E_POINTER;
  1097. }
  1098. pInfo = (CCertTypeInfo *)hCertType;
  1099. return pInfo->SetProperty(wszPropertyName, awszPropertyValue) ;
  1100. }
  1101. HRESULT
  1102. CASetCertTypePropertyEx(
  1103. IN HCERTTYPE hCertType,
  1104. IN LPCWSTR wszPropertyName,
  1105. IN LPVOID pPropertyValue)
  1106. {
  1107. CCertTypeInfo *pInfo;
  1108. if(hCertType == NULL)
  1109. {
  1110. return E_POINTER;
  1111. }
  1112. pInfo = (CCertTypeInfo *)hCertType;
  1113. return pInfo->SetPropertyEx(wszPropertyName, pPropertyValue) ;
  1114. }
  1115. HRESULT
  1116. CAFreeCertTypeProperty(
  1117. IN HCERTTYPE hCertType,
  1118. LPWSTR * awszPropertyValue
  1119. )
  1120. {
  1121. CCertTypeInfo *pInfo;
  1122. if(hCertType == NULL)
  1123. {
  1124. return E_POINTER;
  1125. }
  1126. pInfo = (CCertTypeInfo *)hCertType;
  1127. return pInfo->FreeProperty(awszPropertyValue) ;
  1128. }
  1129. HRESULT
  1130. CAGetCertTypeExtensions(
  1131. IN HCERTTYPE hCertType,
  1132. OUT PCERT_EXTENSIONS * ppCertExtensions
  1133. )
  1134. {
  1135. return CAGetCertTypeExtensionsEx(hCertType, 0, NULL, ppCertExtensions);
  1136. }
  1137. HRESULT
  1138. CAGetCertTypeExtensionsEx(
  1139. IN HCERTTYPE hCertType,
  1140. IN DWORD dwFlags,
  1141. IN LPVOID pParam,
  1142. OUT PCERT_EXTENSIONS * ppCertExtensions
  1143. )
  1144. {
  1145. CCertTypeInfo *pInfo;
  1146. if(hCertType == NULL)
  1147. {
  1148. return E_POINTER;
  1149. }
  1150. pInfo = (CCertTypeInfo *)hCertType;
  1151. return pInfo->GetExtensions(dwFlags, pParam, ppCertExtensions) ;
  1152. }
  1153. HRESULT
  1154. CAFreeCertTypeExtensions(
  1155. IN HCERTTYPE hCertType,
  1156. IN PCERT_EXTENSIONS pCertExtensions
  1157. )
  1158. {
  1159. //should alreays free via LocalFree since CryptUIWizCertRequest freed
  1160. //it via LocalFree
  1161. CCertTypeInfo *pInfo;
  1162. if(pCertExtensions)
  1163. {
  1164. LocalFree(pCertExtensions);
  1165. }
  1166. return S_OK;
  1167. #if 0
  1168. if(hCertType == NULL)
  1169. {
  1170. return E_POINTER;
  1171. }
  1172. pInfo = (CCertTypeInfo *)hCertType;
  1173. return pInfo->FreeExtensions(pCertExtensions) ;
  1174. #endif
  1175. }
  1176. HRESULT
  1177. CASetCertTypeExtension(
  1178. IN HCERTTYPE hCertType,
  1179. IN LPCWSTR wszExtensionName,
  1180. IN DWORD dwFlags,
  1181. IN LPVOID pExtension
  1182. )
  1183. {
  1184. CCertTypeInfo *pInfo;
  1185. if(hCertType == NULL)
  1186. {
  1187. return E_POINTER;
  1188. }
  1189. pInfo = (CCertTypeInfo *)hCertType;
  1190. return pInfo->SetExtension(wszExtensionName, pExtension, dwFlags);
  1191. }
  1192. HRESULT
  1193. CAGetCertTypeFlags(
  1194. IN HCERTTYPE hCertType,
  1195. OUT DWORD * pdwFlags
  1196. )
  1197. {
  1198. return CAGetCertTypeFlagsEx(hCertType, CERTTYPE_GENERAL_FLAG, pdwFlags);
  1199. }
  1200. HRESULT
  1201. CAGetCertTypeFlagsEx(
  1202. IN HCERTTYPE hCertType,
  1203. IN DWORD dwOption,
  1204. OUT DWORD * pdwFlags
  1205. )
  1206. {
  1207. CCertTypeInfo *pInfo;
  1208. if(hCertType == NULL)
  1209. {
  1210. return E_POINTER;
  1211. }
  1212. if(pdwFlags == NULL)
  1213. {
  1214. return E_POINTER;
  1215. }
  1216. pInfo = (CCertTypeInfo *)hCertType;
  1217. *pdwFlags = pInfo->GetFlags(dwOption);
  1218. return S_OK;
  1219. }
  1220. HRESULT
  1221. CASetCertTypeFlags(
  1222. IN HCERTTYPE hCertType,
  1223. IN DWORD dwFlags
  1224. )
  1225. {
  1226. return CASetCertTypeFlagsEx(hCertType, CERTTYPE_GENERAL_FLAG, dwFlags);
  1227. }
  1228. HRESULT
  1229. CASetCertTypeFlagsEx(
  1230. IN HCERTTYPE hCertType,
  1231. IN DWORD dwOption,
  1232. IN DWORD dwFlags
  1233. )
  1234. {
  1235. CCertTypeInfo *pInfo;
  1236. if(hCertType == NULL)
  1237. {
  1238. return E_POINTER;
  1239. }
  1240. pInfo = (CCertTypeInfo *)hCertType;
  1241. return pInfo->SetFlags(dwOption, dwFlags);
  1242. }
  1243. HRESULT
  1244. CAGetCertTypeKeySpec(
  1245. IN HCERTTYPE hCertType,
  1246. OUT DWORD * pdwKeySpec
  1247. )
  1248. {
  1249. CCertTypeInfo *pInfo;
  1250. if(hCertType == NULL)
  1251. {
  1252. return E_POINTER;
  1253. }
  1254. if(pdwKeySpec == NULL)
  1255. {
  1256. return E_POINTER;
  1257. }
  1258. pInfo = (CCertTypeInfo *)hCertType;
  1259. *pdwKeySpec = pInfo->GetKeySpec();
  1260. return S_OK;
  1261. }
  1262. HRESULT
  1263. CASetCertTypeKeySpec(
  1264. IN HCERTTYPE hCertType,
  1265. IN DWORD dwKeySpec
  1266. )
  1267. {
  1268. CCertTypeInfo *pInfo;
  1269. if(hCertType == NULL)
  1270. {
  1271. return E_POINTER;
  1272. }
  1273. pInfo = (CCertTypeInfo *)hCertType;
  1274. pInfo->SetKeySpec(dwKeySpec);
  1275. return S_OK;
  1276. }
  1277. HRESULT
  1278. CAGetCertTypeExpiration(
  1279. IN HCERTTYPE hCertType,
  1280. OUT OPTIONAL FILETIME * pftExpiration,
  1281. OUT OPTIONAL FILETIME * pftOverlap
  1282. )
  1283. {
  1284. CCertTypeInfo *pInfo;
  1285. if(hCertType == NULL)
  1286. {
  1287. return E_POINTER;
  1288. }
  1289. pInfo = (CCertTypeInfo *)hCertType;
  1290. return pInfo->GetExpiration(pftExpiration, pftOverlap);
  1291. }
  1292. HRESULT
  1293. CASetCertTypeExpiration(
  1294. IN HCERTTYPE hCertType,
  1295. IN OPTIONAL FILETIME * pftExpiration,
  1296. IN OPTIONAL FILETIME * pftOverlap
  1297. )
  1298. {
  1299. CCertTypeInfo *pInfo;
  1300. if(hCertType == NULL)
  1301. {
  1302. return E_POINTER;
  1303. }
  1304. pInfo = (CCertTypeInfo *)hCertType;
  1305. return pInfo->SetExpiration(pftExpiration, pftOverlap);
  1306. }
  1307. HRESULT
  1308. CACertTypeSetSecurity(
  1309. IN HCERTTYPE hCertType,
  1310. IN PSECURITY_DESCRIPTOR pSD
  1311. )
  1312. {
  1313. CCertTypeInfo *pInfo;
  1314. if(hCertType == NULL)
  1315. {
  1316. return E_POINTER;
  1317. }
  1318. pInfo = (CCertTypeInfo *)hCertType;
  1319. return pInfo->SetSecurity( pSD );
  1320. }
  1321. HRESULT
  1322. CACertTypeGetSecurity(
  1323. IN HCERTTYPE hCertType,
  1324. OUT PSECURITY_DESCRIPTOR * ppSD
  1325. )
  1326. {
  1327. CCertTypeInfo *pInfo;
  1328. if(hCertType == NULL)
  1329. {
  1330. return E_POINTER;
  1331. }
  1332. pInfo = (CCertTypeInfo *)hCertType;
  1333. return pInfo->GetSecurity( ppSD ) ;
  1334. }
  1335. HRESULT
  1336. CACertTypeAccessCheck(
  1337. IN HCERTTYPE hCertType,
  1338. IN HANDLE ClientToken
  1339. )
  1340. {
  1341. return CACertTypeAccessCheckEx(hCertType, ClientToken, CERTTYPE_ACCESS_CHECK_ENROLL);
  1342. }
  1343. CERTCLIAPI
  1344. HRESULT
  1345. WINAPI
  1346. CACertTypeAccessCheckEx(
  1347. IN HCERTTYPE hCertType,
  1348. IN HANDLE ClientToken,
  1349. IN DWORD dwOption
  1350. )
  1351. {
  1352. CCertTypeInfo *pInfo;
  1353. if(hCertType == NULL)
  1354. {
  1355. return E_POINTER;
  1356. }
  1357. pInfo = (CCertTypeInfo *)hCertType;
  1358. return pInfo->AccessCheck(ClientToken, dwOption);
  1359. }
  1360. CERTCLIAPI
  1361. HRESULT
  1362. WINAPI
  1363. CAInstallDefaultCertType(
  1364. IN DWORD dwFlags
  1365. )
  1366. {
  1367. return CCertTypeInfo::InstallDefaultTypes();
  1368. }
  1369. CERTCLIAPI
  1370. BOOL
  1371. WINAPI
  1372. CAIsCertTypeCurrent(
  1373. IN DWORD dwFlags,
  1374. IN LPWSTR wszCertType
  1375. )
  1376. {
  1377. BOOL fCurrent=FALSE;
  1378. HRESULT hr=E_FAIL;
  1379. DWORD dwIndex=0;
  1380. DWORD dwVersion=0;
  1381. HCERTTYPE hCertType=NULL;
  1382. if(NULL==wszCertType)
  1383. goto error;
  1384. hr=CAFindCertTypeByName(
  1385. wszCertType,
  1386. NULL,
  1387. CT_ENUM_USER_TYPES | CT_FLAG_NO_CACHE_LOOKUP | CT_ENUM_MACHINE_TYPES,
  1388. &hCertType);
  1389. if((S_OK != hr) || (NULL==hCertType))
  1390. goto error;
  1391. //we assume this is a V2 certificate template
  1392. hr=CAGetCertTypePropertyEx(
  1393. hCertType,
  1394. CERTTYPE_PROP_REVISION,
  1395. &dwVersion);
  1396. if(S_OK != hr)
  1397. goto error;
  1398. for(dwIndex=0; dwIndex < g_cDefaultCertTypes; dwIndex++)
  1399. {
  1400. if (0==lstrcmpi(wszCertType, g_aDefaultCertTypes[dwIndex].wszName))
  1401. {
  1402. if (dwVersion >= g_aDefaultCertTypes[dwIndex].dwRevision)
  1403. fCurrent=TRUE;
  1404. break;
  1405. }
  1406. }
  1407. //the template is not default
  1408. if(dwIndex == g_cDefaultCertTypes)
  1409. fCurrent=TRUE;
  1410. error:
  1411. if(hCertType)
  1412. CACloseCertType(hCertType);
  1413. return fCurrent;
  1414. }
  1415. HANDLE
  1416. myEnterCriticalPolicySection(
  1417. IN BOOL bMachine)
  1418. {
  1419. HANDLE hPolicy = NULL;
  1420. HRESULT hr = S_OK;
  1421. // ?CriticalPolicySection calls are delay loaded. Protect with try/except
  1422. __try
  1423. {
  1424. hPolicy = EnterCriticalPolicySection(bMachine); // Delayload wrapped
  1425. }
  1426. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  1427. {
  1428. }
  1429. // (S_OK == hr) does not mean EnterCriticalPolicySection succeeded.
  1430. // It just means no exception was raised.
  1431. if (myIsDelayLoadHResult(hr))
  1432. {
  1433. hPolicy = (HANDLE) (ULONG_PTR) (bMachine? 37 : 49);
  1434. hr = S_OK;
  1435. }
  1436. return(hPolicy);
  1437. }
  1438. BOOL
  1439. myLeaveCriticalPolicySection(
  1440. IN HANDLE hSection)
  1441. {
  1442. HRESULT hr = S_OK;
  1443. BOOL fOk = FALSE;
  1444. // ?CriticalPolicySection calls are delay loaded. Protect with try/except
  1445. __try
  1446. {
  1447. fOk = LeaveCriticalPolicySection(hSection); // Delayload wrapped
  1448. }
  1449. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  1450. {
  1451. }
  1452. // (S_OK == hr) does not mean LeaveCriticalPolicySection succeeded.
  1453. // It just means no exception was raised.
  1454. if (myIsDelayLoadHResult(hr))
  1455. {
  1456. fOk = (HANDLE) (ULONG_PTR) 37 == hSection ||
  1457. (HANDLE) (ULONG_PTR) 49 == hSection;
  1458. hr = S_OK;
  1459. }
  1460. return(fOk);
  1461. }