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.

2938 lines
68 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 2001
  3. Module Name:
  4. csplib.c
  5. General Cryptographic Service Provider Library
  6. Abstract:
  7. Author:
  8. Dan Griffin
  9. Notes:
  10. --*/
  11. #include <nt.h>
  12. #include <ntrtl.h>
  13. #include <nturtl.h>
  14. #include <windows.h>
  15. #include <psapi.h>
  16. #include <rpc.h>
  17. #include <wincrypt.h>
  18. #include <dsysdbg.h>
  19. #include <stdio.h>
  20. #include "csplib.h"
  21. //
  22. // This global must be provided by the "Local" CSP using this library.
  23. //
  24. extern LOCAL_CSP_INFO LocalCspInfo;
  25. #define PROVPATH L"SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider\\"
  26. //
  27. // DllInitialize stores the image path in here during process attach.
  28. //
  29. CHAR l_szImagePath[MAX_PATH];
  30. //
  31. // Debug Support
  32. //
  33. // This uses the debug routines from dsysdbg.h
  34. // Debug output will only be available in chk
  35. // bits.
  36. //
  37. DEFINE_DEBUG2(Csplib)
  38. #if DBG
  39. #define DebugLog(x) CsplibDebugPrint x
  40. #else
  41. #define DebugLog(x)
  42. #endif
  43. #define DEB_ERROR 0x00000001
  44. #define DEB_WARN 0x00000002
  45. #define DEB_TRACE 0x00000004
  46. #define DEB_TRACE_FUNC 0x00000080
  47. #define DEB_TRACE_MEM 0x00000100
  48. #define TRACE_STUFF 0x00000200
  49. static DEBUG_KEY MyDebugKeys[] =
  50. {
  51. {DEB_ERROR, "Error"},
  52. {DEB_WARN, "Warning"},
  53. {DEB_TRACE, "Trace"},
  54. {DEB_TRACE_FUNC, "TraceFuncs"},
  55. {DEB_TRACE_MEM, "TraceMem"},
  56. {0, NULL}
  57. };
  58. #define LOG_BEGIN_FUNCTION(x) \
  59. { DebugLog((DEB_TRACE_FUNC, "%s: Entering\n", #x)); }
  60. #define LOG_END_FUNCTION(x, y) \
  61. { DebugLog((DEB_TRACE_FUNC, "%s: Leaving, status: 0x%x\n", #x, y)); }
  62. #define LOG_CHECK_ALLOC(x) \
  63. { if (NULL == x) { \
  64. dwSts = ERROR_NOT_ENOUGH_MEMORY; \
  65. DebugLog((DEB_TRACE_MEM, "%s: Allocation failed\n", #x)); \
  66. goto Ret; \
  67. } }
  68. //
  69. // Function: ApplyPKCS1SigningFormat
  70. //
  71. // Purpose: Format a buffer with PKCS 1 for signing
  72. //
  73. // Notes:
  74. // If the padding and formatting is successful, the *ppbPKCS1Format parameter
  75. // will be allocated by this routine and must be freed by the caller.
  76. //
  77. DWORD WINAPI ApplyPKCS1SigningFormat(
  78. IN ALG_ID HashAlgid,
  79. IN BYTE *pbHash,
  80. IN DWORD cbHash,
  81. IN DWORD dwFlags,
  82. IN DWORD cbModulus,
  83. OUT PBYTE *ppbPKCS1Format)
  84. {
  85. DWORD dwSts = ERROR_SUCCESS;
  86. BYTE *pbStart = NULL;
  87. BYTE *pbEnd = NULL;
  88. BYTE bTmp = 0;
  89. DWORD i = 0;
  90. DWORD cbAvailableData = cbModulus; // pPubKey->datalen;
  91. *ppbPKCS1Format = NULL;
  92. //
  93. // We know we need at least 3 bytes of padding space.
  94. //
  95. // Note, the final (third) byte of padding is the zeroed-byte at
  96. // location pbPKCS1Format[cbModulus - 1].
  97. //
  98. cbAvailableData -= 3;
  99. // In a few scenarios (involving small RSA keys), the new large SHA
  100. // hashes are too big to be signed by the specified key.
  101. if (cbHash > cbAvailableData)
  102. {
  103. dwSts = (DWORD) NTE_BAD_LEN;
  104. goto Ret;
  105. }
  106. *ppbPKCS1Format = (PBYTE) CspAllocH(cbModulus);
  107. LOG_CHECK_ALLOC(*ppbPKCS1Format);
  108. // insert the block type
  109. (*ppbPKCS1Format)[cbModulus - 2] = 0x01; // Padding byte #1
  110. // insert the type I padding
  111. memset(*ppbPKCS1Format, 0xff, cbModulus - 2);
  112. // Reverse it
  113. for (i = 0; i < cbHash; i++)
  114. (*ppbPKCS1Format)[i] = pbHash[cbHash - (i + 1)];
  115. cbAvailableData -= cbHash;
  116. if ( 0 == (CRYPT_NOHASHOID & dwFlags))
  117. {
  118. switch (HashAlgid)
  119. {
  120. case CALG_MD2:
  121. // PKCS delimit the hash value
  122. pbEnd = (LPBYTE)md2Encodings[0];
  123. pbStart = *ppbPKCS1Format + cbHash;
  124. bTmp = *pbEnd++;
  125. while (0 < bTmp--)
  126. *pbStart++ = *pbEnd++;
  127. *pbStart++ = 0;
  128. break;
  129. case CALG_MD4:
  130. // PKCS delimit the hash value
  131. pbEnd = (LPBYTE)md4Encodings[0];
  132. pbStart = *ppbPKCS1Format + cbHash;
  133. bTmp = *pbEnd++;
  134. while (0 < bTmp--)
  135. *pbStart++ = *pbEnd++;
  136. *pbStart++ = 0;
  137. break;
  138. case CALG_MD5:
  139. // PKCS delimit the hash value
  140. pbEnd = (LPBYTE)md5Encodings[0];
  141. pbStart = *ppbPKCS1Format + cbHash;
  142. bTmp = *pbEnd++;
  143. while (0 < bTmp--)
  144. *pbStart++ = *pbEnd++;
  145. *pbStart++ = 0;
  146. break;
  147. case CALG_SHA:
  148. // PKCS delimit the hash value
  149. pbEnd = (LPBYTE)shaEncodings[0];
  150. pbStart = *ppbPKCS1Format + cbHash;
  151. bTmp = *pbEnd++;
  152. while (0 < bTmp--)
  153. *pbStart++ = *pbEnd++;
  154. *pbStart++ = 0;
  155. break;
  156. case CALG_SSL3_SHAMD5:
  157. // No PKCS padding
  158. pbStart = *ppbPKCS1Format + cbHash;
  159. *pbStart++ = 0;
  160. break;
  161. case CALG_SHA_256:
  162. pbEnd = (LPBYTE) sha256Encodings[0];
  163. pbStart = *ppbPKCS1Format + cbHash;
  164. bTmp = *pbEnd++;
  165. if (bTmp > cbAvailableData)
  166. {
  167. dwSts = (DWORD) NTE_BAD_LEN;
  168. goto Ret;
  169. }
  170. while (0 < bTmp--)
  171. *pbStart++ = *pbEnd++;
  172. *pbStart++ = 0; // Padding byte #2
  173. break;
  174. case CALG_SHA_384:
  175. pbEnd = (LPBYTE) sha384Encodings[0];
  176. pbStart = *ppbPKCS1Format + cbHash;
  177. bTmp = *pbEnd++;
  178. if (bTmp > cbAvailableData)
  179. {
  180. dwSts = (DWORD) NTE_BAD_LEN;
  181. goto Ret;
  182. }
  183. while (0 < bTmp--)
  184. *pbStart++ = *pbEnd++;
  185. *pbStart++ = 0; // Padding byte #2
  186. break;
  187. case CALG_SHA_512:
  188. pbEnd = (LPBYTE) sha512Encodings[0];
  189. pbStart = *ppbPKCS1Format + cbHash;
  190. bTmp = *pbEnd++;
  191. if (bTmp > cbAvailableData)
  192. {
  193. dwSts = (DWORD) NTE_BAD_LEN;
  194. goto Ret;
  195. }
  196. while (0 < bTmp--)
  197. *pbStart++ = *pbEnd++;
  198. *pbStart++ = 0; // Padding byte #2
  199. break;
  200. default:
  201. dwSts = (DWORD)NTE_BAD_ALGID;
  202. goto Ret;
  203. }
  204. }
  205. else
  206. {
  207. (*ppbPKCS1Format)[cbHash] = 0x00;
  208. }
  209. Ret:
  210. if (ERROR_SUCCESS != dwSts &&
  211. NULL != *ppbPKCS1Format)
  212. {
  213. CspFreeH(*ppbPKCS1Format);
  214. *ppbPKCS1Format = NULL;
  215. }
  216. return dwSts;
  217. }
  218. //
  219. // Function: VerifyPKCS2Padding
  220. //
  221. DWORD WINAPI VerifyPKCS2Padding(
  222. IN PBYTE pbPaddedData,
  223. IN DWORD cbModulus,
  224. OUT PBYTE *ppbData,
  225. OUT PDWORD pcbData)
  226. {
  227. DWORD dwSts = ERROR_SUCCESS;
  228. PBYTE pbData = NULL;
  229. DWORD cbData = 0;
  230. DWORD z = 0;
  231. *ppbData = NULL;
  232. *pcbData = 0;
  233. if ((pbPaddedData[cbModulus - 2] != PKCS_BLOCKTYPE_2) ||
  234. (pbPaddedData[cbModulus - 1] != 0))
  235. {
  236. dwSts = NTE_BAD_DATA;
  237. goto Ret;
  238. }
  239. cbData = cbModulus - 3;
  240. while ((cbData > 0) && (pbPaddedData[cbData]))
  241. cbData--;
  242. pbData = (PBYTE) CspAllocH(cbData);
  243. LOG_CHECK_ALLOC(pbData);
  244. // Reverse the session key bytes
  245. for (z = 0; z < cbData; ++z)
  246. pbData[z] = pbPaddedData[cbData - z - 1];
  247. *ppbData = pbData;
  248. pbData = NULL;
  249. *pcbData = cbData;
  250. Ret:
  251. if (pbData)
  252. CspFreeH(pbData);
  253. return dwSts;
  254. }
  255. //
  256. // Function: GetLocalCspInfo
  257. //
  258. PLOCAL_CSP_INFO GetLocalCspInfo(void)
  259. {
  260. return &LocalCspInfo;
  261. }
  262. //
  263. // Function: InitializeLocalCallInfo
  264. //
  265. DWORD InitializeLocalCallInfo(
  266. IN PLOCAL_CALL_INFO pLocalCallInfo)
  267. {
  268. *pLocalCallInfo = FALSE;
  269. return ERROR_SUCCESS;
  270. }
  271. //
  272. // Function: SetLocalCallInfo
  273. //
  274. // Purpose: The local CSP uses this function to indicate to functions in
  275. // this library whether execution of a given API should continue
  276. // after the local CSP has returned.
  277. //
  278. void SetLocalCallInfo(
  279. IN OUT PLOCAL_CALL_INFO pLocalCallInfo,
  280. IN BOOL fContinue)
  281. {
  282. *pLocalCallInfo = fContinue;
  283. }
  284. //
  285. // Function: CheckLocalCallInfo
  286. //
  287. BOOL CheckLocalCallInfo(
  288. IN PLOCAL_CALL_INFO pLocalCallInfo,
  289. IN DWORD dwSts,
  290. OUT BOOL *pfSuccess)
  291. {
  292. if (FALSE == *pLocalCallInfo)
  293. *pfSuccess = (ERROR_SUCCESS == dwSts);
  294. return *pLocalCallInfo;
  295. }
  296. //
  297. // Memory Management
  298. //
  299. //
  300. // Function: CspAllocH
  301. //
  302. LPVOID WINAPI CspAllocH(
  303. IN SIZE_T cBytes)
  304. {
  305. return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cBytes);
  306. }
  307. //
  308. // Function: CspFreeH
  309. //
  310. void WINAPI CspFreeH(
  311. IN LPVOID pMem)
  312. {
  313. HeapFree(GetProcessHeap(), 0, pMem);
  314. }
  315. //
  316. // Function: CspReAllocH
  317. //
  318. LPVOID WINAPI CspReAllocH(
  319. IN LPVOID pMem,
  320. IN SIZE_T cBytes)
  321. {
  322. return HeapReAlloc(
  323. GetProcessHeap(), HEAP_ZERO_MEMORY, pMem, cBytes);
  324. }
  325. //
  326. // Critical Section Management
  327. //
  328. //
  329. // Function: CspInitializeCriticalSection
  330. //
  331. DWORD CspInitializeCriticalSection(
  332. IN CRITICAL_SECTION *pcs)
  333. {
  334. __try {
  335. InitializeCriticalSection(pcs);
  336. }
  337. __except (EXCEPTION_EXECUTE_HANDLER) {
  338. return ERROR_NOT_ENOUGH_MEMORY;
  339. }
  340. return ERROR_SUCCESS;
  341. }
  342. //
  343. // Function: CspEnterCriticalSection
  344. //
  345. DWORD CspEnterCriticalSection(
  346. IN CRITICAL_SECTION *pcs)
  347. {
  348. __try {
  349. EnterCriticalSection(pcs);
  350. }
  351. __except (EXCEPTION_EXECUTE_HANDLER) {
  352. return ERROR_NOT_ENOUGH_MEMORY;
  353. }
  354. return ERROR_SUCCESS;
  355. }
  356. //
  357. // Function: CspLeaveCriticalSection
  358. //
  359. void CspLeaveCriticalSection(
  360. IN CRITICAL_SECTION *pcs)
  361. {
  362. LeaveCriticalSection(pcs);
  363. }
  364. //
  365. // Function: CspDeleteCriticalSection
  366. //
  367. void CspDeleteCriticalSection(
  368. IN CRITICAL_SECTION *pcs)
  369. {
  370. DeleteCriticalSection(pcs);
  371. }
  372. //
  373. // Registration Helpers
  374. //
  375. //
  376. // Function: RegOpenProviderKey
  377. //
  378. DWORD WINAPI RegOpenProviderKey(
  379. IN OUT HKEY *phProviderKey,
  380. IN REGSAM samDesired)
  381. {
  382. DWORD cbProv = 0;
  383. LPWSTR wszProv = NULL;
  384. DWORD dwSts = ERROR_SUCCESS;
  385. DWORD dwIgn = 0;
  386. PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
  387. *phProviderKey = 0;
  388. cbProv = (wcslen(PROVPATH) +
  389. wcslen(pLocalCspInfo->wszProviderName) + 1) * sizeof(WCHAR);
  390. wszProv = (LPWSTR) CspAllocH(cbProv);
  391. if (NULL == wszProv)
  392. {
  393. dwSts = ERROR_NOT_ENOUGH_MEMORY;
  394. goto Ret;
  395. }
  396. swprintf(
  397. wszProv,
  398. L"%s%s",
  399. PROVPATH,
  400. pLocalCspInfo->wszProviderName);
  401. //
  402. // Create or open in local machine for provider
  403. //
  404. dwSts = RegCreateKeyExW(HKEY_LOCAL_MACHINE,
  405. wszProv,
  406. 0L, L"", REG_OPTION_NON_VOLATILE,
  407. samDesired, NULL, phProviderKey,
  408. &dwIgn);
  409. if (ERROR_SUCCESS != dwSts)
  410. goto Ret;
  411. Ret:
  412. if (wszProv)
  413. CspFreeH(wszProv);
  414. if (ERROR_SUCCESS != dwSts && 0 != *phProviderKey)
  415. RegCloseKey(*phProviderKey);
  416. return dwSts;
  417. }
  418. //
  419. // Function: CreateUuidContainerName
  420. //
  421. DWORD WINAPI CreateUuidContainerName(
  422. IN PUSER_CONTEXT pUserCtx)
  423. {
  424. UUID Uuid;
  425. LPWSTR wszUuid = NULL;
  426. DWORD dwSts = ERROR_SUCCESS;
  427. dwSts = (DWORD) UuidCreate(&Uuid);
  428. if (RPC_S_OK != dwSts)
  429. goto Ret;
  430. dwSts = (DWORD) UuidToStringW(&Uuid, &wszUuid);
  431. if (RPC_S_OK != dwSts)
  432. goto Ret;
  433. pUserCtx->wszBaseContainerName = wszUuid;
  434. pUserCtx->fBaseContainerNameIsRpcUuid = TRUE;
  435. wszUuid = NULL;
  436. Ret:
  437. if (wszUuid)
  438. RpcStringFreeW(&wszUuid);
  439. return dwSts;
  440. }
  441. //
  442. // Function: DeleteUserContext
  443. //
  444. DWORD DeleteUserContext(
  445. IN PUSER_CONTEXT pUserContext)
  446. {
  447. DWORD dwSts = ERROR_SUCCESS;
  448. if (pUserContext->pVTableW)
  449. {
  450. if (pUserContext->pVTableW->pbContextInfo)
  451. {
  452. CspFreeH(pUserContext->pVTableW->pbContextInfo);
  453. pUserContext->pVTableW = NULL;
  454. }
  455. if (pUserContext->pVTableW->pszProvName)
  456. {
  457. CspFreeH(pUserContext->pVTableW->pszProvName);
  458. pUserContext->pVTableW->pszProvName = NULL;
  459. }
  460. CspFreeH(pUserContext->pVTableW);
  461. pUserContext->pVTableW = NULL;
  462. }
  463. if (pUserContext->wszBaseContainerName)
  464. {
  465. if (pUserContext->fBaseContainerNameIsRpcUuid)
  466. RpcStringFreeW(&pUserContext->wszBaseContainerName);
  467. else
  468. CspFreeH(pUserContext->wszBaseContainerName);
  469. pUserContext->wszBaseContainerName = NULL;
  470. }
  471. if (pUserContext->wszContainerNameFromCaller)
  472. {
  473. CspFreeH(pUserContext->wszContainerNameFromCaller);
  474. pUserContext->wszContainerNameFromCaller = NULL;
  475. }
  476. if (pUserContext->wszUniqueContainerName)
  477. {
  478. CspFreeH(pUserContext->wszUniqueContainerName);
  479. pUserContext->wszUniqueContainerName = NULL;
  480. }
  481. if (pUserContext->hSupportProv)
  482. {
  483. if (! CryptReleaseContext(pUserContext->hSupportProv, 0))
  484. dwSts = GetLastError();
  485. pUserContext->hSupportProv = 0;
  486. }
  487. return dwSts;
  488. }
  489. //
  490. // Function: DeleteKeyContext
  491. //
  492. DWORD DeleteKeyContext(
  493. IN PKEY_CONTEXT pKeyContext)
  494. {
  495. PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
  496. LOCAL_CALL_INFO LocalCallInfo;
  497. DWORD dwSts = ERROR_SUCCESS;
  498. InitializeLocalCallInfo(&LocalCallInfo);
  499. if (pKeyContext->hSupportKey)
  500. {
  501. if (! CryptDestroyKey(pKeyContext->hSupportKey))
  502. dwSts = GetLastError();
  503. pKeyContext->hSupportKey = 0;
  504. }
  505. if (pKeyContext->pvLocalKeyContext)
  506. {
  507. if (pLocalCspInfo->pfnLocalDestroyKey)
  508. {
  509. pLocalCspInfo->pfnLocalDestroyKey(
  510. pKeyContext,
  511. &LocalCallInfo);
  512. pKeyContext->pvLocalKeyContext = NULL;
  513. }
  514. }
  515. return dwSts;
  516. }
  517. //
  518. // Function: DeleteHashContext
  519. //
  520. DWORD DeleteHashContext(
  521. IN PHASH_CONTEXT pHashContext)
  522. {
  523. PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
  524. LOCAL_CALL_INFO LocalCallInfo;
  525. DWORD dwSts = ERROR_SUCCESS;
  526. InitializeLocalCallInfo(&LocalCallInfo);
  527. if (pHashContext->hSupportHash)
  528. {
  529. if (! CryptDestroyHash(pHashContext->hSupportHash))
  530. dwSts = GetLastError();
  531. pHashContext->hSupportHash = 0;
  532. }
  533. if (pHashContext->pvLocalHashContext)
  534. {
  535. if (pLocalCspInfo->pfnLocalDestroyHash)
  536. {
  537. pLocalCspInfo->pfnLocalDestroyHash(
  538. pHashContext,
  539. &LocalCallInfo);
  540. pHashContext->pvLocalHashContext = NULL;
  541. }
  542. }
  543. return dwSts;
  544. }
  545. /*
  546. - CPAcquireContext
  547. -
  548. * Purpose:
  549. * The CPAcquireContext function is used to acquire a context
  550. * handle to a cryptographic service provider (CSP).
  551. *
  552. *
  553. * Parameters:
  554. * OUT phProv - Handle to a CSP
  555. * IN szContainer - Pointer to a string which is the
  556. * identity of the logged on user
  557. * IN dwFlags - Flags values
  558. * IN pVTable - Pointer to table of function pointers
  559. *
  560. * Returns:
  561. */
  562. BOOL WINAPI
  563. CPAcquireContext(
  564. OUT HCRYPTPROV *phProv,
  565. IN LPCSTR szContainer,
  566. IN DWORD dwFlags,
  567. IN PVTableProvStruc pVTable)
  568. {
  569. ANSI_STRING AnsiContainer;
  570. UNICODE_STRING UnicodeContainer;
  571. ANSI_STRING AnsiProvName;
  572. UNICODE_STRING UnicodeProvName;
  573. BOOL fSuccess = FALSE;
  574. DWORD dwSts;
  575. DWORD dwError = NTE_FAIL;
  576. VTableProvStrucW VTableW;
  577. memset(&AnsiContainer, 0, sizeof(AnsiContainer));
  578. memset(&AnsiProvName, 0, sizeof(AnsiProvName));
  579. memset(&UnicodeContainer, 0, sizeof(UnicodeContainer));
  580. memset(&UnicodeProvName, 0, sizeof(UnicodeProvName));
  581. memset(&VTableW, 0, sizeof(VTableW));
  582. if (szContainer)
  583. {
  584. RtlInitAnsiString(&AnsiContainer, szContainer);
  585. dwSts = RtlAnsiStringToUnicodeString(
  586. &UnicodeContainer,
  587. &AnsiContainer,
  588. TRUE);
  589. if (STATUS_SUCCESS != dwSts)
  590. {
  591. dwError = RtlNtStatusToDosError(dwSts);
  592. goto Ret;
  593. }
  594. }
  595. VTableW.cbContextInfo = pVTable->cbContextInfo;
  596. VTableW.dwProvType = pVTable->dwProvType;
  597. VTableW.FuncReturnhWnd = pVTable->FuncReturnhWnd;
  598. VTableW.pbContextInfo = pVTable->pbContextInfo;
  599. VTableW.Version = pVTable->Version;
  600. RtlInitAnsiString(&AnsiProvName, pVTable->pszProvName);
  601. dwSts = RtlAnsiStringToUnicodeString(
  602. &UnicodeProvName,
  603. &AnsiProvName,
  604. TRUE);
  605. if (STATUS_SUCCESS != dwSts)
  606. {
  607. dwError = RtlNtStatusToDosError(dwSts);
  608. goto Ret;
  609. }
  610. VTableW.pszProvName = UnicodeProvName.Buffer;
  611. if (! CPAcquireContextW(
  612. phProv,
  613. szContainer ? UnicodeContainer.Buffer : NULL,
  614. dwFlags,
  615. &VTableW))
  616. {
  617. dwError = GetLastError();
  618. goto Ret;
  619. }
  620. fSuccess = TRUE;
  621. Ret:
  622. if (szContainer)
  623. RtlFreeUnicodeString(&UnicodeContainer);
  624. RtlFreeUnicodeString(&UnicodeProvName);
  625. if (! fSuccess)
  626. SetLastError(dwError);
  627. return fSuccess;
  628. }
  629. /*
  630. - CPAcquireContextW
  631. -
  632. * Purpose:
  633. * The CPAcquireContextW function is used to acquire a context
  634. * handle to a cryptographic service provider (CSP). using
  635. * UNICODE strings. This is an optional entry point for a CSP.
  636. * It is not used prior to Whistler. There it is used if
  637. * exported by the CSP image, otherwise any string conversions
  638. * are done, and CPAcquireContext is called.
  639. *
  640. *
  641. * Parameters:
  642. * OUT phProv - Handle to a CSP
  643. * IN szContainer - Pointer to a string which is the
  644. * identity of the logged on user
  645. * IN dwFlags - Flags values
  646. * IN pVTable - Pointer to table of function pointers
  647. *
  648. * Returns:
  649. */
  650. BOOL WINAPI
  651. CPAcquireContextW(
  652. OUT HCRYPTPROV *phProv,
  653. IN LPCWSTR szContainer,
  654. IN DWORD dwFlags,
  655. IN PVTableProvStrucW pVTable)
  656. {
  657. PUSER_CONTEXT pUserContext = NULL;
  658. LOCAL_CALL_INFO LocalCallInfo;
  659. DWORD dwSts = ERROR_SUCCESS;
  660. BOOL fSuccess = FALSE;
  661. PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
  662. InitializeLocalCallInfo(&LocalCallInfo);
  663. //
  664. // Invalid to specify a container name with
  665. // VERIFYCONTEXT.
  666. //
  667. if ( (CRYPT_VERIFYCONTEXT & dwFlags) &&
  668. NULL != szContainer)
  669. {
  670. dwSts = NTE_BAD_FLAGS;
  671. goto Ret;
  672. }
  673. pUserContext = (PUSER_CONTEXT) CspAllocH(sizeof(USER_CONTEXT));
  674. LOG_CHECK_ALLOC(pUserContext);
  675. if (szContainer)
  676. {
  677. pUserContext->wszContainerNameFromCaller =
  678. (LPWSTR) CspAllocH((1 + wcslen(szContainer)) * sizeof(WCHAR));
  679. LOG_CHECK_ALLOC(pUserContext->wszContainerNameFromCaller);
  680. wcscpy(
  681. pUserContext->wszContainerNameFromCaller,
  682. szContainer);
  683. }
  684. pUserContext->dwFlags = dwFlags;
  685. //
  686. // Copy the VTableProvStruc that we received from advapi, since
  687. // the info in the struct may be useful later.
  688. //
  689. pUserContext->pVTableW =
  690. (PVTableProvStrucW) CspAllocH(sizeof(VTableProvStrucW));
  691. LOG_CHECK_ALLOC(pUserContext->pVTableW);
  692. // Copy the provider name
  693. pUserContext->pVTableW->pszProvName =
  694. (LPWSTR) CspAllocH((1 + wcslen(pVTable->pszProvName)) * sizeof(WCHAR));
  695. LOG_CHECK_ALLOC(pUserContext->pVTableW->pszProvName);
  696. wcscpy(
  697. pUserContext->pVTableW->pszProvName,
  698. pVTable->pszProvName);
  699. // Copy the context information, if any
  700. if (pVTable->pbContextInfo)
  701. {
  702. pUserContext->pVTableW->pbContextInfo =
  703. (PBYTE) CspAllocH(pVTable->cbContextInfo);
  704. LOG_CHECK_ALLOC(pUserContext->pVTableW->pbContextInfo);
  705. memcpy(
  706. pUserContext->pVTableW->pbContextInfo,
  707. pVTable->pbContextInfo,
  708. pVTable->cbContextInfo);
  709. pUserContext->pVTableW->cbContextInfo = pVTable->cbContextInfo;
  710. }
  711. // Copy the rest of the ProvStruc
  712. pUserContext->pVTableW->dwProvType = pVTable->dwProvType;
  713. pUserContext->pVTableW->FuncReturnhWnd = pVTable->FuncReturnhWnd;
  714. pUserContext->pVTableW->FuncVerifyImage = pVTable->FuncVerifyImage;
  715. pUserContext->pVTableW->Version = pVTable->Version;
  716. if (! CryptAcquireContextW(
  717. &pUserContext->hSupportProv,
  718. NULL,
  719. pLocalCspInfo->wszSupportProviderName,
  720. pLocalCspInfo->dwSupportProviderType,
  721. CRYPT_VERIFYCONTEXT))
  722. {
  723. dwSts = GetLastError();
  724. goto Ret;
  725. }
  726. dwSts = pLocalCspInfo->pfnLocalAcquireContext(
  727. pUserContext,
  728. &LocalCallInfo);
  729. if (ERROR_SUCCESS != dwSts)
  730. goto Ret;
  731. if (CRYPT_DELETEKEYSET & dwFlags)
  732. {
  733. DeleteUserContext(pUserContext);
  734. CspFreeH(pUserContext);
  735. pUserContext = NULL;
  736. }
  737. else
  738. *phProv = (HCRYPTPROV) pUserContext;
  739. Ret:
  740. if (ERROR_SUCCESS != dwSts)
  741. {
  742. DeleteUserContext(pUserContext);
  743. CspFreeH(pUserContext);
  744. SetLastError(dwSts);
  745. fSuccess = FALSE;
  746. }
  747. else
  748. fSuccess = TRUE;
  749. return fSuccess;
  750. }
  751. /*
  752. - CPReleaseContext
  753. -
  754. * Purpose:
  755. * The CPReleaseContext function is used to release a
  756. * context created by CryptAcquireContext.
  757. *
  758. * Parameters:
  759. * IN phProv - Handle to a CSP
  760. * IN dwFlags - Flags values
  761. *
  762. * Returns:
  763. */
  764. BOOL WINAPI
  765. CPReleaseContext(
  766. IN HCRYPTPROV hProv,
  767. IN DWORD dwFlags)
  768. {
  769. PUSER_CONTEXT pUserContext = (PUSER_CONTEXT) hProv;
  770. PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
  771. BOOL fSuccess = TRUE;
  772. DWORD dwSts = ERROR_SUCCESS;
  773. LOCAL_CALL_INFO LocalCallInfo;
  774. InitializeLocalCallInfo(&LocalCallInfo);
  775. dwSts = pLocalCspInfo->pfnLocalReleaseContext(
  776. pUserContext, dwFlags, &LocalCallInfo);
  777. if (ERROR_SUCCESS != dwSts)
  778. fSuccess = FALSE;
  779. //
  780. // Try to free the user context structure, regardless of what the
  781. // local CSP replied in the above call.
  782. //
  783. DeleteUserContext(pUserContext);
  784. if (FALSE == fSuccess)
  785. SetLastError(dwSts);
  786. return fSuccess;
  787. }
  788. /*
  789. - CPGenKey
  790. -
  791. * Purpose:
  792. * Generate cryptographic keys
  793. *
  794. *
  795. * Parameters:
  796. * IN hProv - Handle to a CSP
  797. * IN Algid - Algorithm identifier
  798. * IN dwFlags - Flags values
  799. * OUT phKey - Handle to a generated key
  800. *
  801. * Returns:
  802. */
  803. BOOL WINAPI
  804. CPGenKey(
  805. IN HCRYPTPROV hProv,
  806. IN ALG_ID Algid,
  807. IN DWORD dwFlags,
  808. OUT HCRYPTKEY *phKey)
  809. {
  810. DWORD dwSts = ERROR_SUCCESS;
  811. PKEY_CONTEXT pKeyCtx = NULL;
  812. PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
  813. BOOL fSuccess = FALSE;
  814. PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
  815. LOCAL_CALL_INFO LocalCallInfo;
  816. InitializeLocalCallInfo(&LocalCallInfo);
  817. *phKey = 0;
  818. pKeyCtx = (PKEY_CONTEXT) CspAllocH(sizeof(KEY_CONTEXT));
  819. LOG_CHECK_ALLOC(pKeyCtx);
  820. pKeyCtx->Algid = Algid;
  821. pKeyCtx->dwFlags = 0x0000ffff & dwFlags;
  822. pKeyCtx->cKeyBits = dwFlags >> 16;
  823. pKeyCtx->pUserContext = pUserCtx;
  824. if (pLocalCspInfo->pfnLocalGenKey)
  825. {
  826. dwSts = pLocalCspInfo->pfnLocalGenKey(
  827. pKeyCtx, &LocalCallInfo);
  828. if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
  829. goto Ret;
  830. }
  831. if (! CryptGenKey(
  832. pUserCtx->hSupportProv,
  833. Algid,
  834. dwFlags,
  835. &pKeyCtx->hSupportKey))
  836. {
  837. dwSts = GetLastError();
  838. goto Ret;
  839. }
  840. fSuccess = TRUE;
  841. Ret:
  842. if (TRUE == fSuccess)
  843. {
  844. *phKey = (HCRYPTKEY) pKeyCtx;
  845. pKeyCtx = NULL;
  846. }
  847. if (pKeyCtx)
  848. {
  849. DeleteKeyContext(pKeyCtx);
  850. CspFreeH(pKeyCtx);
  851. }
  852. if (FALSE == fSuccess)
  853. SetLastError(dwSts);
  854. return fSuccess;
  855. }
  856. /*
  857. - CPDeriveKey
  858. -
  859. * Purpose:
  860. * Derive cryptographic keys from base data
  861. *
  862. *
  863. * Parameters:
  864. * IN hProv - Handle to a CSP
  865. * IN Algid - Algorithm identifier
  866. * IN hBaseData - Handle to base data
  867. * IN dwFlags - Flags values
  868. * OUT phKey - Handle to a generated key
  869. *
  870. * Returns:
  871. */
  872. BOOL WINAPI
  873. CPDeriveKey(
  874. IN HCRYPTPROV hProv,
  875. IN ALG_ID Algid,
  876. IN HCRYPTHASH hHash,
  877. IN DWORD dwFlags,
  878. OUT HCRYPTKEY *phKey)
  879. {
  880. DWORD dwSts = ERROR_SUCCESS;
  881. PKEY_CONTEXT pKeyCtx = NULL;
  882. PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
  883. PHASH_CONTEXT pHashCtx = (PHASH_CONTEXT) hHash;
  884. BOOL fSuccess = FALSE;
  885. PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
  886. LOCAL_CALL_INFO LocalCallInfo;
  887. *phKey = 0;
  888. InitializeLocalCallInfo(&LocalCallInfo);
  889. pKeyCtx = (PKEY_CONTEXT) CspAllocH(sizeof(KEY_CONTEXT));
  890. LOG_CHECK_ALLOC(pKeyCtx);
  891. pKeyCtx->pUserContext = pUserCtx;
  892. pKeyCtx->Algid = Algid;
  893. pKeyCtx->cKeyBits = dwFlags >> 16;
  894. pKeyCtx->dwFlags = dwFlags & 0x0000ffff;
  895. if (pLocalCspInfo->pfnLocalDeriveKey)
  896. {
  897. dwSts = pLocalCspInfo->pfnLocalDeriveKey(
  898. pKeyCtx,
  899. pHashCtx,
  900. &LocalCallInfo);
  901. if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
  902. goto Ret;
  903. }
  904. if (! CryptDeriveKey(
  905. pUserCtx->hSupportProv,
  906. Algid,
  907. pHashCtx->hSupportHash,
  908. dwFlags,
  909. &pKeyCtx->hSupportKey))
  910. {
  911. dwSts = GetLastError();
  912. goto Ret;
  913. }
  914. *phKey = (HCRYPTKEY) pKeyCtx;
  915. pKeyCtx = NULL;
  916. fSuccess = TRUE;
  917. Ret:
  918. if (pKeyCtx)
  919. {
  920. DeleteKeyContext(pKeyCtx);
  921. CspFreeH(pKeyCtx);
  922. }
  923. if (FALSE == fSuccess)
  924. SetLastError(dwSts);
  925. return fSuccess;
  926. }
  927. /*
  928. - CPDestroyKey
  929. -
  930. * Purpose:
  931. * Destroys the cryptographic key that is being referenced
  932. * with the hKey parameter
  933. *
  934. *
  935. * Parameters:
  936. * IN hProv - Handle to a CSP
  937. * IN hKey - Handle to a key
  938. *
  939. * Returns:
  940. */
  941. BOOL WINAPI
  942. CPDestroyKey(
  943. IN HCRYPTPROV hProv,
  944. IN HCRYPTKEY hKey)
  945. {
  946. DWORD dwSts = ERROR_SUCCESS;
  947. PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
  948. PKEY_CONTEXT pKeyCtx = (PKEY_CONTEXT) hKey;
  949. dwSts = DeleteKeyContext(pKeyCtx);
  950. CspFreeH(pKeyCtx);
  951. if (ERROR_SUCCESS != dwSts)
  952. SetLastError(dwSts);
  953. return (ERROR_SUCCESS == dwSts);
  954. }
  955. /*
  956. - CPSetKeyParam
  957. -
  958. * Purpose:
  959. * Allows applications to customize various aspects of the
  960. * operations of a key
  961. *
  962. * Parameters:
  963. * IN hProv - Handle to a CSP
  964. * IN hKey - Handle to a key
  965. * IN dwParam - Parameter number
  966. * IN pbData - Pointer to data
  967. * IN dwFlags - Flags values
  968. *
  969. * Returns:
  970. */
  971. BOOL WINAPI
  972. CPSetKeyParam(
  973. IN HCRYPTPROV hProv,
  974. IN HCRYPTKEY hKey,
  975. IN DWORD dwParam,
  976. IN CONST BYTE *pbData,
  977. IN DWORD dwFlags)
  978. {
  979. DWORD dwSts = ERROR_SUCCESS;
  980. PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
  981. PKEY_CONTEXT pKeyCtx = (PKEY_CONTEXT) hKey;
  982. LOCAL_CALL_INFO LocalCallInfo;
  983. BOOL fSuccess = FALSE;
  984. PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
  985. InitializeLocalCallInfo(&LocalCallInfo);
  986. if (pLocalCspInfo->pfnLocalSetKeyParam)
  987. {
  988. dwSts = pLocalCspInfo->pfnLocalSetKeyParam(
  989. pKeyCtx,
  990. dwParam,
  991. (PBYTE) pbData,
  992. dwFlags,
  993. &LocalCallInfo);
  994. if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
  995. goto Ret;
  996. }
  997. if (! CryptSetKeyParam(
  998. pKeyCtx->hSupportKey,
  999. dwParam,
  1000. pbData,
  1001. dwFlags))
  1002. {
  1003. dwSts = GetLastError();
  1004. goto Ret;
  1005. }
  1006. fSuccess = TRUE;
  1007. Ret:
  1008. if (FALSE == fSuccess)
  1009. SetLastError(dwSts);
  1010. return fSuccess;
  1011. }
  1012. /*
  1013. - CPGetKeyParam
  1014. -
  1015. * Purpose:
  1016. * Allows applications to get various aspects of the
  1017. * operations of a key
  1018. *
  1019. * Parameters:
  1020. * IN hProv - Handle to a CSP
  1021. * IN hKey - Handle to a key
  1022. * IN dwParam - Parameter number
  1023. * OUT pbData - Pointer to data
  1024. * IN pdwDataLen - Length of parameter data
  1025. * IN dwFlags - Flags values
  1026. *
  1027. * Returns:
  1028. */
  1029. BOOL WINAPI
  1030. CPGetKeyParam(
  1031. IN HCRYPTPROV hProv,
  1032. IN HCRYPTKEY hKey,
  1033. IN DWORD dwParam,
  1034. OUT LPBYTE pbData,
  1035. IN OUT LPDWORD pcbDataLen,
  1036. IN DWORD dwFlags)
  1037. {
  1038. DWORD dwSts = ERROR_SUCCESS;
  1039. PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
  1040. PKEY_CONTEXT pKeyCtx = (PKEY_CONTEXT) hKey;
  1041. LOCAL_CALL_INFO LocalCallInfo;
  1042. PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
  1043. BOOL fSuccess = FALSE;
  1044. InitializeLocalCallInfo(&LocalCallInfo);
  1045. if (pLocalCspInfo->pfnLocalGetKeyParam)
  1046. {
  1047. dwSts = pLocalCspInfo->pfnLocalGetKeyParam(
  1048. pKeyCtx,
  1049. dwParam,
  1050. pbData,
  1051. pcbDataLen,
  1052. dwFlags,
  1053. &LocalCallInfo);
  1054. if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
  1055. goto Ret;
  1056. }
  1057. if (! CryptGetKeyParam(
  1058. pKeyCtx->hSupportKey,
  1059. dwParam,
  1060. pbData,
  1061. pcbDataLen,
  1062. dwFlags))
  1063. {
  1064. dwSts = GetLastError();
  1065. goto Ret;
  1066. }
  1067. Ret:
  1068. if (FALSE == fSuccess)
  1069. SetLastError(dwSts);
  1070. return fSuccess;
  1071. }
  1072. /*
  1073. - CPSetProvParam
  1074. -
  1075. * Purpose:
  1076. * Allows applications to customize various aspects of the
  1077. * operations of a provider
  1078. *
  1079. * Parameters:
  1080. * IN hProv - Handle to a CSP
  1081. * IN dwParam - Parameter number
  1082. * IN pbData - Pointer to data
  1083. * IN dwFlags - Flags values
  1084. *
  1085. * Returns:
  1086. */
  1087. BOOL WINAPI
  1088. CPSetProvParam(
  1089. IN HCRYPTPROV hProv,
  1090. IN DWORD dwParam,
  1091. IN CONST BYTE *pbData,
  1092. IN DWORD dwFlags)
  1093. {
  1094. DWORD dwSts = ERROR_SUCCESS;
  1095. PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
  1096. LOCAL_CALL_INFO LocalCallInfo;
  1097. PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
  1098. BOOL fSuccess = FALSE;
  1099. InitializeLocalCallInfo(&LocalCallInfo);
  1100. if (pLocalCspInfo->pfnLocalSetProvParam)
  1101. {
  1102. dwSts = pLocalCspInfo->pfnLocalSetProvParam(
  1103. pUserCtx,
  1104. dwParam,
  1105. (PBYTE) pbData,
  1106. dwFlags,
  1107. &LocalCallInfo);
  1108. if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
  1109. goto Ret;
  1110. }
  1111. if (! CryptSetProvParam(
  1112. pUserCtx->hSupportProv,
  1113. dwParam,
  1114. pbData,
  1115. dwFlags))
  1116. {
  1117. dwSts = GetLastError();
  1118. goto Ret;
  1119. }
  1120. fSuccess = TRUE;
  1121. Ret:
  1122. if (FALSE == fSuccess)
  1123. SetLastError(dwSts);
  1124. return fSuccess;
  1125. }
  1126. /*
  1127. - CPGetProvParam
  1128. -
  1129. * Purpose:
  1130. * Allows applications to get various aspects of the
  1131. * operations of a provider
  1132. *
  1133. * Parameters:
  1134. * IN hProv - Handle to a CSP
  1135. * IN dwParam - Parameter number
  1136. * OUT pbData - Pointer to data
  1137. * IN OUT pdwDataLen - Length of parameter data
  1138. * IN dwFlags - Flags values
  1139. *
  1140. * Returns:
  1141. */
  1142. BOOL WINAPI
  1143. CPGetProvParam(
  1144. IN HCRYPTPROV hProv,
  1145. IN DWORD dwParam,
  1146. OUT LPBYTE pbData,
  1147. IN OUT LPDWORD pcbDataLen,
  1148. IN DWORD dwFlags)
  1149. {
  1150. DWORD dwSts = ERROR_SUCCESS;
  1151. PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
  1152. BOOL fSuccess = FALSE;
  1153. DWORD cbData = 0;
  1154. ANSI_STRING AnsiString;
  1155. UNICODE_STRING UnicodeString;
  1156. BOOL fFreeAnsiString = FALSE;
  1157. LOCAL_CALL_INFO LocalCallInfo;
  1158. PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
  1159. BOOL fContinue = TRUE;
  1160. memset(&AnsiString, 0, sizeof(AnsiString));
  1161. memset(&UnicodeString, 0, sizeof(UnicodeString));
  1162. InitializeLocalCallInfo(&LocalCallInfo);
  1163. //
  1164. // First, see if the local CSP wants to service this call
  1165. //
  1166. if (pLocalCspInfo->pfnLocalGetProvParam)
  1167. {
  1168. dwSts = pLocalCspInfo->pfnLocalGetProvParam(
  1169. pUserCtx,
  1170. dwParam,
  1171. pbData,
  1172. pcbDataLen,
  1173. dwFlags,
  1174. &LocalCallInfo);
  1175. if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
  1176. goto Ret;
  1177. }
  1178. //
  1179. // Some prov params are general enough to be serviced "globally"
  1180. // by this lib.
  1181. // Try those before calling the support CSP.
  1182. //
  1183. switch (dwParam)
  1184. {
  1185. case PP_CONTAINER:
  1186. fContinue = FALSE;
  1187. RtlInitUnicodeString(
  1188. &UnicodeString,
  1189. pUserCtx->wszBaseContainerName);
  1190. dwSts = RtlUnicodeStringToAnsiString(
  1191. &AnsiString,
  1192. &UnicodeString,
  1193. TRUE);
  1194. if (STATUS_SUCCESS != dwSts)
  1195. {
  1196. dwSts = RtlNtStatusToDosError(dwSts);
  1197. goto Ret;
  1198. }
  1199. fFreeAnsiString = TRUE;
  1200. cbData = strlen(AnsiString.Buffer) + 1;
  1201. if (*pcbDataLen < cbData || NULL == pbData)
  1202. {
  1203. *pcbDataLen = cbData;
  1204. if (NULL != pbData)
  1205. dwSts = ERROR_MORE_DATA;
  1206. else
  1207. fSuccess = TRUE;
  1208. break;
  1209. }
  1210. *pcbDataLen = cbData;
  1211. strcpy((LPSTR) pbData, AnsiString.Buffer);
  1212. fSuccess = TRUE;
  1213. break;
  1214. case PP_UNIQUE_CONTAINER:
  1215. fContinue = FALSE;
  1216. RtlInitUnicodeString(
  1217. &UnicodeString,
  1218. pUserCtx->wszUniqueContainerName);
  1219. dwSts = RtlUnicodeStringToAnsiString(
  1220. &AnsiString,
  1221. &UnicodeString,
  1222. TRUE);
  1223. if (STATUS_SUCCESS != dwSts)
  1224. {
  1225. dwSts = RtlNtStatusToDosError(dwSts);
  1226. goto Ret;
  1227. }
  1228. fFreeAnsiString = TRUE;
  1229. cbData = strlen(AnsiString.Buffer) + 1;
  1230. if (*pcbDataLen < cbData || NULL == pbData)
  1231. {
  1232. *pcbDataLen = cbData;
  1233. if (NULL != pbData)
  1234. dwSts = ERROR_MORE_DATA;
  1235. else
  1236. fSuccess = TRUE;
  1237. break;
  1238. }
  1239. *pcbDataLen = cbData;
  1240. strcpy((LPSTR) pbData, AnsiString.Buffer);
  1241. fSuccess = TRUE;
  1242. break;
  1243. case PP_NAME:
  1244. fContinue = FALSE;
  1245. RtlInitUnicodeString(
  1246. &UnicodeString,
  1247. pLocalCspInfo->wszProviderName);
  1248. dwSts = RtlUnicodeStringToAnsiString(
  1249. &AnsiString,
  1250. &UnicodeString,
  1251. TRUE);
  1252. if (STATUS_SUCCESS != dwSts)
  1253. {
  1254. dwSts = RtlNtStatusToDosError(dwSts);
  1255. goto Ret;
  1256. }
  1257. fFreeAnsiString = TRUE;
  1258. cbData = strlen(AnsiString.Buffer) + 1;
  1259. if (*pcbDataLen < cbData || NULL == pbData)
  1260. {
  1261. *pcbDataLen = cbData;
  1262. if (NULL != pbData)
  1263. dwSts = ERROR_MORE_DATA;
  1264. else
  1265. fSuccess = TRUE;
  1266. break;
  1267. }
  1268. *pcbDataLen = cbData;
  1269. strcpy((LPSTR) pbData, AnsiString.Buffer);
  1270. fSuccess = TRUE;
  1271. break;
  1272. case PP_PROVTYPE:
  1273. fContinue = FALSE;
  1274. if (*pcbDataLen < sizeof(DWORD) || NULL == pbData)
  1275. {
  1276. *pcbDataLen = sizeof(DWORD);
  1277. if (NULL != pbData)
  1278. dwSts = ERROR_MORE_DATA;
  1279. else
  1280. fSuccess = TRUE;
  1281. break;
  1282. }
  1283. *pcbDataLen = sizeof(DWORD);
  1284. memcpy(
  1285. pbData,
  1286. (PBYTE) &pLocalCspInfo->dwProviderType,
  1287. sizeof(DWORD));
  1288. fSuccess = TRUE;
  1289. break;
  1290. case PP_IMPTYPE:
  1291. fContinue = FALSE;
  1292. if (*pcbDataLen < sizeof(DWORD) || NULL == pbData)
  1293. {
  1294. *pcbDataLen = sizeof(DWORD);
  1295. if (NULL != pbData)
  1296. dwSts = ERROR_MORE_DATA;
  1297. else
  1298. fSuccess = TRUE;
  1299. break;
  1300. }
  1301. *pcbDataLen = sizeof(DWORD);
  1302. memcpy(
  1303. pbData,
  1304. (PBYTE) &pLocalCspInfo->dwImplementationType,
  1305. sizeof(DWORD));
  1306. fSuccess = TRUE;
  1307. break;
  1308. }
  1309. if (FALSE == fContinue)
  1310. goto Ret;
  1311. //
  1312. // Try sending any request that hasn't been filtered by the above checks
  1313. // to the support CSP.
  1314. //
  1315. if (! CryptGetProvParam(
  1316. pUserCtx->hSupportProv,
  1317. dwParam,
  1318. pbData,
  1319. pcbDataLen,
  1320. dwFlags))
  1321. {
  1322. dwSts = GetLastError();
  1323. goto Ret;
  1324. }
  1325. fSuccess = TRUE;
  1326. Ret:
  1327. if (fFreeAnsiString)
  1328. RtlFreeAnsiString(&AnsiString);
  1329. if (FALSE == fSuccess)
  1330. SetLastError(dwSts);
  1331. return fSuccess;
  1332. }
  1333. /*
  1334. - CPSetHashParam
  1335. -
  1336. * Purpose:
  1337. * Allows applications to customize various aspects of the
  1338. * operations of a hash
  1339. *
  1340. * Parameters:
  1341. * IN hProv - Handle to a CSP
  1342. * IN hHash - Handle to a hash
  1343. * IN dwParam - Parameter number
  1344. * IN pbData - Pointer to data
  1345. * IN dwFlags - Flags values
  1346. *
  1347. * Returns:
  1348. */
  1349. BOOL WINAPI
  1350. CPSetHashParam(
  1351. IN HCRYPTPROV hProv,
  1352. IN HCRYPTHASH hHash,
  1353. IN DWORD dwParam,
  1354. IN CONST BYTE *pbData,
  1355. IN DWORD dwFlags)
  1356. {
  1357. BOOL fSuccess = FALSE;
  1358. PHASH_CONTEXT pHashCtx = (PHASH_CONTEXT) hHash;
  1359. LOCAL_CALL_INFO LocalCallInfo;
  1360. PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
  1361. DWORD dwSts = ERROR_SUCCESS;
  1362. InitializeLocalCallInfo(&LocalCallInfo);
  1363. if (pLocalCspInfo->pfnLocalSetHashParam)
  1364. {
  1365. dwSts = pLocalCspInfo->pfnLocalSetHashParam(
  1366. pHashCtx,
  1367. dwParam,
  1368. (PBYTE) pbData,
  1369. dwFlags,
  1370. &LocalCallInfo);
  1371. if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
  1372. goto Ret;
  1373. }
  1374. if (! CryptSetHashParam(
  1375. pHashCtx->hSupportHash,
  1376. dwParam,
  1377. pbData,
  1378. dwFlags))
  1379. {
  1380. dwSts = GetLastError();
  1381. goto Ret;
  1382. }
  1383. fSuccess = TRUE;
  1384. Ret:
  1385. if (FALSE == fSuccess)
  1386. SetLastError(dwSts);
  1387. return fSuccess;
  1388. }
  1389. /*
  1390. - CPGetHashParam
  1391. -
  1392. * Purpose:
  1393. * Allows applications to get various aspects of the
  1394. * operations of a hash
  1395. *
  1396. * Parameters:
  1397. * IN hProv - Handle to a CSP
  1398. * IN hHash - Handle to a hash
  1399. * IN dwParam - Parameter number
  1400. * OUT pbData - Pointer to data
  1401. * IN pdwDataLen - Length of parameter data
  1402. * IN dwFlags - Flags values
  1403. *
  1404. * Returns:
  1405. */
  1406. BOOL WINAPI
  1407. CPGetHashParam(
  1408. IN HCRYPTPROV hProv,
  1409. IN HCRYPTHASH hHash,
  1410. IN DWORD dwParam,
  1411. OUT LPBYTE pbData,
  1412. IN OUT LPDWORD pcbDataLen,
  1413. IN DWORD dwFlags)
  1414. {
  1415. BOOL fSuccess = FALSE;
  1416. PHASH_CONTEXT pHashCtx = (PHASH_CONTEXT) hHash;
  1417. LOCAL_CALL_INFO LocalCallInfo;
  1418. PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
  1419. DWORD dwSts = ERROR_SUCCESS;
  1420. InitializeLocalCallInfo(&LocalCallInfo);
  1421. if (pLocalCspInfo->pfnLocalGetHashParam)
  1422. {
  1423. dwSts = pLocalCspInfo->pfnLocalGetHashParam(
  1424. pHashCtx,
  1425. dwParam,
  1426. pbData,
  1427. pcbDataLen,
  1428. dwFlags,
  1429. &LocalCallInfo);
  1430. if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
  1431. goto Ret;
  1432. }
  1433. if (! CryptGetHashParam(
  1434. pHashCtx->hSupportHash,
  1435. dwParam,
  1436. pbData,
  1437. pcbDataLen,
  1438. dwFlags))
  1439. {
  1440. dwSts = GetLastError();
  1441. goto Ret;
  1442. }
  1443. fSuccess = TRUE;
  1444. Ret:
  1445. if (FALSE == fSuccess)
  1446. SetLastError(dwSts);
  1447. return fSuccess;
  1448. }
  1449. /*
  1450. - CPExportKey
  1451. -
  1452. * Purpose:
  1453. * Export cryptographic keys out of a CSP in a secure manner
  1454. *
  1455. *
  1456. * Parameters:
  1457. * IN hProv - Handle to the CSP user
  1458. * IN hKey - Handle to the key to export
  1459. * IN hPubKey - Handle to exchange public key value of
  1460. * the destination user
  1461. * IN dwBlobType - Type of key blob to be exported
  1462. * IN dwFlags - Flags values
  1463. * OUT pbData - Key blob data
  1464. * IN OUT pdwDataLen - Length of key blob in bytes
  1465. *
  1466. * Returns:
  1467. */
  1468. BOOL WINAPI
  1469. CPExportKey(
  1470. IN HCRYPTPROV hProv,
  1471. IN HCRYPTKEY hKey,
  1472. IN HCRYPTKEY hPubKey,
  1473. IN DWORD dwBlobType,
  1474. IN DWORD dwFlags,
  1475. OUT LPBYTE pbData,
  1476. IN OUT LPDWORD pcbDataLen)
  1477. {
  1478. BOOL fSuccess = FALSE;
  1479. DWORD dwSts = ERROR_SUCCESS;
  1480. PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
  1481. PKEY_CONTEXT pKeyCtx = (PKEY_CONTEXT) hKey;
  1482. PKEY_CONTEXT pPubKeyCtx = (PKEY_CONTEXT) hPubKey;
  1483. LOCAL_CALL_INFO LocalCallInfo;
  1484. PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
  1485. InitializeLocalCallInfo(&LocalCallInfo);
  1486. if (pLocalCspInfo->pfnLocalExportKey)
  1487. {
  1488. dwSts = pLocalCspInfo->pfnLocalExportKey(
  1489. pKeyCtx,
  1490. pPubKeyCtx,
  1491. dwBlobType,
  1492. dwFlags,
  1493. pbData,
  1494. pcbDataLen,
  1495. &LocalCallInfo);
  1496. if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
  1497. goto Ret;
  1498. }
  1499. if (! CryptExportKey(
  1500. pKeyCtx->hSupportKey,
  1501. pPubKeyCtx ? pPubKeyCtx->hSupportKey : 0,
  1502. dwBlobType,
  1503. dwFlags,
  1504. pbData,
  1505. pcbDataLen))
  1506. {
  1507. dwSts = GetLastError();
  1508. goto Ret;
  1509. }
  1510. fSuccess = TRUE;
  1511. Ret:
  1512. if (FALSE == fSuccess)
  1513. SetLastError(dwSts);
  1514. return fSuccess;
  1515. }
  1516. /*
  1517. - CPImportKey
  1518. -
  1519. * Purpose:
  1520. * Import cryptographic keys
  1521. *
  1522. *
  1523. * Parameters:
  1524. * IN hProv - Handle to the CSP user
  1525. * IN pbData - Key blob data
  1526. * IN dwDataLen - Length of the key blob data
  1527. * IN hPubKey - Handle to the exchange public key value of
  1528. * the destination user
  1529. * IN dwFlags - Flags values
  1530. * OUT phKey - Pointer to the handle to the key which was
  1531. * Imported
  1532. *
  1533. * Returns:
  1534. */
  1535. BOOL WINAPI
  1536. CPImportKey(
  1537. IN HCRYPTPROV hProv,
  1538. IN CONST BYTE *pbData,
  1539. IN DWORD cbDataLen,
  1540. IN HCRYPTKEY hPubKey,
  1541. IN DWORD dwFlags,
  1542. OUT HCRYPTKEY *phKey)
  1543. {
  1544. BOOL fSuccess = FALSE;
  1545. DWORD dwSts = ERROR_SUCCESS;
  1546. PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
  1547. PKEY_CONTEXT pKeyCtx = NULL;
  1548. PKEY_CONTEXT pPubKeyCtx = (PKEY_CONTEXT) hPubKey;
  1549. LOCAL_CALL_INFO LocalCallInfo;
  1550. PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
  1551. *phKey = 0;
  1552. InitializeLocalCallInfo(&LocalCallInfo);
  1553. pKeyCtx = (PKEY_CONTEXT) CspAllocH(sizeof(KEY_CONTEXT));
  1554. LOG_CHECK_ALLOC(pKeyCtx);
  1555. pKeyCtx->dwFlags = dwFlags & 0x0000ffff;
  1556. pKeyCtx->pUserContext = pUserCtx;
  1557. if (pLocalCspInfo->pfnLocalImportKey)
  1558. {
  1559. dwSts = pLocalCspInfo->pfnLocalImportKey(
  1560. pKeyCtx,
  1561. (PBYTE) pbData,
  1562. cbDataLen,
  1563. pPubKeyCtx,
  1564. &LocalCallInfo);
  1565. if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
  1566. goto Ret;
  1567. }
  1568. if (! CryptImportKey(
  1569. pUserCtx->hSupportProv,
  1570. pbData,
  1571. cbDataLen,
  1572. pPubKeyCtx ? pPubKeyCtx->hSupportKey : 0,
  1573. dwFlags,
  1574. &pKeyCtx->hSupportKey))
  1575. {
  1576. dwSts = GetLastError();
  1577. goto Ret;
  1578. }
  1579. fSuccess = TRUE;
  1580. Ret:
  1581. if (TRUE == fSuccess)
  1582. {
  1583. *phKey = (HCRYPTKEY) pKeyCtx;
  1584. pKeyCtx = NULL;
  1585. }
  1586. if (pKeyCtx)
  1587. {
  1588. DeleteKeyContext(pKeyCtx);
  1589. CspFreeH(pKeyCtx);
  1590. }
  1591. if (FALSE == fSuccess)
  1592. SetLastError(dwSts);
  1593. return fSuccess;
  1594. }
  1595. /*
  1596. - CPEncrypt
  1597. -
  1598. * Purpose:
  1599. * Encrypt data
  1600. *
  1601. *
  1602. * Parameters:
  1603. * IN hProv - Handle to the CSP user
  1604. * IN hKey - Handle to the key
  1605. * IN hHash - Optional handle to a hash
  1606. * IN Final - Boolean indicating if this is the final
  1607. * block of plaintext
  1608. * IN dwFlags - Flags values
  1609. * IN OUT pbData - Data to be encrypted
  1610. * IN OUT pdwDataLen - Pointer to the length of the data to be
  1611. * encrypted
  1612. * IN dwBufLen - Size of Data buffer
  1613. *
  1614. * Returns:
  1615. */
  1616. BOOL WINAPI
  1617. CPEncrypt(
  1618. IN HCRYPTPROV hProv,
  1619. IN HCRYPTKEY hKey,
  1620. IN HCRYPTHASH hHash,
  1621. IN BOOL fFinal,
  1622. IN DWORD dwFlags,
  1623. IN OUT LPBYTE pbData,
  1624. IN OUT LPDWORD pcbDataLen,
  1625. IN DWORD cbBufLen)
  1626. {
  1627. BOOL fSuccess = FALSE;
  1628. DWORD dwSts = ERROR_SUCCESS;
  1629. PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
  1630. PKEY_CONTEXT pKeyCtx = (PKEY_CONTEXT) hKey;
  1631. PHASH_CONTEXT pHashCtx = (PHASH_CONTEXT) hHash;
  1632. LOCAL_CALL_INFO LocalCallInfo;
  1633. PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
  1634. *pcbDataLen = 0;
  1635. InitializeLocalCallInfo(&LocalCallInfo);
  1636. if (pLocalCspInfo->pfnLocalEncrypt)
  1637. {
  1638. dwSts = pLocalCspInfo->pfnLocalEncrypt(
  1639. pKeyCtx,
  1640. pHashCtx,
  1641. fFinal,
  1642. dwFlags,
  1643. pbData,
  1644. pcbDataLen,
  1645. cbBufLen,
  1646. &LocalCallInfo);
  1647. if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
  1648. goto Ret;
  1649. }
  1650. if (! CryptEncrypt(
  1651. pKeyCtx->hSupportKey,
  1652. pHashCtx ? pHashCtx->hSupportHash : 0,
  1653. fFinal,
  1654. dwFlags,
  1655. pbData,
  1656. pcbDataLen,
  1657. cbBufLen))
  1658. {
  1659. dwSts = GetLastError();
  1660. goto Ret;
  1661. }
  1662. fSuccess = TRUE;
  1663. Ret:
  1664. if (FALSE == fSuccess)
  1665. SetLastError(dwSts);
  1666. return fSuccess;
  1667. }
  1668. /*
  1669. - CPDecrypt
  1670. -
  1671. * Purpose:
  1672. * Decrypt data
  1673. *
  1674. *
  1675. * Parameters:
  1676. * IN hProv - Handle to the CSP user
  1677. * IN hKey - Handle to the key
  1678. * IN hHash - Optional handle to a hash
  1679. * IN Final - Boolean indicating if this is the final
  1680. * block of ciphertext
  1681. * IN dwFlags - Flags values
  1682. * IN OUT pbData - Data to be decrypted
  1683. * IN OUT pdwDataLen - Pointer to the length of the data to be
  1684. * decrypted
  1685. *
  1686. * Returns:
  1687. */
  1688. BOOL WINAPI
  1689. CPDecrypt(
  1690. IN HCRYPTPROV hProv,
  1691. IN HCRYPTKEY hKey,
  1692. IN HCRYPTHASH hHash,
  1693. IN BOOL fFinal,
  1694. IN DWORD dwFlags,
  1695. IN OUT LPBYTE pbData,
  1696. IN OUT LPDWORD pcbDataLen)
  1697. {
  1698. BOOL fSuccess = FALSE;
  1699. DWORD dwSts = ERROR_SUCCESS;
  1700. PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
  1701. PKEY_CONTEXT pKeyCtx = (PKEY_CONTEXT) hKey;
  1702. PHASH_CONTEXT pHashCtx = (PHASH_CONTEXT) hHash;
  1703. LOCAL_CALL_INFO LocalCallInfo;
  1704. PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
  1705. InitializeLocalCallInfo(&LocalCallInfo);
  1706. if (pLocalCspInfo->pfnLocalDecrypt)
  1707. {
  1708. dwSts = pLocalCspInfo->pfnLocalDecrypt(
  1709. pKeyCtx,
  1710. pHashCtx,
  1711. fFinal,
  1712. dwFlags,
  1713. pbData,
  1714. pcbDataLen,
  1715. &LocalCallInfo);
  1716. if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
  1717. goto Ret;
  1718. }
  1719. if (! CryptDecrypt(
  1720. pKeyCtx->hSupportKey,
  1721. pHashCtx ? pHashCtx->hSupportHash : 0,
  1722. fFinal,
  1723. dwFlags,
  1724. pbData,
  1725. pcbDataLen))
  1726. {
  1727. dwSts = GetLastError();
  1728. goto Ret;
  1729. }
  1730. fSuccess = TRUE;
  1731. Ret:
  1732. if (FALSE == fSuccess)
  1733. SetLastError(dwSts);
  1734. return fSuccess;
  1735. }
  1736. /*
  1737. - CPCreateHash
  1738. -
  1739. * Purpose:
  1740. * initate the hashing of a stream of data
  1741. *
  1742. *
  1743. * Parameters:
  1744. * IN hUID - Handle to the user identifcation
  1745. * IN Algid - Algorithm identifier of the hash algorithm
  1746. * to be used
  1747. * IN hKey - Optional handle to a key
  1748. * IN dwFlags - Flags values
  1749. * OUT pHash - Handle to hash object
  1750. *
  1751. * Returns:
  1752. */
  1753. BOOL WINAPI
  1754. CPCreateHash(
  1755. IN HCRYPTPROV hProv,
  1756. IN ALG_ID Algid,
  1757. IN HCRYPTKEY hKey,
  1758. IN DWORD dwFlags,
  1759. OUT HCRYPTHASH *phHash)
  1760. {
  1761. BOOL fSuccess = FALSE;
  1762. PHASH_CONTEXT pHashCtx = NULL;
  1763. PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
  1764. PKEY_CONTEXT pKeyCtx = (PKEY_CONTEXT) hKey;
  1765. DWORD dwSts = ERROR_SUCCESS;
  1766. LOCAL_CALL_INFO LocalCallInfo;
  1767. PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
  1768. *phHash = 0;
  1769. InitializeLocalCallInfo(&LocalCallInfo);
  1770. pHashCtx = (PHASH_CONTEXT) CspAllocH(sizeof(HASH_CONTEXT));
  1771. LOG_CHECK_ALLOC(pHashCtx);
  1772. pHashCtx->Algid = Algid;
  1773. pHashCtx->dwFlags = dwFlags;
  1774. pHashCtx->pUserContext = pUserCtx;
  1775. if (pLocalCspInfo->pfnLocalCreateHash)
  1776. {
  1777. dwSts = pLocalCspInfo->pfnLocalCreateHash(
  1778. pHashCtx,
  1779. pKeyCtx,
  1780. &LocalCallInfo);
  1781. if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
  1782. goto Ret;
  1783. }
  1784. if (! CryptCreateHash(
  1785. pUserCtx->hSupportProv,
  1786. Algid,
  1787. pKeyCtx ? pKeyCtx->hSupportKey : 0,
  1788. dwFlags,
  1789. &pHashCtx->hSupportHash))
  1790. {
  1791. dwSts = GetLastError();
  1792. goto Ret;
  1793. }
  1794. *phHash = (HCRYPTHASH) pHashCtx;
  1795. pHashCtx = NULL;
  1796. fSuccess = TRUE;
  1797. Ret:
  1798. if (pHashCtx)
  1799. {
  1800. DeleteHashContext(pHashCtx);
  1801. CspFreeH(pHashCtx);
  1802. }
  1803. if (FALSE == fSuccess)
  1804. SetLastError(dwSts);
  1805. return fSuccess;
  1806. }
  1807. /*
  1808. - CPHashData
  1809. -
  1810. * Purpose:
  1811. * Compute the cryptograghic hash on a stream of data
  1812. *
  1813. *
  1814. * Parameters:
  1815. * IN hProv - Handle to the user identifcation
  1816. * IN hHash - Handle to hash object
  1817. * IN pbData - Pointer to data to be hashed
  1818. * IN dwDataLen - Length of the data to be hashed
  1819. * IN dwFlags - Flags values
  1820. *
  1821. * Returns:
  1822. */
  1823. BOOL WINAPI
  1824. CPHashData(
  1825. IN HCRYPTPROV hProv,
  1826. IN HCRYPTHASH hHash,
  1827. IN CONST BYTE *pbData,
  1828. IN DWORD cbDataLen,
  1829. IN DWORD dwFlags)
  1830. {
  1831. BOOL fSuccess = FALSE;
  1832. PHASH_CONTEXT pHashCtx = (PHASH_CONTEXT) hHash;
  1833. PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
  1834. DWORD dwSts = ERROR_SUCCESS;
  1835. LOCAL_CALL_INFO LocalCallInfo;
  1836. PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
  1837. InitializeLocalCallInfo(&LocalCallInfo);
  1838. if (pLocalCspInfo->pfnLocalHashData)
  1839. {
  1840. dwSts = pLocalCspInfo->pfnLocalHashData(
  1841. pHashCtx,
  1842. pbData,
  1843. cbDataLen,
  1844. dwFlags,
  1845. &LocalCallInfo);
  1846. if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
  1847. goto Ret;
  1848. }
  1849. if (! CryptHashData(
  1850. pHashCtx->hSupportHash,
  1851. pbData,
  1852. cbDataLen,
  1853. dwFlags))
  1854. {
  1855. dwSts = GetLastError();
  1856. goto Ret;
  1857. }
  1858. fSuccess = TRUE;
  1859. Ret:
  1860. if (FALSE == fSuccess)
  1861. SetLastError(dwSts);
  1862. return fSuccess;
  1863. }
  1864. /*
  1865. - CPHashSessionKey
  1866. -
  1867. * Purpose:
  1868. * Compute the cryptograghic hash on a key object.
  1869. *
  1870. *
  1871. * Parameters:
  1872. * IN hProv - Handle to the user identifcation
  1873. * IN hHash - Handle to hash object
  1874. * IN hKey - Handle to a key object
  1875. * IN dwFlags - Flags values
  1876. *
  1877. * Returns:
  1878. * CRYPT_FAILED
  1879. * CRYPT_SUCCEED
  1880. */
  1881. BOOL WINAPI
  1882. CPHashSessionKey(
  1883. IN HCRYPTPROV hProv,
  1884. IN HCRYPTHASH hHash,
  1885. IN HCRYPTKEY hKey,
  1886. IN DWORD dwFlags)
  1887. {
  1888. BOOL fSuccess = FALSE;
  1889. PHASH_CONTEXT pHashCtx = (PHASH_CONTEXT) hHash;
  1890. PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
  1891. PKEY_CONTEXT pKeyCtx = (PKEY_CONTEXT) hKey;
  1892. DWORD dwSts = ERROR_SUCCESS;
  1893. LOCAL_CALL_INFO LocalCallInfo;
  1894. PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
  1895. InitializeLocalCallInfo(&LocalCallInfo);
  1896. if (pLocalCspInfo->pfnLocalHashSessionKey)
  1897. {
  1898. dwSts = pLocalCspInfo->pfnLocalHashSessionKey(
  1899. pHashCtx,
  1900. pKeyCtx,
  1901. dwFlags,
  1902. &LocalCallInfo);
  1903. if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
  1904. goto Ret;
  1905. }
  1906. if (! CryptHashSessionKey(
  1907. pHashCtx->hSupportHash,
  1908. pKeyCtx ? pKeyCtx->hSupportKey : 0,
  1909. dwFlags))
  1910. {
  1911. dwSts = GetLastError();
  1912. goto Ret;
  1913. }
  1914. fSuccess = TRUE;
  1915. Ret:
  1916. if (FALSE == fSuccess)
  1917. SetLastError(dwSts);
  1918. return fSuccess;
  1919. }
  1920. /*
  1921. - CPSignHash
  1922. -
  1923. * Purpose:
  1924. * Create a digital signature from a hash
  1925. *
  1926. *
  1927. * Parameters:
  1928. * IN hProv - Handle to the user identifcation
  1929. * IN hHash - Handle to hash object
  1930. * IN dwKeySpec - Key pair to that is used to sign with
  1931. * IN sDescription - Description of data to be signed
  1932. * IN dwFlags - Flags values
  1933. * OUT pbSignature - Pointer to signature data
  1934. * IN OUT dwHashLen - Pointer to the len of the signature data
  1935. *
  1936. * Returns:
  1937. */
  1938. BOOL WINAPI
  1939. CPSignHash(
  1940. IN HCRYPTPROV hProv,
  1941. IN HCRYPTHASH hHash,
  1942. IN DWORD dwKeySpec,
  1943. IN LPCWSTR szDescription,
  1944. IN DWORD dwFlags,
  1945. OUT LPBYTE pbSignature,
  1946. IN OUT LPDWORD pcbSigLen)
  1947. {
  1948. BOOL fSuccess = FALSE;
  1949. PHASH_CONTEXT pHashCtx = (PHASH_CONTEXT) hHash;
  1950. PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
  1951. DWORD dwSts = ERROR_SUCCESS;
  1952. LOCAL_CALL_INFO LocalCallInfo;
  1953. PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
  1954. InitializeLocalCallInfo(&LocalCallInfo);
  1955. if (pLocalCspInfo->pfnLocalSignHash)
  1956. {
  1957. dwSts = pLocalCspInfo->pfnLocalSignHash(
  1958. pHashCtx,
  1959. dwKeySpec,
  1960. dwFlags,
  1961. pbSignature,
  1962. pcbSigLen,
  1963. &LocalCallInfo);
  1964. if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
  1965. goto Ret;
  1966. }
  1967. if (! CryptSignHash(
  1968. pHashCtx->hSupportHash,
  1969. dwKeySpec,
  1970. NULL,
  1971. dwFlags,
  1972. pbSignature,
  1973. pcbSigLen))
  1974. {
  1975. dwSts = GetLastError();
  1976. goto Ret;
  1977. }
  1978. fSuccess = TRUE;
  1979. Ret:
  1980. if (FALSE == fSuccess)
  1981. SetLastError(dwSts);
  1982. return fSuccess;
  1983. }
  1984. /*
  1985. - CPDestroyHash
  1986. -
  1987. * Purpose:
  1988. * Destroy the hash object
  1989. *
  1990. *
  1991. * Parameters:
  1992. * IN hProv - Handle to the user identifcation
  1993. * IN hHash - Handle to hash object
  1994. *
  1995. * Returns:
  1996. */
  1997. BOOL WINAPI
  1998. CPDestroyHash(
  1999. IN HCRYPTPROV hProv,
  2000. IN HCRYPTHASH hHash)
  2001. {
  2002. PHASH_CONTEXT pHashCtx = (PHASH_CONTEXT) hHash;
  2003. DWORD dwSts = ERROR_SUCCESS;
  2004. dwSts = DeleteHashContext(pHashCtx);
  2005. CspFreeH(pHashCtx);
  2006. if (ERROR_SUCCESS != dwSts)
  2007. SetLastError(dwSts);
  2008. return (ERROR_SUCCESS == dwSts);
  2009. }
  2010. /*
  2011. - CPVerifySignature
  2012. -
  2013. * Purpose:
  2014. * Used to verify a signature against a hash object
  2015. *
  2016. *
  2017. * Parameters:
  2018. * IN hProv - Handle to the user identifcation
  2019. * IN hHash - Handle to hash object
  2020. * IN pbSignture - Pointer to signature data
  2021. * IN dwSigLen - Length of the signature data
  2022. * IN hPubKey - Handle to the public key for verifying
  2023. * the signature
  2024. * IN sDescription - String describing the signed data
  2025. * IN dwFlags - Flags values
  2026. *
  2027. * Returns:
  2028. */
  2029. BOOL WINAPI
  2030. CPVerifySignature(
  2031. IN HCRYPTPROV hProv,
  2032. IN HCRYPTHASH hHash,
  2033. IN CONST BYTE *pbSignature,
  2034. IN DWORD cbSigLen,
  2035. IN HCRYPTKEY hPubKey,
  2036. IN LPCWSTR szDescription,
  2037. IN DWORD dwFlags)
  2038. {
  2039. BOOL fSuccess = FALSE;
  2040. PHASH_CONTEXT pHashCtx = (PHASH_CONTEXT) hHash;
  2041. PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
  2042. PKEY_CONTEXT pPubKeyCtx = (PKEY_CONTEXT) hPubKey;
  2043. DWORD dwSts = ERROR_SUCCESS;
  2044. LOCAL_CALL_INFO LocalCallInfo;
  2045. PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
  2046. InitializeLocalCallInfo(&LocalCallInfo);
  2047. if (pLocalCspInfo->pfnLocalVerifySignature)
  2048. {
  2049. dwSts = pLocalCspInfo->pfnLocalVerifySignature(
  2050. pHashCtx,
  2051. pbSignature,
  2052. cbSigLen,
  2053. pPubKeyCtx,
  2054. dwFlags,
  2055. &LocalCallInfo);
  2056. if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
  2057. goto Ret;
  2058. }
  2059. if (! CryptVerifySignature(
  2060. pHashCtx->hSupportHash,
  2061. pbSignature,
  2062. cbSigLen,
  2063. pPubKeyCtx->hSupportKey,
  2064. NULL,
  2065. dwFlags))
  2066. {
  2067. dwSts = GetLastError();
  2068. goto Ret;
  2069. }
  2070. fSuccess = TRUE;
  2071. Ret:
  2072. if (FALSE == fSuccess)
  2073. SetLastError(dwSts);
  2074. return fSuccess;
  2075. }
  2076. /*
  2077. - CPGenRandom
  2078. -
  2079. * Purpose:
  2080. * Used to fill a buffer with random bytes
  2081. *
  2082. *
  2083. * Parameters:
  2084. * IN hProv - Handle to the user identifcation
  2085. * IN dwLen - Number of bytes of random data requested
  2086. * IN OUT pbBuffer - Pointer to the buffer where the random
  2087. * bytes are to be placed
  2088. *
  2089. * Returns:
  2090. */
  2091. BOOL WINAPI
  2092. CPGenRandom(
  2093. IN HCRYPTPROV hProv,
  2094. IN DWORD cbLen,
  2095. OUT LPBYTE pbBuffer)
  2096. {
  2097. BOOL fSuccess = FALSE;
  2098. PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
  2099. DWORD dwSts = ERROR_SUCCESS;
  2100. LOCAL_CALL_INFO LocalCallInfo;
  2101. PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
  2102. InitializeLocalCallInfo(&LocalCallInfo);
  2103. if (pLocalCspInfo->pfnLocalGenRandom)
  2104. {
  2105. dwSts = pLocalCspInfo->pfnLocalGenRandom(
  2106. pUserCtx,
  2107. cbLen,
  2108. pbBuffer,
  2109. &LocalCallInfo);
  2110. if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
  2111. goto Ret;
  2112. }
  2113. if (! CryptGenRandom(
  2114. pUserCtx->hSupportProv,
  2115. cbLen,
  2116. pbBuffer))
  2117. {
  2118. dwSts = GetLastError();
  2119. goto Ret;
  2120. }
  2121. fSuccess = TRUE;
  2122. Ret:
  2123. if (FALSE == fSuccess)
  2124. SetLastError(dwSts);
  2125. return fSuccess;
  2126. }
  2127. /*
  2128. - CPGetUserKey
  2129. -
  2130. * Purpose:
  2131. * Gets a handle to a permanent user key
  2132. *
  2133. *
  2134. * Parameters:
  2135. * IN hProv - Handle to the user identifcation
  2136. * IN dwKeySpec - Specification of the key to retrieve
  2137. * OUT phUserKey - Pointer to key handle of retrieved key
  2138. *
  2139. * Returns:
  2140. */
  2141. BOOL WINAPI
  2142. CPGetUserKey(
  2143. IN HCRYPTPROV hProv,
  2144. IN DWORD dwKeySpec,
  2145. OUT HCRYPTKEY *phUserKey)
  2146. {
  2147. BOOL fSuccess = FALSE;
  2148. PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
  2149. PKEY_CONTEXT pKeyCtx = NULL;
  2150. DWORD dwSts = ERROR_SUCCESS;
  2151. LOCAL_CALL_INFO LocalCallInfo;
  2152. PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
  2153. *phUserKey = 0;
  2154. InitializeLocalCallInfo(&LocalCallInfo);
  2155. pKeyCtx = (PKEY_CONTEXT) CspAllocH(sizeof(KEY_CONTEXT));
  2156. LOG_CHECK_ALLOC(pKeyCtx);
  2157. pKeyCtx->Algid = dwKeySpec;
  2158. pKeyCtx->pUserContext = pUserCtx;
  2159. if (pLocalCspInfo->pfnLocalGetUserKey)
  2160. {
  2161. dwSts = pLocalCspInfo->pfnLocalGetUserKey(
  2162. pKeyCtx,
  2163. &LocalCallInfo);
  2164. if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
  2165. goto Ret;
  2166. }
  2167. if (! CryptGetUserKey(
  2168. pUserCtx->hSupportProv,
  2169. dwKeySpec,
  2170. &pKeyCtx->hSupportKey))
  2171. {
  2172. dwSts = GetLastError();
  2173. goto Ret;
  2174. }
  2175. fSuccess = TRUE;
  2176. Ret:
  2177. if (fSuccess)
  2178. {
  2179. *phUserKey = (HCRYPTKEY) pKeyCtx;
  2180. pKeyCtx = NULL;
  2181. }
  2182. if (pKeyCtx)
  2183. {
  2184. DeleteKeyContext(pKeyCtx);
  2185. CspFreeH(pKeyCtx);
  2186. }
  2187. if (FALSE == fSuccess)
  2188. SetLastError(dwSts);
  2189. return fSuccess;
  2190. }
  2191. /*
  2192. - CPDuplicateHash
  2193. -
  2194. * Purpose:
  2195. * Duplicates the state of a hash and returns a handle to it.
  2196. * This is an optional entry. Typically it only occurs in
  2197. * SChannel related CSPs.
  2198. *
  2199. * Parameters:
  2200. * IN hUID - Handle to a CSP
  2201. * IN hHash - Handle to a hash
  2202. * IN pdwReserved - Reserved
  2203. * IN dwFlags - Flags
  2204. * IN phHash - Handle to the new hash
  2205. *
  2206. * Returns:
  2207. */
  2208. BOOL WINAPI
  2209. CPDuplicateHash(
  2210. IN HCRYPTPROV hProv,
  2211. IN HCRYPTHASH hHash,
  2212. IN LPDWORD pdwReserved,
  2213. IN DWORD dwFlags,
  2214. OUT HCRYPTHASH *phHash)
  2215. {
  2216. PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
  2217. PHASH_CONTEXT pHashCtx = (PHASH_CONTEXT) hHash;
  2218. PHASH_CONTEXT pNewHashCtx = NULL;
  2219. DWORD dwSts = ERROR_SUCCESS;
  2220. BOOL fSuccess = FALSE;
  2221. PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
  2222. LOCAL_CALL_INFO LocalCallInfo;
  2223. *phHash = 0;
  2224. InitializeLocalCallInfo(&LocalCallInfo);
  2225. pNewHashCtx = (PHASH_CONTEXT) CspAllocH(sizeof(HASH_CONTEXT));
  2226. LOG_CHECK_ALLOC(pNewHashCtx);
  2227. pNewHashCtx->pUserContext = pUserCtx;
  2228. pNewHashCtx->dwFlags = dwFlags;
  2229. if (pLocalCspInfo->pfnLocalDuplicateHash)
  2230. {
  2231. dwSts = pLocalCspInfo->pfnLocalDuplicateHash(
  2232. pHashCtx,
  2233. pdwReserved,
  2234. pNewHashCtx,
  2235. &LocalCallInfo);
  2236. if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
  2237. goto Ret;
  2238. }
  2239. if (! CryptDuplicateHash(
  2240. pHashCtx->hSupportHash,
  2241. pdwReserved,
  2242. dwFlags,
  2243. &pNewHashCtx->hSupportHash))
  2244. {
  2245. dwSts = GetLastError();
  2246. goto Ret;
  2247. }
  2248. *phHash = (HCRYPTHASH) pNewHashCtx;
  2249. pNewHashCtx = NULL;
  2250. fSuccess = TRUE;
  2251. Ret:
  2252. if (pNewHashCtx)
  2253. {
  2254. DeleteHashContext(pNewHashCtx);
  2255. CspFreeH(pNewHashCtx);
  2256. }
  2257. if (FALSE == fSuccess)
  2258. SetLastError(dwSts);
  2259. return fSuccess;
  2260. }
  2261. /*
  2262. - CPDuplicateKey
  2263. -
  2264. * Purpose:
  2265. * Duplicates the state of a key and returns a handle to it.
  2266. * This is an optional entry. Typically it only occurs in
  2267. * SChannel related CSPs.
  2268. *
  2269. * Parameters:
  2270. * IN hUID - Handle to a CSP
  2271. * IN hKey - Handle to a key
  2272. * IN pdwReserved - Reserved
  2273. * IN dwFlags - Flags
  2274. * IN phKey - Handle to the new key
  2275. *
  2276. * Returns:
  2277. */
  2278. BOOL WINAPI
  2279. CPDuplicateKey(
  2280. IN HCRYPTPROV hProv,
  2281. IN HCRYPTKEY hKey,
  2282. IN LPDWORD pdwReserved,
  2283. IN DWORD dwFlags,
  2284. OUT HCRYPTKEY *phKey)
  2285. {
  2286. PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
  2287. PKEY_CONTEXT pKeyCtx = (PKEY_CONTEXT) hKey;
  2288. PKEY_CONTEXT pNewKeyCtx = NULL;
  2289. BOOL fSuccess = FALSE;
  2290. DWORD dwSts = ERROR_SUCCESS;
  2291. LOCAL_CALL_INFO LocalCallInfo;
  2292. PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
  2293. *phKey = 0;
  2294. InitializeLocalCallInfo(&LocalCallInfo);
  2295. pNewKeyCtx = (PKEY_CONTEXT) CspAllocH(sizeof(KEY_CONTEXT));
  2296. LOG_CHECK_ALLOC(pNewKeyCtx);
  2297. pNewKeyCtx->pUserContext = pUserCtx;
  2298. pNewKeyCtx->dwFlags = dwFlags;
  2299. if (pLocalCspInfo->pfnLocalDuplicateKey)
  2300. {
  2301. dwSts = pLocalCspInfo->pfnLocalDuplicateKey(
  2302. pKeyCtx,
  2303. pdwReserved,
  2304. pNewKeyCtx,
  2305. &LocalCallInfo);
  2306. if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
  2307. goto Ret;
  2308. }
  2309. if (! CryptDuplicateKey(
  2310. pKeyCtx->hSupportKey,
  2311. pdwReserved,
  2312. dwFlags,
  2313. &pNewKeyCtx->hSupportKey))
  2314. {
  2315. dwSts = GetLastError();
  2316. goto Ret;
  2317. }
  2318. *phKey = (HCRYPTKEY) pNewKeyCtx;
  2319. pNewKeyCtx = NULL;
  2320. fSuccess = TRUE;
  2321. Ret:
  2322. if (pNewKeyCtx)
  2323. {
  2324. DeleteKeyContext(pNewKeyCtx);
  2325. CspFreeH(pNewKeyCtx);
  2326. }
  2327. if (FALSE == fSuccess)
  2328. SetLastError(dwSts);
  2329. return fSuccess;
  2330. }
  2331. //
  2332. // Function: DllInitialize
  2333. //
  2334. BOOL WINAPI
  2335. DllInitialize(
  2336. IN PVOID hmod,
  2337. IN ULONG Reason,
  2338. IN PCONTEXT Context) // Unused parameter
  2339. {
  2340. DWORD dwLen = 0;
  2341. static BOOL fLoadedStrings = FALSE;
  2342. static BOOL fInitializedCspState = FALSE;
  2343. BOOL fSuccess = FALSE;
  2344. PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
  2345. switch (Reason)
  2346. {
  2347. case DLL_PROCESS_ATTACH:
  2348. // Get our image name.
  2349. dwLen = GetModuleBaseName(
  2350. GetCurrentProcess(),
  2351. hmod,
  2352. l_szImagePath,
  2353. sizeof(l_szImagePath) / sizeof(l_szImagePath[0]));
  2354. if (0 == dwLen)
  2355. return FALSE;
  2356. DisableThreadLibraryCalls(hmod);
  2357. fSuccess = TRUE;
  2358. break;
  2359. case DLL_PROCESS_DETACH:
  2360. fSuccess = TRUE;
  2361. break;
  2362. }
  2363. if (pLocalCspInfo->pfnLocalDllInitialize)
  2364. {
  2365. fSuccess = pLocalCspInfo->pfnLocalDllInitialize(
  2366. hmod, Reason, Context);
  2367. }
  2368. return fSuccess;
  2369. }
  2370. //
  2371. // Function: DllRegisterServer
  2372. //
  2373. STDAPI
  2374. DllRegisterServer(
  2375. void)
  2376. {
  2377. HKEY hKey = 0;
  2378. DWORD dwVal = 0;
  2379. DWORD dwProvType = PROV_RSA_FULL;
  2380. DWORD dwSts = ERROR_SUCCESS;
  2381. PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
  2382. dwSts = RegOpenProviderKey(&hKey, KEY_ALL_ACCESS);
  2383. if (ERROR_SUCCESS != dwSts)
  2384. goto Ret;
  2385. //
  2386. // Set Image path
  2387. //
  2388. dwSts = RegSetValueExA(hKey, "Image Path", 0L, REG_SZ,
  2389. (LPBYTE) l_szImagePath,
  2390. strlen(l_szImagePath) + 1);
  2391. if (ERROR_SUCCESS != dwSts)
  2392. goto Ret;
  2393. //
  2394. // Set Type
  2395. //
  2396. dwSts = RegSetValueExA(hKey, "Type", 0L, REG_DWORD,
  2397. (LPBYTE) &pLocalCspInfo->dwProviderType,
  2398. sizeof(DWORD));
  2399. if (ERROR_SUCCESS != dwSts)
  2400. goto Ret;
  2401. //
  2402. // Place signature in file value
  2403. //
  2404. dwSts = RegSetValueExA(hKey, "SigInFile", 0L,
  2405. REG_DWORD, (LPBYTE)&dwVal,
  2406. sizeof(DWORD));
  2407. if (ERROR_SUCCESS != dwSts)
  2408. goto Ret;
  2409. //
  2410. // Add CSP default configuration
  2411. //
  2412. if (pLocalCspInfo->pfnLocalDllRegisterServer)
  2413. dwSts = pLocalCspInfo->pfnLocalDllRegisterServer();
  2414. Ret:
  2415. if (hKey)
  2416. RegCloseKey(hKey);
  2417. return dwSts;
  2418. }
  2419. //
  2420. // Function: DllUnregisterServer
  2421. //
  2422. STDAPI
  2423. DllUnregisterServer(
  2424. void)
  2425. {
  2426. PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
  2427. if (pLocalCspInfo->pfnLocalDllUnregisterServer)
  2428. return pLocalCspInfo->pfnLocalDllUnregisterServer();
  2429. else
  2430. return ERROR_SUCCESS;
  2431. }