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.

5603 lines
151 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. // FILE : cryptapi.c //
  3. // DESCRIPTION : Crypto API interface //
  4. // AUTHOR : //
  5. // HISTORY : //
  6. // Dec 6 1994 larrys New //
  7. // Jan 16 1995 larrys Added key verify //
  8. // Jan 25 1995 larrys Added thread safe //
  9. // Jan 27 1995 larrys Added Unicode support //
  10. // Feb 21 1995 larrys Added Unicode support for CryptAcquireContext //
  11. // Feb 21 1995 larrys Fixed Unicode problem in CryptAcquireContext //
  12. // Mar 08 1995 larrys Removed CryptGetLastError //
  13. // Mar 20 1995 larrys Removed Certificate APIs //
  14. // Mar 22 1995 larrys #ifdef in WIN95 code //
  15. // Apr 06 1995 larrys Increased signature key to 1024 bits //
  16. // Apr 07 1995 larrys Removed CryptConfigure //
  17. // Jun 14 1995 larrys Removed pointer from RSA key struct //
  18. // Jun 29 1995 larrys Changed AcquireContext //
  19. // Jul 17 1995 larrys Worked on AcquireContext //
  20. // Aug 01 1995 larrys Removed CryptTranslate //
  21. // And CryptDeinstallProvider //
  22. // Changed CryptInstallProvider to //
  23. // CryptSetProvider //
  24. // Aug 03 1995 larrys Cleanup //
  25. // Aug 10 1995 larrys CryptAcquireContext returns error //
  26. // NTE_BAD_KEYSEY_PARAM now //
  27. // Aug 14 1995 larrys Removed key exchange stuff //
  28. // Aug 17 1995 larrys Changed registry entry to decimcal //
  29. // Aug 23 1995 larrys Changed CryptFinishHash to CryptGetHashValue //
  30. // Aug 28 1995 larrys Removed parameter from CryptVerifySignature //
  31. // Aug 31 1995 larrys Remove GenRandom //
  32. // Sep 14 1995 larrys Code review changes //
  33. // Sep 26 1995 larrys Added Microsoft's signing key //
  34. // Sep 27 1995 larrys Updated with more review changes //
  35. // Oct 06 1995 larrys Added more APIs Get/SetHash/ProvParam //
  36. // Oct 12 1995 larrys Remove CryptGetHashValue //
  37. // Oct 20 1995 larrys Changed test key //
  38. // Oct 24 1995 larrys Removed return of KeySet name //
  39. // Oct 30 1995 larrys Removed WIN95 //
  40. // Nov 9 1995 larrys Disable BUILD1057 //
  41. // Nov 10 1995 larrys Fix a problem in EnterHashCritSec //
  42. // May 30 1996 larrys Added hWnd support //
  43. // Oct 10 1996 jeffspel Reordered SetLastErrors and save error on //
  44. // AcquireContext failure //
  45. // Mar 21 1997 jeffspel Added second tier signatures, new APIs //
  46. // Apr 11 1997 jeffspel Replace critical sections with interlocked //
  47. // inc/dec //
  48. // Oct 02 1997 jeffspel Add caching of CSPs to CryptAcquireContext //
  49. // Oct 10 1997 jeffspel Add verification scheme for signature in file //
  50. // //
  51. // Copyright (C) 1993 Microsoft Corporation All Rights Reserved //
  52. /////////////////////////////////////////////////////////////////////////////
  53. #include "advapi.h"
  54. #include "stdlib.h"
  55. #include <wincrypt.h> // Include here, since not included by LEAN_AND_MEAN
  56. #include <cspdk.h>
  57. #include <ntstatus.h>
  58. #include <rsa.h>
  59. #include <md5.h>
  60. #include <rc4.h>
  61. #include <winperf.h>
  62. #ifndef WIN95
  63. #include <wtypes.h>
  64. #endif
  65. #define IDR_PUBKEY1 102
  66. #ifdef WIN95
  67. #define RtlEqualMemory(a, b, c) memcmp(a, b, c) == 0
  68. #endif
  69. typedef struct _VTableStruc {
  70. // ******************** WARNING **********************************************
  71. // Do not place anything before these FARPROCs we init the table assuming
  72. // that the first Function to call is the first thing in the table.
  73. // ***************************************************************************
  74. FARPROC FuncAcquireContext;
  75. FARPROC FuncReleaseContext;
  76. FARPROC FuncGenKey;
  77. FARPROC FuncDeriveKey;
  78. FARPROC FuncDestroyKey;
  79. FARPROC FuncSetKeyParam;
  80. FARPROC FuncGetKeyParam;
  81. FARPROC FuncExportKey;
  82. FARPROC FuncImportKey;
  83. FARPROC FuncEncrypt;
  84. FARPROC FuncDecrypt;
  85. FARPROC FuncCreateHash;
  86. FARPROC FuncHashData;
  87. FARPROC FuncHashSessionKey;
  88. FARPROC FuncDestroyHash;
  89. FARPROC FuncSignHash;
  90. FARPROC FuncVerifySignature;
  91. FARPROC FuncGenRandom;
  92. FARPROC FuncGetUserKey;
  93. FARPROC FuncSetProvParam;
  94. FARPROC FuncGetProvParam;
  95. FARPROC FuncSetHashParam;
  96. FARPROC FuncGetHashParam;
  97. FARPROC FuncNULL;
  98. FARPROC OptionalFuncDuplicateKey;
  99. FARPROC OptionalFuncDuplicateHash;
  100. FARPROC OptionalFuncNULL;
  101. HANDLE DllHandle; // Handle to open DLL
  102. HCRYPTPROV hProv; // Handle to provider
  103. DWORD Version;
  104. DWORD Inuse;
  105. LONG RefCnt;
  106. } VTableStruc, *PVTableStruc;
  107. typedef struct _VKeyStruc {
  108. // ******************** WARNING **********************************************
  109. // Do not place anything before these FARPROCs we init the table assuming
  110. // that the first Function to call is the first thing in the table.
  111. // ***************************************************************************
  112. FARPROC FuncGenKey;
  113. FARPROC FuncDeriveKey;
  114. FARPROC FuncDestroyKey;
  115. FARPROC FuncSetKeyParam;
  116. FARPROC FuncGetKeyParam;
  117. FARPROC FuncExportKey;
  118. FARPROC FuncImportKey;
  119. FARPROC FuncEncrypt;
  120. FARPROC FuncDecrypt;
  121. FARPROC OptionalFuncDuplicateKey;
  122. HCRYPTPROV hProv; // Handle to provider
  123. HCRYPTKEY hKey; // Handle to key
  124. DWORD Version;
  125. DWORD Inuse;
  126. } VKeyStruc, *PVKeyStruc;
  127. typedef struct _VHashStruc {
  128. // ******************** WARNING **********************************************
  129. // Do not place anything before these FARPROCs we init the table assuming
  130. // that the first Function to call is the first thing in the table.
  131. // ***************************************************************************
  132. FARPROC FuncCreateHash;
  133. FARPROC FuncHashData;
  134. FARPROC FuncHashSessionKey;
  135. FARPROC FuncDestroyHash;
  136. FARPROC FuncSignHash;
  137. FARPROC FuncVerifySignature;
  138. FARPROC FuncSetHashParam;
  139. FARPROC FuncGetHashParam;
  140. FARPROC OptionalFuncDuplicateHash;
  141. HCRYPTPROV hProv; // Handle to provider
  142. HCRYPTHASH hHash; // Handle to hash
  143. DWORD Version;
  144. DWORD Inuse;
  145. } VHashStruc, *PVHashStruc;
  146. //
  147. // Crypto providers have to have the following entry points:
  148. //
  149. LPCSTR FunctionNames[] = {
  150. "CPAcquireContext",
  151. "CPReleaseContext",
  152. "CPGenKey",
  153. "CPDeriveKey",
  154. "CPDestroyKey",
  155. "CPSetKeyParam",
  156. "CPGetKeyParam",
  157. "CPExportKey",
  158. "CPImportKey",
  159. "CPEncrypt",
  160. "CPDecrypt",
  161. "CPCreateHash",
  162. "CPHashData",
  163. "CPHashSessionKey",
  164. "CPDestroyHash",
  165. "CPSignHash",
  166. "CPVerifySignature",
  167. "CPGenRandom",
  168. "CPGetUserKey",
  169. "CPSetProvParam",
  170. "CPGetProvParam",
  171. "CPSetHashParam",
  172. "CPGetHashParam",
  173. NULL
  174. };
  175. LPCSTR OptionalFunctionNames[] = {
  176. "CPDuplicateKey",
  177. "CPDuplicateHash",
  178. NULL
  179. };
  180. HWND hWnd = NULL;
  181. BYTE *pbContextInfo = NULL;
  182. DWORD cbContextInfo;
  183. #define KEYSIZE512 0x48
  184. #define KEYSIZE1024 0x88
  185. // designatred resource for in file signatures
  186. #define OLD_CRYPT_SIG_RESOURCE_NUMBER "#666"
  187. typedef struct _SECONDTIER_SIG
  188. {
  189. DWORD dwMagic;
  190. DWORD cbSig;
  191. BSAFE_PUB_KEY Pub;
  192. } SECOND_TIER_SIG, *PSECOND_TIER_SIG;
  193. #ifdef TEST_BUILD_EXPONENT
  194. #pragma message("WARNING: building advapai32.dll with TESTKEY enabled!")
  195. static struct _TESTKEY {
  196. BSAFE_PUB_KEY PUB;
  197. unsigned char pubmodulus[KEYSIZE512];
  198. } TESTKEY = {
  199. {
  200. 0x66b8443b,
  201. 0x6f5fc900,
  202. 0xa12132fe,
  203. 0xff1b06cf,
  204. 0x2f4826eb,
  205. },
  206. {
  207. 0x3e, 0x69, 0x4f, 0x45, 0x31, 0x95, 0x60, 0x6c,
  208. 0x80, 0xa5, 0x41, 0x99, 0x3e, 0xfc, 0x92, 0x2c,
  209. 0x93, 0xf9, 0x86, 0x23, 0x3d, 0x48, 0x35, 0x81,
  210. 0x19, 0xb6, 0x7c, 0x04, 0x43, 0xe6, 0x3e, 0xd4,
  211. 0xd5, 0x43, 0xaf, 0x52, 0xdd, 0x51, 0x20, 0xac,
  212. 0xc3, 0xca, 0xee, 0x21, 0x9b, 0x4a, 0x2d, 0xf7,
  213. 0xd8, 0x5f, 0x32, 0xeb, 0x49, 0x72, 0xb9, 0x8d,
  214. 0x2e, 0x1a, 0x76, 0x7f, 0xde, 0xc6, 0x75, 0xab,
  215. 0xaf, 0x67, 0xe0, 0xf0, 0x8b, 0x30, 0x20, 0x92,
  216. }
  217. };
  218. #endif
  219. #ifdef MS_INTERNAL_KEY
  220. static struct _mskey {
  221. BSAFE_PUB_KEY PUB;
  222. unsigned char pubmodulus[KEYSIZE1024];
  223. } MSKEY = {
  224. {
  225. 0x2bad85ae,
  226. 0x883adacc,
  227. 0xb32ebd68,
  228. 0xa7ec8b06,
  229. 0x58dbeb81,
  230. },
  231. {
  232. 0x42, 0x34, 0xb7, 0xab, 0x45, 0x0f, 0x60, 0xcd,
  233. 0x8f, 0x77, 0xb5, 0xd1, 0x79, 0x18, 0x34, 0xbe,
  234. 0x66, 0xcb, 0x5c, 0x66, 0x4a, 0x9f, 0x03, 0x18,
  235. 0x13, 0x36, 0x8e, 0x88, 0x21, 0x78, 0xb1, 0x94,
  236. 0xa1, 0xd5, 0x8f, 0x8c, 0xa5, 0xd3, 0x9f, 0x86,
  237. 0x43, 0x89, 0x05, 0xa0, 0xe3, 0xee, 0xe2, 0xd0,
  238. 0xe5, 0x1d, 0x5f, 0xaf, 0xff, 0x85, 0x71, 0x7a,
  239. 0x0a, 0xdb, 0x2e, 0xd8, 0xc3, 0x5f, 0x2f, 0xb1,
  240. 0xf0, 0x53, 0x98, 0x3b, 0x44, 0xee, 0x7f, 0xc9,
  241. 0x54, 0x26, 0xdb, 0xdd, 0xfe, 0x1f, 0xd0, 0xda,
  242. 0x96, 0x89, 0xc8, 0x9e, 0x2b, 0x5d, 0x96, 0xd1,
  243. 0xf7, 0x52, 0x14, 0x04, 0xfb, 0xf8, 0xee, 0x4d,
  244. 0x92, 0xd1, 0xb6, 0x37, 0x6a, 0xe0, 0xaf, 0xde,
  245. 0xc7, 0x41, 0x06, 0x7a, 0xe5, 0x6e, 0xb1, 0x8c,
  246. 0x8f, 0x17, 0xf0, 0x63, 0x8d, 0xaf, 0x63, 0xfd,
  247. 0x22, 0xc5, 0xad, 0x1a, 0xb1, 0xe4, 0x7a, 0x6b,
  248. 0x1e, 0x0e, 0xea, 0x60, 0x56, 0xbd, 0x49, 0xd0,
  249. }
  250. };
  251. #endif
  252. static struct _key {
  253. BSAFE_PUB_KEY PUB;
  254. unsigned char pubmodulus[KEYSIZE1024];
  255. } KEY = {
  256. {
  257. 0x3fcbf1a9,
  258. 0x08f597db,
  259. 0xe4aecab4,
  260. 0x75360f90,
  261. 0x9d6c0f00,
  262. },
  263. {
  264. 0x85, 0xdd, 0x9b, 0xf4, 0x4d, 0x0b, 0xc4, 0x96,
  265. 0x3e, 0x79, 0x86, 0x30, 0x6d, 0x27, 0x31, 0xee,
  266. 0x4a, 0x85, 0xf5, 0xff, 0xbb, 0xa9, 0xbd, 0x81,
  267. 0x86, 0xf2, 0x4f, 0x87, 0x6c, 0x57, 0x55, 0x19,
  268. 0xe4, 0xf4, 0x49, 0xa3, 0x19, 0x27, 0x08, 0x82,
  269. 0x9e, 0xf9, 0x8a, 0x8e, 0x41, 0xd6, 0x91, 0x71,
  270. 0x47, 0x48, 0xee, 0xd6, 0x24, 0x2d, 0xdd, 0x22,
  271. 0x72, 0x08, 0xc6, 0xa7, 0x34, 0x6f, 0x93, 0xd2,
  272. 0xe7, 0x72, 0x57, 0x78, 0x7a, 0x96, 0xc1, 0xe1,
  273. 0x47, 0x38, 0x78, 0x43, 0x53, 0xea, 0xf3, 0x88,
  274. 0x82, 0x66, 0x41, 0x43, 0xd4, 0x62, 0x44, 0x01,
  275. 0x7d, 0xb2, 0x16, 0xb3, 0x50, 0x89, 0xdb, 0x0a,
  276. 0x93, 0x17, 0x02, 0x02, 0x46, 0x49, 0x79, 0x76,
  277. 0x59, 0xb6, 0xb1, 0x2b, 0xfc, 0xb0, 0x9a, 0x21,
  278. 0xe6, 0xfa, 0x2d, 0x56, 0x07, 0x36, 0xbc, 0x13,
  279. 0x7f, 0x1c, 0xde, 0x55, 0xfb, 0x0d, 0x67, 0x0f,
  280. 0xc2, 0x17, 0x45, 0x8a, 0x14, 0x2b, 0xba, 0x55,
  281. }
  282. };
  283. static struct _key2 {
  284. BSAFE_PUB_KEY PUB;
  285. unsigned char pubmodulus[KEYSIZE1024];
  286. } KEY2 = {
  287. {
  288. 0x685fc690,
  289. 0x97d49b6b,
  290. 0x1dccd9d2,
  291. 0xa5ec9b52,
  292. 0x64fd29d7,
  293. },
  294. {
  295. 0x03, 0x8c, 0xa3, 0x9e, 0xfb, 0x93, 0xb6, 0x72,
  296. 0x2a, 0xda, 0x6f, 0xa5, 0xec, 0x26, 0x39, 0x58,
  297. 0x41, 0xcd, 0x3f, 0x49, 0x10, 0x4c, 0xcc, 0x7e,
  298. 0x23, 0x94, 0xf9, 0x5d, 0x9b, 0x2b, 0xa3, 0x6b,
  299. 0xe8, 0xec, 0x52, 0xd9, 0x56, 0x64, 0x74, 0x7c,
  300. 0x44, 0x6f, 0x36, 0xb7, 0x14, 0x9d, 0x02, 0x3c,
  301. 0x0e, 0x32, 0xb6, 0x38, 0x20, 0x25, 0xbd, 0x8c,
  302. 0x9b, 0xd1, 0x46, 0xa7, 0xb3, 0x58, 0x4a, 0xb7,
  303. 0xdd, 0x0e, 0x38, 0xb6, 0x16, 0x44, 0xbf, 0xc1,
  304. 0xca, 0x4d, 0x6a, 0x9f, 0xcb, 0x6f, 0x3c, 0x5f,
  305. 0x03, 0xab, 0x7a, 0xb8, 0x16, 0x70, 0xcf, 0x98,
  306. 0xd0, 0xca, 0x8d, 0x25, 0x57, 0x3a, 0x22, 0x8b,
  307. 0x44, 0x96, 0x37, 0x51, 0x30, 0x00, 0x92, 0x1b,
  308. 0x03, 0xb9, 0xf9, 0x0d, 0xb3, 0x1a, 0xe2, 0xb4,
  309. 0xc5, 0x7b, 0xc9, 0x4b, 0xe2, 0x42, 0x25, 0xfe,
  310. 0x3d, 0x42, 0xfa, 0x45, 0xc6, 0x94, 0xc9, 0x8e,
  311. 0x87, 0x7e, 0xf6, 0x68, 0x90, 0x30, 0x65, 0x10,
  312. }
  313. };
  314. #define CACHESIZE 32
  315. static HANDLE gCSPCache[CACHESIZE];
  316. #define TABLEPROV 0x11111111
  317. #define TABLEKEY 0x22222222
  318. #define TABLEHASH 0x33333333
  319. CHAR szreg[] = "SOFTWARE\\Microsoft\\Cryptography\\Providers\\";
  320. CHAR szusertype[] = "SOFTWARE\\Microsoft\\Cryptography\\Providers\\Type ";
  321. CHAR szmachinetype[] = "SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider Types\\Type ";
  322. CHAR szprovider[] = "SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider\\";
  323. CHAR szenumproviders[] = "SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider";
  324. CHAR szprovidertypes[] = "SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider Types";
  325. BOOL EnterProviderCritSec(IN PVTableStruc pVTable);
  326. void LeaveProviderCritSec(IN PVTableStruc pVTable);
  327. BOOL EnterKeyCritSec(IN PVKeyStruc pVKey);
  328. void LeaveKeyCritSec(IN PVKeyStruc pVKey);
  329. BOOL EnterHashCritSec(IN PVHashStruc pVHash);
  330. void LeaveHashCritSec(IN PVHashStruc pVHash);
  331. BOOL CheckSignatureInFile(LPCWSTR pszImage);
  332. BOOL CProvVerifyImage(LPCSTR lpszImage,
  333. BYTE *pSigData);
  334. BOOL NewVerifyImage(LPCSTR lpszImage,
  335. BYTE *pSigData,
  336. DWORD cbData,
  337. BOOL fUnknownLen);
  338. BOOL BuildVKey(IN PVKeyStruc *ppVKey,
  339. IN PVTableStruc pVTable);
  340. BOOL BuildVHash(
  341. IN PVHashStruc *ppVKey,
  342. IN PVTableStruc pVTable
  343. );
  344. void CPReturnhWnd(HWND *phWnd);
  345. static void __ltoa(DWORD val, char *buf);
  346. #ifdef WIN95
  347. DWORD GetCryptApiExponentValue(VOID); //Entry point from kernel32.
  348. // StrToL
  349. // Can't use CRT routines, so steal from the C runtime sources
  350. DWORD StrToL(CHAR *InStr)
  351. {
  352. DWORD dwVal = 0;
  353. while(*InStr)
  354. {
  355. dwVal = (10 * dwVal) + (*InStr - '0');
  356. InStr++;
  357. }
  358. return dwVal;
  359. }
  360. VOID
  361. RtlInitAnsiString(
  362. OUT PANSI_STRING DestinationString,
  363. IN PCSZ SourceString OPTIONAL
  364. )
  365. /*++
  366. Routine Description:
  367. The RtlInitAnsiString function initializes an NT counted string.
  368. The DestinationString is initialized to point to the SourceString
  369. and the Length and MaximumLength fields of DestinationString are
  370. initialized to the length of the SourceString, which is zero if
  371. SourceString is not specified.
  372. Arguments:
  373. DestinationString - Pointer to the counted string to initialize
  374. SourceString - Optional pointer to a null terminated string that
  375. the counted string is to point to.
  376. Return Value:
  377. None.
  378. --*/
  379. {
  380. ULONG Length;
  381. DestinationString->Buffer = (PCHAR)SourceString;
  382. if (ARGUMENT_PRESENT( SourceString )) {
  383. Length = strlen(SourceString);
  384. DestinationString->Length = (USHORT)Length;
  385. DestinationString->MaximumLength = (USHORT)(Length+1);
  386. }
  387. else {
  388. DestinationString->Length = 0;
  389. DestinationString->MaximumLength = 0;
  390. }
  391. }
  392. VOID
  393. RtlInitUnicodeString(
  394. OUT PUNICODE_STRING DestinationString,
  395. IN PCWSTR SourceString OPTIONAL
  396. )
  397. /*++
  398. Routine Description:
  399. The RtlInitUnicodeString function initializes an NT counted
  400. unicode string. The DestinationString is initialized to point to
  401. the SourceString and the Length and MaximumLength fields of
  402. DestinationString are initialized to the length of the SourceString,
  403. which is zero if SourceString is not specified.
  404. Arguments:
  405. DestinationString - Pointer to the counted string to initialize
  406. SourceString - Optional pointer to a null terminated unicode string that
  407. the counted string is to point to.
  408. Return Value:
  409. None.
  410. --*/
  411. {
  412. ULONG Length;
  413. DestinationString->Buffer = (PWSTR)SourceString;
  414. if (ARGUMENT_PRESENT( SourceString ))
  415. {
  416. Length = wcslen( SourceString ) * sizeof( WCHAR );
  417. DestinationString->Length = (USHORT)Length;
  418. DestinationString->MaximumLength = (USHORT)(Length + sizeof(UNICODE_NULL));
  419. }
  420. else
  421. {
  422. DestinationString->MaximumLength = 0;
  423. DestinationString->Length = 0;
  424. }
  425. }
  426. NTSTATUS
  427. RtlAnsiStringToUnicodeString(
  428. OUT PUNICODE_STRING DestinationString,
  429. IN PANSI_STRING SourceString,
  430. IN BOOLEAN AllocateDestinationString
  431. )
  432. {
  433. ULONG UnicodeLength;
  434. ULONG i;
  435. if (AllocateDestinationString)
  436. {
  437. return STATUS_INVALID_PARAMETER_2;
  438. }
  439. UnicodeLength = SourceString->Length * 2;
  440. if (UnicodeLength > MAXUSHORT)
  441. {
  442. return STATUS_INVALID_PARAMETER_2;
  443. }
  444. if (UnicodeLength > DestinationString->Length)
  445. {
  446. return STATUS_BUFFER_OVERFLOW;
  447. }
  448. for (i = 0; i < SourceString->Length; i++)
  449. {
  450. DestinationString->Buffer[i] = (WCHAR)(SourceString->Buffer[i]);
  451. }
  452. return STATUS_SUCCESS;
  453. }
  454. NTSTATUS
  455. RtlUnicodeStringToAnsiString(
  456. OUT PANSI_STRING DestinationString,
  457. IN PUNICODE_STRING SourceString,
  458. IN BOOLEAN AllocateDestinationString
  459. )
  460. {
  461. ULONG AnsiLength;
  462. ULONG i;
  463. if (AllocateDestinationString)
  464. {
  465. return STATUS_INVALID_PARAMETER_2;
  466. }
  467. if (SourceString->Length & 1)
  468. {
  469. return STATUS_INVALID_PARAMETER_2;
  470. }
  471. AnsiLength = SourceString->Length / 2;
  472. if (AnsiLength > DestinationString->Length)
  473. {
  474. return STATUS_BUFFER_OVERFLOW;
  475. }
  476. for (i = 0; i < AnsiLength; i++)
  477. {
  478. DestinationString->Buffer[i] = (CHAR)(SourceString->Buffer[i]);
  479. }
  480. return STATUS_SUCCESS;
  481. }
  482. NTSTATUS UnicodeStringToAnsiString(OUT PANSI_STRING AnsiString,
  483. IN PUNICODE_STRING UnicodeString)
  484. {
  485. NTSTATUS Status;
  486. AnsiString->Buffer =
  487. HeapAlloc(GetProcessHeap(), 0, UnicodeString->MaximumLength/2);
  488. AnsiString->Length = UnicodeString->Length / 2;
  489. AnsiString->MaximumLength = UnicodeString->MaximumLength / 2;
  490. Status = RtlUnicodeStringToAnsiString(AnsiString, UnicodeString,
  491. FALSE);
  492. AnsiString->Buffer[AnsiString->Length] = '\0';
  493. return(Status);
  494. }
  495. NTSTATUS AnsiStringToUnicodeString(OUT PUNICODE_STRING UnicodeString,
  496. IN PANSI_STRING AnsiString)
  497. {
  498. NTSTATUS Status;
  499. UnicodeString->Buffer =
  500. HeapAlloc(GetProcessHeap(), 0, AnsiString->MaximumLength * 2);
  501. UnicodeString->Length = AnsiString->Length * 2;
  502. UnicodeString->MaximumLength = AnsiString->MaximumLength * 2;
  503. Status = RtlAnsiStringToUnicodeString(UnicodeString, AnsiString,
  504. FALSE);
  505. UnicodeString->Buffer[UnicodeString->Length / sizeof(WCHAR)] =
  506. UNICODE_NULL;
  507. return(Status);
  508. }
  509. VOID FreeAnsiString(PANSI_STRING AnsiString)
  510. {
  511. if (AnsiString->Buffer)
  512. {
  513. HeapFree(GetProcessHeap(), 0, AnsiString->Buffer);
  514. }
  515. }
  516. VOID FreeUnicodeString(PUNICODE_STRING UnicodeString)
  517. {
  518. if (UnicodeString->Buffer)
  519. {
  520. HeapFree(GetProcessHeap(), 0, UnicodeString->Buffer);
  521. }
  522. }
  523. #endif
  524. BOOL CSPInCacheCheck(
  525. LPSTR pszValue,
  526. HANDLE *ph
  527. )
  528. {
  529. HANDLE h = 0;
  530. DWORD i;
  531. BOOL fRet = FALSE;
  532. // check if CSP has been loaded
  533. if (0 == (h = GetModuleHandle(pszValue)))
  534. goto Ret;
  535. // check if the CSP is in the cache designating it as signed
  536. for (i=0;i<CACHESIZE;i++)
  537. {
  538. if (h == gCSPCache[i])
  539. {
  540. *ph = h;
  541. fRet = TRUE;
  542. break;
  543. }
  544. }
  545. Ret:
  546. return fRet;
  547. }
  548. void AddHandleToCSPCache(
  549. HANDLE h
  550. )
  551. {
  552. DWORD i;
  553. // check if the CSP is in the cache designating it as signed
  554. for (i=0;i<CACHESIZE;i++)
  555. {
  556. if (0 == gCSPCache[i])
  557. {
  558. gCSPCache[i] = h;
  559. break;
  560. }
  561. }
  562. }
  563. #ifndef WIN95
  564. /*
  565. - CryptAcquireContextW
  566. -
  567. * Purpose:
  568. * The CryptAcquireContext function is used to acquire a context
  569. * handle to a cryptograghic service provider (CSP).
  570. *
  571. *
  572. * Parameters:
  573. * OUT phProv - Handle to a CSP
  574. * IN pszIdentity - Pointer to the name of the context's
  575. * keyset.
  576. * IN pszProvider - Pointer to the name of the provider.
  577. * IN dwProvType - Requested CSP type
  578. * IN dwFlags - Flags values
  579. *
  580. * Returns:
  581. */
  582. WINADVAPI
  583. BOOL
  584. WINAPI CryptAcquireContextW(OUT HCRYPTPROV *phProv,
  585. IN LPCWSTR pszIdentity,
  586. IN LPCWSTR pszProvider,
  587. IN DWORD dwProvType,
  588. IN DWORD dwFlags)
  589. {
  590. ANSI_STRING AnsiString1;
  591. ANSI_STRING AnsiString2;
  592. UNICODE_STRING UnicodeString1;
  593. UNICODE_STRING UnicodeString2;
  594. NTSTATUS Status = STATUS_SUCCESS;
  595. BOOL rt;
  596. __try
  597. {
  598. memset(&AnsiString1, 0, sizeof(AnsiString1));
  599. memset(&AnsiString2, 0, sizeof(AnsiString2));
  600. memset(&UnicodeString1, 0, sizeof(UnicodeString1));
  601. memset(&UnicodeString2, 0, sizeof(UnicodeString2));
  602. if (NULL != pszIdentity)
  603. {
  604. RtlInitUnicodeString(&UnicodeString1, pszIdentity);
  605. Status = RtlUnicodeStringToAnsiString(&AnsiString1, &UnicodeString1,
  606. TRUE);
  607. }
  608. if (!NT_SUCCESS(Status))
  609. {
  610. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  611. return(CRYPT_FAILED);
  612. }
  613. if (NULL != pszProvider)
  614. {
  615. RtlInitUnicodeString(&UnicodeString2, pszProvider);
  616. Status = RtlUnicodeStringToAnsiString(&AnsiString2, &UnicodeString2,
  617. TRUE);
  618. }
  619. if (!NT_SUCCESS(Status))
  620. {
  621. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  622. return(CRYPT_FAILED);
  623. }
  624. rt = CryptAcquireContextA(phProv, AnsiString1.Buffer,
  625. AnsiString2.Buffer,
  626. dwProvType, dwFlags);
  627. RtlFreeAnsiString(&AnsiString1);
  628. RtlFreeAnsiString(&AnsiString2);
  629. return(rt);
  630. }
  631. __except ( EXCEPTION_EXECUTE_HANDLER )
  632. {
  633. SetLastError(ERROR_INVALID_PARAMETER);
  634. goto Try_Error_Return;
  635. }
  636. Try_Error_Return:
  637. return(CRYPT_FAILED);
  638. }
  639. #else // WIN95
  640. WINADVAPI
  641. BOOL
  642. WINAPI CryptAcquireContextW(OUT HCRYPTPROV *phProv,
  643. IN LPCWSTR pszIdentity,
  644. IN LPCWSTR pszProvider,
  645. IN DWORD dwProvType,
  646. IN DWORD dwFlags)
  647. {
  648. SetLastError((DWORD)ERROR_CALL_NOT_IMPLEMENTED);
  649. return CRYPT_FAILED;
  650. }
  651. #endif // WIN95
  652. /*
  653. - CryptAcquireContextA
  654. -
  655. * Purpose:
  656. * The CryptAcquireContext function is used to acquire a context
  657. * handle to a cryptograghic service provider (CSP).
  658. *
  659. *
  660. * Parameters:
  661. * OUT phProv - Handle to a CSP
  662. * IN OUT pszIdentity - Pointer to the name of the context's
  663. * keyset.
  664. * IN OUT pszProvName - Pointer to the name of the provider.
  665. * IN dwReqProvider - Requested CSP type
  666. * IN dwFlags - Flags values
  667. *
  668. * Returns:
  669. */
  670. WINADVAPI
  671. BOOL
  672. WINAPI CryptAcquireContextA(OUT HCRYPTPROV *phProv,
  673. IN LPCSTR pszIdentity,
  674. IN LPCSTR pszProvName,
  675. IN DWORD dwReqProvider,
  676. IN DWORD dwFlags)
  677. {
  678. HANDLE handle = 0;
  679. DWORD bufsize;
  680. ULONG_PTR *pTable;
  681. PVTableStruc pVTable = NULL;
  682. LPSTR pszTmpProvName = NULL;
  683. DWORD i;
  684. HKEY hCurrUser = 0;
  685. HKEY hKey = 0;
  686. DWORD cbValue;
  687. DWORD cbTemp;
  688. CHAR *pszValue = NULL;
  689. CHAR *pszDest = NULL;
  690. BYTE *SignatureBuf = NULL;
  691. DWORD provtype;
  692. BOOL rt = CRYPT_FAILED;
  693. DWORD dwType;
  694. LONG err;
  695. DWORD dwErr;
  696. CHAR typebuf[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
  697. HCRYPTPROV hTmpProv = 0;
  698. VTableProvStruc VTableProv;
  699. UNICODE_STRING String ;
  700. BOOL SigInFile ;
  701. __try
  702. {
  703. if (dwReqProvider == 0 || dwReqProvider > 999)
  704. {
  705. SetLastError((DWORD) NTE_BAD_PROV_TYPE);
  706. goto Ret;
  707. }
  708. if (pszProvName != NULL && pszProvName[0] != 0)
  709. {
  710. // Do nothing just check for invalid pointers
  711. ;
  712. }
  713. if (pszProvName != NULL && pszProvName[0] != 0)
  714. {
  715. cbValue = strlen(pszProvName);
  716. if ((pszValue = (CHAR *) LocalAlloc(LMEM_ZEROINIT,
  717. (UINT) cbValue +
  718. strlen(szprovider) + 1)) == NULL)
  719. {
  720. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  721. goto Ret;
  722. }
  723. if ((pszTmpProvName = (LPSTR)LocalAlloc(LMEM_ZEROINIT,
  724. (UINT) cbValue + 1)) == NULL)
  725. {
  726. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  727. goto Ret;
  728. }
  729. strcpy(pszTmpProvName, pszProvName);
  730. strcpy(pszValue, szprovider);
  731. strcat(pszValue, pszProvName);
  732. }
  733. else
  734. {
  735. if ((pszValue = (CHAR *) LocalAlloc(LMEM_ZEROINIT,
  736. 5 + strlen(szusertype))) == NULL)
  737. {
  738. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  739. goto Ret;
  740. }
  741. strcpy(pszValue, szusertype);
  742. __ltoa(dwReqProvider, typebuf);
  743. strcat(pszValue, &typebuf[5]);
  744. #ifndef WIN95
  745. err = ERROR_INVALID_PARAMETER;
  746. if (NT_SUCCESS(RtlOpenCurrentUser(KEY_READ, &hCurrUser)))
  747. {
  748. err = RegOpenKeyEx(hCurrUser, (const char *) pszValue,
  749. 0L, KEY_READ, &hKey);
  750. NtClose(hCurrUser);
  751. }
  752. #else
  753. err = RegOpenKeyEx(HKEY_CURRENT_USER, (const char *) pszValue,
  754. 0L, KEY_READ, &hKey);
  755. RegCloseKey(HKEY_CURRENT_USER);
  756. #endif
  757. if (err != ERROR_SUCCESS)
  758. {
  759. LocalFree(pszValue);
  760. if ((pszValue = (CHAR *) LocalAlloc(LMEM_ZEROINIT,
  761. 5 + strlen(szmachinetype))) == NULL)
  762. {
  763. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  764. goto Ret;
  765. }
  766. strcpy(pszValue, szmachinetype);
  767. strcat(pszValue, &typebuf[5]);
  768. if ((err = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  769. (const char *) pszValue, 0L,
  770. KEY_READ, &hKey)) != ERROR_SUCCESS)
  771. {
  772. SetLastError((DWORD) NTE_PROV_TYPE_NOT_DEF);
  773. goto Ret;
  774. }
  775. }
  776. if ((err = RegQueryValueEx(hKey, "Name", NULL, &dwType,
  777. NULL, &cbValue)) != ERROR_SUCCESS)
  778. {
  779. SetLastError((DWORD) NTE_PROV_TYPE_NOT_DEF);
  780. goto Ret;
  781. }
  782. LocalFree(pszValue);
  783. if ((pszValue = (CHAR *) LocalAlloc(LMEM_ZEROINIT,
  784. cbValue +
  785. strlen(szprovider) + 1)) == NULL)
  786. {
  787. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  788. goto Ret;
  789. }
  790. if ((pszTmpProvName = (LPSTR)LocalAlloc(LMEM_ZEROINIT,
  791. (UINT) cbValue + 1)) == NULL)
  792. {
  793. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  794. goto Ret;
  795. }
  796. strcpy(pszValue, szprovider);
  797. cbTemp = cbValue;
  798. if ((err = RegQueryValueEx(hKey, "Name", NULL, &dwType,
  799. (LPBYTE)pszTmpProvName,
  800. &cbTemp)) != ERROR_SUCCESS)
  801. {
  802. SetLastError((DWORD) NTE_PROV_TYPE_NOT_DEF);
  803. goto Ret;
  804. }
  805. strcat(pszValue, pszTmpProvName);
  806. RegCloseKey(hKey);
  807. hKey = 0;
  808. }
  809. if ((err = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  810. (const char *) pszValue,
  811. 0L, KEY_READ, &hKey)) != ERROR_SUCCESS)
  812. {
  813. SetLastError((DWORD) NTE_KEYSET_NOT_DEF);
  814. goto Ret;
  815. }
  816. LocalFree(pszValue);
  817. pszValue = NULL;
  818. cbValue = sizeof(DWORD);
  819. if ((err = RegQueryValueEx(hKey, "Type", NULL, &dwType,
  820. (LPBYTE)&provtype,
  821. &cbValue)) != ERROR_SUCCESS)
  822. {
  823. SetLastError((DWORD) NTE_KEYSET_ENTRY_BAD);
  824. goto Ret;
  825. }
  826. // Check that requested provider type is same as registry entry
  827. if (provtype != dwReqProvider)
  828. {
  829. SetLastError((DWORD) NTE_PROV_TYPE_NO_MATCH);
  830. goto Ret;
  831. }
  832. // Determine size of path for provider
  833. if ((err = RegQueryValueEx(hKey, "Image Path", NULL,
  834. &dwType, NULL, &cbValue)) != ERROR_SUCCESS)
  835. {
  836. SetLastError((DWORD) NTE_KEYSET_ENTRY_BAD);
  837. goto Ret;
  838. }
  839. if ((pszValue = (CHAR *) LocalAlloc(LMEM_ZEROINIT,
  840. (UINT) cbValue)) == NULL)
  841. {
  842. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  843. goto Ret;
  844. }
  845. // Get value from registry
  846. if ((err = RegQueryValueEx(hKey, "Image Path", NULL, &dwType,
  847. (LPBYTE)pszValue, &cbValue)) != ERROR_SUCCESS)
  848. {
  849. SetLastError((DWORD) NTE_KEYSET_ENTRY_BAD);
  850. goto Ret;
  851. }
  852. pszDest = NULL;
  853. cbTemp = 0;
  854. if ((cbTemp = ExpandEnvironmentStrings(pszValue, (CHAR *) &pszDest, cbTemp)) == 0)
  855. {
  856. goto Ret;
  857. }
  858. if ((pszDest = (CHAR *) LocalAlloc(LMEM_ZEROINIT,
  859. (UINT) cbTemp)) == NULL)
  860. {
  861. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  862. goto Ret;
  863. }
  864. if ((cbTemp = ExpandEnvironmentStrings(pszValue, pszDest,
  865. cbTemp)) == 0)
  866. {
  867. goto Ret;
  868. }
  869. LocalFree(pszValue);
  870. pszValue = pszDest;
  871. pszDest = NULL;
  872. cbValue = cbTemp;
  873. if (!CSPInCacheCheck(pszValue, &handle))
  874. {
  875. if ( RtlCreateUnicodeStringFromAsciiz( &String, pszValue ) )
  876. {
  877. // check if the CSP is registered as having the signature in the file
  878. SigInFile = CheckSignatureInFile( String.Buffer );
  879. RtlFreeUnicodeString( &String );
  880. if (! SigInFile )
  881. {
  882. // Determine size of signature
  883. if ((err = RegQueryValueEx(hKey, "Signature", NULL,
  884. &dwType, NULL, &cbValue)) != ERROR_SUCCESS)
  885. {
  886. SetLastError((DWORD) NTE_BAD_SIGNATURE);
  887. goto Ret;
  888. }
  889. if ((SignatureBuf = (LPBYTE)LocalAlloc(LMEM_ZEROINIT,
  890. (UINT) cbValue)) == NULL)
  891. {
  892. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  893. goto Ret;
  894. }
  895. // Get Digital signature from registry
  896. if ((err = RegQueryValueEx(hKey, "Signature", NULL, &dwType,
  897. SignatureBuf,
  898. &cbValue)) != ERROR_SUCCESS)
  899. {
  900. SetLastError((DWORD) NTE_BAD_SIGNATURE);
  901. goto Ret;
  902. }
  903. if (RCRYPT_FAILED(NewVerifyImage(pszValue, SignatureBuf, cbValue, FALSE)))
  904. {
  905. SetLastError((DWORD) NTE_BAD_SIGNATURE);
  906. goto Ret;
  907. }
  908. }
  909. }
  910. if ((handle = LoadLibrary(pszValue)) == NULL)
  911. {
  912. SetLastError((DWORD) NTE_PROVIDER_DLL_FAIL);
  913. goto Ret;
  914. }
  915. AddHandleToCSPCache(handle);
  916. }
  917. // DLLs exist allocate VTable struct to hold address of entry points
  918. bufsize = sizeof(VTableStruc);
  919. if ((pVTable = (PVTableStruc) LocalAlloc(LMEM_ZEROINIT,
  920. (UINT) bufsize)) == NULL)
  921. {
  922. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  923. goto Ret;
  924. }
  925. pTable = (ULONG_PTR *) pVTable;
  926. // Build table of pointers to Crypto API for this DLL
  927. i = 0;
  928. while (FunctionNames[i] != NULL)
  929. {
  930. *pTable = (ULONG_PTR) GetProcAddress(handle, FunctionNames[i]);
  931. if (*pTable == 0)
  932. {
  933. SetLastError((DWORD) NTE_PROVIDER_DLL_FAIL);
  934. goto Ret;
  935. }
  936. pTable++;
  937. i++;
  938. }
  939. // Build the table of optional pointers to Crypto API for this DLL
  940. i = 0;
  941. pTable++;
  942. while (OptionalFunctionNames[i] != NULL)
  943. {
  944. *pTable = (ULONG_PTR) GetProcAddress(handle, OptionalFunctionNames[i]);
  945. pTable++;
  946. i++;
  947. }
  948. pVTable->DllHandle = handle;
  949. memset(&VTableProv, 0, sizeof(VTableProv));
  950. VTableProv.Version = 3;
  951. VTableProv.FuncVerifyImage = (CRYPT_VERIFY_IMAGE_A)CProvVerifyImage;
  952. VTableProv.FuncReturnhWnd = (CRYPT_RETURN_HWND)CPReturnhWnd;
  953. VTableProv.dwProvType = dwReqProvider;
  954. VTableProv.pszProvName = pszTmpProvName;
  955. VTableProv.pbContextInfo = pbContextInfo;
  956. VTableProv.cbContextInfo = cbContextInfo;
  957. *phProv = (HCRYPTPROV) NULL;
  958. rt = (BOOL)pVTable->FuncAcquireContext(&hTmpProv, pszIdentity, dwFlags,
  959. &VTableProv);
  960. if (RCRYPT_SUCCEEDED(rt) &&
  961. ((dwFlags & CRYPT_DELETEKEYSET) != CRYPT_DELETEKEYSET))
  962. {
  963. pVTable->hProv = hTmpProv;
  964. *phProv = (HCRYPTPROV)pVTable;
  965. pVTable->Version = TABLEPROV;
  966. pVTable->Inuse = 1;
  967. pVTable->RefCnt = 1;
  968. }
  969. }
  970. __except ( EXCEPTION_EXECUTE_HANDLER )
  971. {
  972. SetLastError(ERROR_INVALID_PARAMETER);
  973. goto Ret;
  974. }
  975. Ret:
  976. dwErr = GetLastError();
  977. if (pszTmpProvName)
  978. LocalFree(pszTmpProvName);
  979. if (pszValue)
  980. LocalFree(pszValue);
  981. if (hKey)
  982. RegCloseKey(hKey);
  983. if (pszDest)
  984. LocalFree(pszDest);
  985. if (SignatureBuf)
  986. LocalFree(SignatureBuf);
  987. if ((CRYPT_SUCCEED != rt) || (dwFlags & CRYPT_DELETEKEYSET))
  988. {
  989. if (pVTable)
  990. LocalFree(pVTable);
  991. SetLastError(dwErr);
  992. }
  993. return rt;
  994. }
  995. /*
  996. - CryptContextAddRef
  997. -
  998. * Purpose:
  999. * Increments the reference counter on the provider handle.
  1000. *
  1001. * Parameters:
  1002. * IN hProv - Handle to a CSP
  1003. * IN pdwReserved - Reserved parameter
  1004. * IN dwFlags - Flags values
  1005. *
  1006. * Returns:
  1007. * BOOL
  1008. * Use get extended error information use GetLastError
  1009. */
  1010. WINADVAPI
  1011. BOOL
  1012. WINAPI CryptContextAddRef(
  1013. IN HCRYPTPROV hProv,
  1014. IN DWORD *pdwReserved,
  1015. IN DWORD dwFlags
  1016. )
  1017. {
  1018. PVTableStruc pVTable;
  1019. BOOL fRet = CRYPT_FAILED;
  1020. __try
  1021. {
  1022. if ((NULL != pdwReserved) || (0 != dwFlags))
  1023. {
  1024. SetLastError(ERROR_INVALID_PARAMETER);
  1025. goto Ret;
  1026. }
  1027. pVTable = (PVTableStruc) hProv;
  1028. if (pVTable->Version != TABLEPROV)
  1029. {
  1030. SetLastError(ERROR_INVALID_PARAMETER);
  1031. goto Ret;
  1032. }
  1033. if (InterlockedIncrement(&pVTable->RefCnt) <= 0)
  1034. SetLastError(ERROR_INVALID_PARAMETER);
  1035. else
  1036. fRet = CRYPT_SUCCEED;
  1037. }
  1038. __except ( EXCEPTION_EXECUTE_HANDLER )
  1039. {
  1040. SetLastError(ERROR_INVALID_PARAMETER);
  1041. goto Ret;
  1042. }
  1043. Ret:
  1044. return fRet;
  1045. }
  1046. /*
  1047. - CryptReleaseContext
  1048. -
  1049. * Purpose:
  1050. * The CryptReleaseContext function is used to release a
  1051. * context created by CryptAcquireContext.
  1052. *
  1053. * Parameters:
  1054. * IN hProv - Handle to a CSP
  1055. * IN dwFlags - Flags values
  1056. *
  1057. * Returns:
  1058. * BOOL
  1059. * Use get extended error information use GetLastError
  1060. */
  1061. WINADVAPI
  1062. BOOL
  1063. WINAPI CryptReleaseContext(IN HCRYPTPROV hProv,
  1064. IN DWORD dwFlags)
  1065. {
  1066. PVTableStruc pVTable;
  1067. BOOL rt;
  1068. BOOL fRet = CRYPT_FAILED;
  1069. DWORD dwErr = 0;
  1070. __try
  1071. {
  1072. pVTable = (PVTableStruc) hProv;
  1073. if (pVTable->Version != TABLEPROV)
  1074. {
  1075. SetLastError(ERROR_INVALID_PARAMETER);
  1076. goto Ret;
  1077. }
  1078. if (pVTable->RefCnt <= 0)
  1079. {
  1080. SetLastError(ERROR_INVALID_PARAMETER);
  1081. goto Ret;
  1082. }
  1083. if (0 == InterlockedDecrement(&pVTable->RefCnt))
  1084. {
  1085. if (0 < InterlockedDecrement((LPLONG)&pVTable->Inuse))
  1086. {
  1087. InterlockedIncrement((LPLONG)&pVTable->Inuse);
  1088. SetLastError(ERROR_BUSY);
  1089. goto Ret;
  1090. }
  1091. InterlockedIncrement((LPLONG)&pVTable->Inuse);
  1092. if (FALSE == (rt = (BOOL)pVTable->FuncReleaseContext(pVTable->hProv, dwFlags)))
  1093. {
  1094. dwErr = GetLastError();
  1095. }
  1096. pVTable->Version = 0;
  1097. LocalFree(pVTable);
  1098. if (!rt)
  1099. {
  1100. SetLastError(dwErr);
  1101. goto Ret;
  1102. }
  1103. }
  1104. }
  1105. __except ( EXCEPTION_EXECUTE_HANDLER )
  1106. {
  1107. SetLastError(ERROR_INVALID_PARAMETER);
  1108. goto Ret;
  1109. }
  1110. fRet = CRYPT_SUCCEED;
  1111. Ret:
  1112. return fRet;
  1113. }
  1114. /*
  1115. - CryptGenKey
  1116. -
  1117. * Purpose:
  1118. * Generate cryptographic keys
  1119. *
  1120. *
  1121. * Parameters:
  1122. * IN hProv - Handle to a CSP
  1123. * IN Algid - Algorithm identifier
  1124. * IN dwFlags - Flags values
  1125. * OUT phKey - Handle to a generated key
  1126. *
  1127. * Returns:
  1128. */
  1129. WINADVAPI
  1130. BOOL
  1131. WINAPI CryptGenKey(IN HCRYPTPROV hProv,
  1132. IN ALG_ID Algid,
  1133. IN DWORD dwFlags,
  1134. OUT HCRYPTKEY * phKey)
  1135. {
  1136. PVTableStruc pVTable = NULL;
  1137. PVKeyStruc pVKey = NULL;
  1138. BOOL fProvCritSec = FALSE;
  1139. DWORD dwErr;
  1140. BOOL fRet = CRYPT_FAILED;
  1141. __try
  1142. {
  1143. pVTable = (PVTableStruc) hProv;
  1144. if (RCRYPT_FAILED(EnterProviderCritSec(pVTable)))
  1145. {
  1146. goto Ret;
  1147. }
  1148. fProvCritSec = TRUE;
  1149. if (RCRYPT_FAILED(BuildVKey(&pVKey, pVTable)))
  1150. {
  1151. goto Ret;
  1152. }
  1153. if (RCRYPT_FAILED(pVTable->FuncGenKey(pVTable->hProv, Algid, dwFlags,
  1154. phKey)))
  1155. {
  1156. goto Ret;
  1157. }
  1158. pVKey->hKey = *phKey;
  1159. *phKey = (HCRYPTKEY) pVKey;
  1160. pVKey->Version = TABLEKEY;
  1161. pVKey->hProv = hProv;
  1162. pVKey->Inuse = 1;
  1163. }
  1164. __except ( EXCEPTION_EXECUTE_HANDLER )
  1165. {
  1166. SetLastError(ERROR_INVALID_PARAMETER);
  1167. goto Ret;
  1168. }
  1169. fRet = CRYPT_SUCCEED;
  1170. Ret:
  1171. dwErr = GetLastError();
  1172. if (fProvCritSec)
  1173. LeaveProviderCritSec(pVTable);
  1174. if (CRYPT_SUCCEED != fRet)
  1175. {
  1176. if (pVKey)
  1177. LocalFree(pVKey);
  1178. SetLastError(dwErr);
  1179. }
  1180. return fRet;
  1181. }
  1182. /*
  1183. - CryptDuplicateKey
  1184. -
  1185. * Purpose:
  1186. * Duplicate a cryptographic key
  1187. *
  1188. *
  1189. * Parameters:
  1190. * IN hKey - Handle to the key to be duplicated
  1191. * IN pdwReserved - Reserved for later use
  1192. * IN dwFlags - Flags values
  1193. * OUT phKey - Handle to the new duplicate key
  1194. *
  1195. * Returns:
  1196. */
  1197. WINADVAPI
  1198. BOOL
  1199. WINAPI CryptDuplicateKey(
  1200. IN HCRYPTKEY hKey,
  1201. IN DWORD *pdwReserved,
  1202. IN DWORD dwFlags,
  1203. OUT HCRYPTKEY * phKey
  1204. )
  1205. {
  1206. PVTableStruc pVTable = NULL;
  1207. PVKeyStruc pVKey;
  1208. PVKeyStruc pVNewKey = NULL;
  1209. HCRYPTKEY hNewKey;
  1210. BOOL fProvCritSecSet = FALSE;
  1211. DWORD dwErr = 0;
  1212. BOOL fRet = CRYPT_FAILED;
  1213. __try
  1214. {
  1215. if (IsBadWritePtr(phKey, sizeof(HCRYPTKEY)))
  1216. {
  1217. SetLastError(ERROR_INVALID_PARAMETER);
  1218. goto Ret;
  1219. }
  1220. pVKey = (PVKeyStruc) hKey;
  1221. if (pVKey->Version != TABLEKEY)
  1222. {
  1223. SetLastError(ERROR_INVALID_PARAMETER);
  1224. goto Ret;
  1225. }
  1226. if (NULL == pVKey->OptionalFuncDuplicateKey)
  1227. {
  1228. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1229. goto Ret;
  1230. }
  1231. pVTable = (PVTableStruc) pVKey->hProv;
  1232. if (RCRYPT_FAILED(EnterProviderCritSec(pVTable)))
  1233. {
  1234. SetLastError(ERROR_INVALID_PARAMETER);
  1235. goto Ret;
  1236. }
  1237. fProvCritSecSet = TRUE;
  1238. if (RCRYPT_FAILED(BuildVKey(&pVNewKey, pVTable)))
  1239. {
  1240. goto Ret;
  1241. }
  1242. if (RCRYPT_FAILED(pVKey->OptionalFuncDuplicateKey(pVTable->hProv, pVKey->hKey,
  1243. pdwReserved, dwFlags, &hNewKey)))
  1244. {
  1245. goto Ret;
  1246. }
  1247. pVNewKey->hKey = hNewKey;
  1248. pVNewKey->Version = TABLEKEY;
  1249. pVNewKey->hProv = pVKey->hProv;
  1250. pVKey->Inuse = 1;
  1251. *phKey = (HCRYPTKEY) pVNewKey;
  1252. }
  1253. __except ( EXCEPTION_EXECUTE_HANDLER )
  1254. {
  1255. SetLastError(ERROR_INVALID_PARAMETER);
  1256. goto Ret;
  1257. }
  1258. fRet = CRYPT_SUCCEED;
  1259. Ret:
  1260. dwErr = GetLastError();
  1261. if (fProvCritSecSet)
  1262. LeaveProviderCritSec(pVTable);
  1263. if (fRet == CRYPT_FAILED)
  1264. {
  1265. if (NULL != pVNewKey)
  1266. LocalFree(pVNewKey);
  1267. SetLastError(dwErr);
  1268. }
  1269. return fRet;
  1270. }
  1271. /*
  1272. - CryptDeriveKey
  1273. -
  1274. * Purpose:
  1275. * Derive cryptographic keys from base data
  1276. *
  1277. *
  1278. * Parameters:
  1279. * IN hProv - Handle to a CSP
  1280. * IN Algid - Algorithm identifier
  1281. * IN hHash - Handle to hash of base data
  1282. * IN dwFlags - Flags values
  1283. * IN OUT phKey - Handle to a generated key
  1284. *
  1285. * Returns:
  1286. */
  1287. WINADVAPI
  1288. BOOL
  1289. WINAPI CryptDeriveKey(IN HCRYPTPROV hProv,
  1290. IN ALG_ID Algid,
  1291. IN HCRYPTHASH hHash,
  1292. IN DWORD dwFlags,
  1293. IN OUT HCRYPTKEY * phKey)
  1294. {
  1295. PVTableStruc pVTable = NULL;
  1296. PVKeyStruc pVKey = NULL;
  1297. PVHashStruc pVHash = NULL;
  1298. BOOL fProvCritSec = FALSE;
  1299. BOOL fKeyCritSec = FALSE;
  1300. BOOL fHashCritSec = FALSE;
  1301. BOOL fUpdate = FALSE;
  1302. DWORD dwErr = 0;
  1303. BOOL fRet = CRYPT_FAILED;
  1304. __try
  1305. {
  1306. pVTable = (PVTableStruc) hProv;
  1307. if (RCRYPT_FAILED(EnterProviderCritSec(pVTable)))
  1308. {
  1309. goto Ret;
  1310. }
  1311. fProvCritSec = TRUE;
  1312. pVHash = (PVHashStruc) hHash;
  1313. if (RCRYPT_FAILED(EnterHashCritSec(pVHash)))
  1314. {
  1315. goto Ret;
  1316. }
  1317. fHashCritSec = TRUE;
  1318. if (dwFlags & CRYPT_UPDATE_KEY)
  1319. {
  1320. fUpdate = TRUE;
  1321. pVKey = (PVKeyStruc) phKey;
  1322. if (RCRYPT_FAILED(EnterKeyCritSec(pVKey)))
  1323. {
  1324. SetLastError(ERROR_INVALID_PARAMETER);
  1325. goto Ret;
  1326. }
  1327. fKeyCritSec = TRUE;
  1328. }
  1329. else
  1330. {
  1331. if (RCRYPT_FAILED(BuildVKey(&pVKey, pVTable)))
  1332. {
  1333. goto Ret;
  1334. }
  1335. }
  1336. if (RCRYPT_FAILED(pVTable->FuncDeriveKey(pVTable->hProv, Algid,
  1337. pVHash->hHash, dwFlags, phKey)))
  1338. {
  1339. goto Ret;
  1340. }
  1341. if ((dwFlags & CRYPT_UPDATE_KEY) != CRYPT_UPDATE_KEY)
  1342. {
  1343. pVKey->hKey = *phKey;
  1344. *phKey = (HCRYPTKEY)pVKey;
  1345. pVKey->hProv = hProv;
  1346. pVKey->Version = TABLEKEY;
  1347. pVKey->Inuse = 1;
  1348. }
  1349. } __except ( EXCEPTION_EXECUTE_HANDLER )
  1350. {
  1351. SetLastError(ERROR_INVALID_PARAMETER);
  1352. goto Ret;
  1353. }
  1354. fRet = CRYPT_SUCCEED;
  1355. Ret:
  1356. if (CRYPT_SUCCEED != fRet)
  1357. dwErr = GetLastError();
  1358. if (fProvCritSec)
  1359. LeaveProviderCritSec(pVTable);
  1360. if (fHashCritSec)
  1361. LeaveHashCritSec(pVHash);
  1362. if (fKeyCritSec)
  1363. LeaveKeyCritSec(pVKey);
  1364. if (CRYPT_SUCCEED != fRet)
  1365. {
  1366. if (pVKey && (!fUpdate))
  1367. LocalFree(pVKey);
  1368. SetLastError(dwErr);
  1369. }
  1370. return fRet;
  1371. }
  1372. /*
  1373. - CryptDestroyKey
  1374. -
  1375. * Purpose:
  1376. * Destroys the cryptographic key that is being referenced
  1377. * with the hKey parameter
  1378. *
  1379. *
  1380. * Parameters:
  1381. * IN hKey - Handle to a key
  1382. *
  1383. * Returns:
  1384. */
  1385. WINADVAPI
  1386. BOOL
  1387. WINAPI CryptDestroyKey(IN HCRYPTKEY hKey)
  1388. {
  1389. PVTableStruc pVTable = NULL;
  1390. PVKeyStruc pVKey;
  1391. BOOL fProvCritSec = FALSE;
  1392. BOOL rt;
  1393. DWORD dwErr = 0;
  1394. BOOL fRet = CRYPT_FAILED;
  1395. __try
  1396. {
  1397. pVKey = (PVKeyStruc) hKey;
  1398. if (pVKey->Version != TABLEKEY)
  1399. {
  1400. SetLastError(ERROR_INVALID_PARAMETER);
  1401. goto Ret;
  1402. }
  1403. if (0 < InterlockedDecrement((LPLONG)&pVKey->Inuse))
  1404. {
  1405. InterlockedIncrement((LPLONG)&pVKey->Inuse);
  1406. SetLastError(ERROR_BUSY);
  1407. goto Ret;
  1408. }
  1409. InterlockedIncrement((LPLONG)&pVKey->Inuse);
  1410. pVTable = (PVTableStruc) pVKey->hProv;
  1411. if (RCRYPT_FAILED(EnterProviderCritSec(pVTable)))
  1412. {
  1413. goto Ret;
  1414. }
  1415. fProvCritSec = TRUE;
  1416. if (FALSE == (rt = (BOOL)pVKey->FuncDestroyKey(pVTable->hProv, pVKey->hKey)))
  1417. dwErr = GetLastError();
  1418. pVKey->Version = 0;
  1419. LocalFree(pVKey);
  1420. if (!rt)
  1421. {
  1422. SetLastError(dwErr);
  1423. goto Ret;
  1424. }
  1425. } __except ( EXCEPTION_EXECUTE_HANDLER )
  1426. {
  1427. SetLastError(ERROR_INVALID_PARAMETER);
  1428. goto Ret;
  1429. }
  1430. fRet = CRYPT_SUCCEED;
  1431. Ret:
  1432. if (CRYPT_SUCCEED != fRet)
  1433. dwErr = GetLastError();
  1434. if (fProvCritSec)
  1435. LeaveProviderCritSec(pVTable);
  1436. if (CRYPT_SUCCEED != fRet)
  1437. SetLastError(dwErr);
  1438. return fRet;
  1439. }
  1440. /*
  1441. - CryptSetKeyParam
  1442. -
  1443. * Purpose:
  1444. * Allows applications to customize various aspects of the
  1445. * operations of a key
  1446. *
  1447. * Parameters:
  1448. * IN hKey - Handle to a key
  1449. * IN dwParam - Parameter number
  1450. * IN pbData - Pointer to data
  1451. * IN dwFlags - Flags values
  1452. *
  1453. * Returns:
  1454. */
  1455. WINADVAPI
  1456. BOOL
  1457. WINAPI CryptSetKeyParam(IN HCRYPTKEY hKey,
  1458. IN DWORD dwParam,
  1459. IN CONST BYTE *pbData,
  1460. IN DWORD dwFlags)
  1461. {
  1462. PVTableStruc pVTable = NULL;
  1463. PVKeyStruc pVKey;
  1464. BOOL rt = CRYPT_FAILED;
  1465. BOOL fCritSec = FALSE;
  1466. __try
  1467. {
  1468. pVKey = (PVKeyStruc) hKey;
  1469. if (pVKey->Version != TABLEKEY)
  1470. {
  1471. SetLastError(ERROR_INVALID_PARAMETER);
  1472. goto Ret;
  1473. }
  1474. if (0 < InterlockedDecrement((LPLONG)&pVKey->Inuse))
  1475. {
  1476. InterlockedIncrement((LPLONG)&pVKey->Inuse);
  1477. SetLastError(ERROR_BUSY);
  1478. goto Ret;
  1479. }
  1480. InterlockedIncrement((LPLONG)&pVKey->Inuse);
  1481. pVTable = (PVTableStruc) pVKey->hProv;
  1482. if (RCRYPT_FAILED(EnterProviderCritSec(pVTable)))
  1483. {
  1484. goto Ret;
  1485. }
  1486. fCritSec = TRUE;
  1487. rt = (BOOL)pVKey->FuncSetKeyParam(pVTable->hProv, pVKey->hKey,
  1488. dwParam, pbData, dwFlags);
  1489. }
  1490. __except ( EXCEPTION_EXECUTE_HANDLER )
  1491. {
  1492. SetLastError(ERROR_INVALID_PARAMETER);
  1493. goto Ret;
  1494. }
  1495. Ret:
  1496. if (fCritSec)
  1497. LeaveProviderCritSec(pVTable);
  1498. return(rt);
  1499. }
  1500. /*
  1501. - CryptGetKeyParam
  1502. -
  1503. * Purpose:
  1504. * Allows applications to get various aspects of the
  1505. * operations of a key
  1506. *
  1507. * Parameters:
  1508. * IN hKey - Handle to a key
  1509. * IN dwParam - Parameter number
  1510. * IN pbData - Pointer to data
  1511. * IN pdwDataLen - Length of parameter data
  1512. * IN dwFlags - Flags values
  1513. *
  1514. * Returns:
  1515. */
  1516. WINADVAPI
  1517. BOOL
  1518. WINAPI CryptGetKeyParam(IN HCRYPTKEY hKey,
  1519. IN DWORD dwParam,
  1520. IN BYTE *pbData,
  1521. IN DWORD *pdwDataLen,
  1522. IN DWORD dwFlags)
  1523. {
  1524. PVTableStruc pVTable = NULL;
  1525. PVKeyStruc pVKey = NULL;
  1526. BOOL rt = CRYPT_FAILED;
  1527. BOOL fKeyCritSec = FALSE;
  1528. BOOL fTableCritSec = FALSE;
  1529. __try
  1530. {
  1531. pVKey = (PVKeyStruc) hKey;
  1532. if (RCRYPT_FAILED(EnterKeyCritSec(pVKey)))
  1533. {
  1534. goto Ret;
  1535. }
  1536. fKeyCritSec = TRUE;
  1537. pVTable = (PVTableStruc) pVKey->hProv;
  1538. if (RCRYPT_FAILED(EnterProviderCritSec(pVTable)))
  1539. {
  1540. goto Ret;
  1541. }
  1542. fTableCritSec = TRUE;
  1543. rt = (BOOL)pVKey->FuncGetKeyParam(pVTable->hProv, pVKey->hKey,
  1544. dwParam, pbData, pdwDataLen,
  1545. dwFlags);
  1546. }
  1547. __except ( EXCEPTION_EXECUTE_HANDLER )
  1548. {
  1549. SetLastError(ERROR_INVALID_PARAMETER);
  1550. goto Ret;
  1551. }
  1552. Ret:
  1553. if (fKeyCritSec)
  1554. LeaveKeyCritSec(pVKey);
  1555. if (fTableCritSec)
  1556. LeaveProviderCritSec(pVTable);
  1557. return(rt);
  1558. }
  1559. /*
  1560. - CryptGenRandom
  1561. -
  1562. * Purpose:
  1563. * Used to fill a buffer with random bytes
  1564. *
  1565. *
  1566. * Parameters:
  1567. * IN hProv - Handle to the user identifcation
  1568. * IN dwLen - Number of bytes of random data requested
  1569. * OUT pbBuffer - Pointer to the buffer where the random
  1570. * bytes are to be placed
  1571. *
  1572. * Returns:
  1573. */
  1574. WINADVAPI
  1575. BOOL
  1576. WINAPI CryptGenRandom(IN HCRYPTPROV hProv,
  1577. IN DWORD dwLen,
  1578. OUT BYTE *pbBuffer)
  1579. {
  1580. PVTableStruc pVTable = NULL;
  1581. BOOL fTableCritSec = FALSE;
  1582. BOOL rt = CRYPT_FAILED;
  1583. __try
  1584. {
  1585. pVTable = (PVTableStruc) hProv;
  1586. if (RCRYPT_FAILED(EnterProviderCritSec(pVTable)))
  1587. {
  1588. goto Ret;
  1589. }
  1590. fTableCritSec = TRUE;
  1591. rt = (BOOL)pVTable->FuncGenRandom(pVTable->hProv, dwLen, pbBuffer);
  1592. } __except ( EXCEPTION_EXECUTE_HANDLER )
  1593. {
  1594. SetLastError(ERROR_INVALID_PARAMETER);
  1595. goto Ret;
  1596. }
  1597. Ret:
  1598. if (fTableCritSec)
  1599. LeaveProviderCritSec(pVTable);
  1600. return(rt);
  1601. }
  1602. /*
  1603. - CryptGetUserKey
  1604. -
  1605. * Purpose:
  1606. * Gets a handle to a permanent user key
  1607. *
  1608. *
  1609. * Parameters:
  1610. * IN hProv - Handle to the user identifcation
  1611. * IN dwKeySpec - Specification of the key to retrieve
  1612. * OUT phUserKey - Pointer to key handle of retrieved key
  1613. *
  1614. * Returns:
  1615. */
  1616. WINADVAPI
  1617. BOOL
  1618. WINAPI CryptGetUserKey(IN HCRYPTPROV hProv,
  1619. IN DWORD dwKeySpec,
  1620. OUT HCRYPTKEY *phUserKey)
  1621. {
  1622. PVTableStruc pVTable = NULL;
  1623. PVKeyStruc pVKey = NULL;
  1624. BOOL fTableCritSec = FALSE;
  1625. BOOL fRet = CRYPT_FAILED;
  1626. __try
  1627. {
  1628. pVTable = (PVTableStruc) hProv;
  1629. if (RCRYPT_FAILED(EnterProviderCritSec(pVTable)))
  1630. {
  1631. goto Ret;
  1632. }
  1633. fTableCritSec = TRUE;
  1634. if (RCRYPT_FAILED(BuildVKey(&pVKey, pVTable)))
  1635. {
  1636. goto Ret;
  1637. }
  1638. if (RCRYPT_FAILED(pVTable->FuncGetUserKey(pVTable->hProv, dwKeySpec,
  1639. phUserKey)))
  1640. {
  1641. goto Ret;
  1642. }
  1643. pVKey->hKey = *phUserKey;
  1644. pVKey->hProv = hProv;
  1645. *phUserKey = (HCRYPTKEY)pVKey;
  1646. pVKey->Version = TABLEKEY;
  1647. pVKey->Inuse = 1;
  1648. } __except ( EXCEPTION_EXECUTE_HANDLER )
  1649. {
  1650. SetLastError(ERROR_INVALID_PARAMETER);
  1651. goto Ret;
  1652. }
  1653. fRet = CRYPT_SUCCEED;
  1654. Ret:
  1655. if (fTableCritSec)
  1656. LeaveProviderCritSec(pVTable);
  1657. if ((CRYPT_SUCCEED != fRet) && pVKey)
  1658. LocalFree(pVKey);
  1659. return fRet;
  1660. }
  1661. /*
  1662. - CryptExportKey
  1663. -
  1664. * Purpose:
  1665. * Export cryptographic keys out of a CSP in a secure manner
  1666. *
  1667. *
  1668. * Parameters:
  1669. * IN hKey - Handle to the key to export
  1670. * IN hPubKey - Handle to the exchange public key value of
  1671. * the destination user
  1672. * IN dwBlobType - Type of key blob to be exported
  1673. * IN dwFlags - Flags values
  1674. * OUT pbData - Key blob data
  1675. * OUT pdwDataLen - Length of key blob in bytes
  1676. *
  1677. * Returns:
  1678. */
  1679. WINADVAPI
  1680. BOOL
  1681. WINAPI CryptExportKey(IN HCRYPTKEY hKey,
  1682. IN HCRYPTKEY hPubKey,
  1683. IN DWORD dwBlobType,
  1684. IN DWORD dwFlags,
  1685. OUT BYTE *pbData,
  1686. OUT DWORD *pdwDataLen)
  1687. {
  1688. PVTableStruc pVTable = NULL;
  1689. PVKeyStruc pVKey = NULL;
  1690. PVKeyStruc pVPublicKey = NULL;
  1691. BOOL fKeyCritSec = FALSE;
  1692. BOOL fPubKeyCritSec = FALSE;
  1693. BOOL fTableCritSec = FALSE;
  1694. BOOL rt = CRYPT_FAILED;
  1695. __try
  1696. {
  1697. pVKey = (PVKeyStruc) hKey;
  1698. if (RCRYPT_FAILED(EnterKeyCritSec(pVKey)))
  1699. {
  1700. goto Ret;
  1701. }
  1702. fKeyCritSec = TRUE;
  1703. pVTable = (PVTableStruc) pVKey->hProv;
  1704. if (RCRYPT_FAILED(EnterProviderCritSec(pVTable)))
  1705. {
  1706. goto Ret;
  1707. }
  1708. fTableCritSec = TRUE;
  1709. pVPublicKey = (PVKeyStruc) hPubKey;
  1710. if (pVPublicKey != NULL)
  1711. {
  1712. if (RCRYPT_FAILED(EnterKeyCritSec(pVPublicKey)))
  1713. {
  1714. goto Ret;
  1715. }
  1716. fPubKeyCritSec = TRUE;
  1717. }
  1718. rt = (BOOL)pVKey->FuncExportKey(pVTable->hProv, pVKey->hKey,
  1719. (pVPublicKey == NULL ? 0 : pVPublicKey->hKey),
  1720. dwBlobType, dwFlags, pbData,
  1721. pdwDataLen);
  1722. } __except ( EXCEPTION_EXECUTE_HANDLER )
  1723. {
  1724. SetLastError(ERROR_INVALID_PARAMETER);
  1725. goto Ret;
  1726. }
  1727. Ret:
  1728. if (fKeyCritSec)
  1729. LeaveKeyCritSec(pVKey);
  1730. if (fTableCritSec)
  1731. LeaveProviderCritSec(pVTable);
  1732. if (pVPublicKey != NULL)
  1733. {
  1734. if (fPubKeyCritSec)
  1735. LeaveKeyCritSec(pVPublicKey);
  1736. }
  1737. return(rt);
  1738. }
  1739. /*
  1740. - CryptImportKey
  1741. -
  1742. * Purpose:
  1743. * Import cryptographic keys
  1744. *
  1745. *
  1746. * Parameters:
  1747. * IN hProv - Handle to the CSP user
  1748. * IN pbData - Key blob data
  1749. * IN dwDataLen - Length of the key blob data
  1750. * IN hPubKey - Handle to the exchange public key value of
  1751. * the destination user
  1752. * IN dwFlags - Flags values
  1753. * OUT phKey - Pointer to the handle to the key which was
  1754. * Imported
  1755. *
  1756. * Returns:
  1757. */
  1758. WINADVAPI
  1759. BOOL
  1760. WINAPI CryptImportKey(IN HCRYPTPROV hProv,
  1761. IN CONST BYTE *pbData,
  1762. IN DWORD dwDataLen,
  1763. IN HCRYPTKEY hPubKey,
  1764. IN DWORD dwFlags,
  1765. OUT HCRYPTKEY *phKey)
  1766. {
  1767. PVTableStruc pVTable = NULL;
  1768. PVKeyStruc pVKey = NULL;
  1769. PVKeyStruc pVPublicKey = NULL;
  1770. BOOL fKeyCritSec = FALSE;
  1771. BOOL fPubKeyCritSec = FALSE;
  1772. BOOL fTableCritSec = FALSE;
  1773. BOOL fBuiltKey = FALSE;
  1774. BOOL fRet = CRYPT_FAILED;
  1775. __try
  1776. {
  1777. pVTable = (PVTableStruc) hProv;
  1778. if (RCRYPT_FAILED(EnterProviderCritSec(pVTable)))
  1779. {
  1780. goto Ret;
  1781. }
  1782. fTableCritSec = TRUE;
  1783. pVPublicKey = (PVKeyStruc)hPubKey;
  1784. if (pVPublicKey != NULL)
  1785. {
  1786. if (RCRYPT_FAILED(EnterKeyCritSec(pVPublicKey)))
  1787. {
  1788. goto Ret;
  1789. }
  1790. fPubKeyCritSec = TRUE;
  1791. }
  1792. if (dwFlags & CRYPT_UPDATE_KEY)
  1793. {
  1794. pVKey = (PVKeyStruc) phKey;
  1795. if (RCRYPT_FAILED(EnterKeyCritSec(pVKey)))
  1796. {
  1797. goto Ret;
  1798. }
  1799. fKeyCritSec = TRUE;
  1800. }
  1801. else
  1802. {
  1803. if (RCRYPT_FAILED(BuildVKey(&pVKey, pVTable)))
  1804. {
  1805. goto Ret;
  1806. }
  1807. fBuiltKey = TRUE;
  1808. }
  1809. if (RCRYPT_FAILED(pVTable->FuncImportKey(pVTable->hProv, pbData,
  1810. dwDataLen,
  1811. (pVPublicKey == NULL ? 0 : pVPublicKey->hKey),
  1812. dwFlags, phKey)))
  1813. {
  1814. goto Ret;
  1815. }
  1816. if ((dwFlags & CRYPT_UPDATE_KEY) != CRYPT_UPDATE_KEY)
  1817. {
  1818. pVKey->hKey = *phKey;
  1819. *phKey = (HCRYPTKEY) pVKey;
  1820. pVKey->hProv = hProv;
  1821. pVKey->Version = TABLEKEY;
  1822. }
  1823. }
  1824. __except ( EXCEPTION_EXECUTE_HANDLER )
  1825. {
  1826. SetLastError(ERROR_INVALID_PARAMETER);
  1827. goto Ret;
  1828. }
  1829. fRet = CRYPT_SUCCEED;
  1830. Ret:
  1831. if (fTableCritSec)
  1832. LeaveProviderCritSec(pVTable);
  1833. if (pVPublicKey != NULL)
  1834. {
  1835. if (fPubKeyCritSec)
  1836. LeaveKeyCritSec(pVPublicKey);
  1837. }
  1838. if ((dwFlags & CRYPT_UPDATE_KEY) && fKeyCritSec)
  1839. {
  1840. LeaveKeyCritSec(pVKey);
  1841. }
  1842. else if ((CRYPT_SUCCEED != fRet) && fBuiltKey && pVKey)
  1843. {
  1844. LocalFree(pVKey);
  1845. }
  1846. return fRet;
  1847. }
  1848. /*
  1849. - CryptEncrypt
  1850. -
  1851. * Purpose:
  1852. * Encrypt data
  1853. *
  1854. *
  1855. * Parameters:
  1856. * IN hKey - Handle to the key
  1857. * IN hHash - Optional handle to a hash
  1858. * IN Final - Boolean indicating if this is the final
  1859. * block of plaintext
  1860. * IN dwFlags - Flags values
  1861. * IN OUT pbData - Data to be encrypted
  1862. * IN OUT pdwDataLen - Pointer to the length of the data to be
  1863. * encrypted
  1864. * IN dwBufLen - Size of Data buffer
  1865. *
  1866. * Returns:
  1867. */
  1868. WINADVAPI
  1869. BOOL
  1870. WINAPI CryptEncrypt(IN HCRYPTKEY hKey,
  1871. IN HCRYPTHASH hHash,
  1872. IN BOOL Final,
  1873. IN DWORD dwFlags,
  1874. IN OUT BYTE *pbData,
  1875. IN OUT DWORD *pdwDataLen,
  1876. IN DWORD dwBufLen)
  1877. {
  1878. PVTableStruc pVTable = NULL;
  1879. PVKeyStruc pVKey = NULL;
  1880. PVHashStruc pVHash = NULL;
  1881. BOOL fKeyCritSec = FALSE;
  1882. BOOL fTableCritSec = FALSE;
  1883. BOOL fHashCritSec = FALSE;
  1884. BOOL rt = CRYPT_FAILED;
  1885. __try
  1886. {
  1887. pVKey = (PVKeyStruc) hKey;
  1888. if (RCRYPT_FAILED(EnterKeyCritSec(pVKey)))
  1889. {
  1890. goto Ret;
  1891. }
  1892. fKeyCritSec = TRUE;
  1893. pVTable = (PVTableStruc) pVKey->hProv;
  1894. if (RCRYPT_FAILED(EnterProviderCritSec(pVTable)))
  1895. {
  1896. goto Ret;
  1897. }
  1898. fTableCritSec = TRUE;
  1899. pVHash = (PVHashStruc) hHash;
  1900. if (pVHash != NULL)
  1901. {
  1902. if (RCRYPT_FAILED(EnterHashCritSec(pVHash)))
  1903. {
  1904. goto Ret;
  1905. }
  1906. fHashCritSec = TRUE;
  1907. }
  1908. rt = (BOOL)pVKey->FuncEncrypt(pVTable->hProv, pVKey->hKey,
  1909. (pVHash == NULL ? 0 : pVHash->hHash),
  1910. Final, dwFlags, pbData,
  1911. pdwDataLen, dwBufLen);
  1912. }
  1913. __except ( EXCEPTION_EXECUTE_HANDLER )
  1914. {
  1915. SetLastError(ERROR_INVALID_PARAMETER);
  1916. goto Ret;
  1917. }
  1918. Ret:
  1919. if (fTableCritSec)
  1920. LeaveProviderCritSec(pVTable);
  1921. if (fKeyCritSec)
  1922. LeaveKeyCritSec(pVKey);
  1923. if (pVHash != NULL)
  1924. {
  1925. if (fHashCritSec)
  1926. LeaveHashCritSec(pVHash);
  1927. }
  1928. return rt;
  1929. }
  1930. /*
  1931. - CryptDecrypt
  1932. -
  1933. * Purpose:
  1934. * Decrypt data
  1935. *
  1936. *
  1937. * Parameters:
  1938. * IN hKey - Handle to the key
  1939. * IN hHash - Optional handle to a hash
  1940. * IN Final - Boolean indicating if this is the final
  1941. * block of ciphertext
  1942. * IN dwFlags - Flags values
  1943. * IN OUT pbData - Data to be decrypted
  1944. * IN OUT pdwDataLen - Pointer to the length of the data to be
  1945. * decrypted
  1946. *
  1947. * Returns:
  1948. */
  1949. WINADVAPI
  1950. BOOL
  1951. WINAPI CryptDecrypt(IN HCRYPTKEY hKey,
  1952. IN HCRYPTHASH hHash,
  1953. IN BOOL Final,
  1954. IN DWORD dwFlags,
  1955. IN OUT BYTE *pbData,
  1956. IN OUT DWORD *pdwDataLen)
  1957. {
  1958. PVTableStruc pVTable = NULL;
  1959. PVKeyStruc pVKey = NULL;
  1960. PVHashStruc pVHash = NULL;
  1961. BOOL fKeyCritSec = FALSE;
  1962. BOOL fTableCritSec = FALSE;
  1963. BOOL fHashCritSec = FALSE;
  1964. BOOL rt = CRYPT_FAILED;
  1965. __try
  1966. {
  1967. pVKey = (PVKeyStruc) hKey;
  1968. if (RCRYPT_FAILED(EnterKeyCritSec(pVKey)))
  1969. {
  1970. goto Ret;
  1971. }
  1972. fKeyCritSec = TRUE;
  1973. pVTable = (PVTableStruc) pVKey->hProv;
  1974. if (RCRYPT_FAILED(EnterProviderCritSec(pVTable)))
  1975. {
  1976. goto Ret;
  1977. }
  1978. fTableCritSec = TRUE;
  1979. pVHash = (PVHashStruc) hHash;
  1980. if (pVHash != NULL)
  1981. {
  1982. if (RCRYPT_FAILED(EnterHashCritSec(pVHash)))
  1983. {
  1984. goto Ret;
  1985. }
  1986. fHashCritSec = TRUE;
  1987. }
  1988. rt = (BOOL)pVKey->FuncDecrypt(pVTable->hProv, pVKey->hKey,
  1989. (pVHash == NULL ? 0 : pVHash->hHash),
  1990. Final, dwFlags, pbData, pdwDataLen);
  1991. }
  1992. __except ( EXCEPTION_EXECUTE_HANDLER )
  1993. {
  1994. SetLastError(ERROR_INVALID_PARAMETER);
  1995. goto Ret;
  1996. }
  1997. Ret:
  1998. if (fTableCritSec)
  1999. LeaveProviderCritSec(pVTable);
  2000. if (fKeyCritSec)
  2001. LeaveKeyCritSec(pVKey);
  2002. if (pVHash != NULL)
  2003. {
  2004. if (fHashCritSec)
  2005. LeaveHashCritSec(pVHash);
  2006. }
  2007. return(rt);
  2008. }
  2009. /*
  2010. - CryptCreateHash
  2011. -
  2012. * Purpose:
  2013. * initate the hashing of a stream of data
  2014. *
  2015. *
  2016. * Parameters:
  2017. * IN hProv - Handle to the user identifcation
  2018. * IN Algid - Algorithm identifier of the hash algorithm
  2019. * to be used
  2020. * IN hKey - Optional key for MAC algorithms
  2021. * IN dwFlags - Flags values
  2022. * OUT pHash - Handle to hash object
  2023. *
  2024. * Returns:
  2025. */
  2026. WINADVAPI
  2027. BOOL
  2028. WINAPI CryptCreateHash(IN HCRYPTPROV hProv,
  2029. IN ALG_ID Algid,
  2030. IN HCRYPTKEY hKey,
  2031. IN DWORD dwFlags,
  2032. OUT HCRYPTHASH *phHash)
  2033. {
  2034. PVTableStruc pVTable = NULL;
  2035. DWORD bufsize;
  2036. PVKeyStruc pVKey = NULL;
  2037. PVHashStruc pVHash = NULL;
  2038. BOOL fTableCritSec = FALSE;
  2039. BOOL fKeyCritSec = FALSE;
  2040. BOOL fRet = CRYPT_FAILED;
  2041. __try
  2042. {
  2043. pVTable = (PVTableStruc) hProv;
  2044. if (RCRYPT_FAILED(EnterProviderCritSec(pVTable)))
  2045. {
  2046. SetLastError(ERROR_INVALID_PARAMETER);
  2047. goto Ret;
  2048. }
  2049. fTableCritSec = TRUE;
  2050. pVKey = (PVKeyStruc) hKey;
  2051. if (pVKey != NULL)
  2052. {
  2053. if (RCRYPT_FAILED(EnterKeyCritSec(pVKey)))
  2054. {
  2055. SetLastError(ERROR_INVALID_PARAMETER);
  2056. goto Ret;
  2057. }
  2058. fKeyCritSec = TRUE;
  2059. }
  2060. bufsize = sizeof(VHashStruc);
  2061. if (!BuildVHash(&pVHash, pVTable))
  2062. {
  2063. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  2064. goto Ret;
  2065. }
  2066. if (RCRYPT_FAILED(pVTable->FuncCreateHash(pVTable->hProv, Algid,
  2067. (pVKey == NULL ? 0 : pVKey->hKey),
  2068. dwFlags, phHash)))
  2069. {
  2070. goto Ret;
  2071. }
  2072. pVHash->hHash = *phHash;
  2073. *phHash = (HCRYPTHASH) pVHash;
  2074. pVHash->Version = TABLEHASH;
  2075. pVHash->Inuse = 1;
  2076. }
  2077. __except ( EXCEPTION_EXECUTE_HANDLER )
  2078. {
  2079. SetLastError(ERROR_INVALID_PARAMETER);
  2080. goto Ret;
  2081. }
  2082. fRet = CRYPT_SUCCEED;
  2083. Ret:
  2084. if (fTableCritSec)
  2085. LeaveProviderCritSec(pVTable);
  2086. if (pVKey != NULL)
  2087. {
  2088. if (fKeyCritSec)
  2089. LeaveKeyCritSec(pVKey);
  2090. }
  2091. if ((CRYPT_SUCCEED != fRet) && pVHash)
  2092. LocalFree(pVHash);
  2093. return fRet;
  2094. }
  2095. /*
  2096. - CryptDuplicateHash
  2097. -
  2098. * Purpose:
  2099. * Duplicate a cryptographic hash
  2100. *
  2101. *
  2102. * Parameters:
  2103. * IN hHash - Handle to the hash to be duplicated
  2104. * IN pdwReserved - Reserved for later use
  2105. * IN dwFlags - Flags values
  2106. * OUT phHash - Handle to the new duplicate hash
  2107. *
  2108. * Returns:
  2109. */
  2110. WINADVAPI
  2111. BOOL
  2112. WINAPI CryptDuplicateHash(
  2113. IN HCRYPTHASH hHash,
  2114. IN DWORD *pdwReserved,
  2115. IN DWORD dwFlags,
  2116. OUT HCRYPTHASH * phHash
  2117. )
  2118. {
  2119. PVTableStruc pVTable = NULL;
  2120. PVHashStruc pVHash;
  2121. PVHashStruc pVNewHash = NULL;
  2122. HCRYPTHASH hNewHash;
  2123. BOOL fProvCritSecSet = FALSE;
  2124. DWORD dwErr = 0;
  2125. BOOL fRet = CRYPT_FAILED;
  2126. __try
  2127. {
  2128. if (IsBadWritePtr(phHash, sizeof(HCRYPTHASH)))
  2129. {
  2130. SetLastError(ERROR_INVALID_PARAMETER);
  2131. goto Ret;
  2132. }
  2133. pVHash = (PVHashStruc) hHash;
  2134. if (pVHash->Version != TABLEHASH)
  2135. {
  2136. SetLastError(ERROR_INVALID_PARAMETER);
  2137. goto Ret;
  2138. }
  2139. if (NULL == pVHash->OptionalFuncDuplicateHash)
  2140. {
  2141. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  2142. goto Ret;
  2143. }
  2144. pVTable = (PVTableStruc) pVHash->hProv;
  2145. if (RCRYPT_FAILED(EnterProviderCritSec(pVTable)))
  2146. {
  2147. SetLastError(ERROR_INVALID_PARAMETER);
  2148. goto Ret;
  2149. }
  2150. fProvCritSecSet = TRUE;
  2151. if (RCRYPT_FAILED(BuildVHash(&pVNewHash, pVTable)))
  2152. {
  2153. goto Ret;
  2154. }
  2155. if (RCRYPT_FAILED(pVHash->OptionalFuncDuplicateHash(pVTable->hProv, pVHash->hHash,
  2156. pdwReserved, dwFlags, &hNewHash)))
  2157. {
  2158. goto Ret;
  2159. }
  2160. pVNewHash->hHash = hNewHash;
  2161. pVNewHash->Version = TABLEHASH;
  2162. pVNewHash->hProv = pVHash->hProv;
  2163. pVHash->Inuse = 1;
  2164. *phHash = (HCRYPTHASH) pVNewHash;
  2165. }
  2166. __except ( EXCEPTION_EXECUTE_HANDLER )
  2167. {
  2168. SetLastError(ERROR_INVALID_PARAMETER);
  2169. goto Ret;
  2170. }
  2171. fRet = CRYPT_SUCCEED;
  2172. Ret:
  2173. if (CRYPT_SUCCEED != fRet)
  2174. dwErr = GetLastError();
  2175. if ((fRet == CRYPT_FAILED) && (NULL != pVNewHash))
  2176. LocalFree(pVNewHash);
  2177. if (fProvCritSecSet)
  2178. LeaveProviderCritSec(pVTable);
  2179. if (CRYPT_SUCCEED != fRet)
  2180. SetLastError(dwErr);
  2181. return fRet;
  2182. }
  2183. /*
  2184. - CryptHashData
  2185. -
  2186. * Purpose:
  2187. * Compute the cryptograghic hash on a stream of data
  2188. *
  2189. *
  2190. * Parameters:
  2191. * IN hHash - Handle to hash object
  2192. * IN pbData - Pointer to data to be hashed
  2193. * IN dwDataLen - Length of the data to be hashed
  2194. * IN dwFlags - Flags values
  2195. *
  2196. *
  2197. * Returns:
  2198. */
  2199. WINADVAPI
  2200. BOOL
  2201. WINAPI CryptHashData(IN HCRYPTHASH hHash,
  2202. IN CONST BYTE *pbData,
  2203. IN DWORD dwDataLen,
  2204. IN DWORD dwFlags)
  2205. {
  2206. PVTableStruc pVTable = NULL;
  2207. PVHashStruc pVHash = NULL;
  2208. BOOL fProvCritSec = FALSE;
  2209. BOOL fHashCritSec = FALSE;
  2210. DWORD dwErr = 0;
  2211. BOOL fRet = CRYPT_FAILED;
  2212. __try
  2213. {
  2214. pVHash = (PVHashStruc) hHash;
  2215. if (RCRYPT_FAILED(EnterHashCritSec(pVHash)))
  2216. {
  2217. goto Ret;
  2218. }
  2219. fHashCritSec = TRUE;
  2220. pVTable = (PVTableStruc) pVHash->hProv;
  2221. if (RCRYPT_FAILED(EnterProviderCritSec(pVTable)))
  2222. {
  2223. goto Ret;
  2224. }
  2225. fProvCritSec = TRUE;
  2226. if (!pVHash->FuncHashData(pVTable->hProv,
  2227. pVHash->hHash,
  2228. pbData, dwDataLen, dwFlags))
  2229. goto Ret;
  2230. } __except ( EXCEPTION_EXECUTE_HANDLER )
  2231. {
  2232. SetLastError(ERROR_INVALID_PARAMETER);
  2233. goto Ret;
  2234. }
  2235. fRet = CRYPT_SUCCEED;
  2236. Ret:
  2237. if (CRYPT_SUCCEED != fRet)
  2238. dwErr = GetLastError();
  2239. if (fHashCritSec)
  2240. LeaveHashCritSec(pVHash);
  2241. if (fProvCritSec)
  2242. LeaveProviderCritSec(pVTable);
  2243. if (CRYPT_SUCCEED != fRet)
  2244. SetLastError(dwErr);
  2245. return fRet;
  2246. }
  2247. /*
  2248. - CryptHashSessionKey
  2249. -
  2250. * Purpose:
  2251. * Compute the cryptograghic hash on a key object
  2252. *
  2253. *
  2254. * Parameters:
  2255. * IN hHash - Handle to hash object
  2256. * IN hKey - Handle to a key object
  2257. * IN dwFlags - Flags values
  2258. *
  2259. * Returns:
  2260. * CRYPT_FAILED
  2261. * CRYPT_SUCCEED
  2262. */
  2263. WINADVAPI
  2264. BOOL
  2265. WINAPI CryptHashSessionKey(IN HCRYPTHASH hHash,
  2266. IN HCRYPTKEY hKey,
  2267. IN DWORD dwFlags)
  2268. {
  2269. PVTableStruc pVTable = NULL;
  2270. PVHashStruc pVHash = NULL;
  2271. PVKeyStruc pVKey = NULL;
  2272. BOOL fHashCritSec = FALSE;
  2273. BOOL fProvCritSec = FALSE;
  2274. BOOL fKeyCritSec = FALSE;
  2275. BOOL rt = CRYPT_FAILED;
  2276. __try
  2277. {
  2278. pVHash = (PVHashStruc) hHash;
  2279. if (RCRYPT_FAILED(EnterHashCritSec(pVHash)))
  2280. {
  2281. goto Ret;
  2282. }
  2283. fHashCritSec = TRUE;
  2284. pVTable = (PVTableStruc) pVHash->hProv;
  2285. if (RCRYPT_FAILED(EnterProviderCritSec(pVTable)))
  2286. {
  2287. goto Ret;
  2288. }
  2289. fProvCritSec = TRUE;
  2290. pVKey = (PVKeyStruc) hKey;
  2291. if (pVKey != NULL)
  2292. {
  2293. if (RCRYPT_FAILED(EnterKeyCritSec(pVKey)))
  2294. {
  2295. goto Ret;
  2296. }
  2297. fKeyCritSec = TRUE;
  2298. }
  2299. rt = (BOOL)pVHash->FuncHashSessionKey(pVTable->hProv,
  2300. pVHash->hHash,
  2301. pVKey->hKey,
  2302. dwFlags);
  2303. } __except ( EXCEPTION_EXECUTE_HANDLER )
  2304. {
  2305. SetLastError(ERROR_INVALID_PARAMETER);
  2306. goto Ret;
  2307. }
  2308. Ret:
  2309. if (fHashCritSec)
  2310. LeaveHashCritSec(pVHash);
  2311. if (fProvCritSec)
  2312. LeaveProviderCritSec(pVTable);
  2313. if (pVKey != NULL)
  2314. {
  2315. if (fKeyCritSec)
  2316. LeaveKeyCritSec(pVKey);
  2317. }
  2318. return rt;
  2319. }
  2320. /*
  2321. - CryptDestoryHash
  2322. -
  2323. * Purpose:
  2324. * Destory the hash object
  2325. *
  2326. *
  2327. * Parameters:
  2328. * IN hHash - Handle to hash object
  2329. *
  2330. * Returns:
  2331. */
  2332. WINADVAPI
  2333. BOOL
  2334. WINAPI CryptDestroyHash(IN HCRYPTHASH hHash)
  2335. {
  2336. PVTableStruc pVTable = NULL;
  2337. PVHashStruc pVHash;
  2338. BOOL fProvCritSec = FALSE;
  2339. BOOL rt = CRYPT_FAILED;
  2340. __try
  2341. {
  2342. pVHash = (PVHashStruc) hHash;
  2343. if (pVHash->Version != TABLEHASH)
  2344. {
  2345. SetLastError(ERROR_INVALID_PARAMETER);
  2346. goto Ret;
  2347. }
  2348. if (0 < InterlockedDecrement((LPLONG)&pVHash->Inuse))
  2349. {
  2350. InterlockedIncrement((LPLONG)&pVHash->Inuse);
  2351. SetLastError(ERROR_BUSY);
  2352. goto Ret;
  2353. }
  2354. InterlockedIncrement((LPLONG)&pVHash->Inuse);
  2355. pVTable = (PVTableStruc) pVHash->hProv;
  2356. if (RCRYPT_FAILED(EnterProviderCritSec(pVTable)))
  2357. {
  2358. goto Ret;
  2359. }
  2360. fProvCritSec = TRUE;
  2361. rt = (BOOL)pVHash->FuncDestroyHash(pVTable->hProv, pVHash->hHash);
  2362. pVHash->Version = 0;
  2363. LocalFree(pVHash);
  2364. }
  2365. __except ( EXCEPTION_EXECUTE_HANDLER )
  2366. {
  2367. SetLastError(ERROR_INVALID_PARAMETER);
  2368. goto Ret;
  2369. }
  2370. Ret:
  2371. if (fProvCritSec)
  2372. LeaveProviderCritSec(pVTable);
  2373. return rt;
  2374. }
  2375. WINADVAPI
  2376. BOOL
  2377. WINAPI LocalSignHashW(IN HCRYPTHASH hHash,
  2378. IN DWORD dwKeySpec,
  2379. IN LPCWSTR sDescription,
  2380. IN DWORD dwFlags,
  2381. OUT BYTE *pbSignature,
  2382. OUT DWORD *pdwSigLen)
  2383. {
  2384. PVTableStruc pVTable = NULL;
  2385. PVHashStruc pVHash = NULL;
  2386. BOOL fHashCritSec = FALSE;
  2387. BOOL fProvCritSec = FALSE;
  2388. BOOL rt = CRYPT_FAILED;
  2389. __try
  2390. {
  2391. pVHash = (PVHashStruc) hHash;
  2392. if (RCRYPT_FAILED(EnterHashCritSec(pVHash)))
  2393. {
  2394. goto Ret;
  2395. }
  2396. fHashCritSec = TRUE;
  2397. pVTable = (PVTableStruc) pVHash->hProv;
  2398. if (RCRYPT_FAILED(EnterProviderCritSec(pVTable)))
  2399. {
  2400. goto Ret;
  2401. }
  2402. fProvCritSec = TRUE;
  2403. rt = (BOOL)pVHash->FuncSignHash(pVTable->hProv, pVHash->hHash,
  2404. dwKeySpec,
  2405. sDescription, dwFlags,
  2406. pbSignature, pdwSigLen);
  2407. }
  2408. __except ( EXCEPTION_EXECUTE_HANDLER )
  2409. {
  2410. SetLastError(ERROR_INVALID_PARAMETER);
  2411. goto Ret;
  2412. }
  2413. Ret:
  2414. if (fHashCritSec)
  2415. LeaveHashCritSec(pVHash);
  2416. if (fProvCritSec)
  2417. LeaveProviderCritSec(pVTable);
  2418. return rt;
  2419. }
  2420. /*
  2421. - CryptSignHashW
  2422. -
  2423. * Purpose:
  2424. * Create a digital signature from a hash
  2425. *
  2426. *
  2427. * Parameters:
  2428. * IN hHash - Handle to hash object
  2429. * IN dwKeySpec - Key pair that is used to sign with
  2430. * algorithm to be used
  2431. * IN sDescription - Description of data to be signed
  2432. * IN dwFlags - Flags values
  2433. * OUT pbSignture - Pointer to signature data
  2434. * OUT pdwSigLen - Pointer to the len of the signature data
  2435. *
  2436. * Returns:
  2437. */
  2438. #ifndef WIN95
  2439. WINADVAPI
  2440. BOOL
  2441. WINAPI CryptSignHashW(IN HCRYPTHASH hHash,
  2442. IN DWORD dwKeySpec,
  2443. IN LPCWSTR sDescription,
  2444. IN DWORD dwFlags,
  2445. OUT BYTE *pbSignature,
  2446. OUT DWORD *pdwSigLen)
  2447. {
  2448. return LocalSignHashW(hHash, dwKeySpec, sDescription,
  2449. dwFlags, pbSignature, pdwSigLen);
  2450. }
  2451. #else
  2452. WINADVAPI
  2453. BOOL
  2454. WINAPI CryptSignHashW(IN HCRYPTHASH hHash,
  2455. IN DWORD dwKeySpec,
  2456. IN LPCWSTR sDescription,
  2457. IN DWORD dwFlags,
  2458. OUT BYTE *pbSignature,
  2459. OUT DWORD *pdwSigLen)
  2460. {
  2461. SetLastError((DWORD)ERROR_CALL_NOT_IMPLEMENTED);
  2462. return CRYPT_FAILED;
  2463. }
  2464. #endif
  2465. /*
  2466. - CryptSignHashA
  2467. -
  2468. * Purpose:
  2469. * Create a digital signature from a hash
  2470. *
  2471. *
  2472. * Parameters:
  2473. * IN hHash - Handle to hash object
  2474. * IN dwKeySpec - Key pair that is used to sign with
  2475. * algorithm to be used
  2476. * IN sDescription - Description of data to be signed
  2477. * IN dwFlags - Flags values
  2478. * OUT pbSignture - Pointer to signature data
  2479. * OUT pdwSigLen - Pointer to the len of the signature data
  2480. *
  2481. * Returns:
  2482. */
  2483. WINADVAPI
  2484. BOOL
  2485. WINAPI CryptSignHashA(IN HCRYPTHASH hHash,
  2486. IN DWORD dwKeySpec,
  2487. IN LPCSTR sDescription,
  2488. IN DWORD dwFlags,
  2489. OUT BYTE *pbSignature,
  2490. OUT DWORD *pdwSigLen)
  2491. {
  2492. ANSI_STRING AnsiString;
  2493. UNICODE_STRING UnicodeString;
  2494. NTSTATUS Status;
  2495. BOOL rt = CRYPT_FAILED;
  2496. __try
  2497. {
  2498. memset(&AnsiString, 0, sizeof(AnsiString));
  2499. memset(&UnicodeString, 0, sizeof(UnicodeString));
  2500. if (NULL != sDescription)
  2501. {
  2502. RtlInitAnsiString(&AnsiString, sDescription);
  2503. #ifdef WIN95
  2504. Status = AnsiStringToUnicodeString(&UnicodeString, &AnsiString);
  2505. #else
  2506. Status = RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, TRUE);
  2507. #endif
  2508. if ( !NT_SUCCESS(Status) )
  2509. {
  2510. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  2511. goto Ret;
  2512. }
  2513. }
  2514. rt = LocalSignHashW(hHash, dwKeySpec, UnicodeString.Buffer,
  2515. dwFlags, pbSignature, pdwSigLen);
  2516. #ifdef WIN95
  2517. FreeUnicodeString(&UnicodeString);
  2518. #else
  2519. RtlFreeUnicodeString(&UnicodeString);
  2520. #endif
  2521. } __except ( EXCEPTION_EXECUTE_HANDLER )
  2522. {
  2523. SetLastError(ERROR_INVALID_PARAMETER);
  2524. goto Ret;
  2525. }
  2526. Ret:
  2527. return rt;
  2528. }
  2529. WINADVAPI
  2530. BOOL
  2531. WINAPI LocalVerifySignatureW(IN HCRYPTHASH hHash,
  2532. IN CONST BYTE *pbSignature,
  2533. IN DWORD dwSigLen,
  2534. IN HCRYPTKEY hPubKey,
  2535. IN LPCWSTR sDescription,
  2536. IN DWORD dwFlags)
  2537. {
  2538. PVTableStruc pVTable = NULL;
  2539. PVHashStruc pVHash = NULL;
  2540. PVKeyStruc pVKey = NULL;
  2541. BOOL fHashCritSec = FALSE;
  2542. BOOL fProvCritSec = FALSE;
  2543. BOOL fKeyCritSec = FALSE;
  2544. BOOL rt = CRYPT_FAILED;
  2545. __try
  2546. {
  2547. pVHash = (PVHashStruc) hHash;
  2548. if (RCRYPT_FAILED(EnterHashCritSec(pVHash)))
  2549. {
  2550. goto Ret;
  2551. }
  2552. fHashCritSec = TRUE;
  2553. pVTable = (PVTableStruc) pVHash->hProv;
  2554. if (RCRYPT_FAILED(EnterProviderCritSec(pVTable)))
  2555. {
  2556. goto Ret;
  2557. }
  2558. fProvCritSec = TRUE;
  2559. pVKey = (PVKeyStruc) hPubKey;
  2560. if (RCRYPT_FAILED(EnterKeyCritSec(pVKey)))
  2561. {
  2562. goto Ret;
  2563. }
  2564. fKeyCritSec = TRUE;
  2565. rt = (BOOL)pVHash->FuncVerifySignature(pVTable->hProv,
  2566. pVHash->hHash, pbSignature,
  2567. dwSigLen,
  2568. (pVKey == NULL ? 0 : pVKey->hKey),
  2569. sDescription, dwFlags);
  2570. }
  2571. __except ( EXCEPTION_EXECUTE_HANDLER )
  2572. {
  2573. SetLastError(ERROR_INVALID_PARAMETER);
  2574. goto Ret;
  2575. }
  2576. Ret:
  2577. if (fHashCritSec)
  2578. LeaveHashCritSec(pVHash);
  2579. if (fProvCritSec)
  2580. LeaveProviderCritSec(pVTable);
  2581. if (fKeyCritSec)
  2582. LeaveKeyCritSec(pVKey);
  2583. return rt;
  2584. }
  2585. /*
  2586. - CryptVerifySignatureW
  2587. -
  2588. * Purpose:
  2589. * Used to verify a signature against a hash object
  2590. *
  2591. *
  2592. * Parameters:
  2593. * IN hHash - Handle to hash object
  2594. * IN pbSignture - Pointer to signature data
  2595. * IN dwSigLen - Length of the signature data
  2596. * IN hPubKey - Handle to the public key for verifying
  2597. * the signature
  2598. * IN sDescription - String describing the signed data
  2599. * IN dwFlags - Flags values
  2600. *
  2601. * Returns:
  2602. */
  2603. #ifndef WIN95
  2604. WINADVAPI
  2605. BOOL
  2606. WINAPI CryptVerifySignatureW(IN HCRYPTHASH hHash,
  2607. IN CONST BYTE *pbSignature,
  2608. IN DWORD dwSigLen,
  2609. IN HCRYPTKEY hPubKey,
  2610. IN LPCWSTR sDescription,
  2611. IN DWORD dwFlags)
  2612. {
  2613. return LocalVerifySignatureW(hHash, pbSignature, dwSigLen,
  2614. hPubKey, sDescription, dwFlags);
  2615. }
  2616. #else
  2617. WINADVAPI
  2618. BOOL
  2619. WINAPI CryptVerifySignatureW(IN HCRYPTHASH hHash,
  2620. IN CONST BYTE *pbSignature,
  2621. IN DWORD dwSigLen,
  2622. IN HCRYPTKEY hPubKey,
  2623. IN LPCWSTR sDescription,
  2624. IN DWORD dwFlags)
  2625. {
  2626. SetLastError((DWORD)ERROR_CALL_NOT_IMPLEMENTED);
  2627. return CRYPT_FAILED;
  2628. }
  2629. #endif
  2630. /*
  2631. - CryptVerifySignatureA
  2632. -
  2633. * Purpose:
  2634. * Used to verify a signature against a hash object
  2635. *
  2636. *
  2637. * Parameters:
  2638. * IN hHash - Handle to hash object
  2639. * IN pbSignture - Pointer to signature data
  2640. * IN dwSigLen - Length of the signature data
  2641. * IN hPubKey - Handle to the public key for verifying
  2642. * the signature
  2643. * IN sDescription - String describing the signed data
  2644. * IN dwFlags - Flags values
  2645. *
  2646. * Returns:
  2647. */
  2648. WINADVAPI
  2649. BOOL
  2650. WINAPI CryptVerifySignatureA(IN HCRYPTHASH hHash,
  2651. IN CONST BYTE *pbSignature,
  2652. IN DWORD dwSigLen,
  2653. IN HCRYPTKEY hPubKey,
  2654. IN LPCSTR sDescription,
  2655. IN DWORD dwFlags)
  2656. {
  2657. ANSI_STRING AnsiString;
  2658. UNICODE_STRING UnicodeString;
  2659. NTSTATUS Status;
  2660. BOOL rt = CRYPT_FAILED;
  2661. __try
  2662. {
  2663. memset(&AnsiString, 0, sizeof(AnsiString));
  2664. memset(&UnicodeString, 0, sizeof(UnicodeString));
  2665. if (NULL != sDescription)
  2666. {
  2667. RtlInitAnsiString(&AnsiString, sDescription);
  2668. #ifdef WIN95
  2669. Status = AnsiStringToUnicodeString(&UnicodeString, &AnsiString);
  2670. #else
  2671. Status = RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, TRUE);
  2672. #endif
  2673. if ( !NT_SUCCESS(Status) )
  2674. {
  2675. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  2676. goto Ret;
  2677. }
  2678. }
  2679. rt = LocalVerifySignatureW(hHash, pbSignature, dwSigLen,
  2680. hPubKey, UnicodeString.Buffer, dwFlags);
  2681. #ifdef WIN95
  2682. FreeUnicodeString(&UnicodeString);
  2683. #else
  2684. RtlFreeUnicodeString(&UnicodeString);
  2685. #endif
  2686. }
  2687. __except ( EXCEPTION_EXECUTE_HANDLER )
  2688. {
  2689. SetLastError(ERROR_INVALID_PARAMETER);
  2690. goto Ret;
  2691. }
  2692. Ret:
  2693. return rt;
  2694. }
  2695. /*
  2696. - CryptSetProvParam
  2697. -
  2698. * Purpose:
  2699. * Allows applications to customize various aspects of the
  2700. * operations of a provider
  2701. *
  2702. * Parameters:
  2703. * IN hProv - Handle to a provider
  2704. * IN dwParam - Parameter number
  2705. * IN pbData - Pointer to data
  2706. * IN dwFlags - Flags values
  2707. *
  2708. * Returns:
  2709. */
  2710. WINADVAPI
  2711. BOOL
  2712. WINAPI CryptSetProvParam(IN HCRYPTPROV hProv,
  2713. IN DWORD dwParam,
  2714. IN CONST BYTE *pbData,
  2715. IN DWORD dwFlags)
  2716. {
  2717. PVTableStruc pVTable;
  2718. BYTE *pbTmp;
  2719. CRYPT_DATA_BLOB *pBlob;
  2720. BOOL rt = CRYPT_FAILED;
  2721. __try
  2722. {
  2723. if (dwParam == PP_CLIENT_HWND)
  2724. {
  2725. hWnd = *((HWND *) pbData);
  2726. rt = CRYPT_SUCCEED;
  2727. goto Ret;
  2728. }
  2729. else if (dwParam == PP_CONTEXT_INFO)
  2730. {
  2731. pBlob = (CRYPT_DATA_BLOB*)pbData;
  2732. // allocate space for the new context info
  2733. if (NULL == (pbTmp = (BYTE*)LocalAlloc(LMEM_ZEROINIT, pBlob->cbData)))
  2734. {
  2735. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  2736. goto Ret;
  2737. }
  2738. memcpy(pbTmp, pBlob->pbData, pBlob->cbData);
  2739. // free any previously allocated context info
  2740. if (NULL != pbContextInfo)
  2741. {
  2742. LocalFree(pbContextInfo);
  2743. }
  2744. cbContextInfo = pBlob->cbData;
  2745. pbContextInfo = pbTmp;
  2746. rt = CRYPT_SUCCEED;
  2747. goto Ret;
  2748. }
  2749. pVTable = (PVTableStruc) hProv;
  2750. if (pVTable->Version != TABLEPROV)
  2751. {
  2752. SetLastError(ERROR_INVALID_PARAMETER);
  2753. goto Ret;
  2754. }
  2755. if (0 < InterlockedDecrement((LPLONG)&pVTable->Inuse))
  2756. {
  2757. InterlockedIncrement((LPLONG)&pVTable->Inuse);
  2758. SetLastError(ERROR_BUSY);
  2759. goto Ret;
  2760. }
  2761. InterlockedIncrement((LPLONG)&pVTable->Inuse);
  2762. rt = (BOOL)pVTable->FuncSetProvParam(pVTable->hProv, dwParam, pbData,
  2763. dwFlags);
  2764. }
  2765. __except ( EXCEPTION_EXECUTE_HANDLER )
  2766. {
  2767. SetLastError(ERROR_INVALID_PARAMETER);
  2768. goto Ret;
  2769. }
  2770. Ret:
  2771. return(rt);
  2772. }
  2773. /*
  2774. - CryptGetProvParam
  2775. -
  2776. * Purpose:
  2777. * Allows applications to get various aspects of the
  2778. * operations of a provider
  2779. *
  2780. * Parameters:
  2781. * IN hProv - Handle to a proivder
  2782. * IN dwParam - Parameter number
  2783. * IN pbData - Pointer to data
  2784. * IN pdwDataLen - Length of parameter data
  2785. * IN dwFlags - Flags values
  2786. *
  2787. * Returns:
  2788. */
  2789. WINADVAPI
  2790. BOOL
  2791. WINAPI CryptGetProvParam(IN HCRYPTPROV hProv,
  2792. IN DWORD dwParam,
  2793. IN BYTE *pbData,
  2794. IN DWORD *pdwDataLen,
  2795. IN DWORD dwFlags)
  2796. {
  2797. PVTableStruc pVTable = NULL;
  2798. BOOL fProvCritSec = FALSE;
  2799. BOOL rt = CRYPT_FAILED;
  2800. __try
  2801. {
  2802. pVTable = (PVTableStruc) hProv;
  2803. if (RCRYPT_FAILED(EnterProviderCritSec(pVTable)))
  2804. {
  2805. goto Ret;
  2806. }
  2807. fProvCritSec = TRUE;
  2808. rt = (BOOL)pVTable->FuncGetProvParam(pVTable->hProv, dwParam, pbData,
  2809. pdwDataLen, dwFlags);
  2810. }
  2811. __except ( EXCEPTION_EXECUTE_HANDLER )
  2812. {
  2813. SetLastError(ERROR_INVALID_PARAMETER);
  2814. goto Ret;
  2815. }
  2816. Ret:
  2817. if (fProvCritSec)
  2818. LeaveProviderCritSec(pVTable);
  2819. return rt;
  2820. }
  2821. /*
  2822. - CryptSetHashParam
  2823. -
  2824. * Purpose:
  2825. * Allows applications to customize various aspects of the
  2826. * operations of a hash
  2827. *
  2828. * Parameters:
  2829. * IN hHash - Handle to a hash
  2830. * IN dwParam - Parameter number
  2831. * IN pbData - Pointer to data
  2832. * IN dwFlags - Flags values
  2833. *
  2834. * Returns:
  2835. */
  2836. WINADVAPI
  2837. BOOL
  2838. WINAPI CryptSetHashParam(IN HCRYPTHASH hHash,
  2839. IN DWORD dwParam,
  2840. IN CONST BYTE *pbData,
  2841. IN DWORD dwFlags)
  2842. {
  2843. PVTableStruc pVTable = NULL;
  2844. PVHashStruc pVHash;
  2845. BOOL fProvCritSec = FALSE;
  2846. BOOL rt = CRYPT_FAILED;
  2847. __try
  2848. {
  2849. pVHash = (PVHashStruc) hHash;
  2850. if (pVHash->Version != TABLEHASH)
  2851. {
  2852. SetLastError(ERROR_INVALID_PARAMETER);
  2853. goto Ret;
  2854. }
  2855. if (0 < InterlockedDecrement((LPLONG)&pVHash->Inuse))
  2856. {
  2857. InterlockedIncrement((LPLONG)&pVHash->Inuse);
  2858. SetLastError(ERROR_BUSY);
  2859. goto Ret;
  2860. }
  2861. InterlockedIncrement((LPLONG)&pVHash->Inuse);
  2862. pVTable = (PVTableStruc) pVHash->hProv;
  2863. if (RCRYPT_FAILED(EnterProviderCritSec(pVTable)))
  2864. {
  2865. goto Ret;
  2866. }
  2867. fProvCritSec = TRUE;
  2868. rt = (BOOL)pVHash->FuncSetHashParam(pVTable->hProv, pVHash->hHash,
  2869. dwParam, pbData, dwFlags);
  2870. }
  2871. __except ( EXCEPTION_EXECUTE_HANDLER )
  2872. {
  2873. SetLastError(ERROR_INVALID_PARAMETER);
  2874. goto Ret;
  2875. }
  2876. Ret:
  2877. if (fProvCritSec)
  2878. LeaveProviderCritSec(pVTable);
  2879. return rt;
  2880. }
  2881. /*
  2882. - CryptGetHashParam
  2883. -
  2884. * Purpose:
  2885. * Allows applications to get various aspects of the
  2886. * operations of a hash
  2887. *
  2888. * Parameters:
  2889. * IN hHash - Handle to a hash
  2890. * IN dwParam - Parameter number
  2891. * IN pbData - Pointer to data
  2892. * IN pdwDataLen - Length of parameter data
  2893. * IN dwFlags - Flags values
  2894. *
  2895. * Returns:
  2896. */
  2897. WINADVAPI
  2898. BOOL
  2899. WINAPI CryptGetHashParam(IN HCRYPTKEY hHash,
  2900. IN DWORD dwParam,
  2901. IN BYTE *pbData,
  2902. IN DWORD *pdwDataLen,
  2903. IN DWORD dwFlags)
  2904. {
  2905. PVTableStruc pVTable = NULL;
  2906. PVHashStruc pVHash = NULL;
  2907. BOOL fHashCritSec = FALSE;
  2908. BOOL fProvCritSec = FALSE;
  2909. BOOL rt = CRYPT_FAILED;
  2910. __try
  2911. {
  2912. pVHash = (PVHashStruc) hHash;
  2913. if (RCRYPT_FAILED(EnterHashCritSec(pVHash)))
  2914. {
  2915. goto Ret;
  2916. }
  2917. fHashCritSec = TRUE;
  2918. pVTable = (PVTableStruc) pVHash->hProv;
  2919. if (RCRYPT_FAILED(EnterProviderCritSec(pVTable)))
  2920. {
  2921. goto Ret;
  2922. }
  2923. fProvCritSec = TRUE;
  2924. rt = (BOOL)pVHash->FuncGetHashParam(pVTable->hProv, pVHash->hHash,
  2925. dwParam, pbData, pdwDataLen,
  2926. dwFlags);
  2927. }
  2928. __except ( EXCEPTION_EXECUTE_HANDLER )
  2929. {
  2930. SetLastError(ERROR_INVALID_PARAMETER);
  2931. goto Ret;
  2932. }
  2933. Ret:
  2934. if (fHashCritSec)
  2935. LeaveHashCritSec(pVHash);
  2936. if (fProvCritSec)
  2937. LeaveProviderCritSec(pVTable);
  2938. return rt;
  2939. }
  2940. #ifndef WIN95
  2941. /*
  2942. - CryptSetProviderW
  2943. -
  2944. * Purpose:
  2945. * Set a cryptography provider
  2946. *
  2947. *
  2948. * Parameters:
  2949. *
  2950. * IN pszProvName - Name of the provider to install
  2951. * IN dwProvType - Type of the provider to install
  2952. *
  2953. * Returns:
  2954. * BOOL
  2955. * Use get extended error information use GetLastError
  2956. */
  2957. WINADVAPI
  2958. BOOL
  2959. WINAPI CryptSetProviderW(IN LPCWSTR pszProvName,
  2960. IN DWORD dwProvType)
  2961. {
  2962. ANSI_STRING AnsiString;
  2963. UNICODE_STRING UnicodeString;
  2964. NTSTATUS Status;
  2965. BOOL rt = FALSE;
  2966. __try
  2967. {
  2968. RtlInitUnicodeString(&UnicodeString, pszProvName);
  2969. Status = RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeString, TRUE);
  2970. if (!NT_SUCCESS(Status))
  2971. {
  2972. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  2973. goto Ret;
  2974. }
  2975. rt = CryptSetProviderA((LPCSTR) AnsiString.Buffer,
  2976. dwProvType);
  2977. RtlFreeAnsiString(&AnsiString);
  2978. }
  2979. __except ( EXCEPTION_EXECUTE_HANDLER )
  2980. {
  2981. SetLastError(ERROR_INVALID_PARAMETER);
  2982. goto Ret;
  2983. }
  2984. Ret:
  2985. return(rt);
  2986. }
  2987. #else // WIN95
  2988. WINADVAPI
  2989. BOOL
  2990. WINAPI CryptSetProviderW(IN LPCWSTR pszProvName,
  2991. IN DWORD dwProvType)
  2992. {
  2993. SetLastError((DWORD)ERROR_CALL_NOT_IMPLEMENTED);
  2994. return CRYPT_FAILED;
  2995. }
  2996. #endif // WIN95
  2997. /*
  2998. - CryptSetProviderA
  2999. -
  3000. * Purpose:
  3001. * Set a cryptography provider
  3002. *
  3003. *
  3004. * Parameters:
  3005. *
  3006. * IN pszProvName - Name of the provider to install
  3007. * IN dwProvType - Type of the provider to install
  3008. *
  3009. * Returns:
  3010. * BOOL
  3011. * Use get extended error information use GetLastError
  3012. */
  3013. WINADVAPI
  3014. BOOL
  3015. WINAPI CryptSetProviderA(IN LPCSTR pszProvName,
  3016. IN DWORD dwProvType)
  3017. {
  3018. HKEY hCurrUser = 0;
  3019. HKEY hKey = 0;
  3020. LONG err;
  3021. DWORD dwIgn;
  3022. DWORD cbValue;
  3023. CHAR *pszValue = NULL;
  3024. CHAR typebuf[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
  3025. BOOL fRet = CRYPT_FAILED;
  3026. __try
  3027. {
  3028. if (dwProvType == 0 || dwProvType > 999 || pszProvName == NULL)
  3029. {
  3030. SetLastError(ERROR_INVALID_PARAMETER);
  3031. goto Ret;
  3032. }
  3033. cbValue = strlen(pszProvName);
  3034. if ((pszValue = (CHAR *) LocalAlloc(LMEM_ZEROINIT,
  3035. strlen(szusertype) + 5 + 1)) == NULL)
  3036. {
  3037. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  3038. goto Ret;
  3039. }
  3040. strcpy(pszValue, szusertype);
  3041. __ltoa(dwProvType, typebuf);
  3042. strcat(pszValue, &typebuf[5]);
  3043. #ifndef WIN95
  3044. if (!NT_SUCCESS(RtlOpenCurrentUser(KEY_READ | KEY_WRITE, &hCurrUser)))
  3045. {
  3046. SetLastError(ERROR_INVALID_PARAMETER);
  3047. goto Ret;
  3048. }
  3049. if ((err = RegCreateKeyEx(hCurrUser,
  3050. (const char *) pszValue,
  3051. 0L, "", REG_OPTION_NON_VOLATILE,
  3052. KEY_READ | KEY_WRITE, NULL, &hKey,
  3053. &dwIgn)) != ERROR_SUCCESS)
  3054. {
  3055. NtClose(hCurrUser);
  3056. SetLastError(err);
  3057. goto Ret;
  3058. }
  3059. NtClose(hCurrUser);
  3060. #else
  3061. if ((err = RegCreateKeyEx(HKEY_CURRENT_USER,
  3062. (const char *) pszValue,
  3063. 0L, "", REG_OPTION_NON_VOLATILE,
  3064. KEY_READ | KEY_WRITE, NULL, &hKey,
  3065. &dwIgn)) != ERROR_SUCCESS)
  3066. {
  3067. SetLastError(err);
  3068. goto Ret;
  3069. }
  3070. RegClosKey(HKEY_CURRENT_USER);
  3071. #endif
  3072. if ((err = RegSetValueEx(hKey, "Name", 0L, REG_SZ,
  3073. (const LPBYTE) pszProvName,
  3074. cbValue)) != ERROR_SUCCESS)
  3075. {
  3076. SetLastError(err);
  3077. goto Ret;
  3078. }
  3079. }
  3080. __except ( EXCEPTION_EXECUTE_HANDLER )
  3081. {
  3082. SetLastError(ERROR_INVALID_PARAMETER);
  3083. goto Ret;
  3084. }
  3085. fRet = CRYPT_SUCCEED;
  3086. Ret:
  3087. if (pszValue)
  3088. LocalFree(pszValue);
  3089. if (hKey)
  3090. RegCloseKey(hKey);
  3091. return fRet;
  3092. }
  3093. #ifndef WIN95
  3094. /*
  3095. - CryptSetProviderExW
  3096. -
  3097. * Purpose:
  3098. * Set the cryptographic provider as the default
  3099. * either for machine or for user.
  3100. *
  3101. *
  3102. * Parameters:
  3103. *
  3104. * IN pszProvName - Name of the provider to install
  3105. * IN dwProvType - Type of the provider to install
  3106. * IN pdwReserved - Reserved for future use
  3107. * IN dwFlags - Flags parameter (for machine or for user)
  3108. *
  3109. *
  3110. * Returns:
  3111. * BOOL
  3112. * Use get extended error information use GetLastError
  3113. */
  3114. WINADVAPI
  3115. BOOL
  3116. WINAPI CryptSetProviderExW(
  3117. IN LPCWSTR pszProvName,
  3118. IN DWORD dwProvType,
  3119. IN DWORD *pdwReserved,
  3120. IN DWORD dwFlags
  3121. )
  3122. {
  3123. ANSI_STRING AnsiString;
  3124. UNICODE_STRING UnicodeString;
  3125. NTSTATUS Status;
  3126. BOOL fRet = CRYPT_FAILED;
  3127. __try
  3128. {
  3129. RtlInitUnicodeString(&UnicodeString, pszProvName);
  3130. Status = RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeString, TRUE);
  3131. if (!NT_SUCCESS(Status))
  3132. {
  3133. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  3134. goto Ret;
  3135. }
  3136. fRet = CryptSetProviderExA((LPCSTR) AnsiString.Buffer,
  3137. dwProvType,
  3138. pdwReserved,
  3139. dwFlags);
  3140. RtlFreeAnsiString(&AnsiString);
  3141. }
  3142. __except ( EXCEPTION_EXECUTE_HANDLER )
  3143. {
  3144. SetLastError(ERROR_INVALID_PARAMETER);
  3145. goto Ret;
  3146. }
  3147. Ret:
  3148. return fRet;
  3149. }
  3150. #else // WIN95
  3151. WINADVAPI
  3152. BOOL
  3153. WINAPI CryptSetProviderExW(
  3154. IN LPCWSTR pszProvName,
  3155. IN DWORD dwProvType,
  3156. IN DWORD *pdwReserved,
  3157. IN DWORD dwFlags
  3158. )
  3159. {
  3160. SetLastError((DWORD)ERROR_CALL_NOT_IMPLEMENTED);
  3161. return CRYPT_FAILED;
  3162. }
  3163. #endif // WIN95
  3164. /*
  3165. - CryptSetProviderExA
  3166. -
  3167. * Purpose:
  3168. * Set the cryptographic provider as the default
  3169. * either for machine or for user.
  3170. *
  3171. *
  3172. * Parameters:
  3173. *
  3174. * IN pszProvName - Name of the provider to install
  3175. * IN dwProvType - Type of the provider to install
  3176. * IN pdwReserved - Reserved for future use
  3177. * IN dwFlags - Flags parameter (for machine or for user)
  3178. *
  3179. * Returns:
  3180. * BOOL
  3181. * Use get extended error information use GetLastError
  3182. */
  3183. WINADVAPI
  3184. BOOL
  3185. WINAPI CryptSetProviderExA(
  3186. IN LPCSTR pszProvName,
  3187. IN DWORD dwProvType,
  3188. IN DWORD *pdwReserved,
  3189. IN DWORD dwFlags
  3190. )
  3191. {
  3192. HKEY hCurrUser = 0;
  3193. HKEY hRegKey = 0;
  3194. LONG err;
  3195. DWORD dwDisp;
  3196. DWORD cbValue;
  3197. CHAR *pszValue = NULL;
  3198. CHAR *pszFullName = NULL;
  3199. DWORD cbFullName;
  3200. CHAR typebuf[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
  3201. DWORD dwKeyType;
  3202. DWORD dw;
  3203. DWORD cbProvType;
  3204. BOOL fRet = CRYPT_FAILED;
  3205. __try
  3206. {
  3207. if ((dwProvType == 0) || (dwProvType > 999) ||
  3208. (pszProvName == NULL) || (pdwReserved != NULL))
  3209. {
  3210. SetLastError(ERROR_INVALID_PARAMETER);
  3211. goto Ret;
  3212. }
  3213. if ((dwFlags & ~(CRYPT_MACHINE_DEFAULT | CRYPT_USER_DEFAULT | CRYPT_DELETE_DEFAULT)) ||
  3214. ((dwFlags & CRYPT_MACHINE_DEFAULT) && (dwFlags & CRYPT_USER_DEFAULT)))
  3215. {
  3216. SetLastError((DWORD)NTE_BAD_FLAGS);
  3217. goto Ret;
  3218. }
  3219. cbValue = strlen(pszProvName);
  3220. // check if the CSP has been installed
  3221. cbFullName = cbValue + sizeof(szenumproviders) + sizeof(CHAR);
  3222. if (NULL == (pszFullName = (CHAR *) LocalAlloc(LMEM_ZEROINIT, cbFullName)))
  3223. {
  3224. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  3225. goto Ret;
  3226. }
  3227. strcpy(pszFullName, szenumproviders);
  3228. pszFullName[sizeof(szenumproviders) - 1] = '\\';
  3229. strcpy(pszFullName + sizeof(szenumproviders), pszProvName);
  3230. if ((err = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  3231. (const char *) pszFullName,
  3232. 0L, KEY_READ, &hRegKey)) != ERROR_SUCCESS)
  3233. {
  3234. SetLastError(ERROR_INVALID_PARAMETER);
  3235. goto Ret;
  3236. }
  3237. cbProvType = sizeof(dw);
  3238. if (ERROR_SUCCESS != (err = RegQueryValueEx(hRegKey,
  3239. (const char *) "Type",
  3240. NULL, &dwKeyType, (BYTE*)&dw,
  3241. &cbProvType)))
  3242. {
  3243. SetLastError(err);
  3244. goto Ret;
  3245. }
  3246. if (dwProvType != dw)
  3247. {
  3248. SetLastError(ERROR_INVALID_PARAMETER);
  3249. goto Ret;
  3250. }
  3251. if (ERROR_SUCCESS != (err = RegCloseKey(hRegKey)))
  3252. {
  3253. SetLastError(err);
  3254. goto Ret;
  3255. }
  3256. hRegKey = NULL;
  3257. if (dwFlags & CRYPT_MACHINE_DEFAULT)
  3258. {
  3259. if ((pszValue = (CHAR *) LocalAlloc(LMEM_ZEROINIT,
  3260. strlen(szmachinetype) + 5 + 1)) == NULL)
  3261. {
  3262. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  3263. goto Ret;
  3264. }
  3265. strcpy(pszValue, szmachinetype);
  3266. __ltoa(dwProvType, typebuf);
  3267. strcat(pszValue, &typebuf[5]);
  3268. if ((err = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  3269. (const char *) pszValue,
  3270. 0L, NULL, REG_OPTION_NON_VOLATILE,
  3271. KEY_READ | KEY_WRITE, NULL, &hRegKey, &dwDisp)) != ERROR_SUCCESS)
  3272. {
  3273. SetLastError(ERROR_INVALID_PARAMETER);
  3274. goto Ret;
  3275. }
  3276. // check the delete flag
  3277. if (dwFlags & CRYPT_DELETE_DEFAULT)
  3278. {
  3279. if (ERROR_SUCCESS != (err = RegDeleteValue(hRegKey, "Name")))
  3280. {
  3281. SetLastError(err);
  3282. goto Ret;
  3283. }
  3284. fRet = CRYPT_SUCCEED;
  3285. goto Ret;
  3286. }
  3287. }
  3288. else if (dwFlags & CRYPT_USER_DEFAULT)
  3289. {
  3290. if ((pszValue = (CHAR *) LocalAlloc(LMEM_ZEROINIT,
  3291. strlen(szusertype) + 5 + 1)) == NULL)
  3292. {
  3293. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  3294. goto Ret;
  3295. }
  3296. strcpy(pszValue, szusertype);
  3297. __ltoa(dwProvType, typebuf);
  3298. strcat(pszValue, &typebuf[5]);
  3299. #ifndef WIN95
  3300. if (!NT_SUCCESS(RtlOpenCurrentUser(KEY_READ | KEY_WRITE, &hCurrUser)))
  3301. {
  3302. SetLastError(ERROR_INVALID_PARAMETER);
  3303. goto Ret;
  3304. }
  3305. if ((err = RegCreateKeyEx(hCurrUser,
  3306. (const char *) pszValue,
  3307. 0L, NULL, REG_OPTION_NON_VOLATILE,
  3308. KEY_READ | KEY_WRITE, NULL, &hRegKey, &dwDisp)) != ERROR_SUCCESS)
  3309. {
  3310. NtClose(hCurrUser);
  3311. SetLastError(ERROR_INVALID_PARAMETER);
  3312. goto Ret;
  3313. }
  3314. // check the delete flag
  3315. if (dwFlags & CRYPT_DELETE_DEFAULT)
  3316. {
  3317. if (ERROR_SUCCESS != (err = RegDeleteKey(hCurrUser,
  3318. (const char *)pszValue)))
  3319. {
  3320. NtClose(hCurrUser);
  3321. SetLastError(err);
  3322. goto Ret;
  3323. }
  3324. fRet = CRYPT_SUCCEED;
  3325. NtClose(hCurrUser);
  3326. goto Ret;
  3327. }
  3328. NtClose(hCurrUser);
  3329. #else
  3330. if ((err = RegCreateKeyEx(HKEY_CURRENT_USER,
  3331. (const char *) pszValue,
  3332. 0L, NULL, REG_OPTION_NON_VOLATILE,
  3333. KEY_READ | KEY_WRITE, NULL, &hRegKey, &dwDisp)) != ERROR_SUCCESS)
  3334. {
  3335. SetLastError(ERROR_INVALID_PARAMETER);
  3336. goto Ret;
  3337. }
  3338. // check the delete flag
  3339. if (dwFlags & CRYPT_DELETE_DEFAULT)
  3340. {
  3341. if (ERROR_SUCCESS != (err = RegDeleteKey(HKEY_CURRENT_USER,
  3342. (const char *)pszValue)))
  3343. {
  3344. RegCloseKey(HKEY_CURRENT_USER);
  3345. SetLastError(err);
  3346. goto Ret;
  3347. }
  3348. fRet = CRYPT_SUCCEED;
  3349. RegCloseKey(HKEY_CURRENT_USER);
  3350. goto Ret;
  3351. }
  3352. RegCloseKey(HKEY_CURRENT_USER);
  3353. #endif
  3354. }
  3355. if (ERROR_SUCCESS != (err = RegSetValueEx(hRegKey, "Name", 0L, REG_SZ,
  3356. (const LPBYTE) pszProvName, cbValue)))
  3357. {
  3358. SetLastError(err);
  3359. goto Ret;
  3360. }
  3361. }
  3362. __except ( EXCEPTION_EXECUTE_HANDLER )
  3363. {
  3364. SetLastError(ERROR_INVALID_PARAMETER);
  3365. goto Ret;
  3366. }
  3367. fRet = CRYPT_SUCCEED;
  3368. Ret:
  3369. if (pszFullName)
  3370. LocalFree(pszFullName);
  3371. if (pszValue)
  3372. LocalFree(pszValue);
  3373. if (hRegKey)
  3374. RegCloseKey(hRegKey);
  3375. return fRet;
  3376. }
  3377. #ifndef WIN95
  3378. /*
  3379. - CryptGetDefaultProviderW
  3380. -
  3381. * Purpose:
  3382. * Get the default cryptographic provider of the specified
  3383. * type for either the machine or for the user.
  3384. *
  3385. * Parameters:
  3386. * IN dwProvType - Type of the provider to install
  3387. * IN pdwReserved - Reserved for future use
  3388. * IN dwFlags - Flags parameter (for machine or for user)
  3389. * OUT pszProvName - Name of the default provider
  3390. * IN OUT pcbProvName - Length in bytes of the provider name
  3391. *
  3392. *
  3393. * Returns:
  3394. * BOOL
  3395. * Use get extended error information use GetLastError
  3396. */
  3397. WINADVAPI
  3398. BOOL
  3399. WINAPI CryptGetDefaultProviderW(
  3400. IN DWORD dwProvType,
  3401. IN DWORD *pdwReserved,
  3402. IN DWORD dwFlags,
  3403. OUT LPWSTR pszProvName,
  3404. IN OUT DWORD *pcbProvName
  3405. )
  3406. {
  3407. ANSI_STRING AnsiString;
  3408. UNICODE_STRING UnicodeString;
  3409. LPSTR pszName = NULL;
  3410. DWORD cbName;
  3411. NTSTATUS Status;
  3412. BOOL fRet = CRYPT_FAILED;
  3413. memset(&UnicodeString, 0, sizeof(UnicodeString));
  3414. __try
  3415. {
  3416. memset(&AnsiString, 0, sizeof(AnsiString));
  3417. if (!CryptGetDefaultProviderA(dwProvType,
  3418. pdwReserved,
  3419. dwFlags,
  3420. NULL,
  3421. &cbName))
  3422. goto Ret;
  3423. if (NULL == (pszName = LocalAlloc(LMEM_ZEROINIT, cbName)))
  3424. {
  3425. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  3426. goto Ret;
  3427. }
  3428. if (!CryptGetDefaultProviderA(dwProvType,
  3429. pdwReserved,
  3430. dwFlags,
  3431. pszName,
  3432. &cbName))
  3433. goto Ret;
  3434. RtlInitAnsiString(&AnsiString, pszName);
  3435. Status = RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, TRUE);
  3436. if (!NT_SUCCESS(Status))
  3437. {
  3438. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  3439. goto Ret;
  3440. }
  3441. if (NULL == pszProvName)
  3442. {
  3443. *pcbProvName = UnicodeString.Length + sizeof(WCHAR);
  3444. fRet = CRYPT_SUCCEED;
  3445. goto Ret;
  3446. }
  3447. if (*pcbProvName < UnicodeString.Length + sizeof(WCHAR))
  3448. {
  3449. *pcbProvName = UnicodeString.Length + sizeof(WCHAR);
  3450. SetLastError(ERROR_MORE_DATA);
  3451. goto Ret;
  3452. }
  3453. *pcbProvName = UnicodeString.Length + sizeof(WCHAR);
  3454. memset(pszProvName, 0, *pcbProvName);
  3455. memcpy(pszProvName, UnicodeString.Buffer, UnicodeString.Length);
  3456. }
  3457. __except ( EXCEPTION_EXECUTE_HANDLER )
  3458. {
  3459. SetLastError(ERROR_INVALID_PARAMETER);
  3460. goto Ret;
  3461. }
  3462. fRet = CRYPT_SUCCEED;
  3463. Ret:
  3464. if (UnicodeString.Buffer)
  3465. RtlFreeUnicodeString(&UnicodeString);
  3466. if (pszName)
  3467. LocalFree(pszName);
  3468. return fRet;
  3469. }
  3470. #else // WIN95
  3471. WINADVAPI
  3472. BOOL
  3473. WINAPI CryptGetDefaultProviderW(
  3474. IN DWORD dwProvType,
  3475. IN DWORD *pdwReserved,
  3476. IN DWORD dwFlags,
  3477. OUT LPWSTR pszProvName,
  3478. IN OUT DWORD *pcbProvName
  3479. )
  3480. {
  3481. SetLastError((DWORD)ERROR_CALL_NOT_IMPLEMENTED);
  3482. return CRYPT_FAILED;
  3483. }
  3484. #endif // WIN95
  3485. /*
  3486. - CryptGetDefaultProviderA
  3487. -
  3488. * Purpose:
  3489. * Get the default cryptographic provider of the specified
  3490. * type for either the machine or for the user.
  3491. *
  3492. *
  3493. * Parameters:
  3494. * IN dwProvType - Type of the provider to install
  3495. * IN pdwReserved - Reserved for future use
  3496. * IN dwFlags - Flags parameter (for machine or for user)
  3497. * OUT pszProvName - Name of the default provider
  3498. * IN OUT pcbProvName - Length in bytes of the provider name
  3499. * including the NULL terminator
  3500. *
  3501. * Returns:
  3502. * BOOL
  3503. * Use get extended error information use GetLastError
  3504. */
  3505. WINAPI CryptGetDefaultProviderA(
  3506. IN DWORD dwProvType,
  3507. IN DWORD *pdwReserved,
  3508. IN DWORD dwFlags,
  3509. OUT LPSTR pszProvName,
  3510. IN OUT DWORD *pcbProvName
  3511. )
  3512. {
  3513. HKEY hCurrUser = 0;
  3514. HKEY hRegKey = 0;
  3515. LONG err;
  3516. CHAR *pszValue = NULL;
  3517. DWORD dwValType;
  3518. CHAR typebuf[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
  3519. DWORD cbProvName = 0;
  3520. BOOL fRet = CRYPT_FAILED;
  3521. __try
  3522. {
  3523. if (dwProvType == 0 || dwProvType > 999 || pdwReserved != NULL)
  3524. {
  3525. SetLastError(ERROR_INVALID_PARAMETER);
  3526. goto Ret;
  3527. }
  3528. if ((dwFlags & ~(CRYPT_MACHINE_DEFAULT | CRYPT_USER_DEFAULT)) ||
  3529. ((dwFlags & CRYPT_MACHINE_DEFAULT) && (dwFlags & CRYPT_USER_DEFAULT)))
  3530. {
  3531. SetLastError((DWORD)NTE_BAD_FLAGS);
  3532. goto Ret;
  3533. }
  3534. if (dwFlags & CRYPT_USER_DEFAULT)
  3535. {
  3536. if ((pszValue = (CHAR *) LocalAlloc(LMEM_ZEROINIT,
  3537. strlen(szusertype) + 5 + 1)) == NULL)
  3538. {
  3539. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  3540. goto Ret;
  3541. }
  3542. strcpy(pszValue, szusertype);
  3543. __ltoa(dwProvType, typebuf);
  3544. strcat(pszValue, &typebuf[5]);
  3545. #ifndef WIN95
  3546. if (!NT_SUCCESS(RtlOpenCurrentUser(KEY_READ, &hCurrUser)))
  3547. {
  3548. LocalFree(pszValue);
  3549. goto TryMachineSettings;
  3550. }
  3551. if ((err = RegOpenKeyEx(hCurrUser,
  3552. (const char *) pszValue,
  3553. 0L, KEY_READ, &hRegKey)) != ERROR_SUCCESS)
  3554. {
  3555. NtClose(hCurrUser);
  3556. LocalFree(pszValue);
  3557. goto TryMachineSettings;
  3558. }
  3559. NtClose(hCurrUser);
  3560. #else
  3561. if ((err = RegOpenKeyEx(HKEY_CURRENT_USER,
  3562. (const char *) pszValue,
  3563. 0L, KEY_READ, &hRegKey)) != ERROR_SUCCESS)
  3564. {
  3565. LocalFree(pszValue);
  3566. goto TryMachineSettings;
  3567. }
  3568. RegCloseKey(HKEY_CURRENT_USER);
  3569. #endif
  3570. }
  3571. if (dwFlags & CRYPT_MACHINE_DEFAULT)
  3572. {
  3573. TryMachineSettings:
  3574. if ((pszValue = (CHAR *) LocalAlloc(LMEM_ZEROINIT,
  3575. strlen(szmachinetype) + 5 + 1)) == NULL)
  3576. {
  3577. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  3578. goto Ret;
  3579. }
  3580. strcpy(pszValue, szmachinetype);
  3581. __ltoa(dwProvType, typebuf);
  3582. strcat(pszValue, &typebuf[5]);
  3583. if ((err = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  3584. (const char *) pszValue,
  3585. 0L, KEY_READ, &hRegKey)) != ERROR_SUCCESS)
  3586. {
  3587. SetLastError(ERROR_INVALID_PARAMETER);
  3588. goto Ret;
  3589. }
  3590. }
  3591. if ((err = RegQueryValueEx(hRegKey, "Name", 0L, &dwValType,
  3592. NULL,
  3593. &cbProvName)) != ERROR_SUCCESS)
  3594. {
  3595. SetLastError(ERROR_INVALID_PARAMETER);
  3596. goto Ret;
  3597. }
  3598. if (NULL == pszProvName)
  3599. {
  3600. *pcbProvName = cbProvName;
  3601. fRet = CRYPT_SUCCEED;
  3602. goto Ret;
  3603. }
  3604. if (cbProvName > *pcbProvName)
  3605. {
  3606. *pcbProvName = cbProvName;
  3607. SetLastError(ERROR_MORE_DATA);
  3608. goto Ret;
  3609. }
  3610. if ((err = RegQueryValueEx(hRegKey, "Name", 0L, &dwValType,
  3611. (BYTE*)pszProvName,
  3612. &cbProvName)) != ERROR_SUCCESS)
  3613. {
  3614. SetLastError(ERROR_INVALID_PARAMETER);
  3615. goto Ret;
  3616. }
  3617. *pcbProvName = cbProvName;
  3618. }
  3619. __except ( EXCEPTION_EXECUTE_HANDLER )
  3620. {
  3621. SetLastError(ERROR_INVALID_PARAMETER);
  3622. goto Ret;
  3623. }
  3624. fRet = CRYPT_SUCCEED;
  3625. Ret:
  3626. if (hRegKey)
  3627. RegCloseKey(hRegKey);
  3628. if (pszValue)
  3629. LocalFree(pszValue);
  3630. return fRet;
  3631. }
  3632. #ifndef WIN95
  3633. /*
  3634. - CryptEnumProviderTypesW
  3635. -
  3636. * Purpose:
  3637. * Enumerate the provider types.
  3638. *
  3639. * Parameters:
  3640. * IN dwIndex - Index to the provider types to enumerate
  3641. * IN pdwReserved - Reserved for future use
  3642. * IN dwFlags - Flags parameter
  3643. * OUT pdwProvType - Pointer to the provider type
  3644. * OUT pszTypeName - Name of the enumerated provider type
  3645. * IN OUT pcbTypeName - Length of the enumerated provider type
  3646. *
  3647. * Returns:
  3648. * BOOL
  3649. * Use get extended error information use GetLastError
  3650. */
  3651. WINADVAPI
  3652. BOOL
  3653. WINAPI CryptEnumProviderTypesW(
  3654. IN DWORD dwIndex,
  3655. IN DWORD *pdwReserved,
  3656. IN DWORD dwFlags,
  3657. OUT DWORD *pdwProvType,
  3658. OUT LPWSTR pszTypeName,
  3659. IN OUT DWORD *pcbTypeName
  3660. )
  3661. {
  3662. ANSI_STRING AnsiString;
  3663. UNICODE_STRING UnicodeString;
  3664. LPSTR pszTmpTypeName = NULL;
  3665. DWORD cbTmpTypeName = 0;
  3666. NTSTATUS Status;
  3667. BOOL fRet = CRYPT_FAILED;
  3668. memset(&UnicodeString, 0, sizeof(UnicodeString));
  3669. __try
  3670. {
  3671. memset(&AnsiString, 0, sizeof(AnsiString));
  3672. *pcbTypeName = 0;
  3673. if (!CryptEnumProviderTypesA(dwIndex,
  3674. pdwReserved,
  3675. dwFlags,
  3676. pdwProvType,
  3677. NULL,
  3678. &cbTmpTypeName))
  3679. goto Ret;
  3680. if (NULL == (pszTmpTypeName = LocalAlloc(LMEM_ZEROINIT, cbTmpTypeName)))
  3681. {
  3682. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  3683. goto Ret;
  3684. }
  3685. if (!CryptEnumProviderTypesA(dwIndex,
  3686. pdwReserved,
  3687. dwFlags,
  3688. pdwProvType,
  3689. pszTmpTypeName,
  3690. &cbTmpTypeName))
  3691. goto Ret;
  3692. if (0 != cbTmpTypeName)
  3693. {
  3694. RtlInitAnsiString(&AnsiString, pszTmpTypeName);
  3695. Status = RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, TRUE);
  3696. if ( !NT_SUCCESS(Status))
  3697. {
  3698. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  3699. goto Ret;
  3700. }
  3701. // check if caller is asking for length, in addition the name of the provider
  3702. // may not be available, in this case a name length of 0 is returned
  3703. if ((NULL == pszTypeName) || (0 == cbTmpTypeName))
  3704. {
  3705. *pcbTypeName = UnicodeString.Length + sizeof(WCHAR);
  3706. fRet = CRYPT_SUCCEED;
  3707. goto Ret;
  3708. }
  3709. *pcbTypeName = UnicodeString.Length + sizeof(WCHAR);
  3710. if (*pcbTypeName < UnicodeString.Length + sizeof(WCHAR))
  3711. {
  3712. SetLastError(ERROR_MORE_DATA);
  3713. goto Ret;
  3714. }
  3715. memset(pszTypeName, 0, *pcbTypeName);
  3716. memcpy(pszTypeName, UnicodeString.Buffer, UnicodeString.Length);
  3717. }
  3718. }
  3719. __except ( EXCEPTION_EXECUTE_HANDLER )
  3720. {
  3721. SetLastError(ERROR_INVALID_PARAMETER);
  3722. goto Ret;
  3723. }
  3724. fRet = CRYPT_SUCCEED;
  3725. Ret:
  3726. if (UnicodeString.Buffer)
  3727. RtlFreeUnicodeString(&UnicodeString);
  3728. if (pszTmpTypeName)
  3729. LocalFree(pszTmpTypeName);
  3730. return fRet;
  3731. }
  3732. #else // WIN95
  3733. WINADVAPI
  3734. BOOL
  3735. WINAPI CryptEnumProviderTypesW(
  3736. IN DWORD dwIndex,
  3737. IN DWORD *pdwReserved,
  3738. IN DWORD dwFlags,
  3739. OUT DWORD *pdwProvType,
  3740. OUT LPWSTR pszTypeName,
  3741. IN OUT DWORD *pcbTypeName
  3742. )
  3743. {
  3744. SetLastError((DWORD)ERROR_CALL_NOT_IMPLEMENTED);
  3745. return CRYPT_FAILED;
  3746. }
  3747. #endif // WIN95
  3748. /*
  3749. - CryptEnumProviderTypesA
  3750. -
  3751. * Purpose:
  3752. * Enumerate the provider types.
  3753. *
  3754. * Parameters:
  3755. * IN dwIndex - Index to the provider types to enumerate
  3756. * IN pdwReserved - Reserved for future use
  3757. * IN dwFlags - Flags parameter
  3758. * OUT pdwProvType - Pointer to the provider type
  3759. * OUT pszTypeName - Name of the enumerated provider type
  3760. * IN OUT pcbTypeName - Length of the enumerated provider type
  3761. *
  3762. * Returns:
  3763. * BOOL
  3764. * Use get extended error information use GetLastError
  3765. */
  3766. WINADVAPI
  3767. BOOL
  3768. WINAPI CryptEnumProviderTypesA(
  3769. IN DWORD dwIndex,
  3770. IN DWORD *pdwReserved,
  3771. IN DWORD dwFlags,
  3772. OUT DWORD *pdwProvType,
  3773. OUT LPSTR pszTypeName,
  3774. IN OUT DWORD *pcbTypeName
  3775. )
  3776. {
  3777. HKEY hRegKey = 0;
  3778. HKEY hTypeKey = 0;
  3779. LONG err;
  3780. CHAR *pszRegKeyName = NULL;
  3781. DWORD cbClass;
  3782. FILETIME ft;
  3783. CHAR rgcType[] = {'T', 'y', 'p', 'e', ' '};
  3784. LPSTR pszValue;
  3785. long Type;
  3786. DWORD cSubKeys;
  3787. DWORD cbMaxKeyName;
  3788. DWORD cbMaxClass;
  3789. DWORD cValues;
  3790. DWORD cbMaxValName;
  3791. DWORD cbMaxValData;
  3792. DWORD cbTmpTypeName = 0;
  3793. DWORD dwValType;
  3794. BOOL fRet = CRYPT_FAILED;
  3795. __try
  3796. {
  3797. if (NULL != pdwReserved)
  3798. {
  3799. SetLastError(ERROR_INVALID_PARAMETER);
  3800. goto Ret;
  3801. }
  3802. if (0 != dwFlags)
  3803. {
  3804. SetLastError((DWORD)NTE_BAD_FLAGS);
  3805. goto Ret;
  3806. }
  3807. if (ERROR_SUCCESS != (err = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  3808. (const char *) szprovidertypes,
  3809. 0L,
  3810. KEY_READ,
  3811. &hRegKey)))
  3812. {
  3813. SetLastError((DWORD)NTE_FAIL);
  3814. goto Ret;
  3815. }
  3816. if (ERROR_SUCCESS != (err = RegQueryInfoKey(hRegKey,
  3817. NULL,
  3818. NULL,
  3819. NULL,
  3820. &cSubKeys,
  3821. &cbMaxKeyName,
  3822. &cbMaxClass,
  3823. &cValues,
  3824. &cbMaxValName,
  3825. &cbMaxValData,
  3826. NULL,
  3827. &ft)))
  3828. {
  3829. SetLastError((DWORD)NTE_FAIL);
  3830. goto Ret;
  3831. }
  3832. cbMaxKeyName += sizeof(CHAR);
  3833. if (NULL == (pszRegKeyName = LocalAlloc(LMEM_ZEROINIT, cbMaxKeyName)))
  3834. {
  3835. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  3836. goto Ret;
  3837. }
  3838. if (ERROR_SUCCESS != (err = RegEnumKeyEx(hRegKey,
  3839. dwIndex, pszRegKeyName, &cbMaxKeyName, NULL,
  3840. NULL, &cbClass, &ft)))
  3841. {
  3842. if (ERROR_NO_MORE_ITEMS == err)
  3843. {
  3844. SetLastError((DWORD)err);
  3845. }
  3846. else
  3847. {
  3848. SetLastError((DWORD)NTE_FAIL);
  3849. }
  3850. goto Ret;
  3851. }
  3852. if (memcmp(pszRegKeyName, rgcType, sizeof(rgcType)))
  3853. {
  3854. SetLastError((DWORD)NTE_FAIL);
  3855. goto Ret;
  3856. }
  3857. pszValue = pszRegKeyName + sizeof(rgcType);
  3858. #ifdef WIN95
  3859. if (0 == (Type = StrToL(pszValue)))
  3860. #else
  3861. if (0 == (Type = atol(pszValue)))
  3862. #endif
  3863. {
  3864. SetLastError((DWORD)NTE_FAIL);
  3865. goto Ret;
  3866. }
  3867. *pdwProvType = (DWORD)Type;
  3868. // check for the type name
  3869. if (ERROR_SUCCESS != (err = RegOpenKeyEx(hRegKey,
  3870. (const char *)pszRegKeyName,
  3871. 0L,
  3872. KEY_READ,
  3873. &hTypeKey)))
  3874. {
  3875. SetLastError((DWORD)NTE_FAIL);
  3876. goto Ret;
  3877. }
  3878. if ((err = RegQueryValueEx(hTypeKey, "TypeName", 0L, &dwValType,
  3879. NULL, &cbTmpTypeName)) != ERROR_SUCCESS)
  3880. {
  3881. fRet = CRYPT_SUCCEED;
  3882. goto Ret;
  3883. }
  3884. if (NULL == pszTypeName)
  3885. {
  3886. *pcbTypeName = cbTmpTypeName;
  3887. fRet = CRYPT_SUCCEED;
  3888. goto Ret;
  3889. }
  3890. else if (*pcbTypeName < cbTmpTypeName)
  3891. {
  3892. *pcbTypeName = cbTmpTypeName;
  3893. SetLastError(ERROR_MORE_DATA);
  3894. goto Ret;
  3895. }
  3896. if ((err = RegQueryValueEx(hTypeKey, "TypeName", 0L, &dwValType,
  3897. (BYTE*)pszTypeName, &cbTmpTypeName)) != ERROR_SUCCESS)
  3898. {
  3899. SetLastError(ERROR_INVALID_PARAMETER);
  3900. goto Ret;
  3901. }
  3902. *pcbTypeName = cbTmpTypeName;
  3903. }
  3904. __except ( EXCEPTION_EXECUTE_HANDLER )
  3905. {
  3906. SetLastError(ERROR_INVALID_PARAMETER);
  3907. goto Ret;
  3908. }
  3909. fRet = CRYPT_SUCCEED;
  3910. Ret:
  3911. if (hRegKey)
  3912. RegCloseKey(hRegKey);
  3913. if (hTypeKey)
  3914. RegCloseKey(hTypeKey);
  3915. if (pszRegKeyName)
  3916. LocalFree(pszRegKeyName);
  3917. return fRet;
  3918. }
  3919. #ifndef WIN95
  3920. /*
  3921. - CryptEnumProvidersW
  3922. -
  3923. * Purpose:
  3924. * Enumerate the providers.
  3925. *
  3926. * Parameters:
  3927. * IN dwIndex - Index to the providers to enumerate
  3928. * IN pdwReserved - Reserved for future use
  3929. * IN dwFlags - Flags parameter
  3930. * OUT pdwProvType - The type of the provider
  3931. * OUT pszProvName - Name of the enumerated provider
  3932. * IN OUT pcbProvName - Length of the enumerated provider
  3933. *
  3934. * Returns:
  3935. * BOOL
  3936. * Use get extended error information use GetLastError
  3937. */
  3938. WINADVAPI
  3939. BOOL
  3940. WINAPI CryptEnumProvidersW(
  3941. IN DWORD dwIndex,
  3942. IN DWORD *pdwReserved,
  3943. IN DWORD dwFlags,
  3944. OUT DWORD *pdwProvType,
  3945. OUT LPWSTR pszProvName,
  3946. IN OUT DWORD *pcbProvName
  3947. )
  3948. {
  3949. ANSI_STRING AnsiString;
  3950. UNICODE_STRING UnicodeString;
  3951. LPSTR pszTmpProvName = NULL;
  3952. DWORD cbTmpProvName;
  3953. NTSTATUS Status;
  3954. BOOL fRet = CRYPT_FAILED;
  3955. memset(&UnicodeString, 0, sizeof(UnicodeString));
  3956. __try
  3957. {
  3958. memset(&AnsiString, 0, sizeof(AnsiString));
  3959. if (!CryptEnumProvidersA(dwIndex,
  3960. pdwReserved,
  3961. dwFlags,
  3962. pdwProvType,
  3963. NULL,
  3964. &cbTmpProvName))
  3965. goto Ret;
  3966. if (NULL == (pszTmpProvName = LocalAlloc(LMEM_ZEROINIT, cbTmpProvName)))
  3967. {
  3968. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  3969. goto Ret;
  3970. }
  3971. if (!CryptEnumProvidersA(dwIndex,
  3972. pdwReserved,
  3973. dwFlags,
  3974. pdwProvType,
  3975. pszTmpProvName,
  3976. &cbTmpProvName))
  3977. goto Ret;
  3978. RtlInitAnsiString(&AnsiString, pszTmpProvName);
  3979. Status = RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, TRUE);
  3980. if ( !NT_SUCCESS(Status))
  3981. {
  3982. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  3983. goto Ret;
  3984. }
  3985. if (NULL == pszProvName)
  3986. {
  3987. *pcbProvName = UnicodeString.Length + sizeof(WCHAR);
  3988. fRet = CRYPT_SUCCEED;
  3989. goto Ret;
  3990. }
  3991. *pcbProvName = UnicodeString.Length + sizeof(WCHAR);
  3992. if (*pcbProvName < UnicodeString.Length + sizeof(WCHAR))
  3993. {
  3994. SetLastError(ERROR_MORE_DATA);
  3995. goto Ret;
  3996. }
  3997. memset(pszProvName, 0, *pcbProvName);
  3998. memcpy(pszProvName, UnicodeString.Buffer, UnicodeString.Length);
  3999. }
  4000. __except ( EXCEPTION_EXECUTE_HANDLER )
  4001. {
  4002. SetLastError(ERROR_INVALID_PARAMETER);
  4003. goto Ret;
  4004. }
  4005. fRet = CRYPT_SUCCEED;
  4006. Ret:
  4007. if (UnicodeString.Buffer)
  4008. RtlFreeUnicodeString(&UnicodeString);
  4009. if (pszTmpProvName)
  4010. LocalFree(pszTmpProvName);
  4011. return fRet;
  4012. }
  4013. #else // WIN95
  4014. WINADVAPI
  4015. BOOL
  4016. WINAPI CryptEnumProvidersW(
  4017. IN DWORD dwIndex,
  4018. IN DWORD *pdwReserved,
  4019. IN DWORD dwFlags,
  4020. OUT DWORD *pdwProvType,
  4021. OUT LPWSTR pszProvName,
  4022. IN OUT DWORD *pcbProvName
  4023. )
  4024. {
  4025. SetLastError((DWORD)ERROR_CALL_NOT_IMPLEMENTED);
  4026. return CRYPT_FAILED;
  4027. }
  4028. #endif // WIN95
  4029. /*
  4030. - CryptEnumProvidersA
  4031. -
  4032. * Purpose:
  4033. * Enumerate the providers.
  4034. *
  4035. * Parameters:
  4036. * IN dwIndex - Index to the providers to enumerate
  4037. * IN pdwReserved - Reserved for future use
  4038. * IN dwFlags - Flags parameter
  4039. * OUT pdwProvType - The type of the provider
  4040. * OUT pszProvName - Name of the enumerated provider
  4041. * IN OUT pcbProvName - Length of the enumerated provider
  4042. *
  4043. * Returns:
  4044. * BOOL
  4045. * Use get extended error information use GetLastError
  4046. */
  4047. WINADVAPI
  4048. BOOL
  4049. WINAPI CryptEnumProvidersA(
  4050. IN DWORD dwIndex,
  4051. IN DWORD *pdwReserved,
  4052. IN DWORD dwFlags,
  4053. OUT DWORD *pdwProvType,
  4054. OUT LPSTR pszProvName,
  4055. IN OUT DWORD *pcbProvName
  4056. )
  4057. {
  4058. HKEY hRegKey = 0;
  4059. HKEY hProvRegKey = 0;
  4060. LONG err;
  4061. DWORD cbClass;
  4062. FILETIME ft;
  4063. DWORD dwKeyType;
  4064. DWORD cbProvType;
  4065. DWORD dw;
  4066. DWORD cSubKeys;
  4067. DWORD cbMaxKeyName;
  4068. DWORD cbMaxClass;
  4069. DWORD cValues;
  4070. DWORD cbMaxValName;
  4071. DWORD cbMaxValData;
  4072. LPSTR pszTmpProvName = NULL;
  4073. DWORD cbTmpProvName;
  4074. BOOL fRet = CRYPT_FAILED;
  4075. __try
  4076. {
  4077. if (NULL != pdwReserved)
  4078. {
  4079. SetLastError(ERROR_INVALID_PARAMETER);
  4080. goto Ret;
  4081. }
  4082. if (0 != dwFlags)
  4083. {
  4084. SetLastError((DWORD)NTE_BAD_FLAGS);
  4085. goto Ret;
  4086. }
  4087. if (ERROR_SUCCESS != (err = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  4088. (const char *) szenumproviders,
  4089. 0L, KEY_READ, &hRegKey)))
  4090. {
  4091. SetLastError((DWORD)NTE_FAIL);
  4092. goto Ret;
  4093. }
  4094. if (ERROR_SUCCESS != (err = RegQueryInfoKey(hRegKey,
  4095. NULL,
  4096. NULL,
  4097. NULL,
  4098. &cSubKeys,
  4099. &cbMaxKeyName,
  4100. &cbMaxClass,
  4101. &cValues,
  4102. &cbMaxValName,
  4103. &cbMaxValData,
  4104. NULL,
  4105. &ft)))
  4106. {
  4107. SetLastError((DWORD)NTE_FAIL);
  4108. goto Ret;
  4109. }
  4110. cbMaxKeyName += sizeof(CHAR);
  4111. if (NULL == (pszTmpProvName = LocalAlloc(LMEM_ZEROINIT, cbMaxKeyName)))
  4112. {
  4113. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  4114. goto Ret;
  4115. }
  4116. if (ERROR_SUCCESS != (err = RegEnumKeyEx(hRegKey, dwIndex, pszTmpProvName,
  4117. &cbMaxKeyName, NULL,
  4118. NULL, &cbClass, &ft)))
  4119. {
  4120. SetLastError((DWORD)err);
  4121. goto Ret;
  4122. }
  4123. if (ERROR_SUCCESS != (err = RegOpenKeyEx(hRegKey,
  4124. (const char *) pszTmpProvName,
  4125. 0L, KEY_READ, &hProvRegKey)))
  4126. {
  4127. SetLastError((DWORD)NTE_FAIL);
  4128. goto Ret;
  4129. }
  4130. cbProvType = sizeof(dw);
  4131. if (ERROR_SUCCESS != (err = RegQueryValueEx(hProvRegKey,
  4132. (const char *) "Type",
  4133. NULL, &dwKeyType, (BYTE*)&dw,
  4134. &cbProvType)))
  4135. {
  4136. SetLastError((DWORD)NTE_FAIL);
  4137. goto Ret;
  4138. }
  4139. *pdwProvType = dw;
  4140. cbTmpProvName = strlen(pszTmpProvName) + sizeof(CHAR);
  4141. if (NULL != pszProvName)
  4142. {
  4143. if (*pcbProvName < cbTmpProvName)
  4144. {
  4145. *pcbProvName = cbTmpProvName;
  4146. SetLastError(ERROR_MORE_DATA);
  4147. goto Ret;
  4148. }
  4149. strcpy(pszProvName, pszTmpProvName);
  4150. }
  4151. *pcbProvName = cbTmpProvName;
  4152. }
  4153. __except ( EXCEPTION_EXECUTE_HANDLER )
  4154. {
  4155. SetLastError(ERROR_INVALID_PARAMETER);
  4156. goto Ret;
  4157. }
  4158. fRet = CRYPT_SUCCEED;
  4159. Ret:
  4160. if (pszTmpProvName)
  4161. LocalFree(pszTmpProvName);
  4162. if (hRegKey)
  4163. RegCloseKey(hRegKey);
  4164. if (hProvRegKey)
  4165. RegCloseKey(hProvRegKey);
  4166. return fRet;
  4167. }
  4168. BOOL EnterProviderCritSec(IN PVTableStruc pVTable)
  4169. {
  4170. __try
  4171. {
  4172. if (pVTable->Version != TABLEPROV)
  4173. {
  4174. SetLastError(ERROR_INVALID_PARAMETER);
  4175. goto Try_Error_Return;
  4176. }
  4177. InterlockedIncrement((LPLONG)&pVTable->Inuse);
  4178. }
  4179. __except ( EXCEPTION_EXECUTE_HANDLER )
  4180. {
  4181. SetLastError(ERROR_INVALID_PARAMETER);
  4182. goto Try_Error_Return;
  4183. }
  4184. return(CRYPT_SUCCEED);
  4185. Try_Error_Return:
  4186. return(CRYPT_FAILED);
  4187. }
  4188. void LeaveProviderCritSec(IN PVTableStruc pVTable)
  4189. {
  4190. InterlockedDecrement((LPLONG)&pVTable->Inuse);
  4191. }
  4192. BOOL EnterKeyCritSec(IN PVKeyStruc pVKey)
  4193. {
  4194. __try
  4195. {
  4196. if (pVKey->Version != TABLEKEY)
  4197. {
  4198. SetLastError(ERROR_INVALID_PARAMETER);
  4199. goto Try_Error_Return;
  4200. }
  4201. InterlockedIncrement((LPLONG)&pVKey->Inuse);
  4202. }
  4203. __except ( EXCEPTION_EXECUTE_HANDLER )
  4204. {
  4205. SetLastError(ERROR_INVALID_PARAMETER);
  4206. goto Try_Error_Return;
  4207. }
  4208. return(CRYPT_SUCCEED);
  4209. Try_Error_Return:
  4210. return(CRYPT_FAILED);
  4211. }
  4212. void LeaveKeyCritSec(IN PVKeyStruc pVKey)
  4213. {
  4214. InterlockedDecrement((LPLONG)&pVKey->Inuse);
  4215. }
  4216. BOOL EnterHashCritSec(IN PVHashStruc pVHash)
  4217. {
  4218. __try
  4219. {
  4220. if (pVHash->Version != TABLEHASH)
  4221. {
  4222. SetLastError(ERROR_INVALID_PARAMETER);
  4223. goto Try_Error_Return;
  4224. }
  4225. InterlockedIncrement((LPLONG)&pVHash->Inuse);
  4226. }
  4227. __except ( EXCEPTION_EXECUTE_HANDLER )
  4228. {
  4229. SetLastError(ERROR_INVALID_PARAMETER);
  4230. goto Try_Error_Return;
  4231. }
  4232. return(CRYPT_SUCCEED);
  4233. Try_Error_Return:
  4234. return(CRYPT_FAILED);
  4235. }
  4236. void LeaveHashCritSec(IN PVHashStruc pVHash)
  4237. {
  4238. InterlockedDecrement((LPLONG)&pVHash->Inuse);
  4239. }
  4240. BOOL BuildVKey(IN PVKeyStruc *ppVKey,
  4241. IN PVTableStruc pVTable)
  4242. {
  4243. DWORD bufsize;
  4244. PVKeyStruc pVKey;
  4245. bufsize = sizeof(VKeyStruc);
  4246. if ((pVKey = (PVKeyStruc) LocalAlloc(LMEM_ZEROINIT,
  4247. (UINT) bufsize)) == NULL)
  4248. {
  4249. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  4250. return(CRYPT_FAILED);
  4251. }
  4252. pVKey->FuncGenKey = pVTable->FuncGenKey;
  4253. pVKey->FuncDeriveKey = pVTable->FuncDeriveKey;
  4254. pVKey->FuncDestroyKey = pVTable->FuncDestroyKey;
  4255. pVKey->FuncSetKeyParam = pVTable->FuncSetKeyParam;
  4256. pVKey->FuncGetKeyParam = pVTable->FuncGetKeyParam;
  4257. pVKey->FuncExportKey = pVTable->FuncExportKey;
  4258. pVKey->FuncImportKey = pVTable->FuncImportKey;
  4259. pVKey->FuncEncrypt = pVTable->FuncEncrypt;
  4260. pVKey->FuncDecrypt = pVTable->FuncDecrypt;
  4261. pVKey->OptionalFuncDuplicateKey = pVTable->OptionalFuncDuplicateKey;
  4262. pVKey->hProv = pVTable->hProv;
  4263. *ppVKey = pVKey;
  4264. return(CRYPT_SUCCEED);
  4265. }
  4266. BOOL BuildVHash(
  4267. IN PVHashStruc *ppVHash,
  4268. IN PVTableStruc pVTable
  4269. )
  4270. {
  4271. DWORD bufsize;
  4272. PVHashStruc pVHash;
  4273. bufsize = sizeof(VHashStruc);
  4274. if ((pVHash = (PVHashStruc) LocalAlloc(LMEM_ZEROINIT, (UINT) bufsize)) == NULL)
  4275. {
  4276. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  4277. return(CRYPT_FAILED);
  4278. }
  4279. pVHash->FuncCreateHash = pVTable->FuncCreateHash;
  4280. pVHash->FuncHashData = pVTable->FuncHashData;
  4281. pVHash->FuncHashSessionKey = pVTable->FuncHashSessionKey;
  4282. pVHash->FuncDestroyHash = pVTable->FuncDestroyHash;
  4283. pVHash->FuncSignHash = pVTable->FuncSignHash;
  4284. pVHash->FuncVerifySignature = pVTable->FuncVerifySignature;
  4285. pVHash->FuncGetHashParam = pVTable->FuncGetHashParam;
  4286. pVHash->FuncSetHashParam = pVTable->FuncSetHashParam;
  4287. pVHash->OptionalFuncDuplicateHash = pVTable->OptionalFuncDuplicateHash;
  4288. pVHash->hProv = (HCRYPTPROV)pVTable;
  4289. *ppVHash = pVHash;
  4290. return(CRYPT_SUCCEED);
  4291. }
  4292. #define RC4_KEYSIZE 5
  4293. void EncryptKey(BYTE *pdata, DWORD size, BYTE val)
  4294. {
  4295. RC4_KEYSTRUCT key;
  4296. BYTE RealKey[RC4_KEYSIZE] = {0xa2, 0x17, 0x9c, 0x98, 0xca};
  4297. DWORD index;
  4298. for (index = 0; index < RC4_KEYSIZE; index++)
  4299. {
  4300. RealKey[index] ^= val;
  4301. }
  4302. rc4_key(&key, RC4_KEYSIZE, RealKey);
  4303. rc4(&key, size, pdata);
  4304. }
  4305. void MD5HashData(
  4306. BYTE *pb,
  4307. DWORD cb,
  4308. BYTE *pbHash
  4309. )
  4310. {
  4311. MD5_CTX HashState;
  4312. MD5Init(&HashState);
  4313. __try
  4314. {
  4315. MD5Update(&HashState, pb, cb);
  4316. } __except ( EXCEPTION_EXECUTE_HANDLER )
  4317. {
  4318. SetLastError((DWORD) NTE_SIGNATURE_FILE_BAD);
  4319. return;
  4320. }
  4321. // Finish the hash
  4322. MD5Final(&HashState);
  4323. memcpy(pbHash, HashState.digest, 16);
  4324. }
  4325. BOOL CheckSignature(
  4326. BYTE *pbKey,
  4327. DWORD cbKey,
  4328. BYTE *pbSig,
  4329. DWORD cbSig,
  4330. BYTE *pbHash,
  4331. BOOL fUnknownLen)
  4332. {
  4333. BYTE rgbResult[KEYSIZE1024];
  4334. BYTE rgbSig[KEYSIZE1024];
  4335. BYTE rgbKey[sizeof(BSAFE_PUB_KEY) + KEYSIZE1024];
  4336. BYTE rgbKeyHash[16];
  4337. BYTE *pbSecondKey;
  4338. DWORD cbSecondKey;
  4339. BYTE *pbKeySig;
  4340. PSECOND_TIER_SIG pSecondTierSig;
  4341. LPBSAFE_PUB_KEY pTmp;
  4342. BOOL fRet = FALSE;
  4343. memset(rgbResult, 0, KEYSIZE1024);
  4344. memset(rgbSig, 0, KEYSIZE1024);
  4345. // just check the straight signature if version is 1
  4346. pTmp = (LPBSAFE_PUB_KEY)pbKey;
  4347. // check if sig length is the same as the key length
  4348. if (fUnknownLen || (cbSig == pTmp->keylen))
  4349. {
  4350. memcpy(rgbSig, pbSig, pTmp->keylen);
  4351. BSafeEncPublic(pTmp, rgbSig, rgbResult);
  4352. if (RtlEqualMemory(pbHash, rgbResult, 16) &&
  4353. rgbResult[cbKey-1] == 0 &&
  4354. rgbResult[cbKey-2] == 1 &&
  4355. rgbResult[16] == 0 &&
  4356. rgbResult[17] == 0xFF)
  4357. {
  4358. fRet = TRUE;
  4359. goto Ret;
  4360. }
  4361. }
  4362. // check the the second tier signature if the magic equals 2
  4363. pSecondTierSig = (PSECOND_TIER_SIG)pbSig;
  4364. if (0x00000002 != pSecondTierSig->dwMagic)
  4365. goto Ret;
  4366. if (0x31415352 != pSecondTierSig->Pub.magic)
  4367. goto Ret;
  4368. // assign the pointers
  4369. cbSecondKey = sizeof(BSAFE_PUB_KEY) + pSecondTierSig->Pub.keylen;
  4370. pbSecondKey = pbSig + (sizeof(SECOND_TIER_SIG) - sizeof(BSAFE_PUB_KEY));
  4371. pbKeySig = pbSecondKey + cbSecondKey;
  4372. // hash the second tier key
  4373. MD5HashData(pbSecondKey, cbSecondKey, rgbKeyHash);
  4374. // Decrypt the signature data on the second tier key
  4375. memset(rgbResult, 0, sizeof(rgbResult));
  4376. memset(rgbSig, 0, sizeof(rgbSig));
  4377. memcpy(rgbSig, pbKeySig, pSecondTierSig->cbSig);
  4378. BSafeEncPublic(pTmp, rgbSig, rgbResult);
  4379. if ((FALSE == RtlEqualMemory(rgbKeyHash, rgbResult, 16)) ||
  4380. rgbResult[cbKey-1] != 0 ||
  4381. rgbResult[cbKey-2] != 1 ||
  4382. rgbResult[16] != 0 ||
  4383. rgbResult[17] != 0)
  4384. {
  4385. goto Ret;
  4386. }
  4387. // Decrypt the signature data on the CSP
  4388. memset(rgbResult, 0, sizeof(rgbResult));
  4389. memset(rgbSig, 0, sizeof(rgbSig));
  4390. memset(rgbKey, 0, sizeof(rgbKey));
  4391. memcpy(rgbSig, pbKeySig + pSecondTierSig->cbSig, pSecondTierSig->cbSig);
  4392. memcpy(rgbKey, pbSecondKey, cbSecondKey);
  4393. pTmp = (LPBSAFE_PUB_KEY)rgbKey;
  4394. BSafeEncPublic(pTmp, rgbSig, rgbResult);
  4395. if (RtlEqualMemory(pbHash, rgbResult, 16) &&
  4396. rgbResult[pTmp->keylen-1] == 0 &&
  4397. rgbResult[pTmp->keylen-2] == 1 &&
  4398. rgbResult[16] == 0)
  4399. {
  4400. fRet = TRUE;
  4401. }
  4402. Ret:
  4403. return fRet;
  4404. }
  4405. // Given hInst, allocs and returns pointers to signature pulled from
  4406. // resource
  4407. BOOL GetCryptSigResourcePtr(
  4408. HMODULE hInst,
  4409. BYTE **ppbRsrcSig,
  4410. DWORD *pcbRsrcSig
  4411. )
  4412. {
  4413. HRSRC hRsrc;
  4414. BOOL fRet = FALSE;
  4415. // Nab resource handle for our signature
  4416. if (NULL == (hRsrc = FindResource(hInst, OLD_CRYPT_SIG_RESOURCE_NUMBER,
  4417. RT_RCDATA)))
  4418. goto Ret;
  4419. // get a pointer to the actual signature data
  4420. if (NULL == (*ppbRsrcSig = (PBYTE)LoadResource(hInst, hRsrc)))
  4421. goto Ret;
  4422. // determine the size of the resource
  4423. if (0 == (*pcbRsrcSig = SizeofResource(hInst, hRsrc)))
  4424. goto Ret;
  4425. fRet = TRUE;
  4426. Ret:
  4427. return fRet;
  4428. }
  4429. #define CSP_TO_BE_HASHED_CHUNK 4096
  4430. // Given hFile, reads the specified number of bytes (cbToBeHashed) from the file
  4431. // and hashes these bytes. The function does this in chunks.
  4432. BOOL HashBytesOfFile(
  4433. IN HANDLE hFile,
  4434. IN DWORD cbToBeHashed,
  4435. IN OUT MD5_CTX *pMD5Hash
  4436. )
  4437. {
  4438. BYTE rgbChunk[CSP_TO_BE_HASHED_CHUNK];
  4439. DWORD cbRemaining = cbToBeHashed;
  4440. DWORD cbToRead;
  4441. DWORD dwBytesRead;
  4442. BOOL fRet = FALSE;
  4443. //
  4444. // loop over the file for the specified number of bytes
  4445. // updating the hash as we go.
  4446. //
  4447. while (cbRemaining > 0)
  4448. {
  4449. if (cbRemaining < CSP_TO_BE_HASHED_CHUNK)
  4450. cbToRead = cbRemaining;
  4451. else
  4452. cbToRead = CSP_TO_BE_HASHED_CHUNK;
  4453. if(!ReadFile(hFile, rgbChunk, cbToRead, &dwBytesRead, NULL))
  4454. goto Ret;
  4455. if (dwBytesRead != cbToRead)
  4456. goto Ret;
  4457. MD5Update(pMD5Hash, rgbChunk, dwBytesRead);
  4458. cbRemaining -= cbToRead;
  4459. }
  4460. fRet = TRUE;
  4461. Ret:
  4462. return fRet;
  4463. }
  4464. BOOL HashTheFile(
  4465. LPCWSTR pszImage,
  4466. DWORD cbImage,
  4467. BYTE **ppbSig,
  4468. DWORD *pcbSig,
  4469. BYTE *pbHash
  4470. )
  4471. {
  4472. HMODULE hInst;
  4473. MEMORY_BASIC_INFORMATION MemInfo;
  4474. BYTE *pbRsrcSig;
  4475. DWORD cbRsrcSig;
  4476. BYTE *pbStart = NULL;
  4477. BYTE *pbZeroSig = NULL;
  4478. MD5_CTX MD5Hash;
  4479. BYTE *pbPostCRC; // pointer to just after CRC
  4480. DWORD cbCRCToSig; // number of bytes from CRC to sig
  4481. DWORD cbPostSig; // size - (already hashed + signature size)
  4482. BYTE *pbPostSig;
  4483. DWORD *pdwSigInFileVer;
  4484. DWORD *pdwCRCOffset;
  4485. DWORD dwCRCOffset;
  4486. DWORD dwZeroCRC = 0;
  4487. HANDLE File = INVALID_HANDLE_VALUE ;
  4488. HANDLE hMapping = NULL;
  4489. BOOL fRet = FALSE;
  4490. memset(&MD5Hash, 0, sizeof(MD5Hash));
  4491. memset(&MemInfo, 0, sizeof(MemInfo));
  4492. // Load the file
  4493. File = CreateFileW(
  4494. pszImage,
  4495. GENERIC_READ,
  4496. FILE_SHARE_READ,
  4497. NULL,
  4498. OPEN_EXISTING,
  4499. FILE_ATTRIBUTE_NORMAL,
  4500. NULL );
  4501. if ( File == INVALID_HANDLE_VALUE )
  4502. {
  4503. goto Ret ;
  4504. }
  4505. hMapping = CreateFileMapping( File,
  4506. NULL,
  4507. PAGE_READONLY,
  4508. 0,
  4509. 0,
  4510. NULL);
  4511. if(hMapping == NULL)
  4512. {
  4513. goto Ret;
  4514. }
  4515. pbStart = MapViewOfFile(hMapping,
  4516. FILE_MAP_READ,
  4517. 0,
  4518. 0,
  4519. 0);
  4520. if(pbStart == NULL)
  4521. {
  4522. goto Ret;
  4523. }
  4524. // Convert pointer to HMODULE, using the same scheme as
  4525. // LoadLibrary (windows\base\client\module.c).
  4526. hInst = (HMODULE)((ULONG_PTR)pbStart | 0x00000001);
  4527. // the resources signature
  4528. if (!GetCryptSigResourcePtr(hInst, &pbRsrcSig, &cbRsrcSig))
  4529. goto Ret;
  4530. if (cbRsrcSig < (sizeof(DWORD) * 2))
  4531. goto Ret;
  4532. // check the sig in file version and get the CRC offset
  4533. pdwSigInFileVer = (DWORD*)pbRsrcSig;
  4534. pdwCRCOffset = (DWORD*)(pbRsrcSig + sizeof(DWORD));
  4535. dwCRCOffset = *pdwCRCOffset;
  4536. if ((0x00000100 != *pdwSigInFileVer) || (dwCRCOffset > cbImage))
  4537. goto Ret;
  4538. // create a zero byte signature
  4539. if (NULL == (pbZeroSig = (BYTE*)LocalAlloc(LMEM_ZEROINIT, cbRsrcSig)))
  4540. goto Ret;
  4541. memcpy(pbZeroSig, pbRsrcSig, sizeof(DWORD) * 2);
  4542. pbPostCRC = pbStart + *pdwCRCOffset + sizeof(DWORD);
  4543. cbCRCToSig = (DWORD)(pbRsrcSig - pbPostCRC);
  4544. pbPostSig = pbRsrcSig + cbRsrcSig;
  4545. cbPostSig = (cbImage - (DWORD)(pbPostSig - pbStart));
  4546. // allocate the real signature and copy the resource sig into the real sig
  4547. *pcbSig = cbRsrcSig - (sizeof(DWORD) * 2);
  4548. if (NULL == (*ppbSig = (BYTE*)LocalAlloc(LMEM_ZEROINIT, *pcbSig)))
  4549. goto Ret;
  4550. memcpy(*ppbSig, pbRsrcSig + (sizeof(DWORD) * 2), *pcbSig);
  4551. // hash over the relevant data
  4552. MD5Init(&MD5Hash);
  4553. // hash up to the CRC
  4554. if (!HashBytesOfFile(File, dwCRCOffset, &MD5Hash))
  4555. goto Ret;
  4556. // pretend CRC is zeroed
  4557. MD5Update(&MD5Hash, (BYTE*)&dwZeroCRC, sizeof(DWORD));
  4558. if (!SetFilePointer(File, sizeof(DWORD), NULL, FILE_CURRENT))
  4559. {
  4560. goto Ret;
  4561. }
  4562. // hash from CRC to sig resource
  4563. if (!HashBytesOfFile(File, cbCRCToSig, &MD5Hash))
  4564. goto Ret;
  4565. // pretend image has zeroed sig
  4566. MD5Update(&MD5Hash, pbZeroSig, cbRsrcSig);
  4567. if (!SetFilePointer(File, cbRsrcSig, NULL, FILE_CURRENT))
  4568. {
  4569. goto Ret;
  4570. }
  4571. // hash after the sig resource
  4572. if (!HashBytesOfFile(File, cbPostSig, &MD5Hash))
  4573. goto Ret;
  4574. // Finish the hash
  4575. MD5Final(&MD5Hash);
  4576. memcpy(pbHash, MD5Hash.digest, MD5DIGESTLEN);
  4577. fRet = TRUE;
  4578. Ret:
  4579. if (pbZeroSig)
  4580. LocalFree(pbZeroSig);
  4581. if(pbStart)
  4582. UnmapViewOfFile(pbStart);
  4583. if(hMapping)
  4584. CloseHandle(hMapping);
  4585. if ( File != INVALID_HANDLE_VALUE )
  4586. {
  4587. CloseHandle( File );
  4588. }
  4589. return fRet;
  4590. }
  4591. /*
  4592. - CheckAllSignatures
  4593. -
  4594. * Purpose:
  4595. * Check signature against all keys
  4596. *
  4597. *
  4598. * Returns:
  4599. * BOOL
  4600. */
  4601. BOOL CheckAllSignatures(
  4602. BYTE *pbSig,
  4603. DWORD cbSig,
  4604. BYTE *pbHash,
  4605. BOOL fUnknownLen
  4606. )
  4607. {
  4608. BYTE rgbKey[sizeof(BSAFE_PUB_KEY) + KEYSIZE1024];
  4609. BYTE rgbKey2[sizeof(BSAFE_PUB_KEY) + KEYSIZE1024];
  4610. #ifdef MS_INTERNAL_KEY
  4611. BYTE rgbMSKey[sizeof(BSAFE_PUB_KEY) + KEYSIZE1024];
  4612. #endif
  4613. #ifdef TEST_BUILD_EXPONENT
  4614. BYTE rgbTestKey[sizeof(BSAFE_PUB_KEY) + KEYSIZE512];
  4615. #endif
  4616. BOOL fRet = FALSE;
  4617. // decrypt the keys once for each process
  4618. memcpy(rgbKey, (BYTE*)&KEY, sizeof(BSAFE_PUB_KEY) + KEYSIZE1024);
  4619. EncryptKey(rgbKey, sizeof(BSAFE_PUB_KEY) + KEYSIZE1024, 0);
  4620. #ifdef MS_INTERNAL_KEY
  4621. memcpy(rgbMSKey, (BYTE*)&MSKEY, sizeof(BSAFE_PUB_KEY) + KEYSIZE1024);
  4622. EncryptKey(rgbMSKey, sizeof(BSAFE_PUB_KEY) + KEYSIZE1024, 1);
  4623. #endif
  4624. memcpy(rgbKey2, (BYTE*)&KEY2, sizeof(BSAFE_PUB_KEY) + KEYSIZE1024);
  4625. EncryptKey(rgbKey2, sizeof(BSAFE_PUB_KEY) + KEYSIZE1024, 2);
  4626. #ifdef TEST_BUILD_EXPONENT
  4627. memcpy(rgbTestKey, (BYTE*)&TESTKEY, sizeof(BSAFE_PUB_KEY) + KEYSIZE512);
  4628. EncryptKey(rgbTestKey, sizeof(BSAFE_PUB_KEY) + KEYSIZE512, 3);
  4629. #endif // TEST_BUILD_EXPONENT
  4630. if (CRYPT_SUCCEED == (fRet = CheckSignature(rgbKey, 128, pbSig,
  4631. cbSig, pbHash, fUnknownLen)))
  4632. {
  4633. fRet = TRUE;
  4634. goto Ret;
  4635. }
  4636. #ifdef MS_INTERNAL_KEY
  4637. if (CRYPT_SUCCEED == (fRet = CheckSignature(rgbMSKey, 128, pbSig,
  4638. cbSig, pbHash, fUnknownLen)))
  4639. {
  4640. fRet = TRUE;
  4641. goto Ret;
  4642. }
  4643. #endif
  4644. if (CRYPT_SUCCEED == (fRet = CheckSignature(rgbKey2, 128, pbSig,
  4645. cbSig, pbHash, fUnknownLen)))
  4646. {
  4647. fRet = TRUE;
  4648. goto Ret;
  4649. }
  4650. #ifdef TEST_BUILD_EXPONENT
  4651. if (CRYPT_SUCCEED == (fRet = CheckSignature(rgbTestKey, 64, pbSig,
  4652. cbSig, pbHash, fUnknownLen)))
  4653. {
  4654. fRet = TRUE;
  4655. goto Ret;
  4656. }
  4657. #endif // TEST_BUILD_EXPONENT
  4658. Ret:
  4659. return fRet;
  4660. }
  4661. /*
  4662. - CheckSignatureInFile
  4663. -
  4664. * Purpose:
  4665. * Check signature which is in the resource in the file
  4666. *
  4667. *
  4668. * Parameters:
  4669. * IN pszImage - address of file
  4670. *
  4671. * Returns:
  4672. * BOOL
  4673. */
  4674. BOOL CheckSignatureInFile(
  4675. LPCWSTR pszImage)
  4676. {
  4677. DWORD cbImage;
  4678. BYTE *pbSig = NULL;
  4679. DWORD cbSig;
  4680. BYTE rgbHash[MD5DIGESTLEN];
  4681. // DWORD cbHash;
  4682. BOOL fRet = FALSE;
  4683. WIN32_FILE_ATTRIBUTE_DATA FileData ;
  4684. WCHAR FullName[ MAX_PATH ];
  4685. PWSTR FilePart ;
  4686. SYSTEM_KERNEL_DEBUGGER_INFORMATION KdInfo;
  4687. #ifdef PROMISCUOUS_ADVAPI
  4688. #pragma message("WARNING: building promiscuous advapai32.dll!")
  4689. return TRUE;
  4690. #endif
  4691. NtQuerySystemInformation(
  4692. SystemKernelDebuggerInformation,
  4693. &KdInfo,
  4694. sizeof(KdInfo),
  4695. NULL);
  4696. // Allow any CSP to load if a Kd is attached
  4697. // and "responsive"
  4698. if ( TRUE == KdInfo.KernelDebuggerEnabled &&
  4699. FALSE == KdInfo.KernelDebuggerNotPresent)
  4700. return TRUE;
  4701. if ( !SearchPathW(NULL,
  4702. pszImage,
  4703. NULL,
  4704. MAX_PATH,
  4705. FullName,
  4706. &FilePart ) )
  4707. {
  4708. goto Ret ;
  4709. }
  4710. if ( !GetFileAttributesExW( FullName,
  4711. GetFileExInfoStandard,
  4712. &FileData ) )
  4713. {
  4714. goto Ret ;
  4715. }
  4716. if ( FileData.nFileSizeHigh )
  4717. {
  4718. goto Ret ;
  4719. }
  4720. cbImage = FileData.nFileSizeLow ;
  4721. if (!HashTheFile(FullName, cbImage, &pbSig, &cbSig, rgbHash))
  4722. goto Ret;
  4723. // check signature against all public keys
  4724. if (!CheckAllSignatures(pbSig, cbSig, rgbHash, FALSE))
  4725. goto Ret;
  4726. fRet = TRUE;
  4727. Ret:
  4728. if (pbSig)
  4729. LocalFree(pbSig);
  4730. return fRet;
  4731. }
  4732. /*
  4733. - NewVerifyImage
  4734. -
  4735. * Purpose:
  4736. * Check signature of file
  4737. *
  4738. *
  4739. * Parameters:
  4740. * IN lpszImage - address of file
  4741. * IN pSigData - address of signature data
  4742. * IN cbSig - length of signature data
  4743. * IN fUnknownLen - BOOL to tell if length is not passed in
  4744. *
  4745. * Returns:
  4746. * BOOL
  4747. */
  4748. BOOL NewVerifyImage(LPCSTR lpszImage,
  4749. BYTE *pSigData,
  4750. DWORD cbSig,
  4751. BOOL fUnknownLen)
  4752. {
  4753. HFILE hFileProv = HFILE_ERROR;
  4754. DWORD NumBytes;
  4755. DWORD lpdwFileSizeHigh;
  4756. MD5_CTX HashState;
  4757. OFSTRUCT ImageInfoBuf;
  4758. BOOL fRet = CRYPT_FAILED;
  4759. memset(&HashState, 0, sizeof(HashState));
  4760. if (HFILE_ERROR == (hFileProv = OpenFile(lpszImage, &ImageInfoBuf,
  4761. OF_READ)))
  4762. {
  4763. SetLastError((DWORD) NTE_PROV_DLL_NOT_FOUND);
  4764. goto Ret;
  4765. }
  4766. if (0xffffffff == (NumBytes = GetFileSize((HANDLE)IntToPtr(hFileProv),
  4767. &lpdwFileSizeHigh)))
  4768. {
  4769. SetLastError((DWORD) NTE_SIGNATURE_FILE_BAD);
  4770. goto Ret;
  4771. }
  4772. MD5Init(&HashState);
  4773. if (!HashBytesOfFile((HANDLE)IntToPtr(hFileProv), NumBytes, &HashState))
  4774. {
  4775. SetLastError((DWORD) NTE_SIGNATURE_FILE_BAD);
  4776. goto Ret;
  4777. }
  4778. MD5Final(&HashState);
  4779. // check the signature against all keys
  4780. if (!CheckAllSignatures(pSigData, cbSig, HashState.digest, fUnknownLen))
  4781. {
  4782. SetLastError((DWORD) NTE_BAD_SIGNATURE);
  4783. goto Ret;
  4784. }
  4785. fRet = TRUE;
  4786. Ret:
  4787. if (HFILE_ERROR != hFileProv)
  4788. _lclose(hFileProv);
  4789. return fRet;
  4790. }
  4791. /*
  4792. - CProvVerifyImage
  4793. -
  4794. * Purpose:
  4795. * Check signature of file
  4796. *
  4797. *
  4798. * Parameters:
  4799. * IN lpszImage - address of file
  4800. * IN lpSigData - address of signature data
  4801. *
  4802. * Returns:
  4803. * BOOL
  4804. */
  4805. BOOL CProvVerifyImage(LPCSTR lpszImage,
  4806. BYTE *pSigData)
  4807. {
  4808. UNICODE_STRING String ;
  4809. BOOL Result ;
  4810. if (NULL == pSigData)
  4811. {
  4812. if ( RtlCreateUnicodeStringFromAsciiz( &String, lpszImage ) )
  4813. {
  4814. Result = CheckSignatureInFile( String.Buffer );
  4815. RtlFreeUnicodeString( &String );
  4816. }
  4817. else
  4818. {
  4819. Result = FALSE ;
  4820. }
  4821. }
  4822. else
  4823. {
  4824. Result = NewVerifyImage(lpszImage, pSigData, 0, TRUE);
  4825. }
  4826. return Result;
  4827. }
  4828. /*
  4829. - CPReturnhWnd
  4830. -
  4831. * Purpose:
  4832. * Return a window handle back to a CSP
  4833. *
  4834. *
  4835. * Parameters:
  4836. * OUT phWnd - pointer to a hWnd to return
  4837. *
  4838. * Returns:
  4839. * void
  4840. */
  4841. void CPReturnhWnd(HWND *phWnd)
  4842. {
  4843. __try
  4844. {
  4845. *phWnd = hWnd;
  4846. } __except ( EXCEPTION_EXECUTE_HANDLER )
  4847. { ; }
  4848. return;
  4849. }
  4850. static void __ltoa(DWORD val, char *buf)
  4851. {
  4852. char *p; /* pointer to traverse string */
  4853. char *firstdig; /* pointer to first digit */
  4854. char temp; /* temp char */
  4855. unsigned digval; /* value of digit */
  4856. int i;
  4857. p = buf;
  4858. firstdig = p; /* save pointer to first digit */
  4859. for (i = 0; i < 8; i++) {
  4860. digval = (unsigned) (val % 10);
  4861. val /= 10; /* get next digit */
  4862. /* convert to ascii and store */
  4863. *p++ = (char) (digval + '0'); /* a digit */
  4864. }
  4865. /* We now have the digit of the number in the buffer, but in reverse
  4866. order. Thus we reverse them now. */
  4867. *p-- = '\0'; /* terminate string; p points to last digit */
  4868. do {
  4869. temp = *p;
  4870. *p = *firstdig;
  4871. *firstdig = temp; /* swap *p and *firstdig */
  4872. --p;
  4873. ++firstdig; /* advance to next two digits */
  4874. } while (firstdig < p); /* repeat until halfway */
  4875. }