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.

502 lines
12 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1996 - 1999
  6. //
  7. // File: capi.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "windows.h"
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <assert.h>
  14. #include <malloc.h>
  15. #include "crtem.h"
  16. #include "redir.h"
  17. #include "unicode.h"
  18. #ifndef _M_IX86
  19. BOOL
  20. WINAPI
  21. UnicodeDllMain(
  22. HMODULE hInst,
  23. ULONG ulReason,
  24. LPVOID lpReserved
  25. )
  26. {
  27. return TRUE;
  28. }
  29. #else
  30. #ifdef LINK_REDIR
  31. #define pfnAcquireContextW CryptAcquireContextW
  32. #define pfnSignHashW CryptSignHashW
  33. #define pfnVerifySignatureW CryptVerifySignatureW
  34. #define pfnSetProviderW CryptSetProviderW
  35. #define pfnEnumProvidersW CryptEnumProvidersW
  36. #else
  37. static HINSTANCE hCrypt = NULL;
  38. static LPSTR pszCryptName = "advapi32.dll";
  39. static CRYPTACQUIRECONTEXTW *pfnAcquireContextW = NULL;
  40. static CRYPTSIGNHASHW *pfnSignHashW = NULL;
  41. static CRYPTVERIFYSIGNATUREW *pfnVerifySignatureW = NULL;
  42. static CRYPTSETPROVIDERW *pfnSetProviderW = NULL;
  43. typedef WINADVAPI BOOL WINAPI CRYPTENUMPROVIDERSW(
  44. DWORD dwIndex,
  45. DWORD *pdwReserved,
  46. DWORD dwFlags,
  47. DWORD *pdwProvType,
  48. LPWSTR szTypeName,
  49. DWORD *pcbTypeName
  50. );
  51. static CRYPTENUMPROVIDERSW *pfnEnumProvidersW = NULL;
  52. #endif
  53. BOOL
  54. WINAPI
  55. UnicodeDllMain(
  56. HMODULE hInst,
  57. ULONG ulReason,
  58. LPVOID lpReserved)
  59. {
  60. #ifndef LINK_REDIR
  61. switch (ulReason) {
  62. case DLL_PROCESS_ATTACH:
  63. hCrypt = LoadLibraryA(pszCryptName);
  64. pfnAcquireContextW = (CRYPTACQUIRECONTEXTW*)GetProcAddress(
  65. hCrypt,
  66. "CryptAcquireContextW");
  67. pfnSignHashW = (CRYPTSIGNHASHW*)GetProcAddress(
  68. hCrypt,
  69. "CryptSignHashW");
  70. pfnVerifySignatureW = (CRYPTVERIFYSIGNATUREW*)GetProcAddress(
  71. hCrypt,
  72. "CryptVerifySignatureW");
  73. pfnSetProviderW = (CRYPTSETPROVIDERW*)GetProcAddress(
  74. hCrypt,
  75. "CryptSetProviderW");
  76. pfnEnumProvidersW = (CRYPTENUMPROVIDERSW*)GetProcAddress(
  77. hCrypt,
  78. "CryptEnumProvidersW");
  79. break;
  80. case DLL_PROCESS_DETACH:
  81. FreeLibrary( hCrypt);
  82. pfnAcquireContextW = NULL;
  83. pfnSignHashW = NULL;
  84. pfnVerifySignatureW = NULL;
  85. pfnSetProviderW = NULL;
  86. pfnEnumProvidersW = NULL;
  87. break;
  88. default:
  89. break;
  90. }
  91. #endif
  92. return TRUE;
  93. }
  94. BOOL WINAPI CryptAcquireContext9x(
  95. HCRYPTPROV *phProv,
  96. LPCWSTR lpContainer,
  97. LPCWSTR lpProvider,
  98. DWORD dwProvType,
  99. DWORD dwFlags) {
  100. BYTE rgb1[_MAX_PATH];
  101. BYTE rgb2[_MAX_PATH];
  102. char * szContainer = NULL;
  103. char * szProvider = NULL;
  104. LONG err;
  105. err = FALSE;
  106. if(
  107. MkMBStr(rgb1, _MAX_PATH, lpContainer, &szContainer) &&
  108. MkMBStr(rgb2, _MAX_PATH, lpProvider, &szProvider) )
  109. err = CryptAcquireContextA (
  110. phProv,
  111. szContainer,
  112. szProvider,
  113. dwProvType,
  114. dwFlags
  115. );
  116. FreeMBStr(rgb1, szContainer);
  117. FreeMBStr(rgb2, szProvider);
  118. return(err);
  119. }
  120. BOOL WINAPI CryptAcquireContextU(
  121. HCRYPTPROV *phProv,
  122. LPCWSTR lpContainer,
  123. LPCWSTR lpProvider,
  124. DWORD dwProvType,
  125. DWORD dwFlags) {
  126. // Bug in CyptAcquireContextW for NT4
  127. if(FIsWinNT5() && pfnAcquireContextW)
  128. return( pfnAcquireContextW (
  129. phProv,
  130. lpContainer,
  131. lpProvider,
  132. dwProvType,
  133. dwFlags
  134. ));
  135. else
  136. return( CryptAcquireContext9x (
  137. phProv,
  138. lpContainer,
  139. lpProvider,
  140. dwProvType,
  141. dwFlags
  142. ));
  143. }
  144. BOOL WINAPI CryptSignHash9x(
  145. HCRYPTHASH hHash,
  146. DWORD dwKeySpec,
  147. LPCWSTR lpDescription,
  148. DWORD dwFlags,
  149. BYTE *pbSignature,
  150. DWORD *pdwSigLen) {
  151. BYTE rgb[_MAX_PATH];
  152. char * szDescription;
  153. LONG err;
  154. err = FALSE;
  155. if(MkMBStr(rgb, _MAX_PATH, lpDescription, &szDescription))
  156. err = CryptSignHashA (
  157. hHash,
  158. dwKeySpec,
  159. szDescription,
  160. dwFlags,
  161. pbSignature,
  162. pdwSigLen
  163. );
  164. FreeMBStr(rgb, szDescription);
  165. return(err);
  166. }
  167. BOOL WINAPI CryptSignHashU(
  168. HCRYPTHASH hHash,
  169. DWORD dwKeySpec,
  170. LPCWSTR lpDescription,
  171. DWORD dwFlags,
  172. BYTE *pbSignature,
  173. DWORD *pdwSigLen) {
  174. if(FIsWinNT())
  175. return(pfnSignHashW (
  176. hHash,
  177. dwKeySpec,
  178. lpDescription,
  179. dwFlags,
  180. pbSignature,
  181. pdwSigLen
  182. ));
  183. else
  184. return(CryptSignHash9x (
  185. hHash,
  186. dwKeySpec,
  187. lpDescription,
  188. dwFlags,
  189. pbSignature,
  190. pdwSigLen
  191. ));
  192. }
  193. BOOL WINAPI CryptVerifySignature9x(
  194. HCRYPTHASH hHash,
  195. CONST BYTE *pbSignature,
  196. DWORD dwSigLen,
  197. HCRYPTKEY hPubKey,
  198. LPCWSTR lpDescription,
  199. DWORD dwFlags) {
  200. BYTE rgb[_MAX_PATH];
  201. char * szDescription;
  202. LONG err;
  203. err = FALSE;
  204. if(MkMBStr(rgb, _MAX_PATH, lpDescription, &szDescription))
  205. err = CryptVerifySignatureA (
  206. hHash,
  207. pbSignature,
  208. dwSigLen,
  209. hPubKey,
  210. szDescription,
  211. dwFlags
  212. );
  213. FreeMBStr(rgb, szDescription);
  214. return(err);
  215. }
  216. BOOL WINAPI CryptVerifySignatureU(
  217. HCRYPTHASH hHash,
  218. CONST BYTE *pbSignature,
  219. DWORD dwSigLen,
  220. HCRYPTKEY hPubKey,
  221. LPCWSTR lpDescription,
  222. DWORD dwFlags) {
  223. BYTE rgb[_MAX_PATH];
  224. char * szDescription;
  225. LONG err;
  226. if(FIsWinNT())
  227. return(pfnVerifySignatureW (
  228. hHash,
  229. pbSignature,
  230. dwSigLen,
  231. hPubKey,
  232. lpDescription,
  233. dwFlags
  234. ));
  235. else
  236. return(CryptVerifySignature9x (
  237. hHash,
  238. pbSignature,
  239. dwSigLen,
  240. hPubKey,
  241. lpDescription,
  242. dwFlags
  243. ));
  244. }
  245. BOOL WINAPI CryptSetProvider9x(
  246. LPCWSTR lpProvName,
  247. DWORD dwProvType) {
  248. BYTE rgb[_MAX_PATH];
  249. char * szProvName;
  250. LONG err;
  251. err = FALSE;
  252. if(MkMBStr(rgb, _MAX_PATH, lpProvName, &szProvName))
  253. err = CryptSetProviderA (
  254. szProvName,
  255. dwProvType
  256. );
  257. FreeMBStr(rgb, szProvName);
  258. return(err);
  259. }
  260. BOOL WINAPI CryptSetProviderU(
  261. LPCWSTR lpProvName,
  262. DWORD dwProvType) {
  263. if(FIsWinNT())
  264. return(pfnSetProviderW (
  265. lpProvName,
  266. dwProvType
  267. ));
  268. else
  269. return(CryptSetProvider9x (
  270. lpProvName,
  271. dwProvType
  272. ));
  273. }
  274. /*
  275. - CryptEnumProvidersU
  276. -
  277. * Purpose:
  278. * Enumerate the providers.
  279. *
  280. * Parameters:
  281. * IN dwIndex - Index to the providers to enumerate
  282. * IN pdwReserved - Reserved for future use
  283. * IN dwFlags - Flags parameter
  284. * OUT pdwProvType - The type of the provider
  285. * OUT pwszProvName - Name of the enumerated provider
  286. * IN OUT pcbProvName - Length of the enumerated provider
  287. *
  288. * Returns:
  289. * BOOL
  290. * Use get extended error information use GetLastError
  291. */
  292. #define PROVREG L"SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider"
  293. #define PROVTYPEREG L"Type"
  294. BOOL
  295. WINAPI CryptEnumProviders9x(
  296. IN DWORD dwIndex,
  297. IN DWORD *pdwReserved,
  298. IN DWORD dwFlags,
  299. OUT DWORD *pdwProvType,
  300. OUT LPWSTR pwszProvName,
  301. IN OUT DWORD *pcbProvName
  302. )
  303. {
  304. HKEY hRegKey = 0;
  305. HKEY hProvRegKey = 0;
  306. LONG err;
  307. DWORD cbClass;
  308. FILETIME ft;
  309. DWORD dwKeyType;
  310. DWORD cbProvType;
  311. DWORD dw;
  312. DWORD cSubKeys;
  313. DWORD cbMaxKeyName;
  314. DWORD cbMaxClass;
  315. DWORD cValues;
  316. DWORD cbMaxValName;
  317. DWORD cbMaxValData;
  318. LPWSTR pwszTmpProvName = NULL;
  319. DWORD cbTmpProvName;
  320. BOOL fRet = CRYPT_FAILED;
  321. if (NULL != pdwReserved)
  322. {
  323. SetLastError(ERROR_INVALID_PARAMETER);
  324. goto Ret;
  325. }
  326. if (0 != dwFlags)
  327. {
  328. SetLastError((DWORD)NTE_BAD_FLAGS);
  329. goto Ret;
  330. }
  331. if (ERROR_SUCCESS != (err = RegOpenKeyExU(HKEY_LOCAL_MACHINE,
  332. PROVREG,
  333. 0L, KEY_READ, &hRegKey)))
  334. {
  335. SetLastError((DWORD) err);
  336. goto Ret;
  337. }
  338. if (ERROR_SUCCESS != (err = RegQueryInfoKey(hRegKey,
  339. NULL,
  340. &cbClass,
  341. NULL,
  342. &cSubKeys,
  343. &cbMaxKeyName,
  344. &cbMaxClass,
  345. &cValues,
  346. &cbMaxValName,
  347. &cbMaxValData,
  348. NULL,
  349. &ft)))
  350. {
  351. SetLastError((DWORD) err);
  352. goto Ret;
  353. }
  354. cbMaxKeyName += sizeof(CHAR);
  355. if (NULL == (pwszTmpProvName = (LPWSTR) _alloca(cbMaxKeyName * sizeof(WCHAR))))
  356. {
  357. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  358. goto Ret;
  359. }
  360. if (ERROR_SUCCESS != (err = RegEnumKeyExU(hRegKey, dwIndex, pwszTmpProvName,
  361. &cbMaxKeyName, NULL,
  362. NULL, &cbClass, &ft)))
  363. {
  364. SetLastError((DWORD)err);
  365. goto Ret;
  366. }
  367. if (ERROR_SUCCESS != (err = RegOpenKeyExU(hRegKey,
  368. pwszTmpProvName,
  369. 0L, KEY_READ, &hProvRegKey)))
  370. {
  371. SetLastError((DWORD) err);
  372. goto Ret;
  373. }
  374. cbProvType = sizeof(dw);
  375. if (ERROR_SUCCESS != (err = RegQueryValueExU(hProvRegKey,
  376. PROVTYPEREG,
  377. NULL, &dwKeyType, (BYTE*)&dw,
  378. &cbProvType)))
  379. {
  380. SetLastError((DWORD) NTE_PROV_TYPE_ENTRY_BAD);
  381. goto Ret;
  382. }
  383. *pdwProvType = dw;
  384. cbTmpProvName = (wcslen(pwszTmpProvName) + 1) * sizeof(WCHAR);
  385. if (NULL != pwszProvName)
  386. {
  387. if (*pcbProvName < cbTmpProvName)
  388. {
  389. *pcbProvName = cbTmpProvName;
  390. SetLastError(ERROR_MORE_DATA);
  391. goto Ret;
  392. }
  393. wcscpy(pwszProvName, pwszTmpProvName);
  394. }
  395. *pcbProvName = cbTmpProvName;
  396. fRet = CRYPT_SUCCEED;
  397. Ret:
  398. if (hRegKey)
  399. RegCloseKey(hRegKey);
  400. if (hProvRegKey)
  401. RegCloseKey(hProvRegKey);
  402. return fRet;
  403. }
  404. BOOL
  405. WINAPI CryptEnumProvidersU(
  406. IN DWORD dwIndex,
  407. IN DWORD *pdwReserved,
  408. IN DWORD dwFlags,
  409. OUT DWORD *pdwProvType,
  410. OUT LPWSTR pwszProvName,
  411. IN OUT DWORD *pcbProvName
  412. )
  413. {
  414. if(FIsWinNT5() && pfnEnumProvidersW)
  415. return(pfnEnumProvidersW (
  416. dwIndex,
  417. pdwReserved,
  418. dwFlags,
  419. pdwProvType,
  420. pwszProvName,
  421. pcbProvName
  422. ));
  423. else
  424. return(CryptEnumProviders9x (
  425. dwIndex,
  426. pdwReserved,
  427. dwFlags,
  428. pdwProvType,
  429. pwszProvName,
  430. pcbProvName
  431. ));
  432. }
  433. #endif