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.

2045 lines
44 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 "certacl.h"
  19. #include "accctrl.h"
  20. #include <winldap.h>
  21. #define __dwFILE__ __dwFILE_CERTCLIB_CAINFO_CPP__
  22. typedef struct _CA_DEFAULT_PROVIDER {
  23. DWORD dwFlags;
  24. LPWSTR wszName;
  25. } CA_DEFAULT_PROVIDER;
  26. CA_DEFAULT_PROVIDER g_DefaultProviders[] =
  27. {
  28. {0, MS_DEF_PROV_W},
  29. {0, MS_ENHANCED_PROV_W},
  30. {0, MS_DEF_RSA_SIG_PROV_W},
  31. {0, MS_DEF_RSA_SCHANNEL_PROV_W},
  32. {0, MS_DEF_DSS_PROV_W},
  33. {0, MS_DEF_DSS_DH_PROV_W},
  34. {0, MS_ENH_DSS_DH_PROV_W},
  35. {0, MS_DEF_DH_SCHANNEL_PROV_W},
  36. {0, MS_SCARD_PROV_W}
  37. };
  38. DWORD g_cDefaultProviders = sizeof(g_DefaultProviders)/sizeof(g_DefaultProviders[0]);
  39. LPCWSTR
  40. CAGetDN(
  41. IN HCAINFO hCAInfo
  42. )
  43. {
  44. CSASSERT(hCAInfo);
  45. return ((CCAInfo*)hCAInfo)->GetDN();
  46. }
  47. HRESULT
  48. CAFindByName(
  49. IN LPCWSTR wszCAName,
  50. IN LPCWSTR wszScope,
  51. IN DWORD fFlags,
  52. OUT HCAINFO * phCAInfo
  53. )
  54. {
  55. HRESULT hr = S_OK;
  56. WCHAR *wszQueryBase = L"(cn=";
  57. WCHAR *wszQuery = NULL;
  58. DWORD cQuery;
  59. if((wszCAName == NULL) || (phCAInfo == NULL))
  60. {
  61. return E_POINTER;
  62. }
  63. // Generate Query
  64. cQuery = wcslen(wszQueryBase) + wcslen(wszCAName) + 2; // 2 for ending paren and null
  65. wszQuery = (WCHAR *)LocalAlloc(LMEM_FIXED, sizeof(WCHAR)*cQuery);
  66. if(wszQuery == NULL)
  67. {
  68. hr = E_OUTOFMEMORY;
  69. goto error;
  70. }
  71. wcscpy(wszQuery, wszQueryBase);
  72. wcscat(wszQuery, wszCAName);
  73. wcscat(wszQuery, L")");
  74. if(fFlags & CA_FLAG_SCOPE_DNS)
  75. {
  76. hr = CCAInfo::FindDnsDomain(wszQuery, wszScope, fFlags, (CCAInfo **)phCAInfo);
  77. }
  78. else
  79. {
  80. hr = CCAInfo::Find(wszQuery, wszScope, fFlags, (CCAInfo **)phCAInfo);
  81. }
  82. if((hr == S_OK) &&
  83. (*phCAInfo == NULL))
  84. {
  85. hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
  86. }
  87. error:
  88. if(wszQuery)
  89. {
  90. LocalFree(wszQuery);
  91. }
  92. return hr;
  93. }
  94. HRESULT
  95. CAFindByCertType(
  96. IN LPCWSTR wszCertType,
  97. IN LPCWSTR wszScope,
  98. IN DWORD fFlags,
  99. OUT HCAINFO * phCAInfo
  100. )
  101. {
  102. HRESULT hr = S_OK;
  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. WCHAR *wszQueryBase = wszLPAREN L"cACertificateDN=";
  150. WCHAR *wszQuery = NULL;
  151. WCHAR *wszNameStr = NULL;
  152. DWORD cQuery;
  153. if((pIssuerDN == NULL) || (phCAInfo == NULL))
  154. {
  155. return E_POINTER;
  156. }
  157. // Generate Query
  158. // Convert the CAPI2 name to a string
  159. hr = myCertNameToStr(
  160. X509_ASN_ENCODING,
  161. pIssuerDN,
  162. CERT_X500_NAME_STR |
  163. CERT_NAME_STR_REVERSE_FLAG |
  164. CERT_NAME_STR_NO_QUOTING_FLAG,
  165. &wszNameStr);
  166. _JumpIfError(hr, error, "myCertNameToStr");
  167. // Now quote that string with double quotes
  168. // two for ending paren and null, two for the double quotes
  169. cQuery = wcslen(wszQueryBase) + wcslen(wszNameStr) + 4;
  170. wszQuery = (WCHAR *)LocalAlloc(LMEM_FIXED, sizeof(WCHAR)*cQuery);
  171. if(wszQuery == NULL)
  172. {
  173. hr = E_OUTOFMEMORY;
  174. goto error;
  175. }
  176. wcscpy(wszQuery, wszQueryBase);
  177. //wcscat(wszQuery, L"\"");
  178. wcscat(wszQuery, wszNameStr);
  179. //wcscat(wszQuery, L"\"" wszRPAREN);
  180. wcscat(wszQuery, 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. if((wszCAName == NULL) || (phCAInfo == NULL))
  257. {
  258. return E_POINTER;
  259. }
  260. // Generate Query
  261. if(CA_FLAG_SCOPE_DNS & fFlags)
  262. {
  263. hr = CCAInfo::CreateDnsDomain(wszCAName, wszScope, (CCAInfo **)phCAInfo);
  264. }
  265. else
  266. {
  267. hr = CCAInfo::Create(wszCAName, wszScope, (CCAInfo **)phCAInfo);
  268. }
  269. return hr;
  270. }
  271. HRESULT
  272. CAUpdateCA(
  273. IN HCAINFO hCAInfo
  274. )
  275. {
  276. CCAInfo *pInfo;
  277. if(hCAInfo == NULL)
  278. {
  279. return E_POINTER;
  280. }
  281. pInfo = (CCAInfo *)hCAInfo;
  282. return pInfo->Update();
  283. }
  284. HRESULT
  285. CADeleteCA(
  286. IN HCAINFO hCAInfo
  287. )
  288. {
  289. CCAInfo *pInfo;
  290. if(hCAInfo == NULL)
  291. {
  292. return E_POINTER;
  293. }
  294. pInfo = (CCAInfo *)hCAInfo;
  295. return pInfo->Delete();
  296. }
  297. DWORD
  298. CACountCAs(IN HCAINFO hCAInfo)
  299. {
  300. CCAInfo *pInfo;
  301. if(hCAInfo == NULL)
  302. {
  303. return 0;
  304. }
  305. pInfo = (CCAInfo *)hCAInfo;
  306. return pInfo->Count();
  307. }
  308. HRESULT
  309. CACloseCA(IN HCAINFO hCAInfo)
  310. {
  311. CCAInfo *pInfo;
  312. if(hCAInfo == NULL)
  313. {
  314. return E_POINTER;
  315. }
  316. pInfo = (CCAInfo *)hCAInfo;
  317. return pInfo->Release();
  318. }
  319. HRESULT
  320. CAGetCAProperty(
  321. IN HCAINFO hCAInfo,
  322. IN LPCWSTR wszPropertyName,
  323. OUT LPWSTR ** pawszPropertyValue)
  324. {
  325. CCAInfo *pInfo;
  326. if(hCAInfo == NULL)
  327. {
  328. return E_POINTER;
  329. }
  330. pInfo = (CCAInfo *)hCAInfo;
  331. return pInfo->GetProperty(wszPropertyName, pawszPropertyValue);
  332. }
  333. HRESULT
  334. CAFreeCAProperty(
  335. IN HCAINFO hCAInfo,
  336. IN LPWSTR * awszPropertyValue
  337. )
  338. {
  339. CCAInfo *pInfo;
  340. if(hCAInfo == NULL)
  341. {
  342. return E_POINTER;
  343. }
  344. pInfo = (CCAInfo *)hCAInfo;
  345. return pInfo->FreeProperty(awszPropertyValue);
  346. }
  347. HRESULT
  348. CASetCAProperty(
  349. IN HCAINFO hCAInfo,
  350. IN LPCWSTR wszPropertyName,
  351. IN LPWSTR * awszPropertyValue)
  352. {
  353. CCAInfo *pInfo;
  354. if(hCAInfo == NULL)
  355. {
  356. return E_POINTER;
  357. }
  358. pInfo = (CCAInfo *)hCAInfo;
  359. return pInfo->SetProperty(wszPropertyName, awszPropertyValue);
  360. }
  361. HRESULT
  362. CAGetCAFlags(
  363. IN HCAINFO hCAInfo,
  364. OUT DWORD * pdwFlags
  365. )
  366. {
  367. CCAInfo *pInfo;
  368. if(hCAInfo == NULL)
  369. {
  370. return E_POINTER;
  371. }
  372. if(pdwFlags == NULL)
  373. {
  374. return E_POINTER;
  375. }
  376. pInfo = (CCAInfo *)hCAInfo;
  377. *pdwFlags = pInfo->GetFlags();
  378. return S_OK;
  379. }
  380. HRESULT
  381. CASetCAFlags(
  382. IN HCAINFO hCAInfo,
  383. IN DWORD dwFlags
  384. )
  385. {
  386. CCAInfo *pInfo;
  387. if(hCAInfo == NULL)
  388. {
  389. return E_POINTER;
  390. }
  391. pInfo = (CCAInfo *)hCAInfo;
  392. pInfo->SetFlags(dwFlags);
  393. return S_OK;
  394. }
  395. HRESULT
  396. CAGetCACertificate(
  397. IN HCAINFO hCAInfo,
  398. OUT PCCERT_CONTEXT *ppCert)
  399. {
  400. CCAInfo *pInfo;
  401. if(hCAInfo == NULL)
  402. {
  403. return E_POINTER;
  404. }
  405. pInfo = (CCAInfo *)hCAInfo;
  406. return pInfo->GetCertificate(ppCert);
  407. }
  408. HRESULT
  409. CASetCACertificate(
  410. IN HCAINFO hCAInfo,
  411. IN PCCERT_CONTEXT pCert)
  412. {
  413. CCAInfo *pInfo;
  414. if(hCAInfo == NULL)
  415. {
  416. return E_POINTER;
  417. }
  418. pInfo = (CCAInfo *)hCAInfo;
  419. return pInfo->SetCertificate(pCert);
  420. }
  421. HRESULT
  422. CAGetCAExpiration(
  423. HCAINFO hCAInfo,
  424. DWORD * pdwExpiration,
  425. DWORD * pdwUnits
  426. )
  427. {
  428. CCAInfo *pInfo;
  429. if(hCAInfo == NULL)
  430. {
  431. return E_POINTER;
  432. }
  433. pInfo = (CCAInfo *)hCAInfo;
  434. return pInfo->GetExpiration(pdwExpiration, pdwUnits);
  435. }
  436. HRESULT
  437. CASetCAExpiration(
  438. HCAINFO hCAInfo,
  439. DWORD dwExpiration,
  440. DWORD dwUnits
  441. )
  442. {
  443. CCAInfo *pInfo;
  444. if(hCAInfo == NULL)
  445. {
  446. return E_POINTER;
  447. }
  448. pInfo = (CCAInfo *)hCAInfo;
  449. return pInfo->SetExpiration(dwExpiration, dwUnits);
  450. }
  451. HRESULT
  452. CASetCASecurity(
  453. IN HCAINFO hCAInfo,
  454. IN PSECURITY_DESCRIPTOR pSD
  455. )
  456. {
  457. CCAInfo *pInfo;
  458. if(hCAInfo == NULL)
  459. {
  460. return E_POINTER;
  461. }
  462. pInfo = (CCAInfo *)hCAInfo;
  463. return pInfo->SetSecurity( pSD );
  464. }
  465. HRESULT
  466. CAGetCASecurity(
  467. IN HCAINFO hCAInfo,
  468. OUT PSECURITY_DESCRIPTOR * ppSD
  469. )
  470. {
  471. CCAInfo *pInfo;
  472. if(hCAInfo == NULL)
  473. {
  474. return E_POINTER;
  475. }
  476. pInfo = (CCAInfo *)hCAInfo;
  477. return pInfo->GetSecurity( ppSD ) ;
  478. }
  479. CERTCLIAPI
  480. HRESULT
  481. WINAPI
  482. CAAccessCheck(
  483. IN HCAINFO hCAInfo,
  484. IN HANDLE ClientToken
  485. )
  486. {
  487. CCAInfo *pInfo;
  488. if(hCAInfo == NULL)
  489. {
  490. return E_POINTER;
  491. }
  492. pInfo = (CCAInfo *)hCAInfo;
  493. return pInfo->AccessCheck(ClientToken,CERTTYPE_ACCESS_CHECK_ENROLL);
  494. }
  495. CERTCLIAPI
  496. HRESULT
  497. WINAPI
  498. CAAccessCheckEx(
  499. IN HCAINFO hCAInfo,
  500. IN HANDLE ClientToken,
  501. IN DWORD dwOption
  502. )
  503. {
  504. CCAInfo *pInfo;
  505. if(hCAInfo == NULL)
  506. {
  507. return E_POINTER;
  508. }
  509. pInfo = (CCAInfo *)hCAInfo;
  510. return pInfo->AccessCheck(ClientToken,dwOption);
  511. }
  512. HRESULT
  513. CAEnumCertTypesForCAEx(
  514. IN HCAINFO hCAInfo,
  515. IN LPCWSTR wszScope,
  516. IN DWORD dwFlags,
  517. OUT HCERTTYPE * phCertType
  518. )
  519. {
  520. CCAInfo *pInfo;
  521. if(hCAInfo == NULL)
  522. {
  523. return E_POINTER;
  524. }
  525. pInfo = (CCAInfo *)hCAInfo;
  526. if(dwFlags & CA_FLAG_ENUM_ALL_TYPES)
  527. {
  528. return CCertTypeInfo::Enum(wszScope,
  529. dwFlags,
  530. (CCertTypeInfo **)phCertType);
  531. }
  532. return pInfo->EnumSupportedCertTypesEx(wszScope,
  533. dwFlags,
  534. (CCertTypeInfo **)phCertType);
  535. }
  536. HRESULT
  537. CAEnumCertTypesForCA(
  538. IN HCAINFO hCAInfo,
  539. IN DWORD dwFlags,
  540. OUT HCERTTYPE * phCertType
  541. )
  542. {
  543. return CAEnumCertTypesForCAEx(hCAInfo,
  544. NULL,
  545. dwFlags,
  546. phCertType);
  547. }
  548. HRESULT
  549. CAAddCACertificateType(
  550. HCAINFO hCAInfo,
  551. HCERTTYPE hCertType
  552. )
  553. {
  554. CCAInfo *pInfo;
  555. if(hCAInfo == NULL)
  556. {
  557. return E_POINTER;
  558. }
  559. pInfo = (CCAInfo *)hCAInfo;
  560. return pInfo->AddCertType((CCertTypeInfo *)hCertType);
  561. }
  562. HRESULT
  563. CARemoveCACertificateType(
  564. HCAINFO hCAInfo,
  565. HCERTTYPE hCertType
  566. )
  567. {
  568. CCAInfo *pInfo;
  569. if(hCAInfo == NULL)
  570. {
  571. return E_POINTER;
  572. }
  573. pInfo = (CCAInfo *)hCAInfo;
  574. return pInfo->RemoveCertType((CCertTypeInfo *)hCertType);
  575. }
  576. //
  577. // Certificate Type API's
  578. //
  579. HRESULT
  580. CAEnumCertTypes(
  581. IN DWORD dwFlags,
  582. OUT HCERTTYPE * phCertType
  583. )
  584. {
  585. HRESULT hr;
  586. hr = CCertTypeInfo::Enum(NULL,
  587. dwFlags,
  588. (CCertTypeInfo **)phCertType);
  589. return hr;
  590. }
  591. HRESULT
  592. CAEnumCertTypesEx(
  593. IN LPCWSTR wszScope,
  594. IN DWORD dwFlags,
  595. OUT HCERTTYPE * phCertType
  596. )
  597. {
  598. HRESULT hr;
  599. hr = CCertTypeInfo::Enum(wszScope,
  600. dwFlags,
  601. (CCertTypeInfo **)phCertType);
  602. return hr;
  603. }
  604. HRESULT
  605. CAFindCertTypeByName(
  606. IN LPCWSTR wszCertType,
  607. IN HCAINFO hCAInfo,
  608. IN DWORD dwFlags,
  609. OUT HCERTTYPE * phCertType
  610. )
  611. {
  612. HRESULT hr = S_OK;
  613. LPCWSTR awszTypes[2];
  614. if((wszCertType == NULL) || (phCertType == NULL))
  615. {
  616. return E_POINTER;
  617. }
  618. awszTypes[0] = wszCertType;
  619. awszTypes[1] = NULL;
  620. hr = CCertTypeInfo::FindByNames(awszTypes,
  621. ((CT_FLAG_SCOPE_IS_LDAP_HANDLE & dwFlags)?(LPWSTR)hCAInfo:NULL),
  622. dwFlags,
  623. (CCertTypeInfo **)phCertType);
  624. if((hr == S_OK) && (*phCertType == NULL))
  625. {
  626. hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
  627. }
  628. return hr;
  629. }
  630. HRESULT
  631. CACreateCertType(
  632. IN LPCWSTR wszCertType,
  633. IN LPCWSTR wszScope,
  634. IN DWORD, // fFlags
  635. OUT HCERTTYPE * phCertType
  636. )
  637. {
  638. HRESULT hr = S_OK;
  639. if((wszCertType == NULL) || (phCertType == NULL))
  640. {
  641. return E_POINTER;
  642. }
  643. hr = CCertTypeInfo::Create(wszCertType, wszScope, (CCertTypeInfo **)phCertType);
  644. return hr;
  645. }
  646. HRESULT
  647. CAUpdateCertType(
  648. IN HCERTTYPE hCertType
  649. )
  650. {
  651. CCertTypeInfo *pInfo;
  652. if(hCertType == NULL)
  653. {
  654. return E_POINTER;
  655. }
  656. pInfo = (CCertTypeInfo *)hCertType;
  657. return pInfo->Update();
  658. }
  659. HRESULT
  660. CADeleteCertType(
  661. IN HCERTTYPE hCertType
  662. )
  663. {
  664. CCertTypeInfo *pInfo;
  665. if(hCertType == NULL)
  666. {
  667. return E_POINTER;
  668. }
  669. pInfo = (CCertTypeInfo *)hCertType;
  670. return pInfo->Delete();
  671. }
  672. //--------------------------------------------------------------------
  673. //
  674. // CertTypeRetrieveClientToken
  675. //
  676. //--------------------------------------------------------------------
  677. BOOL CertTypeRetrieveClientToken(HANDLE *phToken)
  678. {
  679. HRESULT hr = S_OK;
  680. HANDLE hHandle = NULL;
  681. HANDLE hClientToken = NULL;
  682. hHandle = GetCurrentThread();
  683. if (NULL == hHandle)
  684. {
  685. hr = myHLastError();
  686. }
  687. else
  688. {
  689. if (!OpenThreadToken(hHandle,
  690. TOKEN_QUERY,
  691. TRUE, // open as self
  692. &hClientToken))
  693. {
  694. hr = myHLastError();
  695. CloseHandle(hHandle);
  696. hHandle = NULL;
  697. }
  698. }
  699. if(hr != S_OK)
  700. {
  701. hHandle = GetCurrentProcess();
  702. if (NULL == hHandle)
  703. {
  704. hr = myHLastError();
  705. }
  706. else
  707. {
  708. HANDLE hProcessToken = NULL;
  709. hr = S_OK;
  710. if (!OpenProcessToken(hHandle,
  711. TOKEN_DUPLICATE,
  712. &hProcessToken))
  713. {
  714. hr = myHLastError();
  715. CloseHandle(hHandle);
  716. hHandle = NULL;
  717. }
  718. else
  719. {
  720. if(!DuplicateToken(hProcessToken,
  721. SecurityImpersonation,
  722. &hClientToken))
  723. {
  724. hr = myHLastError();
  725. CloseHandle(hHandle);
  726. hHandle = NULL;
  727. }
  728. CloseHandle(hProcessToken);
  729. }
  730. }
  731. }
  732. if(S_OK == hr)
  733. *phToken = hClientToken;
  734. if(hHandle)
  735. CloseHandle(hHandle);
  736. return (S_OK == hr);
  737. }
  738. HRESULT
  739. CACloneCertType(
  740. IN HCERTTYPE hCertType,
  741. IN LPCWSTR wszCertType,
  742. IN LPCWSTR wszFriendlyName,
  743. IN LPVOID pvldap,
  744. IN DWORD dwFlags,
  745. OUT HCERTTYPE * phCertType
  746. )
  747. {
  748. HRESULT hr=E_INVALIDARG;
  749. DWORD dwFindCT=CT_FLAG_NO_CACHE_LOOKUP | CT_ENUM_MACHINE_TYPES | CT_ENUM_USER_TYPES;
  750. LPWSTR awszProp[2];
  751. DWORD dwEnrollmentFlag=0;
  752. DWORD dwSubjectNameFlag=0;
  753. DWORD dwGeneralFlag=0;
  754. DWORD dwSubjectRequirement=CT_FLAG_SUBJECT_REQUIRE_DIRECTORY_PATH |
  755. CT_FLAG_SUBJECT_REQUIRE_COMMON_NAME |
  756. CT_FLAG_SUBJECT_REQUIRE_EMAIL |
  757. CT_FLAG_SUBJECT_REQUIRE_DNS_AS_CN;
  758. DWORD dwTokenUserSize=0;
  759. DWORD dwAbsSDSize=0;
  760. DWORD dwDaclSize=0;
  761. DWORD dwSaclSize=0;
  762. DWORD dwOwnerSize=0;
  763. DWORD dwPriGrpSize=0;
  764. DWORD dwRelSDSize=0;
  765. ACL_SIZE_INFORMATION aclsizeinfo;
  766. DWORD dwNewAclSize=0;
  767. ACE_HEADER *pFirstAce=NULL;
  768. PACL pAcl=NULL;
  769. BOOL bAclPresent=FALSE;
  770. BOOL bDefaultAcl=FALSE;
  771. DWORD nIndex=0;
  772. BOOL fAddAce=TRUE;
  773. DWORD dwCount=0;
  774. HANDLE hToken=NULL;
  775. TOKEN_USER *pTokenUser=NULL;
  776. PSECURITY_DESCRIPTOR pSID=NULL;
  777. PSECURITY_DESCRIPTOR pAbsSD=NULL;
  778. ACL * pAbsDacl=NULL;
  779. ACL * pAbsSacl=NULL;
  780. SID * pAbsOwner=NULL;
  781. SID * pAbsPriGrp=NULL;
  782. PSECURITY_DESCRIPTOR pNewSD=NULL;
  783. LPWSTR * awszCN=NULL;
  784. HCERTTYPE hNewCertType=NULL;
  785. ACL *pNewDacl=NULL;
  786. DWORD *pdwIndex=NULL;
  787. if((NULL==hCertType) || (NULL==wszCertType) || (NULL==phCertType))
  788. goto error;
  789. *phCertType=NULL;
  790. if(pvldap)
  791. dwFindCT |= CT_FLAG_SCOPE_IS_LDAP_HANDLE;
  792. //make sure the new name does not exit
  793. if(S_OK == CAFindCertTypeByName(
  794. wszCertType,
  795. (HCAINFO)pvldap,
  796. dwFindCT,
  797. &hNewCertType))
  798. {
  799. hr=CRYPT_E_EXISTS;
  800. goto error;
  801. }
  802. //get a new cert type handle
  803. if(S_OK != (hr = CAGetCertTypePropertyEx(hCertType,
  804. CERTTYPE_PROP_CN,
  805. &awszCN)))
  806. goto error;
  807. if((NULL==awszCN) || (NULL==awszCN[0]))
  808. {
  809. hr=HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
  810. goto error;
  811. }
  812. if(S_OK != (hr = CAFindCertTypeByName(
  813. (LPCWSTR)awszCN[0],
  814. (HCAINFO)pvldap,
  815. dwFindCT,
  816. &hNewCertType)))
  817. goto error;
  818. if(NULL==hNewCertType)
  819. {
  820. hr=HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
  821. goto error;
  822. }
  823. //clone by setting the CN
  824. awszProp[0]=(LPWSTR)wszCertType;
  825. awszProp[1]=NULL;
  826. if(S_OK != (hr=CASetCertTypePropertyEx(
  827. hNewCertType,
  828. CERTTYPE_PROP_CN,
  829. awszProp)))
  830. goto error;
  831. //set the friendly name
  832. if(wszFriendlyName)
  833. {
  834. awszProp[0]=(LPWSTR)wszFriendlyName;
  835. awszProp[1]=NULL;
  836. if(S_OK != (hr=CASetCertTypePropertyEx(
  837. hNewCertType,
  838. CERTTYPE_PROP_FRIENDLY_NAME,
  839. awszProp)))
  840. goto error;
  841. }
  842. //turn off autoenrollment bit
  843. if(0 == (CT_CLONE_KEEP_AUTOENROLLMENT_SETTING & dwFlags))
  844. {
  845. if(S_OK != (hr=CAGetCertTypeFlagsEx(
  846. hNewCertType,
  847. CERTTYPE_ENROLLMENT_FLAG,
  848. &dwEnrollmentFlag)))
  849. goto error;
  850. dwEnrollmentFlag &= (~CT_FLAG_AUTO_ENROLLMENT);
  851. if(S_OK != (hr=CASetCertTypeFlagsEx(
  852. hNewCertType,
  853. CERTTYPE_ENROLLMENT_FLAG,
  854. dwEnrollmentFlag)))
  855. goto error;
  856. }
  857. //turn off the subject name requirement for machien template
  858. if(0 == (CT_CLONE_KEEP_SUBJECT_NAME_SETTING & dwFlags))
  859. {
  860. if(S_OK != (hr=CAGetCertTypeFlagsEx(
  861. hNewCertType,
  862. CERTTYPE_GENERAL_FLAG,
  863. &dwGeneralFlag)))
  864. goto error;
  865. if(CT_FLAG_MACHINE_TYPE & dwGeneralFlag)
  866. {
  867. if(S_OK != (hr=CAGetCertTypeFlagsEx(
  868. hNewCertType,
  869. CERTTYPE_SUBJECT_NAME_FLAG,
  870. &dwSubjectNameFlag)))
  871. goto error;
  872. dwSubjectNameFlag &= (~dwSubjectRequirement);
  873. if(S_OK != (hr=CASetCertTypeFlagsEx(
  874. hNewCertType,
  875. CERTTYPE_SUBJECT_NAME_FLAG,
  876. dwSubjectNameFlag)))
  877. goto error;
  878. }
  879. }
  880. //get the client token
  881. if(!CertTypeRetrieveClientToken(&hToken))
  882. {
  883. hr = myHLastError();
  884. goto error;
  885. }
  886. //get the client sid
  887. dwTokenUserSize=0;
  888. if(!GetTokenInformation(
  889. hToken, // handle to access token
  890. TokenUser, // token type
  891. NULL, // buffer
  892. 0, // size of buffer
  893. &dwTokenUserSize)) // required buffer size
  894. {
  895. if (ERROR_INSUFFICIENT_BUFFER!=GetLastError())
  896. {
  897. hr = myHLastError();
  898. goto error;
  899. }
  900. }
  901. if(NULL==(pTokenUser=(TOKEN_USER *)LocalAlloc(LPTR, dwTokenUserSize)))
  902. {
  903. hr=E_OUTOFMEMORY;
  904. goto error;
  905. }
  906. if(!GetTokenInformation(
  907. hToken, // handle to access token
  908. TokenUser, // token type
  909. pTokenUser, // buffer
  910. dwTokenUserSize, // size of buffer
  911. &dwTokenUserSize)) // required buffer size
  912. {
  913. hr = myHLastError();
  914. goto error;
  915. }
  916. //update the ACLs of the template to have the caller as the owner
  917. //of the ACL
  918. if(S_OK != (hr=CACertTypeGetSecurity(
  919. hNewCertType,
  920. &pSID)))
  921. goto error;
  922. //we will delete all ACCESS_DENIED ACEs for the caller
  923. // get the (D)ACL from the security descriptor
  924. if (!GetSecurityDescriptorDacl(pSID, &bAclPresent, &pAcl, &bDefaultAcl))
  925. {
  926. hr = myHLastError();
  927. _JumpError(hr, error, "GetSecurityDescriptorDacl");
  928. }
  929. if(FALSE == bAclPresent)
  930. {
  931. hr=HRESULT_FROM_WIN32(ERROR_INVALID_SECURITY_DESCR);
  932. _JumpError(hr, error, "IsValidSecurityDescriptor");
  933. }
  934. // NULL acl -> allow all access
  935. if (NULL != pAcl)
  936. {
  937. // find out how many ACEs
  938. memset(&aclsizeinfo, 0, sizeof(aclsizeinfo));
  939. if (!GetAclInformation(pAcl, &aclsizeinfo, sizeof(aclsizeinfo), AclSizeInformation))
  940. {
  941. hr = myHLastError();
  942. _JumpError(hr, error, "GetAclInformation");
  943. }
  944. pdwIndex=(DWORD *)LocalAlloc(LPTR, sizeof(DWORD) * (aclsizeinfo.AceCount));
  945. if(NULL==pdwIndex)
  946. {
  947. hr=E_OUTOFMEMORY;
  948. goto error;
  949. }
  950. memset(pdwIndex, 0, sizeof(DWORD) * (aclsizeinfo.AceCount));
  951. dwCount=0;
  952. for (nIndex=0; nIndex < aclsizeinfo.AceCount; nIndex++)
  953. {
  954. ACE_HEADER * pAceHeader=NULL;
  955. ACCESS_ALLOWED_ACE * pAccessAce=NULL;
  956. PSID pSid=NULL;
  957. if (!GetAce(pAcl, nIndex, (void**)&pAceHeader))
  958. {
  959. hr = myHLastError();
  960. _JumpError(hr, error, "GetAce");
  961. }
  962. // find the sid for this ACE
  963. if ((ACCESS_ALLOWED_ACE_TYPE != pAceHeader->AceType) && (ACCESS_DENIED_ACE_TYPE != pAceHeader->AceType))
  964. {
  965. // we are only interested in ace types
  966. continue;
  967. }
  968. // note that ACCESS_ALLOWED_ACE and ACCESS_DENIED_ACE are the same structurally.
  969. pAccessAce=(ACCESS_ALLOWED_ACE *)pAceHeader;
  970. pSid=((BYTE *)&(pAccessAce->SidStart));
  971. // make sure this is the sid we are looking for
  972. if (!EqualSid(pSid, (pTokenUser->User).Sid))
  973. {
  974. continue;
  975. }
  976. if(ACCESS_ALLOWED_ACE_TYPE == pAceHeader->AceType)
  977. {
  978. //change it to allowed for everything
  979. fAddAce=FALSE;
  980. pAceHeader->AceType=ACCESS_ALLOWED_ACE_TYPE;
  981. pAccessAce->Mask=(pAccessAce->Mask) | (ACTRL_CERTSRV_MANAGE_LESS_CONTROL_ACCESS);
  982. }
  983. else
  984. {
  985. //delete the denied ace
  986. if(ACCESS_DENIED_ACE_TYPE == pAceHeader->AceType)
  987. {
  988. pdwIndex[dwCount]=nIndex;
  989. dwCount++;
  990. }
  991. }
  992. }
  993. if(!MakeAbsoluteSD(pSID, NULL, &dwAbsSDSize, NULL, &dwDaclSize, NULL, &dwSaclSize, NULL, &dwOwnerSize, NULL, &dwPriGrpSize))
  994. {
  995. if (ERROR_INSUFFICIENT_BUFFER!=GetLastError())
  996. {
  997. hr = myHLastError();
  998. goto error;
  999. }
  1000. }
  1001. // allocate memory
  1002. if(NULL==(pAbsSD=(PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, dwAbsSDSize)))
  1003. {
  1004. hr=E_OUTOFMEMORY;
  1005. goto error;
  1006. }
  1007. if(NULL==(pAbsDacl=(ACL * )LocalAlloc(LPTR, dwDaclSize)))
  1008. {
  1009. hr=E_OUTOFMEMORY;
  1010. goto error;
  1011. }
  1012. if(NULL==(pAbsSacl=(ACL * )LocalAlloc(LPTR, dwSaclSize)))
  1013. {
  1014. hr=E_OUTOFMEMORY;
  1015. goto error;
  1016. }
  1017. if(NULL==(pAbsOwner=(SID *)LocalAlloc(LPTR, dwOwnerSize)))
  1018. {
  1019. hr=E_OUTOFMEMORY;
  1020. goto error;
  1021. }
  1022. if(NULL==(pAbsPriGrp=(SID *)LocalAlloc(LPTR, dwPriGrpSize)))
  1023. {
  1024. hr=E_OUTOFMEMORY;
  1025. goto error;
  1026. }
  1027. // copy the SD to the memory buffers
  1028. if(!MakeAbsoluteSD(pSID, pAbsSD, &dwAbsSDSize, pAbsDacl, &dwDaclSize, pAbsSacl, &dwSaclSize, pAbsOwner, &dwOwnerSize, pAbsPriGrp, &dwPriGrpSize))
  1029. {
  1030. hr = myHLastError();
  1031. goto error;
  1032. }
  1033. // get the current size info for the dacl
  1034. memset(&aclsizeinfo, 0, sizeof(aclsizeinfo));
  1035. if(!GetAclInformation(pAbsDacl, &aclsizeinfo, sizeof(aclsizeinfo), AclSizeInformation))
  1036. {
  1037. hr = myHLastError();
  1038. _JumpError(hr, error, "GetAclInformation");
  1039. }
  1040. // figure out the new size
  1041. dwNewAclSize=aclsizeinfo.AclBytesInUse
  1042. +sizeof(ACCESS_ALLOWED_ACE)
  1043. -sizeof(DWORD) //ACCESS_ALLOWED_ACE::SidStart
  1044. +GetLengthSid((pTokenUser->User).Sid);
  1045. // allocate memory
  1046. pNewDacl=(ACL *)LocalAlloc(LPTR, dwNewAclSize);
  1047. if(NULL == pNewDacl)
  1048. {
  1049. hr=E_OUTOFMEMORY;
  1050. _JumpError(hr, error, "LocalAlloc");
  1051. }
  1052. // init the header
  1053. if(!InitializeAcl(pNewDacl, dwNewAclSize, ACL_REVISION_DS))
  1054. {
  1055. hr = myHLastError();
  1056. _JumpError(hr, error, "InitializeAcl");
  1057. }
  1058. // find the first ace in the dacl
  1059. if(!GetAce(pAbsDacl, 0, (void **)&pFirstAce))
  1060. {
  1061. hr = myHLastError();
  1062. _JumpError(hr, error, "GetAce");
  1063. }
  1064. // add all the old aces
  1065. if(!AddAce(pNewDacl, ACL_REVISION_DS, 0, pFirstAce, aclsizeinfo.AclBytesInUse-sizeof(ACL)))
  1066. {
  1067. hr = myHLastError();
  1068. _JumpError(hr, error, "AddAce");
  1069. }
  1070. //delete ACEs
  1071. for(nIndex=0; nIndex < dwCount; nIndex++)
  1072. {
  1073. //the ACEs in pNewDacl is repacked after each deletion.
  1074. //the pdwIndex[] has to be adjusted
  1075. if(!DeleteAce(pNewDacl, (pdwIndex[nIndex]-nIndex)))
  1076. {
  1077. hr = myHLastError();
  1078. _JumpError(hr, error, "DeleteAce");
  1079. }
  1080. }
  1081. // add the new ace for caller to allow FULL control other than DS_CONTROL
  1082. if(TRUE == fAddAce)
  1083. {
  1084. if(!AddAccessAllowedAce(pNewDacl, ACL_REVISION_DS, ACTRL_CERTSRV_MANAGE_LESS_CONTROL_ACCESS, (pTokenUser->User).Sid))
  1085. {
  1086. hr = myHLastError();
  1087. _JumpError(hr, error, "AddAccessDeniedAce");
  1088. }
  1089. }
  1090. // stick the new dacl in the sd
  1091. if(!SetSecurityDescriptorDacl(pAbsSD, TRUE, pNewDacl, FALSE))
  1092. {
  1093. hr = myHLastError();
  1094. _JumpError(hr, error, "SetSecurityDescriptorDacl");
  1095. }
  1096. // set the owner of the security descriptor as the caller
  1097. if(!SetSecurityDescriptorOwner(
  1098. pAbsSD, // SD
  1099. (pTokenUser->User).Sid, // SID for owner
  1100. FALSE)) // flag for default
  1101. {
  1102. hr = myHLastError();
  1103. goto error;
  1104. }
  1105. //convert the absolute SD to its relative form
  1106. if(!MakeSelfRelativeSD(pAbsSD, NULL, &dwRelSDSize))
  1107. {
  1108. if (ERROR_INSUFFICIENT_BUFFER!=GetLastError())
  1109. {
  1110. hr = myHLastError();
  1111. goto error;
  1112. }
  1113. }
  1114. // allocate memory
  1115. if(NULL==(pNewSD=(PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, dwRelSDSize)))
  1116. {
  1117. hr=E_OUTOFMEMORY;
  1118. goto error;
  1119. }
  1120. // copy the SD to the new memory buffer
  1121. if (!MakeSelfRelativeSD(pAbsSD, pNewSD, &dwRelSDSize))
  1122. {
  1123. hr = myHLastError();
  1124. goto error;
  1125. }
  1126. //set the relative SID
  1127. if(S_OK != (hr=CACertTypeSetSecurity(
  1128. hNewCertType,
  1129. pNewSD)))
  1130. goto error;
  1131. }
  1132. *phCertType=hNewCertType;
  1133. hNewCertType=NULL;
  1134. hr=S_OK;
  1135. error:
  1136. if(pdwIndex)
  1137. LocalFree(pdwIndex);
  1138. if (pNewDacl)
  1139. LocalFree(pNewDacl);
  1140. if(hToken)
  1141. CloseHandle(hToken);
  1142. if(pTokenUser)
  1143. LocalFree(pTokenUser);
  1144. if(pSID)
  1145. LocalFree(pSID);
  1146. if (NULL!=pAbsSD)
  1147. LocalFree(pAbsSD);
  1148. if (NULL!=pAbsDacl)
  1149. LocalFree(pAbsDacl);
  1150. if (NULL!=pAbsSacl)
  1151. LocalFree(pAbsSacl);
  1152. if (NULL!=pAbsOwner)
  1153. LocalFree(pAbsOwner);
  1154. if (NULL!=pAbsPriGrp)
  1155. LocalFree(pAbsPriGrp);
  1156. if (NULL!=pNewSD)
  1157. LocalFree(pNewSD);
  1158. if(awszCN)
  1159. CAFreeCertTypeProperty(hCertType, awszCN);
  1160. if(hNewCertType)
  1161. CACloseCertType(hNewCertType);
  1162. return hr;
  1163. }
  1164. HRESULT
  1165. CAEnumNextCertType(
  1166. IN HCERTTYPE hPrevCertType,
  1167. OUT HCERTTYPE * phCertTypeInfo
  1168. )
  1169. {
  1170. CCertTypeInfo *pInfo;
  1171. if(hPrevCertType == NULL)
  1172. {
  1173. return E_POINTER;
  1174. }
  1175. pInfo = (CCertTypeInfo *)hPrevCertType;
  1176. return pInfo->Next((CCertTypeInfo **)phCertTypeInfo);
  1177. }
  1178. DWORD
  1179. CACountCertTypes(IN HCERTTYPE hCertType)
  1180. {
  1181. CCertTypeInfo *pInfo;
  1182. if(hCertType == NULL)
  1183. {
  1184. return 0;
  1185. }
  1186. pInfo = (CCertTypeInfo *)hCertType;
  1187. return pInfo->Count();
  1188. }
  1189. HRESULT
  1190. CACloseCertType(IN HCERTTYPE hCertTypeInfo)
  1191. {
  1192. CCertTypeInfo *pInfo;
  1193. if(hCertTypeInfo == NULL)
  1194. {
  1195. return E_POINTER;
  1196. }
  1197. pInfo = (CCertTypeInfo *)hCertTypeInfo;
  1198. return pInfo->Release();
  1199. }
  1200. HRESULT
  1201. CAGetCertTypeProperty(
  1202. IN HCERTTYPE hCertType,
  1203. IN LPCWSTR wszPropertyName,
  1204. OUT LPWSTR ** pawszPropertyValue)
  1205. {
  1206. CCertTypeInfo *pInfo;
  1207. if(hCertType == NULL)
  1208. {
  1209. return E_POINTER;
  1210. }
  1211. pInfo = (CCertTypeInfo *)hCertType;
  1212. return pInfo->GetProperty(wszPropertyName, pawszPropertyValue);
  1213. }
  1214. HRESULT
  1215. CAGetCertTypePropertyEx(
  1216. IN HCERTTYPE hCertType,
  1217. IN LPCWSTR wszPropertyName,
  1218. OUT LPVOID pPropertyValue)
  1219. {
  1220. CCertTypeInfo *pInfo;
  1221. if(hCertType == NULL)
  1222. {
  1223. return E_POINTER;
  1224. }
  1225. pInfo = (CCertTypeInfo *)hCertType;
  1226. return pInfo->GetPropertyEx(wszPropertyName, pPropertyValue);
  1227. }
  1228. HRESULT
  1229. CASetCertTypeProperty(
  1230. IN HCERTTYPE hCertType,
  1231. IN LPCWSTR wszPropertyName,
  1232. IN LPWSTR * awszPropertyValue)
  1233. {
  1234. CCertTypeInfo *pInfo;
  1235. if(hCertType == NULL)
  1236. {
  1237. return E_POINTER;
  1238. }
  1239. pInfo = (CCertTypeInfo *)hCertType;
  1240. return pInfo->SetProperty(wszPropertyName, awszPropertyValue) ;
  1241. }
  1242. HRESULT
  1243. CASetCertTypePropertyEx(
  1244. IN HCERTTYPE hCertType,
  1245. IN LPCWSTR wszPropertyName,
  1246. IN LPVOID pPropertyValue)
  1247. {
  1248. CCertTypeInfo *pInfo;
  1249. if(hCertType == NULL)
  1250. {
  1251. return E_POINTER;
  1252. }
  1253. pInfo = (CCertTypeInfo *)hCertType;
  1254. return pInfo->SetPropertyEx(wszPropertyName, pPropertyValue) ;
  1255. }
  1256. HRESULT
  1257. CAFreeCertTypeProperty(
  1258. IN HCERTTYPE hCertType,
  1259. LPWSTR * awszPropertyValue
  1260. )
  1261. {
  1262. CCertTypeInfo *pInfo;
  1263. if(hCertType == NULL)
  1264. {
  1265. return E_POINTER;
  1266. }
  1267. pInfo = (CCertTypeInfo *)hCertType;
  1268. return pInfo->FreeProperty(awszPropertyValue) ;
  1269. }
  1270. HRESULT
  1271. CAGetCertTypeExtensions(
  1272. IN HCERTTYPE hCertType,
  1273. OUT PCERT_EXTENSIONS * ppCertExtensions
  1274. )
  1275. {
  1276. return CAGetCertTypeExtensionsEx(hCertType, 0, NULL, ppCertExtensions);
  1277. }
  1278. HRESULT
  1279. CAGetCertTypeExtensionsEx(
  1280. IN HCERTTYPE hCertType,
  1281. IN DWORD dwFlags,
  1282. IN LPVOID, // pParam
  1283. OUT PCERT_EXTENSIONS * ppCertExtensions
  1284. )
  1285. {
  1286. CCertTypeInfo *pInfo;
  1287. if(hCertType == NULL)
  1288. {
  1289. return E_POINTER;
  1290. }
  1291. pInfo = (CCertTypeInfo *)hCertType;
  1292. return pInfo->GetExtensions(dwFlags, ppCertExtensions);
  1293. }
  1294. HRESULT
  1295. CAFreeCertTypeExtensions(
  1296. IN HCERTTYPE, // hCertType
  1297. IN PCERT_EXTENSIONS pCertExtensions
  1298. )
  1299. {
  1300. //should alreays free via LocalFree since CryptUIWizCertRequest freed
  1301. //it via LocalFree
  1302. if(pCertExtensions)
  1303. {
  1304. LocalFree(pCertExtensions);
  1305. }
  1306. return S_OK;
  1307. #if 0
  1308. CCertTypeInfo *pInfo;
  1309. if(hCertType == NULL)
  1310. {
  1311. return E_POINTER;
  1312. }
  1313. pInfo = (CCertTypeInfo *)hCertType;
  1314. return pInfo->FreeExtensions(pCertExtensions) ;
  1315. #endif
  1316. }
  1317. HRESULT
  1318. CASetCertTypeExtension(
  1319. IN HCERTTYPE hCertType,
  1320. IN LPCWSTR wszExtensionName,
  1321. IN DWORD dwFlags,
  1322. IN LPVOID pExtension
  1323. )
  1324. {
  1325. CCertTypeInfo *pInfo;
  1326. if(hCertType == NULL)
  1327. {
  1328. return E_POINTER;
  1329. }
  1330. pInfo = (CCertTypeInfo *)hCertType;
  1331. return pInfo->SetExtension(wszExtensionName, pExtension, dwFlags);
  1332. }
  1333. HRESULT
  1334. CAGetCertTypeFlags(
  1335. IN HCERTTYPE hCertType,
  1336. OUT DWORD * pdwFlags
  1337. )
  1338. {
  1339. return CAGetCertTypeFlagsEx(hCertType, CERTTYPE_GENERAL_FLAG, pdwFlags);
  1340. }
  1341. HRESULT
  1342. CAGetCertTypeFlagsEx(
  1343. IN HCERTTYPE hCertType,
  1344. IN DWORD dwOption,
  1345. OUT DWORD * pdwFlags
  1346. )
  1347. {
  1348. CCertTypeInfo *pInfo;
  1349. if(hCertType == NULL)
  1350. {
  1351. return E_POINTER;
  1352. }
  1353. if(pdwFlags == NULL)
  1354. {
  1355. return E_POINTER;
  1356. }
  1357. pInfo = (CCertTypeInfo *)hCertType;
  1358. *pdwFlags = pInfo->GetFlags(dwOption);
  1359. return S_OK;
  1360. }
  1361. HRESULT
  1362. CASetCertTypeFlags(
  1363. IN HCERTTYPE hCertType,
  1364. IN DWORD dwFlags
  1365. )
  1366. {
  1367. return CASetCertTypeFlagsEx(hCertType, CERTTYPE_GENERAL_FLAG, dwFlags);
  1368. }
  1369. HRESULT
  1370. CASetCertTypeFlagsEx(
  1371. IN HCERTTYPE hCertType,
  1372. IN DWORD dwOption,
  1373. IN DWORD dwFlags
  1374. )
  1375. {
  1376. CCertTypeInfo *pInfo;
  1377. if(hCertType == NULL)
  1378. {
  1379. return E_POINTER;
  1380. }
  1381. pInfo = (CCertTypeInfo *)hCertType;
  1382. return pInfo->SetFlags(dwOption, dwFlags);
  1383. }
  1384. HRESULT
  1385. CAGetCertTypeKeySpec(
  1386. IN HCERTTYPE hCertType,
  1387. OUT DWORD * pdwKeySpec
  1388. )
  1389. {
  1390. CCertTypeInfo *pInfo;
  1391. if(hCertType == NULL)
  1392. {
  1393. return E_POINTER;
  1394. }
  1395. if(pdwKeySpec == NULL)
  1396. {
  1397. return E_POINTER;
  1398. }
  1399. pInfo = (CCertTypeInfo *)hCertType;
  1400. *pdwKeySpec = pInfo->GetKeySpec();
  1401. return S_OK;
  1402. }
  1403. HRESULT
  1404. CASetCertTypeKeySpec(
  1405. IN HCERTTYPE hCertType,
  1406. IN DWORD dwKeySpec
  1407. )
  1408. {
  1409. CCertTypeInfo *pInfo;
  1410. if(hCertType == NULL)
  1411. {
  1412. return E_POINTER;
  1413. }
  1414. pInfo = (CCertTypeInfo *)hCertType;
  1415. pInfo->SetKeySpec(dwKeySpec);
  1416. return S_OK;
  1417. }
  1418. HRESULT
  1419. CAGetCertTypeExpiration(
  1420. IN HCERTTYPE hCertType,
  1421. OUT OPTIONAL FILETIME * pftExpiration,
  1422. OUT OPTIONAL FILETIME * pftOverlap
  1423. )
  1424. {
  1425. CCertTypeInfo *pInfo;
  1426. if(hCertType == NULL)
  1427. {
  1428. return E_POINTER;
  1429. }
  1430. pInfo = (CCertTypeInfo *)hCertType;
  1431. return pInfo->GetExpiration(pftExpiration, pftOverlap);
  1432. }
  1433. HRESULT
  1434. CASetCertTypeExpiration(
  1435. IN HCERTTYPE hCertType,
  1436. IN OPTIONAL FILETIME * pftExpiration,
  1437. IN OPTIONAL FILETIME * pftOverlap
  1438. )
  1439. {
  1440. CCertTypeInfo *pInfo;
  1441. if(hCertType == NULL)
  1442. {
  1443. return E_POINTER;
  1444. }
  1445. pInfo = (CCertTypeInfo *)hCertType;
  1446. return pInfo->SetExpiration(pftExpiration, pftOverlap);
  1447. }
  1448. HRESULT
  1449. CACertTypeSetSecurity(
  1450. IN HCERTTYPE hCertType,
  1451. IN PSECURITY_DESCRIPTOR pSD
  1452. )
  1453. {
  1454. CCertTypeInfo *pInfo;
  1455. if(hCertType == NULL)
  1456. {
  1457. return E_POINTER;
  1458. }
  1459. pInfo = (CCertTypeInfo *)hCertType;
  1460. return pInfo->SetSecurity( pSD );
  1461. }
  1462. HRESULT
  1463. CACertTypeGetSecurity(
  1464. IN HCERTTYPE hCertType,
  1465. OUT PSECURITY_DESCRIPTOR * ppSD
  1466. )
  1467. {
  1468. CCertTypeInfo *pInfo;
  1469. if(hCertType == NULL)
  1470. {
  1471. return E_POINTER;
  1472. }
  1473. pInfo = (CCertTypeInfo *)hCertType;
  1474. return pInfo->GetSecurity( ppSD ) ;
  1475. }
  1476. HRESULT
  1477. CACertTypeAccessCheck(
  1478. IN HCERTTYPE hCertType,
  1479. IN HANDLE ClientToken
  1480. )
  1481. {
  1482. return CACertTypeAccessCheckEx(hCertType, ClientToken, CERTTYPE_ACCESS_CHECK_ENROLL);
  1483. }
  1484. CERTCLIAPI
  1485. HRESULT
  1486. WINAPI
  1487. CACertTypeAccessCheckEx(
  1488. IN HCERTTYPE hCertType,
  1489. IN HANDLE ClientToken,
  1490. IN DWORD dwOption
  1491. )
  1492. {
  1493. CCertTypeInfo *pInfo;
  1494. if(hCertType == NULL)
  1495. {
  1496. return E_POINTER;
  1497. }
  1498. pInfo = (CCertTypeInfo *)hCertType;
  1499. return pInfo->AccessCheck(ClientToken, dwOption);
  1500. }
  1501. CERTCLIAPI
  1502. HRESULT
  1503. WINAPI
  1504. CAInstallDefaultCertType(
  1505. IN DWORD // dwFlags
  1506. )
  1507. {
  1508. return CCertTypeInfo::InstallDefaultTypes();
  1509. }
  1510. CERTCLIAPI
  1511. BOOL
  1512. WINAPI
  1513. CAIsCertTypeCurrent(
  1514. IN DWORD, // dwFlags
  1515. IN LPWSTR wszCertType
  1516. )
  1517. {
  1518. BOOL fCurrent=FALSE;
  1519. HRESULT hr=E_FAIL;
  1520. DWORD dwCT=0;
  1521. DWORD dwDefault=0;
  1522. DWORD dwCount=0;
  1523. BOOL fFound=FALSE;
  1524. DWORD dwFound=0;
  1525. DWORD dwVersion=0;
  1526. CCertTypeInfo *pInfo=NULL;
  1527. HCERTTYPE hNewCertType=NULL;
  1528. HCERTTYPE hCurCertType=NULL;
  1529. LPWSTR *awszCertTypeName=NULL;
  1530. //get all the templates on the directory
  1531. hr = CAEnumCertTypesEx(
  1532. NULL,
  1533. CT_ENUM_USER_TYPES | CT_ENUM_MACHINE_TYPES | CT_FLAG_NO_CACHE_LOOKUP,
  1534. &hCurCertType);
  1535. if((S_OK != hr) || (NULL==hCurCertType))
  1536. goto error;
  1537. dwCount = CACountCertTypes(hCurCertType);
  1538. if(0 == dwCount)
  1539. goto error;
  1540. //enumrating all templates on the directory
  1541. for(dwCT = 0; dwCT < dwCount; dwCT++ )
  1542. {
  1543. if(awszCertTypeName)
  1544. {
  1545. CAFreeCertTypeProperty(hCurCertType, awszCertTypeName);
  1546. awszCertTypeName=NULL;
  1547. }
  1548. //check if we have a new certificate template
  1549. if(dwCT > 0)
  1550. {
  1551. hr = CAEnumNextCertType(hCurCertType, &hNewCertType);
  1552. if((S_OK != hr) || (NULL == hNewCertType))
  1553. {
  1554. break;
  1555. }
  1556. CACloseCertType(hCurCertType);
  1557. hCurCertType=hNewCertType;
  1558. }
  1559. //get the template name
  1560. hr = CAGetCertTypePropertyEx(
  1561. hCurCertType,
  1562. CERTTYPE_PROP_DN,
  1563. &awszCertTypeName);
  1564. if((S_OK != hr) ||
  1565. (NULL == awszCertTypeName) ||
  1566. (NULL == awszCertTypeName[0])
  1567. )
  1568. {
  1569. goto error;
  1570. }
  1571. //for all templates requested, verify against the default list
  1572. if((NULL == wszCertType) || (0 == mylstrcmpiL(awszCertTypeName[0], wszCertType)))
  1573. {
  1574. if(wszCertType)
  1575. fFound=TRUE;
  1576. for(dwDefault=0; dwDefault < g_cDefaultCertTypes; dwDefault++)
  1577. {
  1578. if(0==mylstrcmpiL(awszCertTypeName[0], g_aDefaultCertTypes[dwDefault].wszName))
  1579. {
  1580. break;
  1581. }
  1582. }
  1583. //match the default name list
  1584. if(dwDefault < g_cDefaultCertTypes)
  1585. {
  1586. hr=CAGetCertTypePropertyEx(
  1587. hCurCertType,
  1588. CERTTYPE_PROP_REVISION,
  1589. &dwVersion);
  1590. if(S_OK != hr)
  1591. goto error;
  1592. if (dwVersion < g_aDefaultCertTypes[dwDefault].dwRevision)
  1593. goto error;
  1594. pInfo = (CCertTypeInfo *)hCurCertType;
  1595. if(!(pInfo->IsValidSecurityOwner()))
  1596. goto error;
  1597. //mark that we found a good default template
  1598. dwFound++;
  1599. }
  1600. }
  1601. }
  1602. //all requested template has to be checked
  1603. if(wszCertType)
  1604. {
  1605. if(FALSE == fFound)
  1606. goto error;
  1607. }
  1608. else
  1609. {
  1610. if(dwFound != g_cDefaultCertTypes)
  1611. goto error;
  1612. }
  1613. fCurrent=TRUE;
  1614. error:
  1615. if(awszCertTypeName)
  1616. {
  1617. if(hCurCertType)
  1618. {
  1619. CAFreeCertTypeProperty(hCurCertType, awszCertTypeName);
  1620. }
  1621. }
  1622. if(hCurCertType)
  1623. {
  1624. CACloseCertType(hCurCertType);
  1625. }
  1626. return fCurrent;
  1627. }
  1628. HANDLE
  1629. myEnterCriticalPolicySection(
  1630. IN BOOL bMachine)
  1631. {
  1632. HANDLE hPolicy = NULL;
  1633. HRESULT hr = S_OK;
  1634. // ?CriticalPolicySection calls are delay loaded. Protect with try/except
  1635. __try
  1636. {
  1637. hPolicy = EnterCriticalPolicySection(bMachine); // Delayload wrapped
  1638. }
  1639. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  1640. {
  1641. }
  1642. // (S_OK == hr) does not mean EnterCriticalPolicySection succeeded.
  1643. // It just means no exception was raised.
  1644. if (myIsDelayLoadHResult(hr))
  1645. {
  1646. hPolicy = (HANDLE) (ULONG_PTR) (bMachine? 37 : 49);
  1647. hr = S_OK;
  1648. }
  1649. return(hPolicy);
  1650. }
  1651. BOOL
  1652. myLeaveCriticalPolicySection(
  1653. IN HANDLE hSection)
  1654. {
  1655. HRESULT hr = S_OK;
  1656. BOOL fOk = FALSE;
  1657. // ?CriticalPolicySection calls are delay loaded. Protect with try/except
  1658. __try
  1659. {
  1660. fOk = LeaveCriticalPolicySection(hSection); // Delayload wrapped
  1661. }
  1662. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  1663. {
  1664. }
  1665. // (S_OK == hr) does not mean LeaveCriticalPolicySection succeeded.
  1666. // It just means no exception was raised.
  1667. if (myIsDelayLoadHResult(hr))
  1668. {
  1669. fOk = (HANDLE) (ULONG_PTR) 37 == hSection ||
  1670. (HANDLE) (ULONG_PTR) 49 == hSection;
  1671. hr = S_OK;
  1672. }
  1673. return(fOk);
  1674. }