Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1372 lines
45 KiB

  1. //depot/Lab03_N/DS/security/cryptoapi/common/keysvc/keysvcc.cpp#9 - edit change 6380 (text)
  2. //+-------------------------------------------------------------------------
  3. //
  4. // Microsoft Windows
  5. //
  6. // Copyright (C) Microsoft Corporation, 1997 - 1999
  7. //
  8. // File: keysvcc.cpp
  9. //
  10. //--------------------------------------------------------------------------
  11. #include <windows.h>
  12. #include <wincrypt.h>
  13. #include "keysvc.h"
  14. #include "cryptui.h"
  15. #include "lenroll.h"
  16. #include "keysvcc.h"
  17. #include "unicode.h"
  18. #include "waitsvc.h"
  19. typedef struct _WZR_RPC_BINDING_LIST
  20. {
  21. LPCSTR pszProtSeq;
  22. LPCSTR pszEndpoint;
  23. } WZR_RPC_BINDING_LIST;
  24. WZR_RPC_BINDING_LIST g_awzrBindingList[] =
  25. {
  26. { KEYSVC_LOCAL_PROT_SEQ, KEYSVC_LOCAL_ENDPOINT },
  27. { KEYSVC_DEFAULT_PROT_SEQ, KEYSVC_DEFAULT_ENDPOINT},
  28. { KEYSVC_LEGACY_PROT_SEQ, KEYSVC_LEGACY_ENDPOINT}
  29. };
  30. DWORD g_cwzrBindingList = sizeof(g_awzrBindingList)/sizeof(g_awzrBindingList[0]);
  31. /****************************************
  32. * Client side Key Service handles
  33. ****************************************/
  34. typedef struct _KEYSVCC_INFO_ {
  35. KEYSVC_HANDLE hKeySvc;
  36. handle_t hRPCBinding;
  37. } KEYSVCC_INFO, *PKEYSVCC_INFO;
  38. void InitUnicodeString(
  39. PKEYSVC_UNICODE_STRING pUnicodeString,
  40. LPCWSTR pszString
  41. )
  42. {
  43. pUnicodeString->Length = wcslen(pszString) * sizeof(WCHAR);
  44. pUnicodeString->MaximumLength = pUnicodeString->Length + sizeof(WCHAR);
  45. pUnicodeString->Buffer = (USHORT*)pszString;
  46. }
  47. //*****************************************************
  48. //
  49. // Implementation of Client API for Key Service
  50. //
  51. //*****************************************************
  52. ULONG KeyOpenKeyServiceEx
  53. (/* [in] */ RPC_IF_HANDLE rpc_ifspec,
  54. /* [in] */ LPSTR pszMachineName,
  55. /* [in] */ KEYSVC_TYPE OwnerType,
  56. /* [in] */ LPWSTR pwszOwnerName,
  57. /* [in] */ void *pAuthentication,
  58. /* [out][in] */ void *pReserved,
  59. /* [out] */ KEYSVCC_HANDLE *phKeySvcCli)
  60. {
  61. PKEYSVC_BLOB pVersion = NULL;
  62. KEYSVC_BLOB Authentication;
  63. PKEYSVC_BLOB pAuth;
  64. unsigned char *pStringBinding = NULL;
  65. PKEYSVCC_INFO pKeySvcCliInfo = NULL;
  66. KEYSVC_UNICODE_STRING OwnerName;
  67. ULONG ulErr = 0;
  68. DWORD i;
  69. static BOOL fDone = FALSE;
  70. memset(&Authentication, 0, sizeof(Authentication));
  71. memset(&OwnerName, 0, sizeof(OwnerName));
  72. if (NULL != pAuthentication)
  73. {
  74. ulErr = ERROR_INVALID_PARAMETER;
  75. goto Ret;
  76. }
  77. if (NULL != pwszOwnerName)
  78. {
  79. InitUnicodeString(&OwnerName, pwszOwnerName);
  80. }
  81. // allocate for the client key service handle
  82. if (NULL == (pKeySvcCliInfo =
  83. (PKEYSVCC_INFO)LocalAlloc(LMEM_ZEROINIT,
  84. sizeof(KEYSVCC_INFO))))
  85. {
  86. ulErr = ERROR_NOT_ENOUGH_MEMORY;
  87. goto Ret;
  88. }
  89. //
  90. // before doing the Bind operation, wait for the cryptography
  91. // service to be available.
  92. //
  93. WaitForCryptService(L"ProtectedStorage", &fDone);
  94. for (i = 0; i < g_cwzrBindingList; i++)
  95. {
  96. if (RPC_S_OK != RpcNetworkIsProtseqValid(
  97. (unsigned char *)g_awzrBindingList[i].pszProtSeq))
  98. {
  99. continue;
  100. }
  101. ulErr = RpcStringBindingComposeA(
  102. NULL,
  103. (unsigned char *)g_awzrBindingList[i].pszProtSeq,
  104. (unsigned char *)pszMachineName,
  105. (unsigned char *)g_awzrBindingList[i].pszEndpoint,
  106. NULL,
  107. &pStringBinding);
  108. if (RPC_S_OK != ulErr)
  109. {
  110. continue;
  111. }
  112. ulErr = RpcBindingFromStringBinding(
  113. pStringBinding,
  114. &pKeySvcCliInfo->hRPCBinding);
  115. if (NULL != pStringBinding)
  116. {
  117. RpcStringFree(&pStringBinding);
  118. }
  119. if (RPC_S_OK != ulErr)
  120. {
  121. continue;
  122. }
  123. ulErr = RpcEpResolveBinding(pKeySvcCliInfo->hRPCBinding, rpc_ifspec);
  124. if (RPC_S_OK != ulErr)
  125. {
  126. continue;
  127. }
  128. __try
  129. {
  130. ulErr = KeyrOpenKeyService(pKeySvcCliInfo->hRPCBinding,
  131. OwnerType, &OwnerName,
  132. 0, &Authentication,
  133. &pVersion, &pKeySvcCliInfo->hKeySvc);
  134. *phKeySvcCli = (KEYSVCC_HANDLE)pKeySvcCliInfo;
  135. }
  136. __except ( EXCEPTION_EXECUTE_HANDLER )
  137. {
  138. ulErr = _exception_code();
  139. }
  140. if (RPC_S_OK == ulErr)
  141. {
  142. break;
  143. }
  144. }
  145. if(RPC_S_OK != ulErr)
  146. {
  147. goto Ret;
  148. }
  149. if (NULL != pReserved)
  150. {
  151. PKEYSVC_OPEN_KEYSVC_INFO pOpenInfoCaller = (PKEYSVC_OPEN_KEYSVC_INFO)pReserved;
  152. if (pOpenInfoCaller->ulSize != sizeof(KEYSVC_OPEN_KEYSVC_INFO))
  153. {
  154. ulErr = ERROR_INVALID_PARAMETER;
  155. goto Ret;
  156. }
  157. if (NULL == pVersion)
  158. {
  159. pOpenInfoCaller->ulVersion = KEYSVC_VERSION_W2K;
  160. }
  161. else
  162. {
  163. if (NULL == pVersion->pb)
  164. {
  165. ulErr = ERROR_INVALID_PARAMETER;
  166. goto Ret;
  167. }
  168. PKEYSVC_OPEN_KEYSVC_INFO pOpenInfoCallee = (PKEYSVC_OPEN_KEYSVC_INFO)pVersion->pb;
  169. if (pOpenInfoCallee->ulSize != sizeof(KEYSVC_OPEN_KEYSVC_INFO))
  170. {
  171. ulErr = ERROR_INVALID_PARAMETER;
  172. goto Ret;
  173. }
  174. pOpenInfoCaller->ulVersion = pOpenInfoCallee->ulVersion;
  175. }
  176. }
  177. Ret:
  178. __try
  179. {
  180. if (NULL != pVersion)
  181. midl_user_free(pVersion);
  182. if (pStringBinding)
  183. RpcStringFree(&pStringBinding);
  184. if (0 != ulErr)
  185. {
  186. if (pKeySvcCliInfo)
  187. {
  188. // close the RPC binding
  189. if (pKeySvcCliInfo->hRPCBinding)
  190. RpcBindingFree(&pKeySvcCliInfo->hRPCBinding);
  191. LocalFree(pKeySvcCliInfo);
  192. }
  193. }
  194. }
  195. __except ( EXCEPTION_EXECUTE_HANDLER )
  196. {
  197. ulErr = _exception_code();
  198. }
  199. return ulErr;
  200. }
  201. ULONG KeyOpenKeyService
  202. (/* [in] */ LPSTR pszMachineName,
  203. /* [in] */ KEYSVC_TYPE OwnerType,
  204. /* [in] */ LPWSTR pwszOwnerName,
  205. /* [in] */ void *pAuthentication,
  206. /* [out][in] */ void *pReserved,
  207. /* [out] */ KEYSVCC_HANDLE *phKeySvcCli)
  208. {
  209. return KeyOpenKeyServiceEx
  210. (IKeySvc_v1_0_c_ifspec,
  211. pszMachineName,
  212. OwnerType,
  213. pwszOwnerName,
  214. pAuthentication,
  215. pReserved,
  216. phKeySvcCli);
  217. }
  218. ULONG KeyEnumerateProviders(
  219. /* [in] */ KEYSVCC_HANDLE hKeySvcCli,
  220. /* [out][in] */ void *pReserved,
  221. /* [out][in] */ ULONG *pcProviderCount,
  222. /* [size_is][size_is][out][in] */ PKEYSVC_PROVIDER_INFO *ppProviders)
  223. {
  224. PKEYSVC_BLOB pTmpReserved = NULL;
  225. PKEYSVCC_INFO pKeySvcCliInfo = NULL;
  226. ULONG ulErr = 0;
  227. __try
  228. {
  229. if (NULL == hKeySvcCli)
  230. {
  231. ulErr = ERROR_INVALID_PARAMETER;
  232. goto Ret;
  233. }
  234. pKeySvcCliInfo = (PKEYSVCC_INFO)hKeySvcCli;
  235. ulErr = KeyrEnumerateProviders(pKeySvcCliInfo->hRPCBinding,
  236. pKeySvcCliInfo->hKeySvc,
  237. &pTmpReserved,
  238. pcProviderCount, ppProviders);
  239. }
  240. __except ( EXCEPTION_EXECUTE_HANDLER )
  241. {
  242. ulErr = _exception_code();
  243. }
  244. Ret:
  245. return ulErr;
  246. }
  247. ULONG KeyEnumerateProviderTypes(
  248. /* [in] */ KEYSVCC_HANDLE hKeySvcCli,
  249. /* [out][in] */ void *pReserved,
  250. /* [out][in] */ ULONG *pcProviderCount,
  251. /* [size_is][size_is][out][in] */ PKEYSVC_PROVIDER_INFO *ppProviders)
  252. {
  253. PKEYSVC_BLOB pTmpReserved = NULL;
  254. PKEYSVCC_INFO pKeySvcCliInfo = NULL;
  255. ULONG ulErr = 0;
  256. __try
  257. {
  258. if (NULL == hKeySvcCli)
  259. {
  260. ulErr = ERROR_INVALID_PARAMETER;
  261. goto Ret;
  262. }
  263. pKeySvcCliInfo = (PKEYSVCC_INFO)hKeySvcCli;
  264. ulErr = KeyrEnumerateProviderTypes(pKeySvcCliInfo->hRPCBinding,
  265. pKeySvcCliInfo->hKeySvc,
  266. &pTmpReserved,
  267. pcProviderCount, ppProviders);
  268. }
  269. __except ( EXCEPTION_EXECUTE_HANDLER )
  270. {
  271. ulErr = _exception_code();
  272. }
  273. Ret:
  274. return ulErr;
  275. }
  276. ULONG KeyEnumerateProvContainers(
  277. /* [in] */ KEYSVCC_HANDLE hKeySvcCli,
  278. /* [in] */ KEYSVC_PROVIDER_INFO Provider,
  279. /* [in, out] */ void *pReserved,
  280. /* [in, out] */ ULONG *pcContainerCount,
  281. /* [in, out][size_is(,*pcContainerCount)] */
  282. PKEYSVC_UNICODE_STRING *ppContainers)
  283. {
  284. PKEYSVC_BLOB pTmpReserved = NULL;
  285. PKEYSVCC_INFO pKeySvcCliInfo = NULL;
  286. ULONG ulErr = 0;
  287. __try
  288. {
  289. if (NULL == hKeySvcCli)
  290. {
  291. ulErr = ERROR_INVALID_PARAMETER;
  292. goto Ret;
  293. }
  294. pKeySvcCliInfo = (PKEYSVCC_INFO)hKeySvcCli;
  295. return KeyrEnumerateProvContainers(pKeySvcCliInfo->hRPCBinding,
  296. pKeySvcCliInfo->hKeySvc,
  297. Provider,
  298. &pTmpReserved, pcContainerCount,
  299. ppContainers);
  300. }
  301. __except ( EXCEPTION_EXECUTE_HANDLER )
  302. {
  303. ulErr = _exception_code();
  304. }
  305. Ret:
  306. return ulErr;
  307. }
  308. ULONG KeyCloseKeyService(
  309. /* [in] */ KEYSVCC_HANDLE hKeySvcCli,
  310. /* [out][in] */ void *pReserved)
  311. {
  312. PKEYSVCC_INFO pKeySvcCliInfo = NULL;
  313. PKEYSVC_BLOB pTmpReserved = NULL;
  314. ULONG ulErr = 0;
  315. __try
  316. {
  317. if (NULL == hKeySvcCli)
  318. {
  319. ulErr = ERROR_INVALID_PARAMETER;
  320. goto Ret;
  321. }
  322. pKeySvcCliInfo = (PKEYSVCC_INFO)hKeySvcCli;
  323. ulErr = KeyrCloseKeyService(pKeySvcCliInfo->hRPCBinding,
  324. pKeySvcCliInfo->hKeySvc,
  325. &pTmpReserved);
  326. }
  327. __except ( EXCEPTION_EXECUTE_HANDLER )
  328. {
  329. ulErr = _exception_code();
  330. }
  331. Ret:
  332. return ulErr;
  333. }
  334. ULONG KeyGetDefaultProvider(
  335. /* [in] */ KEYSVCC_HANDLE hKeySvcCli,
  336. /* [in] */ ULONG ulProvType,
  337. /* [in] */ ULONG ulFlags,
  338. /* [out][in] */ void *pReserved,
  339. /* [out] */ ULONG *pulDefType,
  340. /* [out] */ PKEYSVC_PROVIDER_INFO *ppProvider)
  341. {
  342. PKEYSVCC_INFO pKeySvcCliInfo = NULL;
  343. PKEYSVC_BLOB pTmpReserved = NULL;
  344. ULONG ulErr = 0;
  345. __try
  346. {
  347. if (NULL == hKeySvcCli)
  348. {
  349. ulErr = ERROR_INVALID_PARAMETER;
  350. goto Ret;
  351. }
  352. pKeySvcCliInfo = (PKEYSVCC_INFO)hKeySvcCli;
  353. ulErr = KeyrGetDefaultProvider(pKeySvcCliInfo->hRPCBinding,
  354. pKeySvcCliInfo->hKeySvc,
  355. ulProvType, ulFlags,
  356. &pTmpReserved, pulDefType,
  357. ppProvider);
  358. }
  359. __except ( EXCEPTION_EXECUTE_HANDLER )
  360. {
  361. ulErr = _exception_code();
  362. }
  363. Ret:
  364. return ulErr;
  365. }
  366. ULONG KeySetDefaultProvider(
  367. /* [in] */ KEYSVCC_HANDLE hKeySvcCli,
  368. /* [in] */ ULONG ulFlags,
  369. /* [out][in] */ void *pReserved,
  370. /* [in] */ KEYSVC_PROVIDER_INFO Provider)
  371. {
  372. PKEYSVCC_INFO pKeySvcCliInfo = NULL;
  373. PKEYSVC_BLOB pTmpReserved = NULL;
  374. ULONG ulErr = 0;
  375. __try
  376. {
  377. if (NULL == hKeySvcCli)
  378. {
  379. ulErr = ERROR_INVALID_PARAMETER;
  380. goto Ret;
  381. }
  382. pKeySvcCliInfo = (PKEYSVCC_INFO)hKeySvcCli;
  383. ulErr = KeyrSetDefaultProvider(pKeySvcCliInfo->hRPCBinding,
  384. pKeySvcCliInfo->hKeySvc,
  385. ulFlags, &pTmpReserved,
  386. Provider);
  387. }
  388. __except ( EXCEPTION_EXECUTE_HANDLER )
  389. {
  390. ulErr = _exception_code();
  391. }
  392. Ret:
  393. return ulErr;
  394. }
  395. ULONG KeyEnroll
  396. (/* [in] */ KEYSVCC_HANDLE hKeySvcCli,
  397. /* [in] */ LPSTR pszMachineName, //IN Required: name of the remote machine
  398. /* [in] */ BOOL fKeyService, //IN Required: Whether the function is called remotely
  399. /* [in] */ DWORD dwPurpose, //IN Required: Indicates type of request - enroll/renew
  400. /* [in] */ LPWSTR pszAcctName, //IN Optional: Account name the service runs under
  401. /* [in] */ void *pAuthentication, //RESERVED must be NULL
  402. /* [in] */ BOOL fEnroll, //IN Required: Whether it is enrollment or renew
  403. /* [in] */ LPWSTR pszCALocation, //IN Required: The ca machine name
  404. /* [in] */ LPWSTR pszCAName, //IN Required: The ca name
  405. /* [in] */ BOOL fNewKey, //IN Required: Set the TRUE if new private key is needed
  406. /* [in] */ PCERT_REQUEST_PVK_NEW pKeyNew, //IN Required: The private key information
  407. /* [in] */ CERT_BLOB *pCert, //IN Optional: The old certificate if renewing
  408. /* [in] */ PCERT_REQUEST_PVK_NEW pRenewKey, //IN Optional: The new private key information
  409. /* [in] */ LPWSTR pszHashAlg, //IN Optional: The hash algorithm
  410. /* [in] */ LPWSTR pszDesStore, //IN Optional: The destination store
  411. /* [in] */ DWORD dwStoreFlags, //IN Optional: Flags for cert store.
  412. /* [in] */ PCERT_ENROLL_INFO pRequestInfo, //IN Required: The information about the cert request
  413. /* [in] */ LPWSTR pszAttributes, //IN Optional: Attribute string for request
  414. /* [in] */ DWORD dwFlags, //RESERVED must be 0
  415. /* [in] */ BYTE *pReserved, //RESERVED must be NULL
  416. /* [out] */ CERT_BLOB *pPKCS7Blob, //OUT Optional: The PKCS7 from the CA
  417. /* [out] */ CERT_BLOB *pHashBlob, //OUT Optioanl: The SHA1 hash of the enrolled/renewed certificate
  418. /* [out] */ DWORD *pdwStatus) //OUT Optional: The status of the enrollment/renewal
  419. {
  420. PKEYSVC_BLOB pReservedBlob = NULL;
  421. KEYSVC_UNICODE_STRING AcctName;
  422. KEYSVC_UNICODE_STRING CALocation;
  423. KEYSVC_UNICODE_STRING CAName;
  424. KEYSVC_UNICODE_STRING DesStore;
  425. KEYSVC_UNICODE_STRING HashAlg;
  426. KEYSVC_BLOB *pPKCS7KeySvcBlob = NULL;
  427. KEYSVC_BLOB *pHashKeySvcBlob = NULL;
  428. KEYSVC_CERT_ENROLL_INFO EnrollInfo;
  429. KEYSVC_CERT_REQUEST_PVK_NEW NewKeyInfo;
  430. KEYSVC_CERT_REQUEST_PVK_NEW RenewKeyInfo;
  431. KEYSVC_BLOB CertBlob;
  432. DWORD i;
  433. DWORD j;
  434. PKEYSVCC_INFO pKeySvcCliInfo = NULL;
  435. DWORD dwErr = 0;
  436. DWORD cbExtensions;
  437. PBYTE pbExtensions;
  438. __try
  439. {
  440. // initialize everything
  441. memset(pPKCS7Blob, 0, sizeof(CERT_BLOB));
  442. memset(pHashBlob, 0, sizeof(CERT_BLOB));
  443. memset(&AcctName, 0, sizeof(AcctName));
  444. memset(&CALocation, 0, sizeof(CALocation));
  445. memset(&CAName, 0, sizeof(CAName));
  446. memset(&HashAlg, 0, sizeof(HashAlg));
  447. memset(&DesStore, 0, sizeof(DesStore));
  448. memset(&NewKeyInfo, 0, sizeof(NewKeyInfo));
  449. memset(&EnrollInfo, 0, sizeof(EnrollInfo));
  450. memset(&RenewKeyInfo, 0, sizeof(RenewKeyInfo));
  451. memset(&CertBlob, 0, sizeof(CertBlob));
  452. if (NULL == hKeySvcCli)
  453. {
  454. dwErr = ERROR_INVALID_PARAMETER;
  455. goto Ret;
  456. }
  457. pKeySvcCliInfo = (PKEYSVCC_INFO)hKeySvcCli;
  458. // set up the key service unicode structs
  459. if (pszAcctName)
  460. InitUnicodeString(&AcctName, pszAcctName);
  461. if (pszCALocation)
  462. InitUnicodeString(&CALocation, pszCALocation);
  463. if (pszCAName)
  464. InitUnicodeString(&CAName, pszCAName);
  465. if (pszHashAlg)
  466. InitUnicodeString(&HashAlg, pszHashAlg);
  467. if (pszDesStore)
  468. InitUnicodeString(&DesStore, pszDesStore);
  469. // set up the new key info structure for the remote call
  470. NewKeyInfo.ulProvType = pKeyNew->dwProvType;
  471. if (pKeyNew->pwszProvider)
  472. {
  473. InitUnicodeString(&NewKeyInfo.Provider, pKeyNew->pwszProvider);
  474. }
  475. NewKeyInfo.ulProviderFlags = pKeyNew->dwProviderFlags;
  476. if (pKeyNew->pwszKeyContainer)
  477. {
  478. InitUnicodeString(&NewKeyInfo.KeyContainer,
  479. pKeyNew->pwszKeyContainer);
  480. }
  481. NewKeyInfo.ulKeySpec = pKeyNew->dwKeySpec;
  482. NewKeyInfo.ulGenKeyFlags = pKeyNew->dwGenKeyFlags;
  483. // set up the usage OIDs
  484. if (pRequestInfo->pwszUsageOID)
  485. {
  486. InitUnicodeString(&EnrollInfo.UsageOID, pRequestInfo->pwszUsageOID);
  487. }
  488. // set up the cert DN Name
  489. if (pRequestInfo->pwszCertDNName)
  490. {
  491. InitUnicodeString(&EnrollInfo.CertDNName, pRequestInfo->pwszCertDNName);
  492. }
  493. // set up the request info structure for the remote call
  494. EnrollInfo.ulPostOption = pRequestInfo->dwPostOption;
  495. if (pRequestInfo->pwszFriendlyName)
  496. {
  497. InitUnicodeString(&EnrollInfo.FriendlyName,
  498. pRequestInfo->pwszFriendlyName);
  499. }
  500. if (pRequestInfo->pwszDescription)
  501. {
  502. InitUnicodeString(&EnrollInfo.Description,
  503. pRequestInfo->pwszDescription);
  504. }
  505. if (pszAttributes)
  506. {
  507. InitUnicodeString(&EnrollInfo.Attributes, pszAttributes);
  508. }
  509. // convert the cert extensions
  510. // NOTE, the extensions structure cannot be simply cast,
  511. // as the structures have different packing behaviors in
  512. // 64 bit systems.
  513. EnrollInfo.cExtensions = pRequestInfo->dwExtensions;
  514. cbExtensions = EnrollInfo.cExtensions*(sizeof(PKEYSVC_CERT_EXTENSIONS) +
  515. sizeof(KEYSVC_CERT_EXTENSIONS));
  516. for(i=0; i < EnrollInfo.cExtensions; i++)
  517. {
  518. cbExtensions += pRequestInfo->prgExtensions[i]->cExtension*
  519. sizeof(KEYSVC_CERT_EXTENSION);
  520. }
  521. EnrollInfo.prgExtensions = (PKEYSVC_CERT_EXTENSIONS*)midl_user_allocate( cbExtensions);
  522. if(NULL == EnrollInfo.prgExtensions)
  523. {
  524. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  525. goto Ret;
  526. }
  527. pbExtensions = (PBYTE)(EnrollInfo.prgExtensions + EnrollInfo.cExtensions);
  528. for(i=0; i < EnrollInfo.cExtensions; i++)
  529. {
  530. EnrollInfo.prgExtensions[i] = (PKEYSVC_CERT_EXTENSIONS)pbExtensions;
  531. pbExtensions += sizeof(KEYSVC_CERT_EXTENSIONS);
  532. EnrollInfo.prgExtensions[i]->cExtension = pRequestInfo->prgExtensions[i]->cExtension;
  533. EnrollInfo.prgExtensions[i]->rgExtension = (PKEYSVC_CERT_EXTENSION)pbExtensions;
  534. pbExtensions += sizeof(KEYSVC_CERT_EXTENSION)*EnrollInfo.prgExtensions[i]->cExtension;
  535. for(j=0; j < EnrollInfo.prgExtensions[i]->cExtension; j++)
  536. {
  537. EnrollInfo.prgExtensions[i]->rgExtension[j].pszObjId =
  538. pRequestInfo->prgExtensions[i]->rgExtension[j].pszObjId;
  539. EnrollInfo.prgExtensions[i]->rgExtension[j].fCritical =
  540. pRequestInfo->prgExtensions[i]->rgExtension[j].fCritical;
  541. EnrollInfo.prgExtensions[i]->rgExtension[j].cbData =
  542. pRequestInfo->prgExtensions[i]->rgExtension[j].Value.cbData;
  543. EnrollInfo.prgExtensions[i]->rgExtension[j].pbData =
  544. pRequestInfo->prgExtensions[i]->rgExtension[j].Value.pbData;
  545. }
  546. }
  547. // if doing renewal then make sure have everything needed
  548. if ((CRYPTUI_WIZ_CERT_RENEW == dwPurpose) &&
  549. ((NULL == pRenewKey) || (NULL == pCert)))
  550. {
  551. dwErr = ERROR_INVALID_PARAMETER;
  552. goto Ret;
  553. }
  554. // set up the new key info structure for the remote call
  555. if (pRenewKey)
  556. {
  557. RenewKeyInfo.ulProvType = pRenewKey->dwProvType;
  558. if (pRenewKey->pwszProvider)
  559. {
  560. InitUnicodeString(&RenewKeyInfo.Provider, pRenewKey->pwszProvider);
  561. }
  562. RenewKeyInfo.ulProviderFlags = pRenewKey->dwProviderFlags;
  563. if (pRenewKey->pwszKeyContainer)
  564. {
  565. InitUnicodeString(&RenewKeyInfo.KeyContainer,
  566. pRenewKey->pwszKeyContainer);
  567. }
  568. RenewKeyInfo.ulKeySpec = pRenewKey->dwKeySpec;
  569. RenewKeyInfo.ulGenKeyFlags = pRenewKey->dwGenKeyFlags;
  570. }
  571. // set up the cert blob for renewal
  572. if (pCert)
  573. {
  574. CertBlob.cb = pCert->cbData;
  575. CertBlob.pb = pCert->pbData;
  576. }
  577. // make the remote enrollment call
  578. if (0 != (dwErr = KeyrEnroll(pKeySvcCliInfo->hRPCBinding, fKeyService, dwPurpose,
  579. &AcctName, &CALocation, &CAName, fNewKey,
  580. &NewKeyInfo, &CertBlob, &RenewKeyInfo,
  581. &HashAlg, &DesStore, dwStoreFlags,
  582. &EnrollInfo, dwFlags, &pReservedBlob,
  583. &pPKCS7KeySvcBlob,
  584. &pHashKeySvcBlob, pdwStatus)))
  585. goto Ret;
  586. // allocate and copy the output parameters
  587. if (pPKCS7KeySvcBlob->cb)
  588. {
  589. pPKCS7Blob->cbData = pPKCS7KeySvcBlob->cb;
  590. if (NULL == (pPKCS7Blob->pbData =
  591. (BYTE*)midl_user_allocate(pPKCS7Blob->cbData)))
  592. {
  593. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  594. goto Ret;
  595. }
  596. memcpy(pPKCS7Blob->pbData, pPKCS7KeySvcBlob->pb,
  597. pPKCS7Blob->cbData);
  598. }
  599. if (pHashKeySvcBlob->cb)
  600. {
  601. pHashBlob->cbData = pHashKeySvcBlob->cb;
  602. if (NULL == (pHashBlob->pbData =
  603. (BYTE*)midl_user_allocate(pHashBlob->cbData)))
  604. {
  605. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  606. goto Ret;
  607. }
  608. memcpy(pHashBlob->pbData, pHashKeySvcBlob->pb, pHashBlob->cbData);
  609. }
  610. }
  611. __except ( EXCEPTION_EXECUTE_HANDLER )
  612. {
  613. return _exception_code();
  614. }
  615. Ret:
  616. __try
  617. {
  618. if (pPKCS7KeySvcBlob)
  619. {
  620. midl_user_free(pPKCS7KeySvcBlob);
  621. }
  622. if (pHashKeySvcBlob)
  623. {
  624. midl_user_free(pHashKeySvcBlob);
  625. }
  626. }
  627. __except ( EXCEPTION_EXECUTE_HANDLER )
  628. {
  629. return _exception_code();
  630. }
  631. return dwErr;
  632. }
  633. // Params needed for create:
  634. //
  635. // Params not needed for submit:
  636. // all except pszMachineName, dwPurpose, dwFlags, fEnroll, dwStoreFlags, hRequest, and dwFlags.
  637. //
  638. // Params not needed for free:
  639. // all except pszMachineName, hRequest, and dwFlags.
  640. //
  641. ULONG KeyEnroll_V2
  642. (/* [in] */ KEYSVCC_HANDLE hKeySvcCli,
  643. /* [in] */ LPSTR pszMachineName, //IN Required: name of the remote machine
  644. /* [in] */ BOOL fKeyService, //IN Required: Whether the function is called remotely
  645. /* [in] */ DWORD dwPurpose, //IN Required: Indicates type of request - enroll/renew
  646. /* [in] */ DWORD dwFlags, //IN Required: Flags for enrollment
  647. /* [in] */ LPWSTR pszAcctName, //IN Optional: Account name the service runs under
  648. /* [in] */ void *pAuthentication, //RESERVED must be NULL
  649. /* [in] */ BOOL fEnroll, //IN Required: Whether it is enrollment or renew
  650. /* [in] */ LPWSTR pszCALocation, //IN Required: The ca machine names to attempt to enroll with
  651. /* [in] */ LPWSTR pszCAName, //IN Required: The ca names to attempt to enroll with
  652. /* [in] */ BOOL fNewKey, //IN Required: Set the TRUE if new private key is needed
  653. /* [in] */ PCERT_REQUEST_PVK_NEW pKeyNew, //IN Required: The private key information
  654. /* [in] */ CERT_BLOB *pCert, //IN Optional: The old certificate if renewing
  655. /* [in] */ PCERT_REQUEST_PVK_NEW pRenewKey, //IN Optional: The new private key information
  656. /* [in] */ LPWSTR pszHashAlg, //IN Optional: The hash algorithm
  657. /* [in] */ LPWSTR pszDesStore, //IN Optional: The destination store
  658. /* [in] */ DWORD dwStoreFlags, //IN Optional: Flags for cert store.
  659. /* [in] */ PCERT_ENROLL_INFO pRequestInfo, //IN Required: The information about the cert request
  660. /* [in] */ LPWSTR pszAttributes, //IN Optional: Attribute string for request
  661. /* [in] */ DWORD dwReservedFlags, //RESERVED must be 0
  662. /* [in] */ BYTE *pReserved, //RESERVED must be NULL
  663. /* [in][out] */ HANDLE *phRequest, //IN OUT Optional: A handle to a created request
  664. /* [out] */ CERT_BLOB *pPKCS7Blob, //OUT Optional: The PKCS7 from the CA
  665. /* [out] */ CERT_BLOB *pHashBlob, //OUT Optioanl: The SHA1 hash of the enrolled/renewed certificate
  666. /* [out] */ DWORD *pdwStatus) //OUT Optional: The status of the enrollment/renewal
  667. {
  668. PKEYSVC_BLOB pReservedBlob = NULL;
  669. KEYSVC_UNICODE_STRING AcctName;
  670. KEYSVC_UNICODE_STRING CALocation;
  671. KEYSVC_UNICODE_STRING CAName;
  672. KEYSVC_UNICODE_STRING DesStore;
  673. KEYSVC_UNICODE_STRING HashAlg;
  674. KEYSVC_BLOB KeySvcRequest;
  675. KEYSVC_BLOB *pKeySvcRequest = NULL;
  676. KEYSVC_BLOB *pPKCS7KeySvcBlob = NULL;
  677. KEYSVC_BLOB *pHashKeySvcBlob = NULL;
  678. ULONG ulKeySvcStatus = 0;
  679. KEYSVC_CERT_ENROLL_INFO EnrollInfo;
  680. KEYSVC_CERT_REQUEST_PVK_NEW_V2 NewKeyInfo;
  681. KEYSVC_CERT_REQUEST_PVK_NEW_V2 RenewKeyInfo;
  682. KEYSVC_BLOB CertBlob;
  683. DWORD i;
  684. DWORD j;
  685. DWORD dwErr = 0;
  686. DWORD cbExtensions;
  687. PBYTE pbExtensions;
  688. BOOL fCreateRequest = 0 == (dwFlags & (CRYPTUI_WIZ_SUBMIT_ONLY | CRYPTUI_WIZ_FREE_ONLY));
  689. PKEYSVCC_INFO pKeySvcCliInfo = NULL;
  690. __try
  691. {
  692. //////////////////////////////////////////////////////////////
  693. //
  694. // INITIALIZATION:
  695. //
  696. //////////////////////////////////////////////////////////////
  697. if (NULL != pPKCS7Blob) { memset(pPKCS7Blob, 0, sizeof(CERT_BLOB)); }
  698. if (NULL != pHashBlob) { memset(pHashBlob, 0, sizeof(CERT_BLOB)); }
  699. if (NULL != phRequest && NULL != *phRequest)
  700. {
  701. pKeySvcRequest = &KeySvcRequest;
  702. pKeySvcRequest->cb = sizeof(*phRequest);
  703. pKeySvcRequest->pb = (BYTE *)phRequest;
  704. }
  705. memset(&AcctName, 0, sizeof(AcctName));
  706. memset(&CALocation, 0, sizeof(CALocation));
  707. memset(&CAName, 0, sizeof(CAName));
  708. memset(&HashAlg, 0, sizeof(HashAlg));
  709. memset(&DesStore, 0, sizeof(DesStore));
  710. memset(&NewKeyInfo, 0, sizeof(NewKeyInfo));
  711. memset(&EnrollInfo, 0, sizeof(EnrollInfo));
  712. memset(&RenewKeyInfo, 0, sizeof(RenewKeyInfo));
  713. memset(&CertBlob, 0, sizeof(CertBlob));
  714. //////////////////////////////////////////////////////////////
  715. //
  716. // PROCEDURE BODY:
  717. //
  718. //////////////////////////////////////////////////////////////
  719. if (NULL == hKeySvcCli)
  720. {
  721. dwErr = ERROR_INVALID_PARAMETER;
  722. goto Ret;
  723. }
  724. pKeySvcCliInfo = (PKEYSVCC_INFO)hKeySvcCli;
  725. // set up the key service unicode structs
  726. if (pszAcctName)
  727. InitUnicodeString(&AcctName, pszAcctName);
  728. if (pszCALocation)
  729. InitUnicodeString(&CALocation, pszCALocation);
  730. if (pszCAName)
  731. InitUnicodeString(&CAName, pszCAName);
  732. if (pszHashAlg)
  733. InitUnicodeString(&HashAlg, pszHashAlg);
  734. if (pszDesStore)
  735. InitUnicodeString(&DesStore, pszDesStore);
  736. // set up the new key info structure for the remote call
  737. // This is only necessary if we are actually _creating_ a request.
  738. // Submit-only and free-only operations can skip this operation.
  739. //
  740. if (TRUE == fCreateRequest)
  741. {
  742. NewKeyInfo.ulProvType = pKeyNew->dwProvType;
  743. if (pKeyNew->pwszProvider)
  744. {
  745. InitUnicodeString(&NewKeyInfo.Provider, pKeyNew->pwszProvider);
  746. }
  747. NewKeyInfo.ulProviderFlags = pKeyNew->dwProviderFlags;
  748. if (pKeyNew->pwszKeyContainer)
  749. {
  750. InitUnicodeString(&NewKeyInfo.KeyContainer,
  751. pKeyNew->pwszKeyContainer);
  752. }
  753. NewKeyInfo.ulKeySpec = pKeyNew->dwKeySpec;
  754. NewKeyInfo.ulGenKeyFlags = pKeyNew->dwGenKeyFlags;
  755. NewKeyInfo.ulEnrollmentFlags = pKeyNew->dwEnrollmentFlags;
  756. NewKeyInfo.ulSubjectNameFlags = pKeyNew->dwSubjectNameFlags;
  757. NewKeyInfo.ulPrivateKeyFlags = pKeyNew->dwPrivateKeyFlags;
  758. NewKeyInfo.ulGeneralFlags = pKeyNew->dwGeneralFlags;
  759. // set up the usage OIDs
  760. if (pRequestInfo->pwszUsageOID)
  761. {
  762. InitUnicodeString(&EnrollInfo.UsageOID, pRequestInfo->pwszUsageOID);
  763. }
  764. // set up the cert DN Name
  765. if (pRequestInfo->pwszCertDNName)
  766. {
  767. InitUnicodeString(&EnrollInfo.CertDNName, pRequestInfo->pwszCertDNName);
  768. }
  769. // set up the request info structure for the remote call
  770. EnrollInfo.ulPostOption = pRequestInfo->dwPostOption;
  771. if (pRequestInfo->pwszFriendlyName)
  772. {
  773. InitUnicodeString(&EnrollInfo.FriendlyName,
  774. pRequestInfo->pwszFriendlyName);
  775. }
  776. if (pRequestInfo->pwszDescription)
  777. {
  778. InitUnicodeString(&EnrollInfo.Description,
  779. pRequestInfo->pwszDescription);
  780. }
  781. if (pszAttributes)
  782. {
  783. InitUnicodeString(&EnrollInfo.Attributes, pszAttributes);
  784. }
  785. // convert the cert extensions
  786. // NOTE, the extensions structure cannot be simply cast,
  787. // as the structures have different packing behaviors in
  788. // 64 bit systems.
  789. EnrollInfo.cExtensions = pRequestInfo->dwExtensions;
  790. cbExtensions = EnrollInfo.cExtensions*(sizeof(PKEYSVC_CERT_EXTENSIONS) +
  791. sizeof(KEYSVC_CERT_EXTENSIONS));
  792. for(i=0; i < EnrollInfo.cExtensions; i++)
  793. {
  794. cbExtensions += pRequestInfo->prgExtensions[i]->cExtension*
  795. sizeof(KEYSVC_CERT_EXTENSION);
  796. }
  797. EnrollInfo.prgExtensions = (PKEYSVC_CERT_EXTENSIONS*)midl_user_allocate( cbExtensions);
  798. if(NULL == EnrollInfo.prgExtensions)
  799. {
  800. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  801. goto Ret;
  802. }
  803. pbExtensions = (PBYTE)(EnrollInfo.prgExtensions + EnrollInfo.cExtensions);
  804. for(i=0; i < EnrollInfo.cExtensions; i++)
  805. {
  806. EnrollInfo.prgExtensions[i] = (PKEYSVC_CERT_EXTENSIONS)pbExtensions;
  807. pbExtensions += sizeof(KEYSVC_CERT_EXTENSIONS);
  808. EnrollInfo.prgExtensions[i]->cExtension = pRequestInfo->prgExtensions[i]->cExtension;
  809. EnrollInfo.prgExtensions[i]->rgExtension = (PKEYSVC_CERT_EXTENSION)pbExtensions;
  810. pbExtensions += sizeof(KEYSVC_CERT_EXTENSION)*EnrollInfo.prgExtensions[i]->cExtension;
  811. for(j=0; j < EnrollInfo.prgExtensions[i]->cExtension; j++)
  812. {
  813. EnrollInfo.prgExtensions[i]->rgExtension[j].pszObjId =
  814. pRequestInfo->prgExtensions[i]->rgExtension[j].pszObjId;
  815. EnrollInfo.prgExtensions[i]->rgExtension[j].fCritical =
  816. pRequestInfo->prgExtensions[i]->rgExtension[j].fCritical;
  817. EnrollInfo.prgExtensions[i]->rgExtension[j].cbData =
  818. pRequestInfo->prgExtensions[i]->rgExtension[j].Value.cbData;
  819. EnrollInfo.prgExtensions[i]->rgExtension[j].pbData =
  820. pRequestInfo->prgExtensions[i]->rgExtension[j].Value.pbData;
  821. }
  822. }
  823. // if doing renewal then make sure have everything needed
  824. if ((CRYPTUI_WIZ_CERT_RENEW == dwPurpose) &&
  825. ((NULL == pRenewKey) || (NULL == pCert)))
  826. {
  827. dwErr = ERROR_INVALID_PARAMETER;
  828. goto Ret;
  829. }
  830. // set up the new key info structure for the remote call
  831. if (pRenewKey)
  832. {
  833. RenewKeyInfo.ulProvType = pRenewKey->dwProvType;
  834. if (pRenewKey->pwszProvider)
  835. {
  836. InitUnicodeString(&RenewKeyInfo.Provider, pRenewKey->pwszProvider);
  837. }
  838. RenewKeyInfo.ulProviderFlags = pRenewKey->dwProviderFlags;
  839. if (pRenewKey->pwszKeyContainer)
  840. {
  841. InitUnicodeString(&RenewKeyInfo.KeyContainer,
  842. pRenewKey->pwszKeyContainer);
  843. }
  844. RenewKeyInfo.ulKeySpec = pRenewKey->dwKeySpec;
  845. RenewKeyInfo.ulGenKeyFlags = pRenewKey->dwGenKeyFlags;
  846. RenewKeyInfo.ulEnrollmentFlags = pRenewKey->dwEnrollmentFlags;
  847. RenewKeyInfo.ulSubjectNameFlags = pRenewKey->dwSubjectNameFlags;
  848. RenewKeyInfo.ulPrivateKeyFlags = pRenewKey->dwPrivateKeyFlags;
  849. RenewKeyInfo.ulGeneralFlags = pRenewKey->dwGeneralFlags;
  850. }
  851. // set up the cert blob for renewal
  852. if (pCert)
  853. {
  854. CertBlob.cb = pCert->cbData;
  855. CertBlob.pb = pCert->pbData;
  856. }
  857. }
  858. // make the remote enrollment call
  859. if (0 != (dwErr = KeyrEnroll_V2
  860. (pKeySvcCliInfo->hRPCBinding,
  861. fKeyService,
  862. dwPurpose,
  863. dwFlags,
  864. &AcctName,
  865. &CALocation,
  866. &CAName,
  867. fNewKey,
  868. &NewKeyInfo,
  869. &CertBlob,
  870. &RenewKeyInfo,
  871. &HashAlg,
  872. &DesStore,
  873. dwStoreFlags,
  874. &EnrollInfo,
  875. dwReservedFlags,
  876. &pReservedBlob,
  877. &pKeySvcRequest,
  878. &pPKCS7KeySvcBlob,
  879. &pHashKeySvcBlob,
  880. &ulKeySvcStatus)))
  881. goto Ret;
  882. // allocate and copy the output parameters.
  883. if ((NULL != pKeySvcRequest) &&
  884. (0 < pKeySvcRequest->cb) &&
  885. (NULL != phRequest))
  886. {
  887. memcpy(phRequest, pKeySvcRequest->pb, sizeof(*phRequest));
  888. }
  889. if ((NULL != pPKCS7KeySvcBlob) &&
  890. (0 < pPKCS7KeySvcBlob->cb) &&
  891. (NULL != pPKCS7Blob))
  892. {
  893. pPKCS7Blob->cbData = pPKCS7KeySvcBlob->cb;
  894. if (NULL == (pPKCS7Blob->pbData =
  895. (BYTE*)midl_user_allocate(pPKCS7Blob->cbData)))
  896. {
  897. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  898. goto Ret;
  899. }
  900. memcpy(pPKCS7Blob->pbData, pPKCS7KeySvcBlob->pb,
  901. pPKCS7Blob->cbData);
  902. }
  903. if ((NULL != pHashKeySvcBlob) &&
  904. (0 < pHashKeySvcBlob->cb) &&
  905. (NULL != pHashBlob))
  906. {
  907. pHashBlob->cbData = pHashKeySvcBlob->cb;
  908. if (NULL == (pHashBlob->pbData =
  909. (BYTE*)midl_user_allocate(pHashBlob->cbData)))
  910. {
  911. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  912. goto Ret;
  913. }
  914. memcpy(pHashBlob->pbData, pHashKeySvcBlob->pb, pHashBlob->cbData);
  915. }
  916. if (NULL != pdwStatus)
  917. {
  918. *pdwStatus = (DWORD)ulKeySvcStatus;
  919. }
  920. }
  921. __except ( EXCEPTION_EXECUTE_HANDLER )
  922. {
  923. return _exception_code();
  924. }
  925. Ret:
  926. __try
  927. {
  928. if(EnrollInfo.prgExtensions)
  929. {
  930. midl_user_free(EnrollInfo.prgExtensions);
  931. }
  932. if (pKeySvcRequest)
  933. {
  934. midl_user_free(pKeySvcRequest);
  935. }
  936. if (pPKCS7KeySvcBlob)
  937. {
  938. midl_user_free(pPKCS7KeySvcBlob);
  939. }
  940. if (pHashKeySvcBlob)
  941. {
  942. midl_user_free(pHashKeySvcBlob);
  943. }
  944. }
  945. __except ( EXCEPTION_EXECUTE_HANDLER )
  946. {
  947. return _exception_code();
  948. }
  949. return dwErr;
  950. }
  951. ULONG KeyExportCert(
  952. /* [in] */ KEYSVCC_HANDLE hKeySvcCli,
  953. /* [in] */ LPWSTR pwszPassword,
  954. /* [in] */ LPWSTR pwszCertStore,
  955. /* [in] */ ULONG cHashCount,
  956. /* [size_is][in] */ KEYSVC_CERT_HASH *pHashes,
  957. /* [in] */ ULONG ulFlags,
  958. /* [in, out] */ void *pReserved,
  959. /* [out] */ PKEYSVC_BLOB *ppPFXBlob)
  960. {
  961. PKEYSVCC_INFO pKeySvcCliInfo = NULL;
  962. PKEYSVC_BLOB pTmpReserved = NULL;
  963. KEYSVC_UNICODE_STRING Password;
  964. KEYSVC_UNICODE_STRING CertStore;
  965. ULONG ulErr = 0;
  966. __try
  967. {
  968. memset(&Password, 0, sizeof(Password));
  969. memset(&CertStore, 0, sizeof(CertStore));
  970. if (NULL == hKeySvcCli)
  971. {
  972. ulErr = ERROR_INVALID_PARAMETER;
  973. goto Ret;
  974. }
  975. pKeySvcCliInfo = (PKEYSVCC_INFO)hKeySvcCli;
  976. InitUnicodeString(&Password, pwszPassword);
  977. InitUnicodeString(&CertStore, pwszCertStore);
  978. ulErr = KeyrExportCert(pKeySvcCliInfo->hRPCBinding,
  979. pKeySvcCliInfo->hKeySvc,
  980. &Password, &CertStore,
  981. cHashCount, pHashes,
  982. ulFlags, &pTmpReserved, ppPFXBlob);
  983. }
  984. __except ( EXCEPTION_EXECUTE_HANDLER )
  985. {
  986. ulErr = _exception_code();
  987. }
  988. Ret:
  989. return ulErr;
  990. }
  991. ULONG KeyImportCert(
  992. /* [in] */ KEYSVCC_HANDLE hKeySvcCli,
  993. /* [in] */ LPWSTR pwszPassword,
  994. /* [in] */ LPWSTR pwszCertStore,
  995. /* [in] */ PKEYSVC_BLOB pPFXBlob,
  996. /* [in] */ ULONG ulFlags,
  997. /* [in, out] */ void *pReserved)
  998. {
  999. PKEYSVCC_INFO pKeySvcCliInfo = NULL;
  1000. PKEYSVC_BLOB pTmpReserved = NULL;
  1001. KEYSVC_UNICODE_STRING Password;
  1002. KEYSVC_UNICODE_STRING CertStore;
  1003. ULONG ulErr = 0;
  1004. __try
  1005. {
  1006. memset(&Password, 0, sizeof(Password));
  1007. memset(&CertStore, 0, sizeof(CertStore));
  1008. if (NULL == hKeySvcCli)
  1009. {
  1010. ulErr = ERROR_INVALID_PARAMETER;
  1011. goto Ret;
  1012. }
  1013. pKeySvcCliInfo = (PKEYSVCC_INFO)hKeySvcCli;
  1014. InitUnicodeString(&Password, pwszPassword);
  1015. InitUnicodeString(&CertStore, pwszCertStore);
  1016. ulErr = KeyrImportCert(pKeySvcCliInfo->hRPCBinding,
  1017. pKeySvcCliInfo->hKeySvc,
  1018. &Password, &CertStore,
  1019. pPFXBlob, ulFlags, &pTmpReserved);
  1020. }
  1021. __except ( EXCEPTION_EXECUTE_HANDLER )
  1022. {
  1023. ulErr = _exception_code();
  1024. }
  1025. Ret:
  1026. return ulErr;
  1027. }
  1028. ULONG KeyEnumerateAvailableCertTypes(
  1029. /* [in] */ KEYSVCC_HANDLE hKeySvcCli,
  1030. /* [out][in] */ void *pReserved,
  1031. /* [out][in] */ ULONG *pcCertTypeCount,
  1032. /* [in, out][size_is(,*pcCertTypeCount)] */
  1033. PKEYSVC_UNICODE_STRING *ppCertTypes)
  1034. {
  1035. PKEYSVC_BLOB pTmpReserved = NULL;
  1036. PKEYSVCC_INFO pKeySvcCliInfo = NULL;
  1037. ULONG ulErr = 0;
  1038. __try
  1039. {
  1040. if (NULL == hKeySvcCli)
  1041. {
  1042. ulErr = ERROR_INVALID_PARAMETER;
  1043. goto Ret;
  1044. }
  1045. pKeySvcCliInfo = (PKEYSVCC_INFO)hKeySvcCli;
  1046. ulErr = KeyrEnumerateAvailableCertTypes(pKeySvcCliInfo->hRPCBinding,
  1047. pKeySvcCliInfo->hKeySvc,
  1048. &pTmpReserved,
  1049. pcCertTypeCount,
  1050. ppCertTypes);
  1051. }
  1052. __except ( EXCEPTION_EXECUTE_HANDLER )
  1053. {
  1054. ulErr = _exception_code();
  1055. }
  1056. Ret:
  1057. return ulErr;
  1058. }
  1059. ULONG KeyEnumerateCAs(
  1060. /* [in] */ KEYSVCC_HANDLE hKeySvcCli,
  1061. /* [out][in] */ void *pReserved,
  1062. /* [in] */ ULONG ulFlags,
  1063. /* [out][in] */ ULONG *pcCACount,
  1064. /* [in, out][size_is(,*pcCACount)] */
  1065. PKEYSVC_UNICODE_STRING *ppCAs)
  1066. {
  1067. PKEYSVC_BLOB pTmpReserved = NULL;
  1068. PKEYSVCC_INFO pKeySvcCliInfo = NULL;
  1069. ULONG ulErr = 0;
  1070. __try
  1071. {
  1072. if (NULL == hKeySvcCli)
  1073. {
  1074. ulErr = ERROR_INVALID_PARAMETER;
  1075. goto Ret;
  1076. }
  1077. pKeySvcCliInfo = (PKEYSVCC_INFO)hKeySvcCli;
  1078. ulErr = KeyrEnumerateCAs(pKeySvcCliInfo->hRPCBinding,
  1079. pKeySvcCliInfo->hKeySvc,
  1080. &pTmpReserved,
  1081. ulFlags,
  1082. pcCACount,
  1083. ppCAs);
  1084. }
  1085. __except ( EXCEPTION_EXECUTE_HANDLER )
  1086. {
  1087. ulErr = _exception_code();
  1088. }
  1089. Ret:
  1090. return ulErr;
  1091. }
  1092. extern "C" ULONG KeyQueryRequestStatus
  1093. (/* [in] */ KEYSVCC_HANDLE hKeySvcCli,
  1094. /* [in] */ HANDLE hRequest,
  1095. /* [out, ref] */ CRYPTUI_WIZ_QUERY_CERT_REQUEST_INFO *pQueryInfo)
  1096. {
  1097. KEYSVC_QUERY_CERT_REQUEST_INFO ksQueryCertRequestInfo;
  1098. PKEYSVCC_INFO pKeySvcCliInfo = NULL;
  1099. ULONG ulErr = 0;
  1100. __try
  1101. {
  1102. if (NULL == hKeySvcCli || NULL == pQueryInfo)
  1103. {
  1104. ulErr = ERROR_INVALID_PARAMETER;
  1105. goto Ret;
  1106. }
  1107. ZeroMemory(&ksQueryCertRequestInfo, sizeof(ksQueryCertRequestInfo));
  1108. pKeySvcCliInfo = (PKEYSVCC_INFO)hKeySvcCli;
  1109. ulErr = KeyrQueryRequestStatus
  1110. (pKeySvcCliInfo->hRPCBinding,
  1111. (unsigned __int64)hRequest,
  1112. &ksQueryCertRequestInfo);
  1113. if (ERROR_SUCCESS == ulErr)
  1114. {
  1115. pQueryInfo->dwSize = ksQueryCertRequestInfo.ulSize;
  1116. pQueryInfo->dwStatus = ksQueryCertRequestInfo.ulStatus;
  1117. }
  1118. }
  1119. __except ( EXCEPTION_EXECUTE_HANDLER )
  1120. {
  1121. ulErr = _exception_code();
  1122. }
  1123. Ret:
  1124. return ulErr;
  1125. }
  1126. ULONG RKeyOpenKeyService
  1127. (/* [in] */ LPSTR pszMachineName,
  1128. /* [in] */ KEYSVC_TYPE OwnerType,
  1129. /* [in] */ LPWSTR pwszOwnerName,
  1130. /* [in] */ void *pAuthentication,
  1131. /* [out][in] */ void *pReserved,
  1132. /* [out] */ KEYSVCC_HANDLE *phKeySvcCli)
  1133. {
  1134. BOOL fMustCloseKeyService = FALSE; // TRUE if the cleanup code must close key service
  1135. DWORD dwResult;
  1136. LPWSTR pwszServerPrincName = NULL;
  1137. PKEYSVCC_INFO pKeySvcCliInfo = NULL;
  1138. dwResult = KeyOpenKeyServiceEx
  1139. (IKeySvcR_v1_0_c_ifspec,
  1140. pszMachineName,
  1141. OwnerType,
  1142. pwszOwnerName,
  1143. pAuthentication,
  1144. pReserved,
  1145. phKeySvcCli);
  1146. if (ERROR_SUCCESS != dwResult)
  1147. goto error;
  1148. fMustCloseKeyService = TRUE;
  1149. pKeySvcCliInfo = (PKEYSVCC_INFO)(*phKeySvcCli);
  1150. dwResult = RpcMgmtInqServerPrincNameW(pKeySvcCliInfo->hRPCBinding, RPC_C_AUTHN_GSS_NEGOTIATE, &pwszServerPrincName);
  1151. if (RPC_S_OK != dwResult)
  1152. goto error;
  1153. dwResult = RpcBindingSetAuthInfoW
  1154. (pKeySvcCliInfo->hRPCBinding,
  1155. pwszServerPrincName,
  1156. RPC_C_AUTHN_LEVEL_PKT_PRIVACY, // Calls are authenticated and encrypted
  1157. RPC_C_AUTHN_GSS_NEGOTIATE,
  1158. NULL,
  1159. RPC_C_AUTHZ_NONE
  1160. );
  1161. if (ERROR_SUCCESS != dwResult)
  1162. goto error;
  1163. fMustCloseKeyService = FALSE;
  1164. dwResult = ERROR_SUCCESS;
  1165. error:
  1166. if (fMustCloseKeyService) { RKeyCloseKeyService(phKeySvcCli, 0); }
  1167. if (NULL != pwszServerPrincName) { RpcStringFreeW(&pwszServerPrincName); }
  1168. return dwResult;
  1169. }
  1170. ULONG RKeyCloseKeyService(
  1171. /* [in] */ KEYSVCC_HANDLE hKeySvcCli,
  1172. /* [out][in] */ void *pReserved)
  1173. {
  1174. return KeyCloseKeyService(hKeySvcCli, pReserved);
  1175. }
  1176. ULONG RKeyPFXInstall
  1177. (/* [in] */ KEYSVCC_HANDLE hKeySvcCli,
  1178. /* [in] */ PKEYSVC_BLOB pPFX,
  1179. /* [in] */ PKEYSVC_UNICODE_STRING pPassword,
  1180. /* [in] */ ULONG ulFlags)
  1181. {
  1182. PKEYSVCC_INFO pKeySvcCliInfo = NULL;
  1183. PKEYSVC_BLOB pTmpReserved = NULL;
  1184. ULONG ulErr = 0;
  1185. __try
  1186. {
  1187. if (NULL == hKeySvcCli)
  1188. {
  1189. ulErr = ERROR_INVALID_PARAMETER;
  1190. goto Ret;
  1191. }
  1192. pKeySvcCliInfo = (PKEYSVCC_INFO)hKeySvcCli;
  1193. ulErr = RKeyrPFXInstall(pKeySvcCliInfo->hRPCBinding,
  1194. pPFX,
  1195. pPassword,
  1196. ulFlags);
  1197. }
  1198. __except ( EXCEPTION_EXECUTE_HANDLER )
  1199. {
  1200. ulErr = _exception_code();
  1201. }
  1202. Ret:
  1203. return ulErr;
  1204. }