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.

3145 lines
74 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1999
  5. //
  6. // File: policy.cpp
  7. //
  8. // Contents: Cert Server Policy Module implementation
  9. //
  10. //---------------------------------------------------------------------------
  11. #include "pch.cpp"
  12. #pragma hdrstop
  13. #include <assert.h>
  14. #include "celib.h"
  15. #include "policy.h"
  16. #include "module.h"
  17. BOOL fDebug = DBG_CERTSRV;
  18. #ifndef DBG_CERTSRV
  19. #error -- DBG_CERTSRV not defined!
  20. #endif
  21. // worker
  22. HRESULT
  23. polGetServerCallbackInterface(
  24. OUT ICertServerPolicy **ppServer,
  25. IN LONG Context)
  26. {
  27. HRESULT hr;
  28. if (NULL == ppServer)
  29. {
  30. hr = E_POINTER;
  31. _JumpError(hr, error, "Policy:polGetServerCallbackInterface");
  32. }
  33. hr = CoCreateInstance(
  34. CLSID_CCertServerPolicy,
  35. NULL, // pUnkOuter
  36. CLSCTX_INPROC_SERVER,
  37. IID_ICertServerPolicy,
  38. (VOID **) ppServer);
  39. _JumpIfError(hr, error, "Policy:CoCreateInstance");
  40. if (NULL == *ppServer)
  41. {
  42. hr = E_UNEXPECTED;
  43. _JumpError(hr, error, "Policy:CoCreateInstance");
  44. }
  45. // only set context if nonzero
  46. if (0 != Context)
  47. {
  48. hr = (*ppServer)->SetContext(Context);
  49. _JumpIfError(hr, error, "Policy:SetContext");
  50. }
  51. error:
  52. return hr;
  53. }
  54. HRESULT
  55. polGetProperty(
  56. IN ICertServerPolicy *pServer,
  57. IN BOOL fRequest,
  58. IN WCHAR const *pwszPropertyName,
  59. IN DWORD PropType,
  60. OUT VARIANT *pvarOut)
  61. {
  62. HRESULT hr;
  63. BSTR strName = NULL;
  64. VariantInit(pvarOut);
  65. strName = SysAllocString(pwszPropertyName);
  66. if (NULL == strName)
  67. {
  68. hr = E_OUTOFMEMORY;
  69. _JumpError(hr, error, "Policy:SysAllocString");
  70. }
  71. if (fRequest)
  72. {
  73. hr = pServer->GetRequestProperty(strName, PropType, pvarOut);
  74. _JumpIfErrorStr2(
  75. hr,
  76. error,
  77. "Policy:GetRequestProperty",
  78. pwszPropertyName,
  79. CERTSRV_E_PROPERTY_EMPTY);
  80. }
  81. else
  82. {
  83. hr = pServer->GetCertificateProperty(strName, PropType, pvarOut);
  84. _JumpIfErrorStr2(
  85. hr,
  86. error,
  87. "Policy:GetCertificateProperty",
  88. pwszPropertyName,
  89. CERTSRV_E_PROPERTY_EMPTY);
  90. }
  91. error:
  92. if (NULL != strName)
  93. {
  94. SysFreeString(strName);
  95. }
  96. return(hr);
  97. }
  98. HRESULT
  99. polGetStringProperty(
  100. IN ICertServerPolicy *pServer,
  101. IN BOOL fRequest,
  102. IN WCHAR const *pwszPropertyName,
  103. OUT BSTR *pstrOut)
  104. {
  105. HRESULT hr;
  106. VARIANT var;
  107. VariantInit(&var);
  108. if (NULL != *pstrOut)
  109. {
  110. SysFreeString(*pstrOut);
  111. *pstrOut = NULL;
  112. }
  113. hr = polGetProperty(
  114. pServer,
  115. fRequest,
  116. pwszPropertyName,
  117. PROPTYPE_STRING,
  118. &var);
  119. _JumpIfError2(
  120. hr,
  121. error,
  122. "Policy:polGetProperty",
  123. CERTSRV_E_PROPERTY_EMPTY);
  124. if (VT_BSTR != var.vt || NULL == var.bstrVal || L'\0' == var.bstrVal)
  125. {
  126. hr = CERTSRV_E_PROPERTY_EMPTY;
  127. _JumpError(hr, error, "Policy:polGetProperty");
  128. }
  129. *pstrOut = var.bstrVal;
  130. var.vt = VT_EMPTY;
  131. hr = S_OK;
  132. error:
  133. VariantClear(&var);
  134. return(hr);
  135. }
  136. HRESULT
  137. polGetLongProperty(
  138. IN ICertServerPolicy *pServer,
  139. IN BOOL fRequest,
  140. IN WCHAR const *pwszPropertyName,
  141. OUT LONG *plOut)
  142. {
  143. HRESULT hr;
  144. VARIANT var;
  145. VariantInit(&var);
  146. hr = polGetProperty(
  147. pServer,
  148. fRequest,
  149. pwszPropertyName,
  150. PROPTYPE_LONG,
  151. &var);
  152. _JumpIfError2(hr, error, "Policy:polGetProperty", CERTSRV_E_PROPERTY_EMPTY);
  153. if (VT_I4 != var.vt)
  154. {
  155. hr = CERTSRV_E_PROPERTY_EMPTY;
  156. _JumpError(hr, error, "Policy:polGetProperty");
  157. }
  158. *plOut = var.lVal;
  159. hr = S_OK;
  160. error:
  161. VariantClear(&var);
  162. return(hr);
  163. }
  164. HRESULT
  165. polGetRequestStringProperty(
  166. IN ICertServerPolicy *pServer,
  167. IN WCHAR const *pwszPropertyName,
  168. OUT BSTR *pstrOut)
  169. {
  170. HRESULT hr;
  171. hr = polGetStringProperty(pServer, TRUE, pwszPropertyName, pstrOut);
  172. _JumpIfError2(hr, error, "polGetStringProperty", CERTSRV_E_PROPERTY_EMPTY);
  173. error:
  174. return(hr);
  175. }
  176. HRESULT
  177. polGetCertificateStringProperty(
  178. IN ICertServerPolicy *pServer,
  179. IN WCHAR const *pwszPropertyName,
  180. OUT BSTR *pstrOut)
  181. {
  182. HRESULT hr;
  183. hr = polGetStringProperty(pServer, FALSE, pwszPropertyName, pstrOut);
  184. _JumpIfError2(hr, error, "polGetStringProperty", CERTSRV_E_PROPERTY_EMPTY);
  185. error:
  186. return(hr);
  187. }
  188. HRESULT
  189. polGetRequestLongProperty(
  190. IN ICertServerPolicy *pServer,
  191. IN WCHAR const *pwszPropertyName,
  192. OUT LONG *plOut)
  193. {
  194. HRESULT hr;
  195. hr = polGetLongProperty(pServer, TRUE, pwszPropertyName, plOut);
  196. _JumpIfError2(hr, error, "polGetLongProperty", CERTSRV_E_PROPERTY_EMPTY);
  197. error:
  198. return(hr);
  199. }
  200. HRESULT
  201. polGetCertificateLongProperty(
  202. IN ICertServerPolicy *pServer,
  203. IN WCHAR const *pwszPropertyName,
  204. OUT LONG *plOut)
  205. {
  206. HRESULT hr;
  207. hr = polGetLongProperty(pServer, FALSE, pwszPropertyName, plOut);
  208. _JumpIfError2(hr, error, "polGetLongProperty", CERTSRV_E_PROPERTY_EMPTY);
  209. error:
  210. return(hr);
  211. }
  212. HRESULT
  213. polGetRequestAttribute(
  214. IN ICertServerPolicy *pServer,
  215. IN WCHAR const *pwszAttributeName,
  216. OUT BSTR *pstrOut)
  217. {
  218. HRESULT hr;
  219. BSTR strName = NULL;
  220. strName = SysAllocString(pwszAttributeName);
  221. if (NULL == strName)
  222. {
  223. hr = E_OUTOFMEMORY;
  224. _JumpError(hr, error, "Policy:SysAllocString");
  225. }
  226. hr = pServer->GetRequestAttribute(strName, pstrOut);
  227. _JumpIfErrorStr2(
  228. hr,
  229. error,
  230. "Policy:GetRequestAttribute",
  231. pwszAttributeName,
  232. CERTSRV_E_PROPERTY_EMPTY);
  233. error:
  234. if (NULL != strName)
  235. {
  236. SysFreeString(strName);
  237. }
  238. return(hr);
  239. }
  240. HRESULT
  241. polGetCertificateExtension(
  242. IN ICertServerPolicy *pServer,
  243. IN WCHAR const *pwszExtensionName,
  244. IN DWORD dwPropType,
  245. IN OUT VARIANT *pvarOut)
  246. {
  247. HRESULT hr;
  248. BSTR strName = NULL;
  249. strName = SysAllocString(pwszExtensionName);
  250. if (NULL == strName)
  251. {
  252. hr = E_OUTOFMEMORY;
  253. _JumpError(hr, error, "Policy:SysAllocString");
  254. }
  255. hr = pServer->GetCertificateExtension(strName, dwPropType, pvarOut);
  256. _JumpIfErrorStr2(
  257. hr,
  258. error,
  259. "Policy:GetCertificateExtension",
  260. pwszExtensionName,
  261. CERTSRV_E_PROPERTY_EMPTY);
  262. error:
  263. if (NULL != strName)
  264. {
  265. SysFreeString(strName);
  266. }
  267. return(hr);
  268. }
  269. HRESULT
  270. polSetCertificateExtension(
  271. IN ICertServerPolicy *pServer,
  272. IN WCHAR const *pwszExtensionName,
  273. IN DWORD dwPropType,
  274. IN DWORD dwExtFlags,
  275. IN VARIANT const *pvarIn)
  276. {
  277. HRESULT hr;
  278. BSTR strName = NULL;
  279. strName = SysAllocString(pwszExtensionName);
  280. if (NULL == strName)
  281. {
  282. hr = E_OUTOFMEMORY;
  283. _JumpError(hr, error, "Policy:SysAllocString");
  284. }
  285. hr = pServer->SetCertificateExtension(
  286. strName,
  287. dwPropType,
  288. dwExtFlags,
  289. pvarIn);
  290. _JumpIfErrorStr(
  291. hr,
  292. error,
  293. "Policy:SetCertificateExtension",
  294. pwszExtensionName);
  295. error:
  296. if (NULL != strName)
  297. {
  298. SysFreeString(strName);
  299. }
  300. return(hr);
  301. }
  302. //+--------------------------------------------------------------------------
  303. // CCertPolicySample::~CCertPolicySample -- destructor
  304. //
  305. // free memory associated with this instance
  306. //+--------------------------------------------------------------------------
  307. CCertPolicySample::~CCertPolicySample()
  308. {
  309. _Cleanup();
  310. }
  311. VOID
  312. CCertPolicySample::_FreeStringArray(
  313. IN OUT DWORD *pcString,
  314. IN OUT LPWSTR **papwsz)
  315. {
  316. LPWSTR *apwsz = *papwsz;
  317. DWORD i;
  318. if (NULL != apwsz)
  319. {
  320. for (i = *pcString; i-- > 0; )
  321. {
  322. if (NULL != apwsz[i])
  323. {
  324. DBGPRINT((fDebug, "_FreeStringArray[%u]: '%ws'\n", i, apwsz[i]));
  325. LocalFree(apwsz[i]);
  326. }
  327. }
  328. LocalFree(apwsz);
  329. *papwsz = NULL;
  330. }
  331. *pcString = 0;
  332. }
  333. //+--------------------------------------------------------------------------
  334. // CCertPolicySample::_Cleanup -- free memory associated with this instance
  335. //
  336. // free memory associated with this instance
  337. //+--------------------------------------------------------------------------
  338. VOID
  339. CCertPolicySample::_Cleanup()
  340. {
  341. DWORD i;
  342. if (m_strDescription)
  343. {
  344. SysFreeString(m_strDescription);
  345. m_strDescription = NULL;
  346. }
  347. // RevocationExtension variables:
  348. if (NULL != m_wszASPRevocationURL)
  349. {
  350. LocalFree(m_wszASPRevocationURL);
  351. m_wszASPRevocationURL = NULL;
  352. }
  353. _FreeStringArray(&m_cEnableRequestExtensions, &m_apwszEnableRequestExtensions);
  354. _FreeStringArray(&m_cEnableEnrolleeRequestExtensions, &m_apwszEnableEnrolleeRequestExtensions);
  355. _FreeStringArray(&m_cDisableExtensions, &m_apwszDisableExtensions);
  356. if (NULL != m_strCAName)
  357. {
  358. SysFreeString(m_strCAName);
  359. m_strCAName = NULL;
  360. }
  361. if (NULL != m_strCASanitizedName)
  362. {
  363. SysFreeString(m_strCASanitizedName);
  364. m_strCASanitizedName = NULL;
  365. }
  366. if (NULL != m_strCASanitizedDSName)
  367. {
  368. SysFreeString(m_strCASanitizedDSName);
  369. m_strCASanitizedDSName = NULL;
  370. }
  371. if (NULL != m_strRegStorageLoc)
  372. {
  373. SysFreeString(m_strRegStorageLoc);
  374. m_strRegStorageLoc = NULL;
  375. }
  376. if (NULL != m_pCert)
  377. {
  378. CertFreeCertificateContext(m_pCert);
  379. m_pCert = NULL;
  380. }
  381. if (m_strMachineDNSName)
  382. {
  383. SysFreeString(m_strMachineDNSName);
  384. m_strMachineDNSName=NULL;
  385. }
  386. }
  387. HRESULT
  388. CCertPolicySample::_ReadRegistryString(
  389. IN HKEY hkey,
  390. IN BOOL fURL,
  391. IN WCHAR const *pwszRegName,
  392. IN WCHAR const *pwszSuffix,
  393. OUT LPWSTR *ppwszOut)
  394. {
  395. HRESULT hr;
  396. WCHAR *pwszRegValue = NULL;
  397. DWORD cbValue;
  398. DWORD dwType;
  399. *ppwszOut = NULL;
  400. hr = RegQueryValueEx(
  401. hkey,
  402. pwszRegName,
  403. NULL, // lpdwReserved
  404. &dwType,
  405. NULL,
  406. &cbValue);
  407. _JumpIfErrorStr2(
  408. hr,
  409. error,
  410. "Policy:RegQueryValueEx",
  411. pwszRegName,
  412. ERROR_FILE_NOT_FOUND);
  413. if (REG_SZ != dwType && REG_MULTI_SZ != dwType)
  414. {
  415. hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
  416. _JumpErrorStr(hr, error, "Policy:RegQueryValueEx TYPE", pwszRegName);
  417. }
  418. if (NULL != pwszSuffix)
  419. {
  420. cbValue += wcslen(pwszSuffix) * sizeof(WCHAR);
  421. }
  422. pwszRegValue = (WCHAR *) LocalAlloc(LMEM_FIXED, cbValue + sizeof(WCHAR));
  423. if (NULL == pwszRegValue)
  424. {
  425. hr = E_OUTOFMEMORY;
  426. _JumpErrorStr(hr, error, "Policy:LocalAlloc", pwszRegName);
  427. }
  428. hr = RegQueryValueEx(
  429. hkey,
  430. pwszRegName,
  431. NULL, // lpdwReserved
  432. &dwType,
  433. (BYTE *) pwszRegValue,
  434. &cbValue);
  435. _JumpIfErrorStr(hr, error, "Policy:RegQueryValueEx", pwszRegName);
  436. // Handle malformed registry values cleanly:
  437. pwszRegValue[cbValue / sizeof(WCHAR)] = L'\0';
  438. if (NULL != pwszSuffix)
  439. {
  440. wcscat(pwszRegValue, pwszSuffix);
  441. }
  442. hr = ceFormatCertsrvStringArray(
  443. fURL, // fURL
  444. m_strMachineDNSName, // pwszServerName_p1_2
  445. m_strCASanitizedName, // pwszSanitizedName_p3_7
  446. m_iCert, // iCert_p4
  447. MAXDWORD, // iCertTarget_p4
  448. L"", // pwszDomainDN_p5
  449. L"", // pwszConfigDN_p6
  450. m_iCRL, // iCRL_p8
  451. FALSE, // fDeltaCRL_p9
  452. TRUE, // fDSAttrib_p10_11
  453. 1, // cStrings
  454. (LPCWSTR *) &pwszRegValue, // apwszStringsIn
  455. ppwszOut); // apwszStringsOut
  456. _JumpIfError(hr, error, "Policy:ceFormatCertsrvStringArray");
  457. error:
  458. if (NULL != pwszRegValue)
  459. {
  460. LocalFree(pwszRegValue);
  461. }
  462. return(ceHError(hr)); // Reg routines return Win32 error codes
  463. }
  464. #if DBG_CERTSRV
  465. VOID
  466. CCertPolicySample::_DumpStringArray(
  467. IN char const *pszType,
  468. IN DWORD count,
  469. IN LPWSTR const *apwsz)
  470. {
  471. DWORD i;
  472. WCHAR const *pwszName;
  473. for (i = 0; i < count; i++)
  474. {
  475. pwszName = L"";
  476. if (iswdigit(apwsz[i][0]))
  477. {
  478. pwszName = ceGetOIDName(apwsz[i]); // Static: do not free!
  479. }
  480. DBGPRINT((
  481. fDebug,
  482. "%hs[%u]: %ws%hs%ws\n",
  483. pszType,
  484. i,
  485. apwsz[i],
  486. L'\0' != *pwszName? " -- " : "",
  487. pwszName));
  488. }
  489. }
  490. #endif // DBG_CERTSRV
  491. HRESULT
  492. CCertPolicySample::_SetSystemStringProp(
  493. IN ICertServerPolicy *pServer,
  494. IN WCHAR const *pwszName,
  495. OPTIONAL IN WCHAR const *pwszValue)
  496. {
  497. HRESULT hr;
  498. BSTR strName = NULL;
  499. VARIANT varValue;
  500. varValue.vt = VT_NULL;
  501. varValue.bstrVal = NULL;
  502. if (!ceConvertWszToBstr(&strName, pwszName, -1))
  503. {
  504. hr = E_OUTOFMEMORY;
  505. _JumpError(hr, error, "Policy:ceConvertWszToBstr");
  506. }
  507. if (NULL != pwszValue)
  508. {
  509. if (!ceConvertWszToBstr(&varValue.bstrVal, pwszValue, -1))
  510. {
  511. hr = E_OUTOFMEMORY;
  512. _JumpError(hr, error, "Policy:ceConvertWszToBstr");
  513. }
  514. varValue.vt = VT_BSTR;
  515. }
  516. hr = pServer->SetCertificateProperty(strName, PROPTYPE_STRING, &varValue);
  517. _JumpIfError(hr, error, "Policy:SetCertificateProperty");
  518. error:
  519. VariantClear(&varValue);
  520. if (NULL != strName)
  521. {
  522. SysFreeString(strName);
  523. }
  524. return(hr);
  525. }
  526. HRESULT
  527. CCertPolicySample::_AddStringArray(
  528. IN WCHAR const *pwszzValue,
  529. IN BOOL fURL,
  530. IN OUT DWORD *pcStrings,
  531. IN OUT LPWSTR **papwszRegValues)
  532. {
  533. HRESULT hr;
  534. DWORD cString = 0;
  535. WCHAR const *pwsz;
  536. LPCWSTR *awszFormatStrings = NULL;
  537. LPWSTR *awszOutputStrings = NULL;
  538. // Count the number of strings we're adding
  539. for (pwsz = pwszzValue; L'\0' != *pwsz; pwsz += wcslen(pwsz) + 1)
  540. {
  541. cString++;
  542. }
  543. if (0 == cString) // no strings
  544. {
  545. hr = S_OK;
  546. goto error;
  547. }
  548. awszFormatStrings = (LPCWSTR *) LocalAlloc(
  549. LMEM_FIXED | LMEM_ZEROINIT,
  550. cString * sizeof(LPWSTR));
  551. if (NULL == awszFormatStrings)
  552. {
  553. hr = E_OUTOFMEMORY;
  554. _JumpError(hr, error, "Policy:LocalAlloc");
  555. }
  556. cString = 0;
  557. for (pwsz = pwszzValue; L'\0' != *pwsz; pwsz += wcslen(pwsz) + 1)
  558. {
  559. // Skip strings that start with a an unescaped minus sign.
  560. // Strings with an escaped minus sign (2 minus signs) are not skipped.
  561. if (L'-' == *pwsz)
  562. {
  563. pwsz++;
  564. if (L'-' != *pwsz)
  565. {
  566. continue;
  567. }
  568. }
  569. awszFormatStrings[cString++] = pwsz;
  570. }
  571. // if no strings to add, don't modify
  572. if (cString > 0)
  573. {
  574. awszOutputStrings = (LPWSTR *) LocalAlloc(
  575. LMEM_FIXED | LMEM_ZEROINIT,
  576. (cString + *pcStrings) * sizeof(LPWSTR));
  577. if (NULL == awszOutputStrings)
  578. {
  579. hr = E_OUTOFMEMORY;
  580. _JumpError(hr, error, "Policy:LocalAlloc");
  581. }
  582. if (0 != *pcStrings)
  583. {
  584. assert(NULL != *papwszRegValues);
  585. CopyMemory(
  586. awszOutputStrings,
  587. *papwszRegValues,
  588. *pcStrings * sizeof(LPWSTR));
  589. }
  590. hr = ceFormatCertsrvStringArray(
  591. fURL, // fURL
  592. m_strMachineDNSName, // pwszServerName_p1_2
  593. m_strCASanitizedName, // pwszSanitizedName_p3_7
  594. m_iCert, // iCert_p4
  595. MAXDWORD, // iCertTarget_p4
  596. L"", // pwszDomainDN_p5
  597. L"", // pwszConfigDN_p6
  598. m_iCRL, // iCRL_p8
  599. FALSE, // fDeltaCRL_p9
  600. TRUE, // fDSAttrib_p10_11
  601. cString, // cStrings
  602. awszFormatStrings, // apwszStringsIn
  603. awszOutputStrings + (*pcStrings)); // apwszStringsOut
  604. _JumpIfError(hr, error, "Policy:ceFormatCertsrvStringArray");
  605. *pcStrings = (*pcStrings) + cString;
  606. if (*papwszRegValues)
  607. {
  608. LocalFree(*papwszRegValues);
  609. }
  610. *papwszRegValues = awszOutputStrings;
  611. awszOutputStrings = NULL;
  612. }
  613. hr = S_OK;
  614. error:
  615. if (NULL != awszOutputStrings)
  616. {
  617. LocalFree(awszOutputStrings);
  618. }
  619. if (NULL != awszFormatStrings)
  620. {
  621. LocalFree(awszFormatStrings);
  622. }
  623. return(hr);
  624. }
  625. HRESULT
  626. CCertPolicySample::_ReadRegistryStringArray(
  627. IN HKEY hkey,
  628. IN BOOL fURL,
  629. IN DWORD dwFlags,
  630. IN DWORD cRegNames,
  631. IN DWORD *aFlags,
  632. IN WCHAR const * const *apwszRegNames,
  633. IN OUT DWORD *pcStrings,
  634. IN OUT LPWSTR **papwszRegValues)
  635. {
  636. HRESULT hr;
  637. DWORD i;
  638. WCHAR *pwszzValue = NULL;
  639. DWORD cbValue;
  640. DWORD dwType;
  641. for (i = 0; i < cRegNames; i++)
  642. {
  643. if (0 == (dwFlags & aFlags[i]))
  644. {
  645. continue;
  646. }
  647. if (NULL != pwszzValue)
  648. {
  649. LocalFree(pwszzValue);
  650. pwszzValue = NULL;
  651. }
  652. hr = RegQueryValueEx(
  653. hkey,
  654. apwszRegNames[i],
  655. NULL, // lpdwReserved
  656. &dwType,
  657. NULL,
  658. &cbValue);
  659. if (S_OK != hr)
  660. {
  661. _PrintErrorStr2(
  662. hr,
  663. "Policy:RegQueryValueEx",
  664. apwszRegNames[i],
  665. ERROR_FILE_NOT_FOUND);
  666. continue;
  667. }
  668. if (REG_SZ != dwType && REG_MULTI_SZ != dwType)
  669. {
  670. hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
  671. _PrintErrorStr(hr, "Policy:RegQueryValueEx TYPE", apwszRegNames[i]);
  672. continue;
  673. }
  674. // Handle malformed registry values cleanly by adding two WCHAR L'\0's
  675. // allocate space for 3 WCHARs to allow for unaligned (odd) cbValue;
  676. pwszzValue = (WCHAR *) LocalAlloc(
  677. LMEM_FIXED,
  678. cbValue + 3 * sizeof(WCHAR));
  679. if (NULL == pwszzValue)
  680. {
  681. hr = E_OUTOFMEMORY;
  682. _JumpErrorStr(hr, error, "Policy:LocalAlloc", apwszRegNames[i]);
  683. }
  684. hr = RegQueryValueEx(
  685. hkey,
  686. apwszRegNames[i],
  687. NULL, // lpdwReserved
  688. &dwType,
  689. (BYTE *) pwszzValue,
  690. &cbValue);
  691. if (S_OK != hr)
  692. {
  693. _PrintErrorStr(hr, "Policy:RegQueryValueEx", apwszRegNames[i]);
  694. continue;
  695. }
  696. // Handle malformed registry values cleanly:
  697. pwszzValue[cbValue / sizeof(WCHAR)] = L'\0';
  698. pwszzValue[cbValue / sizeof(WCHAR) + 1] = L'\0';
  699. hr = _AddStringArray(
  700. pwszzValue,
  701. fURL,
  702. pcStrings,
  703. papwszRegValues);
  704. _JumpIfErrorStr(hr, error, "_AddStringArray", apwszRegNames[i]);
  705. }
  706. hr = S_OK;
  707. error:
  708. if (NULL != pwszzValue)
  709. {
  710. LocalFree(pwszzValue);
  711. }
  712. return(hr);
  713. }
  714. //+--------------------------------------------------------------------------
  715. // CCertPolicySample::_InitRevocationExtension
  716. //
  717. //+--------------------------------------------------------------------------
  718. VOID
  719. CCertPolicySample::_InitRevocationExtension(
  720. IN HKEY hkey)
  721. {
  722. HRESULT hr;
  723. DWORD dwType;
  724. DWORD cb;
  725. cb = sizeof(m_dwRevocationFlags);
  726. hr = RegQueryValueEx(
  727. hkey,
  728. wszREGREVOCATIONTYPE,
  729. NULL, // lpdwReserved
  730. &dwType,
  731. (BYTE *) &m_dwRevocationFlags,
  732. &cb);
  733. if (S_OK != hr ||
  734. REG_DWORD != dwType ||
  735. sizeof(m_dwRevocationFlags) != cb)
  736. {
  737. m_dwRevocationFlags = 0;
  738. goto error;
  739. }
  740. DBGPRINT((fDebug, "Revocation Flags = %x\n", m_dwRevocationFlags));
  741. // clean up from previous call
  742. if (NULL != m_wszASPRevocationURL)
  743. {
  744. LocalFree(m_wszASPRevocationURL);
  745. m_wszASPRevocationURL = NULL;
  746. }
  747. if (REVEXT_ASPENABLE & m_dwRevocationFlags)
  748. {
  749. hr = _ReadRegistryString(
  750. hkey,
  751. TRUE, // fURL
  752. wszREGREVOCATIONURL, // pwszRegName
  753. L"?", // pwszSuffix
  754. &m_wszASPRevocationURL); // pstrRegValue
  755. _JumpIfErrorStr(hr, error, "_ReadRegistryString", wszREGREVOCATIONURL);
  756. _DumpStringArray("ASP", 1, &m_wszASPRevocationURL);
  757. }
  758. error:
  759. ;
  760. }
  761. //+--------------------------------------------------------------------------
  762. // CCertPolicySample::_InitRequestExtensionList
  763. //
  764. //+--------------------------------------------------------------------------
  765. VOID
  766. CCertPolicySample::_InitRequestExtensionList(
  767. IN HKEY hkey)
  768. {
  769. HRESULT hr;
  770. DWORD adwFlags[] = {
  771. EDITF_REQUESTEXTENSIONLIST,
  772. };
  773. WCHAR *apwszRegNames[] = {
  774. wszREGENABLEREQUESTEXTENSIONLIST,
  775. };
  776. WCHAR *apwszRegNamesEnrollee[] = {
  777. wszREGENABLEENROLLEEREQUESTEXTENSIONLIST,
  778. };
  779. assert(ARRAYSIZE(adwFlags) == ARRAYSIZE(apwszRegNames));
  780. assert(ARRAYSIZE(adwFlags) == ARRAYSIZE(apwszRegNamesEnrollee));
  781. // clean up from previous call
  782. if (NULL != m_apwszEnableRequestExtensions)
  783. {
  784. _FreeStringArray(
  785. &m_cEnableRequestExtensions,
  786. &m_apwszEnableRequestExtensions);
  787. }
  788. if (NULL != m_apwszEnableEnrolleeRequestExtensions)
  789. {
  790. _FreeStringArray(
  791. &m_cEnableEnrolleeRequestExtensions,
  792. &m_apwszEnableEnrolleeRequestExtensions);
  793. }
  794. hr = _ReadRegistryStringArray(
  795. hkey,
  796. FALSE, // fURL
  797. m_dwEditFlags,
  798. ARRAYSIZE(adwFlags),
  799. adwFlags,
  800. apwszRegNames,
  801. &m_cEnableRequestExtensions,
  802. &m_apwszEnableRequestExtensions);
  803. _JumpIfError(hr, error, "_ReadRegistryStringArray");
  804. _DumpStringArray(
  805. "Request",
  806. m_cEnableRequestExtensions,
  807. m_apwszEnableRequestExtensions);
  808. hr = _ReadRegistryStringArray(
  809. hkey,
  810. FALSE, // fURL
  811. m_dwEditFlags,
  812. ARRAYSIZE(adwFlags),
  813. adwFlags,
  814. apwszRegNamesEnrollee,
  815. &m_cEnableEnrolleeRequestExtensions,
  816. &m_apwszEnableEnrolleeRequestExtensions);
  817. _JumpIfError(hr, error, "_ReadRegistryStringArray");
  818. _DumpStringArray(
  819. "EnrolleeRequest",
  820. m_cEnableEnrolleeRequestExtensions,
  821. m_apwszEnableEnrolleeRequestExtensions);
  822. error:
  823. ;
  824. }
  825. //+--------------------------------------------------------------------------
  826. // CCertPolicySample::_InitDisableExtensionList
  827. //
  828. //+--------------------------------------------------------------------------
  829. VOID
  830. CCertPolicySample::_InitDisableExtensionList(
  831. IN HKEY hkey)
  832. {
  833. HRESULT hr;
  834. DWORD adwFlags[] = {
  835. EDITF_DISABLEEXTENSIONLIST,
  836. };
  837. WCHAR *apwszRegNames[] = {
  838. wszREGDISABLEEXTENSIONLIST,
  839. };
  840. assert(ARRAYSIZE(adwFlags) == ARRAYSIZE(apwszRegNames));
  841. // clean up from previous call
  842. if (NULL != m_apwszDisableExtensions)
  843. {
  844. _FreeStringArray(&m_cDisableExtensions, &m_apwszDisableExtensions);
  845. }
  846. hr = _ReadRegistryStringArray(
  847. hkey,
  848. FALSE, // fURL
  849. m_dwEditFlags,
  850. ARRAYSIZE(adwFlags),
  851. adwFlags,
  852. apwszRegNames,
  853. &m_cDisableExtensions,
  854. &m_apwszDisableExtensions);
  855. _JumpIfError(hr, error, "_ReadRegistryStringArray");
  856. _DumpStringArray(
  857. "Disable",
  858. m_cDisableExtensions,
  859. m_apwszDisableExtensions);
  860. error:
  861. ;
  862. }
  863. //+--------------------------------------------------------------------------
  864. // CCertPolicySample::Initialize
  865. //
  866. // Returns S_OK on success.
  867. //+--------------------------------------------------------------------------
  868. STDMETHODIMP
  869. CCertPolicySample::Initialize(
  870. /* [in] */ BSTR const strConfig)
  871. {
  872. HRESULT hr;
  873. HKEY hkey = NULL;
  874. DWORD dwType;
  875. DWORD dwSize;
  876. ICertServerPolicy *pServer = NULL;
  877. BOOL fUpgraded;
  878. BSTR bstrDescription = NULL;
  879. CERT_RDN_ATTR rdnAttr = { szOID_COMMON_NAME, CERT_RDN_ANY_TYPE, };
  880. rdnAttr.Value.pbData = NULL;
  881. DBGPRINT((fDebug, "Policy:Initialize:\n"));
  882. __try
  883. {
  884. _Cleanup();
  885. m_strCAName = SysAllocString(strConfig);
  886. if (NULL == m_strCAName)
  887. {
  888. hr = E_OUTOFMEMORY;
  889. _LeaveError(hr, "CCertPolicySample::SysAllocString");
  890. }
  891. // force loading the description from resources
  892. hr = GetDescription(&bstrDescription);
  893. _LeaveIfError(hr, "CCertPolicySample::GetDescription");
  894. // get server callbacks
  895. hr = polGetServerCallbackInterface(&pServer, 0);
  896. _LeaveIfError(hr, "Policy:polGetServerCallbackInterface");
  897. hr = ReqInitialize(pServer);
  898. _JumpIfError(hr, error, "ReqInitialize");
  899. // get storage location
  900. hr = polGetCertificateStringProperty(
  901. pServer,
  902. wszPROPMODULEREGLOC,
  903. &m_strRegStorageLoc);
  904. _LeaveIfErrorStr(
  905. hr,
  906. "Policy:polGetCertificateStringProperty",
  907. wszPROPMODULEREGLOC);
  908. // get CA type
  909. hr = polGetCertificateLongProperty(
  910. pServer,
  911. wszPROPCATYPE,
  912. (LONG *) &m_CAType);
  913. _LeaveIfErrorStr(
  914. hr,
  915. "Policy:polGetCertificateLongProperty",
  916. wszPROPCATYPE);
  917. // get sanitized name
  918. hr = polGetCertificateStringProperty(
  919. pServer,
  920. wszPROPSANITIZEDCANAME,
  921. &m_strCASanitizedName);
  922. _LeaveIfErrorStr(
  923. hr,
  924. "Policy:polGetCertificateStringProperty",
  925. wszPROPSANITIZEDCANAME);
  926. // get sanitized name
  927. hr = polGetCertificateStringProperty(
  928. pServer,
  929. wszPROPSANITIZEDSHORTNAME,
  930. &m_strCASanitizedDSName);
  931. _LeaveIfErrorStr(
  932. hr,
  933. "Policy:polGetCertificateStringProperty",
  934. wszPROPSANITIZEDSHORTNAME);
  935. hr = polGetCertificateLongProperty(
  936. pServer,
  937. wszPROPSERVERUPGRADED,
  938. (LONG *) &fUpgraded);
  939. if (S_OK != hr)
  940. {
  941. fUpgraded = FALSE;
  942. _PrintErrorStr(
  943. hr,
  944. "Policy:polGetCertificateLongProperty",
  945. wszPROPSERVERUPGRADED);
  946. }
  947. hr = RegOpenKeyEx(
  948. HKEY_LOCAL_MACHINE,
  949. m_strRegStorageLoc,
  950. 0, // dwReserved
  951. fUpgraded?
  952. KEY_ALL_ACCESS :
  953. (KEY_ENUMERATE_SUB_KEYS | KEY_EXECUTE | KEY_QUERY_VALUE),
  954. &hkey);
  955. _LeaveIfErrorStr(
  956. hr,
  957. "Policy:Initialize:RegOpenKeyEx",
  958. m_strRegStorageLoc);
  959. // Ignore error codes.
  960. dwSize = sizeof(m_dwDispositionFlags);
  961. hr = RegQueryValueEx(
  962. hkey,
  963. wszREGREQUESTDISPOSITION,
  964. 0,
  965. &dwType,
  966. (BYTE *) &m_dwDispositionFlags,
  967. &dwSize);
  968. if (S_OK != hr || REG_DWORD != dwType)
  969. {
  970. m_dwDispositionFlags = REQDISP_PENDINGFIRST | REQDISP_ISSUE;
  971. }
  972. DBGPRINT((
  973. fDebug,
  974. "Disposition Flags = %x\n",
  975. m_dwDispositionFlags));
  976. dwSize = sizeof(m_dwEditFlags);
  977. hr = RegQueryValueEx(
  978. hkey,
  979. wszREGEDITFLAGS,
  980. 0,
  981. &dwType,
  982. (BYTE *) &m_dwEditFlags,
  983. &dwSize);
  984. if (S_OK != hr || REG_DWORD != dwType)
  985. {
  986. m_dwEditFlags =
  987. EDITF_DEFAULT_STANDALONE;
  988. }
  989. if (fUpgraded)
  990. {
  991. DBGPRINT((
  992. fDebug,
  993. "Initialize: setting EDITF_SERVERUPGRADED\n"));
  994. m_dwEditFlags |= EDITF_SERVERUPGRADED;
  995. dwSize = sizeof(m_dwEditFlags);
  996. hr = RegSetValueEx(
  997. hkey,
  998. wszREGEDITFLAGS,
  999. 0,
  1000. REG_DWORD,
  1001. (BYTE *) &m_dwEditFlags,
  1002. dwSize);
  1003. _PrintIfError(hr, "Policy:RegSetValueEx");
  1004. }
  1005. DBGPRINT((fDebug, "Edit Flags = %x\n", m_dwEditFlags));
  1006. dwSize = sizeof(m_CAPathLength);
  1007. hr = RegQueryValueEx(
  1008. hkey,
  1009. wszREGCAPATHLENGTH,
  1010. 0,
  1011. &dwType,
  1012. (BYTE *) &m_CAPathLength,
  1013. &dwSize);
  1014. if (S_OK != hr || REG_DWORD != dwType)
  1015. {
  1016. m_CAPathLength = CAPATHLENGTH_INFINITE;
  1017. }
  1018. DBGPRINT((fDebug, "CAPathLength = %x\n", m_CAPathLength));
  1019. // Initialize the insertion string array.
  1020. // Machine DNS name (%1)
  1021. hr = polGetCertificateStringProperty(
  1022. pServer,
  1023. wszPROPMACHINEDNSNAME,
  1024. &m_strMachineDNSName);
  1025. _LeaveIfErrorStr(
  1026. hr,
  1027. "Policy:polGetCertificateStringProperty",
  1028. wszPROPMACHINEDNSNAME);
  1029. hr = polGetCertificateLongProperty(
  1030. pServer,
  1031. wszPROPCERTCOUNT,
  1032. (LONG *) &m_iCert);
  1033. _LeaveIfErrorStr(
  1034. hr,
  1035. "Policy:polGetCertificateLongProperty",
  1036. wszPROPCERTCOUNT);
  1037. if (0 == m_iCert) // no CA certs?
  1038. {
  1039. hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  1040. _LeaveIfErrorStr(
  1041. hr,
  1042. "Policy:polGetCertificateLongProperty",
  1043. wszPROPCERTCOUNT);
  1044. }
  1045. m_iCert--;
  1046. hr = polGetCertificateLongProperty(
  1047. pServer,
  1048. wszPROPCRLINDEX,
  1049. (LONG *) &m_iCRL);
  1050. _LeaveIfErrorStr(
  1051. hr,
  1052. "Policy:polGetCertificateLongProperty",
  1053. wszPROPCRLINDEX);
  1054. _InitRevocationExtension(hkey);
  1055. _InitRequestExtensionList(hkey);
  1056. _InitDisableExtensionList(hkey);
  1057. hr = S_OK;
  1058. }
  1059. __except(hr = ceHError(GetExceptionCode()), EXCEPTION_EXECUTE_HANDLER)
  1060. {
  1061. _PrintError(hr, "Exception");
  1062. }
  1063. error:
  1064. if (NULL != bstrDescription)
  1065. {
  1066. SysFreeString(bstrDescription);
  1067. }
  1068. if (NULL != hkey)
  1069. {
  1070. RegCloseKey(hkey);
  1071. }
  1072. if (NULL != pServer)
  1073. {
  1074. pServer->Release();
  1075. }
  1076. return(ceHError(hr)); // Reg routines return Win32 error codes
  1077. }
  1078. DWORD
  1079. polFindObjIdInList(
  1080. IN WCHAR const *pwsz,
  1081. IN DWORD count,
  1082. IN WCHAR const * const *ppwsz)
  1083. {
  1084. DWORD i;
  1085. for (i = 0; i < count; i++)
  1086. {
  1087. if (NULL == pwsz || NULL == ppwsz[i])
  1088. {
  1089. i = count;
  1090. break;
  1091. }
  1092. if (0 == wcscmp(pwsz, ppwsz[i]))
  1093. {
  1094. break;
  1095. }
  1096. }
  1097. return(i < count? i : MAXDWORD);
  1098. }
  1099. HRESULT
  1100. CCertPolicySample::_EnumerateExtensions(
  1101. IN ICertServerPolicy *pServer,
  1102. IN LONG bNewRequest,
  1103. IN BOOL fFirstPass,
  1104. IN BOOL fEnableEnrolleeExtensions,
  1105. IN DWORD cCriticalExtensions,
  1106. OPTIONAL IN WCHAR const * const *apwszCriticalExtensions)
  1107. {
  1108. HRESULT hr;
  1109. HRESULT hr2;
  1110. BSTR strName = NULL;
  1111. LONG ExtFlags;
  1112. VARIANT varValue;
  1113. BOOL fClose = FALSE;
  1114. BOOL fEnable;
  1115. BOOL fDisable;
  1116. BOOL fCritical;
  1117. VariantInit(&varValue);
  1118. hr = pServer->EnumerateExtensionsSetup(0);
  1119. _JumpIfError(hr, error, "Policy:EnumerateExtensionsSetup");
  1120. fClose = TRUE;
  1121. while (TRUE)
  1122. {
  1123. hr = pServer->EnumerateExtensions(&strName);
  1124. if (S_FALSE == hr)
  1125. {
  1126. hr = S_OK;
  1127. break;
  1128. }
  1129. _JumpIfError(hr, error, "Policy:EnumerateExtensions");
  1130. hr = pServer->GetCertificateExtension(
  1131. strName,
  1132. PROPTYPE_BINARY,
  1133. &varValue);
  1134. _JumpIfError(hr, error, "Policy:GetCertificateExtension");
  1135. hr = pServer->GetCertificateExtensionFlags(&ExtFlags);
  1136. _JumpIfError(hr, error, "Policy:GetCertificateExtensionFlags");
  1137. fEnable = FALSE;
  1138. fDisable = FALSE;
  1139. fCritical = FALSE;
  1140. if (fFirstPass)
  1141. {
  1142. if (bNewRequest && (EXTENSION_DISABLE_FLAG & ExtFlags))
  1143. {
  1144. switch (EXTENSION_ORIGIN_MASK & ExtFlags)
  1145. {
  1146. case EXTENSION_ORIGIN_REQUEST:
  1147. case EXTENSION_ORIGIN_RENEWALCERT:
  1148. case EXTENSION_ORIGIN_PKCS7:
  1149. case EXTENSION_ORIGIN_CMC:
  1150. if ((EDITF_ENABLEREQUESTEXTENSIONS & m_dwEditFlags) ||
  1151. MAXDWORD != polFindObjIdInList(
  1152. strName,
  1153. m_cEnableRequestExtensions,
  1154. m_apwszEnableRequestExtensions) ||
  1155. (fEnableEnrolleeExtensions &&
  1156. MAXDWORD != polFindObjIdInList(
  1157. strName,
  1158. m_cEnableEnrolleeRequestExtensions,
  1159. m_apwszEnableEnrolleeRequestExtensions)))
  1160. {
  1161. ExtFlags &= ~EXTENSION_DISABLE_FLAG;
  1162. fEnable = TRUE;
  1163. }
  1164. break;
  1165. }
  1166. }
  1167. }
  1168. else
  1169. {
  1170. if (0 == (EXTENSION_DISABLE_FLAG & ExtFlags) &&
  1171. MAXDWORD != polFindObjIdInList(
  1172. strName,
  1173. m_cDisableExtensions,
  1174. m_apwszDisableExtensions))
  1175. {
  1176. ExtFlags |= EXTENSION_DISABLE_FLAG;
  1177. fDisable = TRUE;
  1178. }
  1179. if (0 == (EXTENSION_CRITICAL_FLAG & ExtFlags) &&
  1180. MAXDWORD != polFindObjIdInList(
  1181. strName,
  1182. cCriticalExtensions,
  1183. apwszCriticalExtensions))
  1184. {
  1185. ExtFlags |= EXTENSION_CRITICAL_FLAG;
  1186. fCritical = TRUE;
  1187. }
  1188. }
  1189. if (fDisable || fEnable)
  1190. {
  1191. hr = pServer->SetCertificateExtension(
  1192. strName,
  1193. PROPTYPE_BINARY,
  1194. ExtFlags,
  1195. &varValue);
  1196. _JumpIfError(hr, error, "Policy:SetCertificateExtension");
  1197. }
  1198. if (fFirstPass || fDisable || fEnable)
  1199. {
  1200. DBGPRINT((
  1201. fDebug,
  1202. "Policy:EnumerateExtensions(%ws, Flags=%x, %x bytes)%hs%hs\n",
  1203. strName,
  1204. ExtFlags,
  1205. SysStringByteLen(varValue.bstrVal),
  1206. fDisable? " DISABLING" : (fEnable? " ENABLING" : ""),
  1207. fCritical? " +CRITICAL" : ""));
  1208. }
  1209. if (NULL != strName)
  1210. {
  1211. SysFreeString(strName);
  1212. strName = NULL;
  1213. }
  1214. VariantClear(&varValue);
  1215. }
  1216. error:
  1217. if (fClose)
  1218. {
  1219. hr2 = pServer->EnumerateExtensionsClose();
  1220. if (S_OK != hr2)
  1221. {
  1222. if (S_OK == hr)
  1223. {
  1224. hr = hr2;
  1225. }
  1226. _PrintError(hr2, "Policy:EnumerateExtensionsClose");
  1227. }
  1228. }
  1229. if (NULL != strName)
  1230. {
  1231. SysFreeString(strName);
  1232. }
  1233. VariantClear(&varValue);
  1234. return(hr);
  1235. }
  1236. HRESULT
  1237. EnumerateAttributes(
  1238. IN ICertServerPolicy *pServer)
  1239. {
  1240. HRESULT hr;
  1241. HRESULT hr2;
  1242. BSTR strName = NULL;
  1243. BOOL fClose = FALSE;
  1244. BSTR strValue = NULL;
  1245. hr = pServer->EnumerateAttributesSetup(0);
  1246. _JumpIfError(hr, error, "Policy:EnumerateAttributesSetup");
  1247. fClose = TRUE;
  1248. while (TRUE)
  1249. {
  1250. hr = pServer->EnumerateAttributes(&strName);
  1251. if (S_FALSE == hr)
  1252. {
  1253. hr = S_OK;
  1254. break;
  1255. }
  1256. _JumpIfError(hr, error, "Policy:EnumerateAttributes");
  1257. hr = pServer->GetRequestAttribute(strName, &strValue);
  1258. _JumpIfError(hr, error, "Policy:GetRequestAttribute");
  1259. DBGPRINT((
  1260. fDebug,
  1261. "Policy:EnumerateAttributes(%ws = %ws)\n",
  1262. strName,
  1263. strValue));
  1264. if (NULL != strName)
  1265. {
  1266. SysFreeString(strName);
  1267. strName = NULL;
  1268. }
  1269. if (NULL != strValue)
  1270. {
  1271. SysFreeString(strValue);
  1272. strValue = NULL;
  1273. }
  1274. }
  1275. error:
  1276. if (fClose)
  1277. {
  1278. hr2 = pServer->EnumerateAttributesClose();
  1279. if (S_OK != hr2)
  1280. {
  1281. _PrintError(hr2, "Policy:EnumerateAttributesClose");
  1282. if (S_OK == hr)
  1283. {
  1284. hr = hr2;
  1285. }
  1286. }
  1287. }
  1288. if (NULL != strName)
  1289. {
  1290. SysFreeString(strName);
  1291. }
  1292. if (NULL != strValue)
  1293. {
  1294. SysFreeString(strValue);
  1295. }
  1296. return(hr);
  1297. }
  1298. HRESULT
  1299. GetRequestId(
  1300. IN ICertServerPolicy *pServer,
  1301. OUT LONG *plRequestId)
  1302. {
  1303. HRESULT hr;
  1304. hr = polGetRequestLongProperty(pServer, wszPROPREQUESTREQUESTID, plRequestId);
  1305. _JumpIfError(hr, error, "Policy:polGetRequestLongProperty");
  1306. DBGPRINT((
  1307. fDebug,
  1308. "Policy:GetRequestId(%ws = %u)\n",
  1309. wszPROPREQUESTREQUESTID,
  1310. *plRequestId));
  1311. error:
  1312. return(hr);
  1313. }
  1314. //+--------------------------------------------------------------------------
  1315. // CCertPolicySample::_AddRevocationExtension
  1316. //
  1317. // Returns S_OK on success.
  1318. //+--------------------------------------------------------------------------
  1319. HRESULT
  1320. CCertPolicySample::_AddRevocationExtension(
  1321. IN ICertServerPolicy *pServer)
  1322. {
  1323. HRESULT hr = S_OK;
  1324. BSTR strASPExtension = NULL;
  1325. VARIANT varExtension;
  1326. if (NULL != m_wszASPRevocationURL)
  1327. {
  1328. strASPExtension = SysAllocString(m_wszASPRevocationURL);
  1329. if (NULL == strASPExtension)
  1330. {
  1331. hr = E_OUTOFMEMORY;
  1332. _JumpError(hr, error, "Policy:SysAllocString");
  1333. }
  1334. varExtension.vt = VT_BSTR;
  1335. varExtension.bstrVal = strASPExtension;
  1336. hr = polSetCertificateExtension(
  1337. pServer,
  1338. TEXT(szOID_NETSCAPE_REVOCATION_URL),
  1339. PROPTYPE_STRING,
  1340. 0,
  1341. &varExtension);
  1342. _JumpIfErrorStr(hr, error, "Policy:polSetCertificateExtension", L"ASP");
  1343. }
  1344. error:
  1345. if (NULL != strASPExtension)
  1346. {
  1347. SysFreeString(strASPExtension);
  1348. }
  1349. return(hr);
  1350. }
  1351. #define HIGHBIT(bitno) (1 << (7 - (bitno))) // bit counted from high end
  1352. #define SSLBIT_CLIENT ((BYTE) HIGHBIT(0)) // certified for client auth
  1353. #define SSLBIT_SERVER ((BYTE) HIGHBIT(1)) // certified for server auth
  1354. #define SSLBIT_SMIME ((BYTE) HIGHBIT(2)) // certified for S/MIME
  1355. #define SSLBIT_SIGN ((BYTE) HIGHBIT(3)) // certified for signing
  1356. #define SSLBIT_RESERVED ((BYTE) HIGHBIT(4)) // reserved for future use
  1357. #define SSLBIT_CASSL ((BYTE) HIGHBIT(5)) // CA for SSL auth certs
  1358. #define SSLBIT_CASMIME ((BYTE) HIGHBIT(6)) // CA for S/MIME certs
  1359. #define SSLBIT_CASIGN ((BYTE) HIGHBIT(7)) // CA for signing certs
  1360. #define NSCERTTYPE_CLIENT ((BYTE) SSLBIT_CLIENT)
  1361. #define NSCERTTYPE_SERVER ((BYTE) (SSLBIT_SERVER | SSLBIT_CLIENT))
  1362. #define NSCERTTYPE_SMIME ((BYTE) SSLBIT_SMIME)
  1363. #define NSCERTTYPE_CA ((BYTE) (SSLBIT_CASSL | SSLBIT_CASMIME | SSLBIT_CASIGN))
  1364. //+--------------------------------------------------------------------------
  1365. // CCertPolicySample::_AddOldCertTypeExtension
  1366. //
  1367. // Returns S_OK on success.
  1368. //+--------------------------------------------------------------------------
  1369. HRESULT
  1370. CCertPolicySample::_AddOldCertTypeExtension(
  1371. IN ICertServerPolicy *pServer,
  1372. IN BOOL fCA)
  1373. {
  1374. HRESULT hr = S_OK;
  1375. ICertEncodeBitString *pBitString = NULL;
  1376. BSTR strExtension = NULL;
  1377. VARIANT varExtension;
  1378. BSTR strBitString = NULL;
  1379. BSTR strCertType = NULL;
  1380. CERT_BASIC_CONSTRAINTS2_INFO Constraints;
  1381. VARIANT varConstraints;
  1382. DWORD cb;
  1383. VariantInit(&varConstraints);
  1384. if (EDITF_ADDOLDCERTTYPE & m_dwEditFlags)
  1385. {
  1386. BYTE CertType;
  1387. if (!fCA)
  1388. {
  1389. hr = polGetCertificateExtension(
  1390. pServer,
  1391. TEXT(szOID_BASIC_CONSTRAINTS2),
  1392. PROPTYPE_BINARY,
  1393. &varConstraints);
  1394. if (S_OK == hr)
  1395. {
  1396. cb = sizeof(Constraints);
  1397. if (!CryptDecodeObject(
  1398. X509_ASN_ENCODING,
  1399. X509_BASIC_CONSTRAINTS2,
  1400. (BYTE const *) varConstraints.bstrVal,
  1401. SysStringByteLen(varConstraints.bstrVal),
  1402. 0,
  1403. &Constraints,
  1404. &cb))
  1405. {
  1406. hr = ceHLastError();
  1407. _JumpError(hr, error, "Policy:CryptDecodeObject");
  1408. }
  1409. fCA = Constraints.fCA;
  1410. }
  1411. }
  1412. hr = CoCreateInstance(
  1413. CLSID_CCertEncodeBitString,
  1414. NULL, // pUnkOuter
  1415. CLSCTX_INPROC_SERVER,
  1416. IID_ICertEncodeBitString,
  1417. (VOID **) &pBitString);
  1418. _JumpIfError(hr, error, "Policy:CoCreateInstance");
  1419. CertType = NSCERTTYPE_CLIENT; // Default to client auth. cert
  1420. if (fCA)
  1421. {
  1422. CertType = NSCERTTYPE_CA;
  1423. }
  1424. else
  1425. {
  1426. hr = polGetRequestAttribute(pServer, wszPROPCERTTYPE, &strCertType);
  1427. if (S_OK == hr)
  1428. {
  1429. if (0 == celstrcmpiL(strCertType, L"server"))
  1430. {
  1431. CertType = NSCERTTYPE_SERVER;
  1432. }
  1433. }
  1434. }
  1435. if (!ceConvertWszToBstr(
  1436. &strBitString,
  1437. (WCHAR const *) &CertType,
  1438. sizeof(CertType)))
  1439. {
  1440. hr = E_OUTOFMEMORY;
  1441. _JumpError(hr, error, "Policy:ceConvertWszToBstr");
  1442. }
  1443. hr = pBitString->Encode(
  1444. sizeof(CertType) * 8,
  1445. strBitString,
  1446. &strExtension);
  1447. _JumpIfError(hr, error, "Policy:BitString:Encode");
  1448. varExtension.vt = VT_BSTR;
  1449. varExtension.bstrVal = strExtension;
  1450. hr = polSetCertificateExtension(
  1451. pServer,
  1452. TEXT(szOID_NETSCAPE_CERT_TYPE),
  1453. PROPTYPE_BINARY,
  1454. 0,
  1455. &varExtension);
  1456. _JumpIfError(hr, error, "Policy:polSetCertificateExtension");
  1457. }
  1458. error:
  1459. VariantClear(&varConstraints);
  1460. if (NULL != strExtension)
  1461. {
  1462. SysFreeString(strExtension);
  1463. }
  1464. if (NULL != strBitString)
  1465. {
  1466. SysFreeString(strBitString);
  1467. }
  1468. if (NULL != strCertType)
  1469. {
  1470. SysFreeString(strCertType);
  1471. }
  1472. if (NULL != pBitString)
  1473. {
  1474. pBitString->Release();
  1475. }
  1476. return(hr);
  1477. }
  1478. //+--------------------------------------------------------------------------
  1479. // CCertPolicySample::_AddAuthorityKeyId
  1480. //
  1481. // Returns S_OK on success.
  1482. //+--------------------------------------------------------------------------
  1483. HRESULT
  1484. CCertPolicySample::_AddAuthorityKeyId(
  1485. IN ICertServerPolicy *pServer)
  1486. {
  1487. HRESULT hr = S_OK;
  1488. BYTE *pbEncoded = NULL;
  1489. DWORD cbEncoded;
  1490. BSTR strExtension = NULL;
  1491. VARIANT varExtension;
  1492. VARIANT varExtensionT;
  1493. PCERT_AUTHORITY_KEY_ID2_INFO pInfo = NULL;
  1494. DWORD cbInfo = 0;
  1495. LONG ExtFlags = 0;
  1496. VariantInit(&varExtension);
  1497. // Optimization
  1498. if ((EDITF_ENABLEAKIKEYID |
  1499. EDITF_ENABLEAKIISSUERNAME |
  1500. EDITF_ENABLEAKIISSUERSERIAL) ==
  1501. ((EDITF_ENABLEAKIKEYID |
  1502. EDITF_ENABLEAKIISSUERNAME |
  1503. EDITF_ENABLEAKIISSUERSERIAL |
  1504. EDITF_ENABLEAKICRITICAL) & m_dwEditFlags))
  1505. {
  1506. goto error;
  1507. }
  1508. hr = polGetCertificateExtension(
  1509. pServer,
  1510. TEXT(szOID_AUTHORITY_KEY_IDENTIFIER2),
  1511. PROPTYPE_BINARY,
  1512. &varExtension);
  1513. _JumpIfError(hr, error, "Policy:polGetCertificateExtension");
  1514. hr = pServer->GetCertificateExtensionFlags(&ExtFlags);
  1515. _JumpIfError(hr, error, "Policy:GetCertificateExtensionFlags");
  1516. if (VT_BSTR != varExtension.vt)
  1517. {
  1518. hr = E_INVALIDARG;
  1519. _JumpError(hr, error, "Policy:GetCertificateExtension");
  1520. }
  1521. cbInfo = 0;
  1522. if (!ceDecodeObject(
  1523. X509_ASN_ENCODING,
  1524. X509_AUTHORITY_KEY_ID2,
  1525. (BYTE *) varExtension.bstrVal,
  1526. SysStringByteLen(varExtension.bstrVal),
  1527. FALSE,
  1528. (VOID **) &pInfo,
  1529. &cbInfo))
  1530. {
  1531. hr = ceHLastError();
  1532. _JumpIfError(hr, error, "Policy:ceDecodeObject");
  1533. }
  1534. // Make Any Modifications Here
  1535. if (0 == (EDITF_ENABLEAKIKEYID & m_dwEditFlags))
  1536. {
  1537. pInfo->KeyId.cbData = 0;
  1538. pInfo->KeyId.pbData = NULL;
  1539. }
  1540. if (0 == (EDITF_ENABLEAKIISSUERNAME & m_dwEditFlags))
  1541. {
  1542. pInfo->AuthorityCertIssuer.cAltEntry = 0;
  1543. pInfo->AuthorityCertIssuer.rgAltEntry = NULL;
  1544. }
  1545. if (0 == (EDITF_ENABLEAKIISSUERSERIAL & m_dwEditFlags))
  1546. {
  1547. pInfo->AuthorityCertSerialNumber.cbData = 0;
  1548. pInfo->AuthorityCertSerialNumber.pbData = NULL;
  1549. }
  1550. if (EDITF_ENABLEAKICRITICAL & m_dwEditFlags)
  1551. {
  1552. ExtFlags |= EXTENSION_CRITICAL_FLAG;
  1553. }
  1554. if (0 ==
  1555. ((EDITF_ENABLEAKIKEYID |
  1556. EDITF_ENABLEAKIISSUERNAME |
  1557. EDITF_ENABLEAKIISSUERSERIAL) & m_dwEditFlags))
  1558. {
  1559. ExtFlags |= EXTENSION_DISABLE_FLAG;
  1560. }
  1561. if (!ceEncodeObject(
  1562. X509_ASN_ENCODING,
  1563. X509_AUTHORITY_KEY_ID2,
  1564. pInfo,
  1565. 0,
  1566. FALSE,
  1567. &pbEncoded,
  1568. &cbEncoded))
  1569. {
  1570. hr = ceHLastError();
  1571. _JumpError(hr, error, "Policy:ceEncodeObject");
  1572. }
  1573. if (!ceConvertWszToBstr(
  1574. &strExtension,
  1575. (WCHAR const *) pbEncoded,
  1576. cbEncoded))
  1577. {
  1578. hr = E_OUTOFMEMORY;
  1579. _JumpError(hr, error, "Policy:ceConvertWszToBstr");
  1580. }
  1581. varExtensionT.vt = VT_BSTR;
  1582. varExtensionT.bstrVal = strExtension;
  1583. hr = polSetCertificateExtension(
  1584. pServer,
  1585. TEXT(szOID_AUTHORITY_KEY_IDENTIFIER2),
  1586. PROPTYPE_BINARY,
  1587. ExtFlags,
  1588. &varExtensionT);
  1589. _JumpIfError(hr, error, "Policy:polSetCertificateExtension(AuthorityKeyId2)");
  1590. error:
  1591. VariantClear(&varExtension);
  1592. if (NULL != pInfo)
  1593. {
  1594. LocalFree(pInfo);
  1595. }
  1596. if (NULL != pbEncoded)
  1597. {
  1598. LocalFree(pbEncoded);
  1599. }
  1600. if (NULL != strExtension)
  1601. {
  1602. SysFreeString(strExtension);
  1603. }
  1604. return(hr);
  1605. }
  1606. //+--------------------------------------------------------------------------
  1607. // CCertPolicy::_AddDefaultKeyUsageExtension
  1608. //
  1609. // Returns S_OK on success.
  1610. //+--------------------------------------------------------------------------
  1611. HRESULT
  1612. CCertPolicySample::_AddDefaultKeyUsageExtension(
  1613. IN ICertServerPolicy *pServer,
  1614. IN BOOL fCA)
  1615. {
  1616. HRESULT hr;
  1617. BSTR strName = NULL;
  1618. ICertEncodeBitString *pBitString = NULL;
  1619. BSTR strExtension = NULL;
  1620. VARIANT varExtension;
  1621. BSTR strBitString = NULL;
  1622. CERT_BASIC_CONSTRAINTS2_INFO Constraints;
  1623. VARIANT varConstraints;
  1624. VARIANT varKeyUsage;
  1625. CRYPT_BIT_BLOB *pKeyUsage = NULL;
  1626. DWORD cb;
  1627. BYTE abKeyUsage[1];
  1628. BYTE *pbKeyUsage;
  1629. DWORD cbKeyUsage;
  1630. VariantInit(&varConstraints);
  1631. VariantInit(&varKeyUsage);
  1632. if (EDITF_ADDOLDKEYUSAGE & m_dwEditFlags)
  1633. {
  1634. BOOL fModified = FALSE;
  1635. if (!fCA)
  1636. {
  1637. hr = polGetCertificateExtension(
  1638. pServer,
  1639. TEXT(szOID_BASIC_CONSTRAINTS2),
  1640. PROPTYPE_BINARY,
  1641. &varConstraints);
  1642. if (S_OK == hr)
  1643. {
  1644. cb = sizeof(Constraints);
  1645. if (!CryptDecodeObject(
  1646. X509_ASN_ENCODING,
  1647. X509_BASIC_CONSTRAINTS2,
  1648. (BYTE const *) varConstraints.bstrVal,
  1649. SysStringByteLen(varConstraints.bstrVal),
  1650. 0,
  1651. &Constraints,
  1652. &cb))
  1653. {
  1654. hr = ceHLastError();
  1655. _JumpError(hr, error, "Policy:CryptDecodeObject");
  1656. }
  1657. fCA = Constraints.fCA;
  1658. }
  1659. }
  1660. ZeroMemory(abKeyUsage, sizeof(abKeyUsage));
  1661. pbKeyUsage = abKeyUsage;
  1662. cbKeyUsage = sizeof(abKeyUsage);
  1663. hr = polGetCertificateExtension(
  1664. pServer,
  1665. TEXT(szOID_KEY_USAGE),
  1666. PROPTYPE_BINARY,
  1667. &varKeyUsage);
  1668. if (S_OK == hr)
  1669. {
  1670. if (!ceDecodeObject(
  1671. X509_ASN_ENCODING,
  1672. X509_KEY_USAGE,
  1673. (BYTE const *) varKeyUsage.bstrVal,
  1674. SysStringByteLen(varKeyUsage.bstrVal),
  1675. FALSE,
  1676. (VOID **) &pKeyUsage,
  1677. &cb))
  1678. {
  1679. hr = GetLastError();
  1680. _PrintError(hr, "Policy:ceDecodeObject");
  1681. }
  1682. else if (0 != cb && NULL != pKeyUsage && 0 != pKeyUsage->cbData)
  1683. {
  1684. pbKeyUsage = pKeyUsage->pbData;
  1685. cbKeyUsage = pKeyUsage->cbData;
  1686. }
  1687. }
  1688. if ((CERT_KEY_ENCIPHERMENT_KEY_USAGE & pbKeyUsage[0]) &&
  1689. (CERT_KEY_AGREEMENT_KEY_USAGE & pbKeyUsage[0]))
  1690. {
  1691. pbKeyUsage[0] &= ~CERT_KEY_AGREEMENT_KEY_USAGE;
  1692. pbKeyUsage[0] |= CERT_DIGITAL_SIGNATURE_KEY_USAGE;
  1693. fModified = TRUE;
  1694. }
  1695. if (fCA)
  1696. {
  1697. pbKeyUsage[0] |= ceCASIGN_KEY_USAGE;
  1698. fModified = TRUE;
  1699. }
  1700. if (fModified)
  1701. {
  1702. hr = CoCreateInstance(
  1703. CLSID_CCertEncodeBitString,
  1704. NULL, // pUnkOuter
  1705. CLSCTX_INPROC_SERVER,
  1706. IID_ICertEncodeBitString,
  1707. (VOID **) &pBitString);
  1708. _JumpIfError(hr, error, "Policy:CoCreateInstance");
  1709. if (!ceConvertWszToBstr(
  1710. &strBitString,
  1711. (WCHAR const *) pbKeyUsage,
  1712. cbKeyUsage))
  1713. {
  1714. hr = E_OUTOFMEMORY;
  1715. _JumpError(hr, error, "Policy:ceConvertWszToBstr");
  1716. }
  1717. hr = pBitString->Encode(cbKeyUsage * 8, strBitString, &strExtension);
  1718. _JumpIfError(hr, error, "Policy:Encode");
  1719. if (!ceConvertWszToBstr(&strName, TEXT(szOID_KEY_USAGE), -1))
  1720. {
  1721. hr = E_OUTOFMEMORY;
  1722. _JumpError(hr, error, "Policy:ceConvertWszToBstr");
  1723. }
  1724. varExtension.vt = VT_BSTR;
  1725. varExtension.bstrVal = strExtension;
  1726. hr = pServer->SetCertificateExtension(
  1727. strName,
  1728. PROPTYPE_BINARY,
  1729. 0,
  1730. &varExtension);
  1731. _JumpIfError(hr, error, "Policy:SetCertificateExtension");
  1732. }
  1733. }
  1734. hr = S_OK;
  1735. error:
  1736. VariantClear(&varConstraints);
  1737. VariantClear(&varKeyUsage);
  1738. if (NULL != pKeyUsage)
  1739. {
  1740. LocalFree(pKeyUsage);
  1741. }
  1742. if (NULL != strName)
  1743. {
  1744. SysFreeString(strName);
  1745. }
  1746. if (NULL != strExtension)
  1747. {
  1748. SysFreeString(strExtension);
  1749. }
  1750. if (NULL != strBitString)
  1751. {
  1752. SysFreeString(strBitString);
  1753. }
  1754. if (NULL != pBitString)
  1755. {
  1756. pBitString->Release();
  1757. }
  1758. return(hr);
  1759. }
  1760. HRESULT
  1761. CCertPolicySample::_AddEnhancedKeyUsageExtension(
  1762. IN ICertServerPolicy *pServer)
  1763. {
  1764. HRESULT hr;
  1765. BSTR strUsage = NULL;
  1766. char *pszUsage = NULL;
  1767. char *psz;
  1768. char *pszNext;
  1769. CERT_ENHKEY_USAGE ceu;
  1770. CERT_POLICIES_INFO cpi;
  1771. BYTE *pbKeyUsage = NULL;
  1772. DWORD cbKeyUsage;
  1773. BYTE *pbPolicies = NULL;
  1774. DWORD cbPolicies;
  1775. CERT_POLICY_INFO *pcpi = NULL;
  1776. DWORD i;
  1777. VARIANT varExtension;
  1778. ZeroMemory(&ceu, sizeof(ceu));
  1779. ZeroMemory(&cpi, sizeof(cpi));
  1780. VariantInit(&varExtension);
  1781. if (0 == (EDITF_ATTRIBUTEEKU & m_dwEditFlags))
  1782. {
  1783. hr = S_OK;
  1784. goto error;
  1785. }
  1786. hr = polGetRequestAttribute(pServer, wszPROPCERTUSAGE, &strUsage);
  1787. if (S_OK != hr)
  1788. {
  1789. hr = S_OK;
  1790. goto error;
  1791. }
  1792. if (!ceConvertWszToSz(&pszUsage, strUsage, -1))
  1793. {
  1794. hr = E_OUTOFMEMORY;
  1795. _JumpError(hr, error, "Policy:ceConvertWszToSz");
  1796. }
  1797. for (psz = pszUsage; '\0' != *psz; psz = pszNext)
  1798. {
  1799. pszNext = &psz[strcspn(psz, ",")];
  1800. if ('\0' != *pszNext)
  1801. {
  1802. pszNext++;
  1803. }
  1804. ceu.cUsageIdentifier++;
  1805. }
  1806. if (0 == ceu.cUsageIdentifier)
  1807. {
  1808. hr = S_OK;
  1809. goto error;
  1810. }
  1811. ceu.rgpszUsageIdentifier = (char **) LocalAlloc(
  1812. LMEM_FIXED,
  1813. ceu.cUsageIdentifier * sizeof(ceu.rgpszUsageIdentifier[0]));
  1814. if (NULL == ceu.rgpszUsageIdentifier)
  1815. {
  1816. hr = E_OUTOFMEMORY;
  1817. _JumpError(hr, error, "Policy:myLocalAlloc");
  1818. }
  1819. // Destructively parse comma separated ObjIds into individual strings
  1820. i = 0;
  1821. for (psz = pszUsage; '\0' != *psz; psz = pszNext)
  1822. {
  1823. char *pszEnd;
  1824. assert(i < ceu.cUsageIdentifier);
  1825. pszNext = &psz[strcspn(psz, ",")];
  1826. pszEnd = pszNext;
  1827. if ('\0' != *pszNext)
  1828. {
  1829. *pszNext++ = '\0';
  1830. }
  1831. while (' ' == *psz)
  1832. {
  1833. psz++;
  1834. }
  1835. while (pszEnd > psz && ' ' == *--pszEnd)
  1836. {
  1837. *pszEnd = '\0';
  1838. }
  1839. if ('\0' != *psz)
  1840. {
  1841. hr = ceVerifyObjIdA(psz);
  1842. _JumpIfError(hr, error, "Policy:ceVerifyObjIdA");
  1843. ceu.rgpszUsageIdentifier[i++] = psz;
  1844. }
  1845. }
  1846. ceu.cUsageIdentifier = i;
  1847. if (0 == ceu.cUsageIdentifier)
  1848. {
  1849. hr = S_OK;
  1850. goto error;
  1851. }
  1852. if (!ceEncodeObject(
  1853. X509_ASN_ENCODING,
  1854. X509_ENHANCED_KEY_USAGE,
  1855. &ceu,
  1856. 0,
  1857. FALSE,
  1858. &pbKeyUsage,
  1859. &cbKeyUsage))
  1860. {
  1861. hr = ceHLastError();
  1862. _JumpError(hr, error, "Policy:ceEncodeObject");
  1863. }
  1864. varExtension.bstrVal = NULL;
  1865. if (!ceConvertWszToBstr(
  1866. &varExtension.bstrVal,
  1867. (WCHAR const *) pbKeyUsage,
  1868. cbKeyUsage))
  1869. {
  1870. hr = E_OUTOFMEMORY;
  1871. _JumpError(hr, error, "Policy:ceConvertWszToBstr");
  1872. }
  1873. varExtension.vt = VT_BSTR;
  1874. hr = polSetCertificateExtension(
  1875. pServer,
  1876. TEXT(szOID_ENHANCED_KEY_USAGE),
  1877. PROPTYPE_BINARY,
  1878. 0,
  1879. &varExtension);
  1880. _JumpIfError(hr, error, "Policy:polSetCertificateExtension");
  1881. cpi.cPolicyInfo = ceu.cUsageIdentifier;
  1882. cpi.rgPolicyInfo = (CERT_POLICY_INFO *) LocalAlloc(
  1883. LMEM_FIXED | LMEM_ZEROINIT,
  1884. cpi.cPolicyInfo * sizeof(cpi.rgPolicyInfo[0]));
  1885. if (NULL == cpi.rgPolicyInfo)
  1886. {
  1887. hr = E_OUTOFMEMORY;
  1888. _JumpError(hr, error, "Policy:LocalAlloc");
  1889. }
  1890. for (i = 0; i < cpi.cPolicyInfo; i++)
  1891. {
  1892. cpi.rgPolicyInfo[i].pszPolicyIdentifier = ceu.rgpszUsageIdentifier[i];
  1893. }
  1894. if (!ceEncodeObject(
  1895. X509_ASN_ENCODING,
  1896. X509_CERT_POLICIES,
  1897. &cpi,
  1898. 0,
  1899. FALSE,
  1900. &pbPolicies,
  1901. &cbPolicies))
  1902. {
  1903. hr = ceHLastError();
  1904. _JumpError(hr, error, "Policy:ceEncodeObject");
  1905. }
  1906. if (!ceConvertWszToBstr(
  1907. &varExtension.bstrVal,
  1908. (WCHAR const *) pbPolicies,
  1909. cbPolicies))
  1910. {
  1911. hr = E_OUTOFMEMORY;
  1912. _JumpError(hr, error, "Policy:ceConvertWszToBstr");
  1913. }
  1914. hr = polSetCertificateExtension(
  1915. pServer,
  1916. TEXT(szOID_APPLICATION_CERT_POLICIES),
  1917. PROPTYPE_BINARY,
  1918. 0,
  1919. &varExtension);
  1920. _JumpIfError(hr, error, "Policy:polSetCertificateExtension");
  1921. error:
  1922. if (NULL != pcpi)
  1923. {
  1924. LocalFree(pcpi);
  1925. }
  1926. VariantClear(&varExtension);
  1927. if (NULL != ceu.rgpszUsageIdentifier)
  1928. {
  1929. LocalFree(ceu.rgpszUsageIdentifier);
  1930. }
  1931. if (NULL != pbPolicies)
  1932. {
  1933. LocalFree(pbPolicies);
  1934. }
  1935. if (NULL != pbKeyUsage)
  1936. {
  1937. LocalFree(pbKeyUsage);
  1938. }
  1939. if (NULL != pszUsage)
  1940. {
  1941. LocalFree(pszUsage);
  1942. }
  1943. if (NULL != strUsage)
  1944. {
  1945. SysFreeString(strUsage);
  1946. }
  1947. return(hr);
  1948. }
  1949. //+--------------------------------------------------------------------------
  1950. // CCertPolicy::_AddDefaultBasicConstraintsExtension
  1951. //
  1952. // Returns S_OK on success.
  1953. //+--------------------------------------------------------------------------
  1954. HRESULT
  1955. CCertPolicySample::_AddDefaultBasicConstraintsExtension(
  1956. IN ICertServerPolicy *pServer,
  1957. IN BOOL fCA)
  1958. {
  1959. HRESULT hr;
  1960. VARIANT varExtension;
  1961. LONG ExtFlags;
  1962. CERT_EXTENSION Ext;
  1963. CERT_EXTENSION *pExtension = NULL;
  1964. BSTR strCertType = NULL;
  1965. VariantInit(&varExtension);
  1966. if (EDITF_BASICCONSTRAINTSCA & m_dwEditFlags)
  1967. {
  1968. hr = polGetCertificateExtension(
  1969. pServer,
  1970. TEXT(szOID_BASIC_CONSTRAINTS2),
  1971. PROPTYPE_BINARY,
  1972. &varExtension);
  1973. if (S_OK == hr)
  1974. {
  1975. CERT_BASIC_CONSTRAINTS2_INFO Constraints;
  1976. DWORD cb;
  1977. hr = pServer->GetCertificateExtensionFlags(&ExtFlags);
  1978. if (S_OK == hr)
  1979. {
  1980. Ext.pszObjId = szOID_BASIC_CONSTRAINTS2;
  1981. Ext.fCritical = FALSE;
  1982. if (EXTENSION_CRITICAL_FLAG & ExtFlags)
  1983. {
  1984. Ext.fCritical = TRUE;
  1985. }
  1986. Ext.Value.pbData = (BYTE *) varExtension.bstrVal;
  1987. Ext.Value.cbData = SysStringByteLen(varExtension.bstrVal);
  1988. pExtension = &Ext;
  1989. cb = sizeof(Constraints);
  1990. if (!fCA && CryptDecodeObject(
  1991. X509_ASN_ENCODING,
  1992. X509_BASIC_CONSTRAINTS2,
  1993. Ext.Value.pbData,
  1994. Ext.Value.cbData,
  1995. 0,
  1996. &Constraints,
  1997. &cb))
  1998. {
  1999. fCA = Constraints.fCA;
  2000. }
  2001. }
  2002. }
  2003. }
  2004. if (EDITF_ATTRIBUTECA & m_dwEditFlags)
  2005. {
  2006. if (!fCA)
  2007. {
  2008. hr = polGetRequestAttribute(pServer, wszPROPCERTTYPE, &strCertType);
  2009. if (S_OK == hr)
  2010. {
  2011. if (0 == celstrcmpiL(strCertType, L"ca"))
  2012. {
  2013. fCA = TRUE;
  2014. }
  2015. }
  2016. }
  2017. if (!fCA)
  2018. {
  2019. hr = polGetRequestAttribute(pServer, wszPROPCERTTEMPLATE, &strCertType);
  2020. if (S_OK == hr)
  2021. {
  2022. if (0 == celstrcmpiL(strCertType, wszCERTTYPE_SUBORDINATE_CA) ||
  2023. 0 == celstrcmpiL(strCertType, wszCERTTYPE_CROSS_CA))
  2024. {
  2025. fCA = TRUE;
  2026. }
  2027. }
  2028. }
  2029. }
  2030. // For standalone, the extension is only enabled if it's a CA
  2031. hr = AddBasicConstraintsCommon(pServer, pExtension, fCA, fCA);
  2032. _JumpIfError(hr, error, "Policy:AddBasicConstraintsCommon");
  2033. error:
  2034. VariantClear(&varExtension);
  2035. if (NULL != strCertType)
  2036. {
  2037. SysFreeString(strCertType);
  2038. }
  2039. return(hr);
  2040. }
  2041. HRESULT
  2042. CCertPolicySample::AddBasicConstraintsCommon(
  2043. IN ICertServerPolicy *pServer,
  2044. IN CERT_EXTENSION const *pExtension,
  2045. IN BOOL fCA,
  2046. IN BOOL fEnableExtension)
  2047. {
  2048. HRESULT hr;
  2049. BSTR strExtension = NULL;
  2050. VARIANT varExtension;
  2051. CERT_CONTEXT const *pIssuerCert;
  2052. CERT_EXTENSION *pIssuerExtension;
  2053. LONG ExtFlags = 0;
  2054. BYTE *pbConstraints = NULL;
  2055. CERT_BASIC_CONSTRAINTS2_INFO Constraints;
  2056. CERT_BASIC_CONSTRAINTS2_INFO IssuerConstraints;
  2057. ZeroMemory(&IssuerConstraints, sizeof(IssuerConstraints));
  2058. DWORD cb;
  2059. pIssuerCert = _GetIssuer(pServer);
  2060. if (NULL == pIssuerCert)
  2061. {
  2062. hr = E_POINTER;
  2063. _JumpError(hr, error, "_GetIssuer");
  2064. }
  2065. if (NULL != pExtension)
  2066. {
  2067. cb = sizeof(Constraints);
  2068. if (!CryptDecodeObject(
  2069. X509_ASN_ENCODING,
  2070. X509_BASIC_CONSTRAINTS2,
  2071. pExtension->Value.pbData,
  2072. pExtension->Value.cbData,
  2073. 0,
  2074. &Constraints,
  2075. &cb))
  2076. {
  2077. hr = ceHLastError();
  2078. _JumpError(hr, error, "Policy:CryptDecodeObject");
  2079. }
  2080. // Cert templates use CAPATHLENGTH_INFINITE to indicate
  2081. // fPathLenConstraint should be FALSE.
  2082. if (CAPATHLENGTH_INFINITE == Constraints.dwPathLenConstraint)
  2083. {
  2084. // NOTE: This is ok as certcli already sets fPathLenConstraint to FALSE
  2085. // for templates in this case.
  2086. Constraints.fPathLenConstraint = FALSE;
  2087. // NOTE: This is ok as autoenrollment ignores dwPathLenConstraint
  2088. // if fPathLenConstraint is FALSE;
  2089. Constraints.dwPathLenConstraint = 0;
  2090. }
  2091. if (pExtension->fCritical)
  2092. {
  2093. ExtFlags = EXTENSION_CRITICAL_FLAG;
  2094. }
  2095. }
  2096. else
  2097. {
  2098. Constraints.fCA = fCA;
  2099. Constraints.fPathLenConstraint = FALSE;
  2100. Constraints.dwPathLenConstraint = 0;
  2101. }
  2102. if (EDITF_BASICCONSTRAINTSCRITICAL & m_dwEditFlags)
  2103. {
  2104. ExtFlags = EXTENSION_CRITICAL_FLAG;
  2105. }
  2106. // Check basic constraints against the issuer's cert.
  2107. pIssuerExtension = CertFindExtension(
  2108. szOID_BASIC_CONSTRAINTS2,
  2109. pIssuerCert->pCertInfo->cExtension,
  2110. pIssuerCert->pCertInfo->rgExtension);
  2111. if (NULL != pIssuerExtension)
  2112. {
  2113. cb = sizeof(IssuerConstraints);
  2114. if (!CryptDecodeObject(
  2115. X509_ASN_ENCODING,
  2116. X509_BASIC_CONSTRAINTS2,
  2117. pIssuerExtension->Value.pbData,
  2118. pIssuerExtension->Value.cbData,
  2119. 0,
  2120. &IssuerConstraints,
  2121. &cb))
  2122. {
  2123. hr = ceHLastError();
  2124. _JumpError(hr, error, "Policy:CryptDecodeObject");
  2125. }
  2126. if (!IssuerConstraints.fCA)
  2127. {
  2128. hr = CERTSRV_E_INVALID_CA_CERTIFICATE;
  2129. _JumpError(hr, error, "Policy:CA cert not a CA cert");
  2130. }
  2131. }
  2132. if (Constraints.fCA)
  2133. {
  2134. if (IssuerConstraints.fPathLenConstraint)
  2135. {
  2136. if (0 == IssuerConstraints.dwPathLenConstraint)
  2137. {
  2138. hr = CERTSRV_E_INVALID_CA_CERTIFICATE;
  2139. _JumpError(hr, error, "Policy:CA cert is a leaf CA cert");
  2140. }
  2141. if (!Constraints.fPathLenConstraint ||
  2142. Constraints.dwPathLenConstraint >
  2143. IssuerConstraints.dwPathLenConstraint - 1)
  2144. {
  2145. Constraints.fPathLenConstraint = TRUE;
  2146. Constraints.dwPathLenConstraint =
  2147. IssuerConstraints.dwPathLenConstraint - 1;
  2148. }
  2149. }
  2150. if (CAPATHLENGTH_INFINITE != m_CAPathLength)
  2151. {
  2152. if (0 == m_CAPathLength)
  2153. {
  2154. hr = CERTSRV_E_INVALID_CA_CERTIFICATE;
  2155. _JumpError(hr, error, "Policy:Registry says not to issue CA certs");
  2156. }
  2157. if (!Constraints.fPathLenConstraint ||
  2158. Constraints.dwPathLenConstraint > m_CAPathLength - 1)
  2159. {
  2160. Constraints.fPathLenConstraint = TRUE;
  2161. Constraints.dwPathLenConstraint = m_CAPathLength - 1;
  2162. }
  2163. }
  2164. }
  2165. if (!fEnableExtension)
  2166. {
  2167. ExtFlags |= EXTENSION_DISABLE_FLAG;
  2168. }
  2169. if (!ceEncodeObject(
  2170. X509_ASN_ENCODING,
  2171. X509_BASIC_CONSTRAINTS2,
  2172. &Constraints,
  2173. 0,
  2174. FALSE,
  2175. &pbConstraints,
  2176. &cb))
  2177. {
  2178. hr = ceHLastError();
  2179. _JumpError(hr, error, "Policy:ceEncodeObject");
  2180. }
  2181. if (!ceConvertWszToBstr(
  2182. &strExtension,
  2183. (WCHAR const *) pbConstraints,
  2184. cb))
  2185. {
  2186. hr = E_OUTOFMEMORY;
  2187. _JumpError(hr, error, "Policy:ceConvertWszToBstr");
  2188. }
  2189. varExtension.vt = VT_BSTR;
  2190. varExtension.bstrVal = strExtension;
  2191. hr = polSetCertificateExtension(
  2192. pServer,
  2193. TEXT(szOID_BASIC_CONSTRAINTS2),
  2194. PROPTYPE_BINARY,
  2195. ExtFlags,
  2196. &varExtension);
  2197. _JumpIfError(hr, error, "Policy:polSetCertificateExtension");
  2198. error:
  2199. if (NULL != pbConstraints)
  2200. {
  2201. LocalFree(pbConstraints);
  2202. }
  2203. if (NULL != strExtension)
  2204. {
  2205. SysFreeString(strExtension);
  2206. }
  2207. return(hr);
  2208. }
  2209. //+--------------------------------------------------------------------------
  2210. // CCertPolicy::_SetValidityPeriod
  2211. //
  2212. // Returns S_OK on success.
  2213. //+--------------------------------------------------------------------------
  2214. HRESULT
  2215. CCertPolicySample::_SetValidityPeriod(
  2216. IN ICertServerPolicy *pServer)
  2217. {
  2218. HRESULT hr;
  2219. BSTR strPeriodString = NULL;
  2220. BSTR strPeriodCount = NULL;
  2221. BSTR strNameNotBefore = NULL;
  2222. BSTR strNameNotAfter = NULL;
  2223. VARIANT varValue;
  2224. LONG lDelta;
  2225. ENUM_PERIOD enumValidityPeriod;
  2226. BOOL fValidDigitString;
  2227. VariantInit(&varValue);
  2228. if (!(EDITF_ATTRIBUTEENDDATE & m_dwEditFlags))
  2229. {
  2230. hr = S_OK;
  2231. goto error;
  2232. }
  2233. hr = polGetRequestAttribute(
  2234. pServer,
  2235. wszPROPVALIDITYPERIODSTRING,
  2236. &strPeriodString);
  2237. if (S_OK != hr)
  2238. {
  2239. _PrintErrorStr2(
  2240. hr,
  2241. "Policy:polGetRequestAttribute",
  2242. wszPROPVALIDITYPERIODSTRING,
  2243. CERTSRV_E_PROPERTY_EMPTY);
  2244. if (CERTSRV_E_PROPERTY_EMPTY == hr)
  2245. {
  2246. hr = S_OK;
  2247. }
  2248. goto error;
  2249. }
  2250. hr = polGetRequestAttribute(
  2251. pServer,
  2252. wszPROPVALIDITYPERIODCOUNT,
  2253. &strPeriodCount);
  2254. if (S_OK != hr)
  2255. {
  2256. _PrintErrorStr2(
  2257. hr,
  2258. "Policy:polGetRequestAttribute",
  2259. wszPROPVALIDITYPERIODCOUNT,
  2260. CERTSRV_E_PROPERTY_EMPTY);
  2261. if (CERTSRV_E_PROPERTY_EMPTY == hr)
  2262. {
  2263. hr = S_OK;
  2264. }
  2265. goto error;
  2266. }
  2267. // Swap Count and String BSTRs if backwards -- Windows 2000 had it wrong.
  2268. lDelta = ceWtoI(strPeriodCount, &fValidDigitString);
  2269. if (!fValidDigitString)
  2270. {
  2271. BSTR str = strPeriodCount;
  2272. strPeriodCount = strPeriodString;
  2273. strPeriodString = str;
  2274. lDelta = ceWtoI(strPeriodCount, &fValidDigitString);
  2275. if (!fValidDigitString)
  2276. {
  2277. hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
  2278. _JumpError(hr, error, "Policy:ceWtoI");
  2279. }
  2280. }
  2281. hr = ceTranslatePeriodUnits(strPeriodString, lDelta, &enumValidityPeriod, &lDelta);
  2282. _JumpIfError(hr, error, "Policy:ceTranslatePeriodUnits");
  2283. strNameNotBefore = SysAllocString(wszPROPCERTIFICATENOTBEFOREDATE);
  2284. if (NULL == strNameNotBefore)
  2285. {
  2286. hr = E_OUTOFMEMORY;
  2287. _JumpError(hr, error, "Policy:SysAllocString");
  2288. }
  2289. hr = pServer->GetCertificateProperty(
  2290. strNameNotBefore,
  2291. PROPTYPE_DATE,
  2292. &varValue);
  2293. _JumpIfError(hr, error, "Policy:GetCertificateProperty");
  2294. hr = ceMakeExprDate(&varValue.date, lDelta, enumValidityPeriod);
  2295. _JumpIfError(hr, error, "Policy:ceMakeExprDate");
  2296. strNameNotAfter = SysAllocString(wszPROPCERTIFICATENOTAFTERDATE);
  2297. if (NULL == strNameNotAfter)
  2298. {
  2299. hr = E_OUTOFMEMORY;
  2300. _JumpError(hr, error, "Policy:SysAllocString");
  2301. }
  2302. hr = pServer->SetCertificateProperty(
  2303. strNameNotAfter,
  2304. PROPTYPE_DATE,
  2305. &varValue);
  2306. _JumpIfError(hr, error, "Policy:SetCertificateProperty");
  2307. hr = S_OK;
  2308. error:
  2309. VariantClear(&varValue);
  2310. if (NULL != strPeriodString)
  2311. {
  2312. SysFreeString(strPeriodString);
  2313. }
  2314. if (NULL != strPeriodCount)
  2315. {
  2316. SysFreeString(strPeriodCount);
  2317. }
  2318. if (NULL != strNameNotBefore)
  2319. {
  2320. SysFreeString(strNameNotBefore);
  2321. }
  2322. if (NULL != strNameNotAfter)
  2323. {
  2324. SysFreeString(strNameNotAfter);
  2325. }
  2326. return(hr);
  2327. }
  2328. //+--------------------------------------------------------------------------
  2329. // CCertPolicySample::_AddV1TemplateNameExtension
  2330. //
  2331. // Returns S_OK on success.
  2332. //+--------------------------------------------------------------------------
  2333. HRESULT
  2334. CCertPolicySample::AddV1TemplateNameExtension(
  2335. IN ICertServerPolicy *pServer,
  2336. OPTIONAL IN WCHAR const *pwszTemplateName)
  2337. {
  2338. HRESULT hr;
  2339. BSTR strName = NULL;
  2340. LONG ExtFlags = 0;
  2341. VARIANT varExtension;
  2342. CERT_NAME_VALUE *pName = NULL;
  2343. CERT_NAME_VALUE NameValue;
  2344. DWORD cbEncoded;
  2345. BYTE *pbEncoded = NULL;
  2346. BOOL fUpdate = TRUE;
  2347. VariantInit(&varExtension);
  2348. strName = SysAllocString(TEXT(szOID_ENROLL_CERTTYPE_EXTENSION));
  2349. if (NULL == strName)
  2350. {
  2351. hr = E_OUTOFMEMORY;
  2352. _JumpError(hr, error, "Policy:SysAllocString");
  2353. }
  2354. hr = pServer->GetCertificateExtension(
  2355. strName,
  2356. PROPTYPE_BINARY,
  2357. &varExtension);
  2358. _PrintIfError2(hr, "Policy:GetCertificateExtension", hr);
  2359. if (CERTSRV_E_PROPERTY_EMPTY == hr)
  2360. {
  2361. if (NULL == pwszTemplateName)
  2362. {
  2363. hr = S_OK;
  2364. goto error;
  2365. }
  2366. }
  2367. else
  2368. {
  2369. _JumpIfError(hr, error, "Policy:GetCertificateExtension");
  2370. hr = pServer->GetCertificateExtensionFlags(&ExtFlags);
  2371. _JumpIfError(hr, error, "Policy:GetCertificateExtensionFlags");
  2372. if (VT_BSTR == varExtension.vt &&
  2373. 0 == (EXTENSION_DISABLE_FLAG & ExtFlags) &&
  2374. NULL != pwszTemplateName)
  2375. {
  2376. if (!ceDecodeObject(
  2377. X509_ASN_ENCODING,
  2378. X509_UNICODE_ANY_STRING,
  2379. (BYTE *) varExtension.bstrVal,
  2380. SysStringByteLen(varExtension.bstrVal),
  2381. FALSE,
  2382. (VOID **) &pName,
  2383. &cbEncoded))
  2384. {
  2385. hr = ceHLastError();
  2386. _JumpError(hr, error, "Policy:ceDecodeObject");
  2387. }
  2388. // case sensitive compare -- be sure to match case of template
  2389. if (0 == lstrcmp(
  2390. (WCHAR const *) pName->Value.pbData,
  2391. pwszTemplateName))
  2392. {
  2393. fUpdate = FALSE;
  2394. }
  2395. }
  2396. }
  2397. if (fUpdate)
  2398. {
  2399. if (NULL == pwszTemplateName)
  2400. {
  2401. ExtFlags |= EXTENSION_DISABLE_FLAG;
  2402. }
  2403. else
  2404. {
  2405. VariantClear(&varExtension);
  2406. varExtension.bstrVal = NULL;
  2407. NameValue.dwValueType = CERT_RDN_UNICODE_STRING;
  2408. NameValue.Value.pbData = (BYTE *) pwszTemplateName;
  2409. NameValue.Value.cbData = 0;
  2410. if (!ceEncodeObject(
  2411. X509_ASN_ENCODING,
  2412. X509_UNICODE_ANY_STRING,
  2413. &NameValue,
  2414. 0,
  2415. FALSE,
  2416. &pbEncoded,
  2417. &cbEncoded))
  2418. {
  2419. hr = ceHLastError();
  2420. _JumpError(hr, error, "Policy:ceEncodeObject");
  2421. }
  2422. if (!ceConvertWszToBstr(
  2423. &varExtension.bstrVal,
  2424. (WCHAR const *) pbEncoded,
  2425. cbEncoded))
  2426. {
  2427. hr = E_OUTOFMEMORY;
  2428. _JumpError(hr, error, "Policy:ceConvertWszToBstr");
  2429. }
  2430. varExtension.vt = VT_BSTR;
  2431. ExtFlags &= ~EXTENSION_DISABLE_FLAG;
  2432. }
  2433. hr = pServer->SetCertificateExtension(
  2434. strName,
  2435. PROPTYPE_BINARY,
  2436. ExtFlags,
  2437. &varExtension);
  2438. _JumpIfError(hr, error, "Policy:SetCertificateExtension");
  2439. }
  2440. hr = S_OK;
  2441. error:
  2442. VariantClear(&varExtension);
  2443. if (NULL != strName)
  2444. {
  2445. SysFreeString(strName);
  2446. }
  2447. if (NULL != pName)
  2448. {
  2449. LocalFree(pName);
  2450. }
  2451. if (NULL != pbEncoded)
  2452. {
  2453. LocalFree(pbEncoded);
  2454. }
  2455. return(hr);
  2456. }
  2457. STDMETHODIMP
  2458. CCertPolicySample::VerifyRequest(
  2459. /* [in] */ BSTR const, // strConfig
  2460. /* [in] */ LONG Context,
  2461. /* [in] */ LONG bNewRequest,
  2462. /* [in] */ LONG, // Flags
  2463. /* [out, retval] */ LONG __RPC_FAR *pDisposition)
  2464. {
  2465. HRESULT hr = E_FAIL;
  2466. ICertServerPolicy *pServer = NULL;
  2467. LONG lRequestId;
  2468. CRequestInstance Request;
  2469. BSTR strDisposition = NULL;
  2470. BOOL fEnableEnrolleeExtensions;
  2471. BOOL fReenroll = FALSE;
  2472. DWORD cCriticalExtensions = 0;
  2473. WCHAR const * const *apwszCriticalExtensions = NULL;
  2474. lRequestId = 0;
  2475. __try
  2476. {
  2477. if (NULL == pDisposition)
  2478. {
  2479. hr = E_POINTER;
  2480. _LeaveError(hr, "Policy:pDisposition");
  2481. }
  2482. *pDisposition = VR_INSTANT_BAD;
  2483. hr = polGetServerCallbackInterface(&pServer, Context);
  2484. _LeaveIfError(hr, "Policy:polGetServerCallbackInterface");
  2485. hr = GetRequestId(pServer, &lRequestId);
  2486. _JumpIfError(hr, deny, "Policy:GetRequestId");
  2487. // only need to check user access for original submitter:
  2488. // resubmit can only be called by admins
  2489. if (bNewRequest && (0 == (m_dwEditFlags & EDITF_IGNOREREQUESTERGROUP)))
  2490. {
  2491. BOOL fRequesterAccess = FALSE;
  2492. // Is this user allowed to request certs?
  2493. hr = polGetCertificateLongProperty(
  2494. pServer,
  2495. wszPROPREQUESTERCAACCESS,
  2496. (LONG *) &fRequesterAccess);
  2497. _PrintIfErrorStr(
  2498. hr,
  2499. "Policy:polGetCertificateLongProperty",
  2500. wszPROPREQUESTERCAACCESS);
  2501. if (hr != S_OK || !fRequesterAccess)
  2502. {
  2503. hr = CERTSRV_E_ENROLL_DENIED;
  2504. _JumpError(hr, deny, "Policy:fRequesterAccess");
  2505. }
  2506. }
  2507. hr = Request.Initialize(
  2508. this,
  2509. pServer,
  2510. &fEnableEnrolleeExtensions);
  2511. _LeaveIfError(hr, "Policy:VerifyRequest:Request.Initialize");
  2512. hr = _EnumerateExtensions(
  2513. pServer,
  2514. bNewRequest,
  2515. TRUE,
  2516. fEnableEnrolleeExtensions,
  2517. 0,
  2518. NULL);
  2519. _LeaveIfError(hr, "_EnumerateExtensions");
  2520. {
  2521. hr = _AddDefaultBasicConstraintsExtension(
  2522. pServer,
  2523. Request.IsCARequest());
  2524. _LeaveIfError(hr, "_AddDefaultBasicConstraintsExtension");
  2525. hr = _AddDefaultKeyUsageExtension(pServer, Request.IsCARequest());
  2526. _LeaveIfError(hr, "_AddDefaultKeyUsageExtension");
  2527. hr = _AddEnhancedKeyUsageExtension(pServer);
  2528. _LeaveIfError(hr, "_AddEnhancedKeyUsageExtension");
  2529. }
  2530. hr = _SetValidityPeriod(pServer);
  2531. _LeaveIfError(hr, "_SetValidityPeriod");
  2532. hr = EnumerateAttributes(pServer);
  2533. _LeaveIfError(hr, "Policy:EnumerateAttributes");
  2534. hr = _AddRevocationExtension(pServer);
  2535. _LeaveIfError(hr, "_AddRevocationExtension");
  2536. hr = _AddOldCertTypeExtension(pServer, Request.IsCARequest());
  2537. _LeaveIfError(hr, "_AddOldCertTypeExtension");
  2538. hr = _AddAuthorityKeyId(pServer);
  2539. _LeaveIfError(hr, "_AddAuthorityKeyId");
  2540. // pass hr as Disposition
  2541. if ((EDITF_DISABLEEXTENSIONLIST & m_dwEditFlags) ||
  2542. NULL != apwszCriticalExtensions)
  2543. {
  2544. hr = _EnumerateExtensions(
  2545. pServer,
  2546. bNewRequest,
  2547. FALSE,
  2548. FALSE,
  2549. cCriticalExtensions,
  2550. apwszCriticalExtensions);
  2551. _LeaveIfError(hr, "_EnumerateExtensions");
  2552. }
  2553. if (bNewRequest &&
  2554. (
  2555. (REQDISP_PENDINGFIRST & m_dwDispositionFlags)))
  2556. {
  2557. *pDisposition = VR_PENDING;
  2558. }
  2559. else switch (REQDISP_MASK & m_dwDispositionFlags)
  2560. {
  2561. default:
  2562. case REQDISP_PENDING:
  2563. *pDisposition = VR_PENDING;
  2564. break;
  2565. case REQDISP_ISSUE:
  2566. *pDisposition = VR_INSTANT_OK;
  2567. break;
  2568. case REQDISP_DENY:
  2569. *pDisposition = VR_INSTANT_BAD;
  2570. break;
  2571. case REQDISP_USEREQUESTATTRIBUTE:
  2572. *pDisposition = VR_INSTANT_OK;
  2573. hr = polGetRequestAttribute(
  2574. pServer,
  2575. wszPROPDISPOSITION,
  2576. &strDisposition);
  2577. if (S_OK == hr)
  2578. {
  2579. if (0 == celstrcmpiL(strDisposition, wszPROPDISPOSITIONDENY))
  2580. {
  2581. *pDisposition = VR_INSTANT_BAD;
  2582. }
  2583. if (0 == celstrcmpiL(strDisposition, wszPROPDISPOSITIONPENDING))
  2584. {
  2585. *pDisposition = VR_PENDING;
  2586. }
  2587. }
  2588. hr = S_OK;
  2589. break;
  2590. }
  2591. deny:
  2592. if (FAILED(hr))
  2593. {
  2594. *pDisposition = hr; // pass failed HRESULT back as Disposition
  2595. }
  2596. else if (hr != S_OK)
  2597. {
  2598. *pDisposition = VR_INSTANT_BAD;
  2599. }
  2600. hr = S_OK;
  2601. }
  2602. __except(hr = ceHError(GetExceptionCode()), EXCEPTION_EXECUTE_HANDLER)
  2603. {
  2604. _PrintError(hr, "Exception");
  2605. }
  2606. {
  2607. HRESULT hr2 = hr;
  2608. #define wszFORMATREQUESTID L"RequestId=%u"
  2609. WCHAR wszRequestId[ARRAYSIZE(wszFORMATREQUESTID) + cwcDWORDSPRINTF];
  2610. if (S_OK == hr2 && NULL != pDisposition && FAILED(*pDisposition))
  2611. {
  2612. hr2 = *pDisposition;
  2613. }
  2614. if (S_OK != hr2)
  2615. {
  2616. wsprintf(wszRequestId, wszFORMATREQUESTID, lRequestId);
  2617. _PrintErrorStr(hr2, "VerifyRequest", wszRequestId);
  2618. }
  2619. }
  2620. if (NULL != strDisposition)
  2621. {
  2622. SysFreeString(strDisposition);
  2623. }
  2624. if (NULL != pServer)
  2625. {
  2626. pServer->Release();
  2627. }
  2628. //_PrintIfError(hr, "Policy:VerifyRequest(hr)");
  2629. //_PrintError(*pDisposition, "Policy:VerifyRequest(*pDisposition)");
  2630. return(hr);
  2631. }
  2632. //+--------------------------------------------------------------------------
  2633. // CCertPolicySample::GetDescription
  2634. //
  2635. // Returns S_OK on success.
  2636. //+--------------------------------------------------------------------------
  2637. STDMETHODIMP
  2638. CCertPolicySample::GetDescription(
  2639. /* [out, retval] */ BSTR __RPC_FAR *pstrDescription)
  2640. {
  2641. HRESULT hr = S_OK;
  2642. WCHAR sz[MAX_PATH];
  2643. if(!m_strDescription)
  2644. {
  2645. assert(wcslen(wsz_SAMPLE_DESCRIPTION) < ARRAYSIZE(sz));
  2646. wcsncpy(sz, wsz_SAMPLE_DESCRIPTION, ARRAYSIZE(sz));
  2647. sz[ARRAYSIZE(sz) - 1] = L'\0';
  2648. m_strDescription = SysAllocString(sz);
  2649. if (NULL == m_strDescription)
  2650. {
  2651. hr = E_OUTOFMEMORY;
  2652. return hr;
  2653. }
  2654. }
  2655. if (NULL != *pstrDescription)
  2656. {
  2657. SysFreeString(*pstrDescription);
  2658. }
  2659. *pstrDescription = SysAllocString(m_strDescription);
  2660. if (NULL == *pstrDescription)
  2661. {
  2662. hr = E_OUTOFMEMORY;
  2663. }
  2664. return(hr);
  2665. }
  2666. //+--------------------------------------------------------------------------
  2667. // CCertPolicySample::ShutDown
  2668. //
  2669. // Returns S_OK on success.
  2670. //+--------------------------------------------------------------------------
  2671. STDMETHODIMP
  2672. CCertPolicySample::ShutDown(VOID)
  2673. {
  2674. // called once, as Server unloading policy dll
  2675. _Cleanup();
  2676. return(S_OK);
  2677. }
  2678. //+--------------------------------------------------------------------------
  2679. // CCertPolicySample::GetManageModule
  2680. //
  2681. // Returns S_OK on success.
  2682. //+--------------------------------------------------------------------------
  2683. STDMETHODIMP
  2684. CCertPolicySample::GetManageModule(
  2685. /* [out, retval] */ ICertManageModule **ppManageModule)
  2686. {
  2687. HRESULT hr;
  2688. *ppManageModule = NULL;
  2689. hr = CoCreateInstance(
  2690. CLSID_CCertManagePolicyModuleSample,
  2691. NULL, // pUnkOuter
  2692. CLSCTX_INPROC_SERVER,
  2693. IID_ICertManageModule,
  2694. (VOID **) ppManageModule);
  2695. _JumpIfError(hr, error, "CoCreateInstance");
  2696. error:
  2697. return(hr);
  2698. }
  2699. //+--------------------------------------------------------------------------
  2700. // CCertPolicySample::_GetIssuer
  2701. //
  2702. // Returns S_OK on success.
  2703. //+--------------------------------------------------------------------------
  2704. PCCERT_CONTEXT
  2705. CCertPolicySample::_GetIssuer(
  2706. IN ICertServerPolicy *pServer)
  2707. {
  2708. HRESULT hr;
  2709. VARIANT varValue;
  2710. BSTR strName = NULL;
  2711. VariantInit(&varValue);
  2712. if (NULL != m_pCert)
  2713. {
  2714. hr = S_OK;
  2715. goto error;
  2716. }
  2717. strName = SysAllocString(wszPROPRAWCACERTIFICATE);
  2718. if (NULL == strName)
  2719. {
  2720. hr = E_OUTOFMEMORY;
  2721. _JumpError(hr, error, "Policy:SysAllocString");
  2722. }
  2723. hr = pServer->GetCertificateProperty(strName, PROPTYPE_BINARY, &varValue);
  2724. _JumpIfError(hr, error, "Policy:GetCertificateProperty");
  2725. m_pCert = CertCreateCertificateContext(
  2726. X509_ASN_ENCODING,
  2727. (BYTE *) varValue.bstrVal,
  2728. SysStringByteLen(varValue.bstrVal));
  2729. if (NULL == m_pCert)
  2730. {
  2731. hr = ceHLastError();
  2732. _JumpError(hr, error, "Policy:CertCreateCertificateContext");
  2733. }
  2734. error:
  2735. VariantClear(&varValue);
  2736. if (NULL != strName)
  2737. {
  2738. SysFreeString(strName);
  2739. }
  2740. return(m_pCert);
  2741. }
  2742. STDMETHODIMP
  2743. CCertPolicySample::InterfaceSupportsErrorInfo(
  2744. IN REFIID riid)
  2745. {
  2746. static const IID *arr[] =
  2747. {
  2748. &IID_ICertPolicy,
  2749. };
  2750. for (int i = 0; i < sizeof(arr)/sizeof(arr[0]); i++)
  2751. {
  2752. if (IsEqualGUID(*arr[i], riid))
  2753. {
  2754. return(S_OK);
  2755. }
  2756. }
  2757. return(S_FALSE);
  2758. }