Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

877 lines
21 KiB

  1. /*-----------------------------------------------------------------------------
  2. * Copyright (C) Microsoft Corporation, 1995 - 1999
  3. * All rights reserved.
  4. *
  5. * This file is part of the Microsoft Private Communication Technology
  6. * reference implementation, version 1.0
  7. *
  8. * The Private Communication Technology reference implementation, version 1.0
  9. * ("PCTRef"), is being provided by Microsoft to encourage the development and
  10. * enhancement of an open standard for secure general-purpose business and
  11. * personal communications on open networks. Microsoft is distributing PCTRef
  12. * at no charge irrespective of whether you use PCTRef for non-commercial or
  13. * commercial use.
  14. *
  15. * Microsoft expressly disclaims any warranty for PCTRef and all derivatives of
  16. * it. PCTRef and any related documentation is provided "as is" without
  17. * warranty of any kind, either express or implied, including, without
  18. * limitation, the implied warranties or merchantability, fitness for a
  19. * particular purpose, or noninfringement. Microsoft shall have no obligation
  20. * to provide maintenance, support, upgrades or new releases to you or to anyone
  21. * receiving from you PCTRef or your modifications. The entire risk arising out
  22. * of use or performance of PCTRef remains with you.
  23. *
  24. * Please see the file LICENSE.txt,
  25. * or http://pct.microsoft.com/pct/pctlicen.txt
  26. * for more information on licensing.
  27. *
  28. * Please see http://pct.microsoft.com/pct/pct.htm for The Private
  29. * Communication Technology Specification version 1.0 ("PCT Specification")
  30. *
  31. * 1/23/96
  32. *----------------------------------------------------------------------------*/
  33. /*-----------------------------------------------------------------------------
  34. * RSA Public Key Cryptosystem, RC4, MD2, MD5 and RSA are trademarks
  35. * of RSA Data Security, Inc.
  36. *----------------------------------------------------------------------------*/
  37. #include <spbase.h>
  38. #include <wincrypt.h>
  39. #ifdef __cplusplus
  40. extern "C" {
  41. #endif
  42. #include <rsa.h>
  43. #include <md2.h>
  44. #include <md5.h>
  45. #ifdef __cplusplus
  46. }
  47. #endif
  48. static unsigned char MD5_PRELUDE[] = {
  49. 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7,
  50. 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10
  51. };
  52. static unsigned char MD2_PRELUDE[] = {
  53. 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7,
  54. 0x0d, 0x02, 0x02, 0x05, 0x00, 0x04, 0x10
  55. };
  56. static VOID
  57. ReverseMemCopy(
  58. PUCHAR Dest,
  59. PUCHAR Source,
  60. ULONG Size)
  61. {
  62. PUCHAR p;
  63. p = Dest + Size - 1;
  64. do
  65. {
  66. *p-- = *Source++;
  67. } while (p >= Dest);
  68. }
  69. BOOL
  70. WINAPI
  71. SigRSAMD2Sign(
  72. PUCHAR pData,
  73. DWORD cbData,
  74. PUCHAR pSigned,
  75. DWORD *pcbSigned,
  76. PctPrivateKey *pKey);
  77. BOOL
  78. WINAPI
  79. SigRSAMD5Sign(
  80. PUCHAR pData,
  81. DWORD cbData,
  82. PUCHAR pSigned,
  83. DWORD *pcbSigned,
  84. PctPrivateKey *pKey);
  85. BOOL
  86. WINAPI SigRSASHAMD5Sign(
  87. PUCHAR pData,
  88. DWORD cbData,
  89. PUCHAR pSigned,
  90. DWORD *pcbSigned,
  91. PctPrivateKey *pKey);
  92. BOOL
  93. WINAPI SigRSAMD2Verify(
  94. PUCHAR pData,
  95. DWORD cbData,
  96. PUCHAR pSigned,
  97. DWORD cbSigned,
  98. PctPublicKey *pKey);
  99. BOOL
  100. WINAPI SigRSAMD5Verify(
  101. PUCHAR pData,
  102. DWORD cbData,
  103. PUCHAR pSigned,
  104. DWORD cbSigned,
  105. PctPublicKey *pKey);
  106. BOOL
  107. WINAPI SigRSASHAMD5Verify(
  108. PUCHAR pData,
  109. DWORD cbData,
  110. PUCHAR pSigned,
  111. DWORD cbSigned,
  112. PctPublicKey *pKey);
  113. #define ADVAPI32_PATH TEXT("advapi32.dll")
  114. #define CRYPT_CREATE_HASH_NAME TEXT("CryptCreateHash")
  115. #define CRYPT_HASH_DATA_NAME TEXT("CryptHashData")
  116. #define CRYPT_SIGN_HASH_NAMEA TEXT("CryptSignHashA")
  117. #define CRYPT_SIGN_HASH_NAMEW TEXT("CryptSignHashW")
  118. #define CRYPT_DESTROY_HASH_NAME TEXT("CryptDestroyHash")
  119. #define CRYPT_SET_HASH_PARAM_NAME TEXT("CryptSetHashParam")
  120. typedef BOOL
  121. ( WINAPI * CRYPT_CREATE_HASH_FN)(
  122. HCRYPTPROV hProv,
  123. ALG_ID Algid,
  124. HCRYPTKEY hKey,
  125. DWORD dwFlags,
  126. HCRYPTHASH *phHash);
  127. typedef BOOL
  128. ( WINAPI * CRYPT_HASH_DATA_FN)(
  129. HCRYPTHASH hHash,
  130. CONST BYTE *pbData,
  131. DWORD dwDataLen,
  132. DWORD dwFlags);
  133. typedef BOOL
  134. ( WINAPI * CRYPT_DESTROY_HASH_FN) (
  135. HCRYPTHASH hHash);
  136. typedef BOOL
  137. ( WINAPI * CRYPT_SIGN_HASH_FNA)(
  138. HCRYPTHASH hHash,
  139. DWORD dwKeySpec,
  140. LPCSTR sDescription,
  141. DWORD dwFlags,
  142. BYTE *pbSignature,
  143. DWORD *pdwSigLen);
  144. typedef BOOL
  145. ( WINAPI * CRYPT_SIGN_HASH_FNW)(
  146. HCRYPTHASH hHash,
  147. DWORD dwKeySpec,
  148. LPCWSTR sDescription,
  149. DWORD dwFlags,
  150. BYTE *pbSignature,
  151. DWORD *pdwSigLen);
  152. typedef BOOL
  153. ( WINAPI * CRYPT_SET_HASH_PARAM_FN)(
  154. HCRYPTHASH hHash,
  155. DWORD dwParam,
  156. BYTE *pbData,
  157. DWORD dwFlags);
  158. HINSTANCE g_hAdvapi32 = NULL;
  159. CRYPT_CREATE_HASH_FN g_CryptCreateHash = NULL;
  160. CRYPT_HASH_DATA_FN g_CryptHashData = NULL;
  161. CRYPT_DESTROY_HASH_FN g_CryptDestroyHash = NULL;
  162. CRYPT_SIGN_HASH_FNA g_CryptSignHashA = NULL;
  163. CRYPT_SIGN_HASH_FNW g_CryptSignHashW = NULL;
  164. CRYPT_SET_HASH_PARAM_FN g_CryptSetHashParam = NULL;
  165. SignatureSystem sigRSAMD2 = { SP_SIG_RSA_MD2, SigRSAMD2Sign, SigRSAMD2Verify};
  166. SignatureSystem sigRSAMD5 = { SP_SIG_RSA_MD5, SigRSAMD5Sign, SigRSAMD5Verify};
  167. SignatureSystem sigRSASHAMD5 = { SP_SIG_RSA_SHAMD5, SigRSASHAMD5Sign, SigRSASHAMD5Verify};
  168. BOOL
  169. WINAPI capiCryptCreateHash(
  170. HCRYPTPROV hProv,
  171. ALG_ID Algid,
  172. HCRYPTKEY hKey,
  173. DWORD dwFlags,
  174. HCRYPTHASH *phHash)
  175. {
  176. if(!g_hAdvapi32)
  177. {
  178. g_hAdvapi32 = LoadLibrary(ADVAPI32_PATH);
  179. if(!g_hAdvapi32)
  180. {
  181. return FALSE;
  182. }
  183. }
  184. if(!g_CryptCreateHash)
  185. {
  186. g_CryptCreateHash = (CRYPT_CREATE_HASH_FN)GetProcAddress(g_hAdvapi32, CRYPT_CREATE_HASH_NAME);
  187. if(!g_CryptCreateHash)
  188. {
  189. return FALSE;
  190. }
  191. }
  192. return g_CryptCreateHash(hProv, Algid, hKey, dwFlags, phHash);
  193. }
  194. BOOL
  195. WINAPI capiCryptHashData(
  196. HCRYPTHASH hHash,
  197. CONST BYTE *pbData,
  198. DWORD dwDataLen,
  199. DWORD dwFlags)
  200. {
  201. if(!g_hAdvapi32)
  202. {
  203. g_hAdvapi32 = LoadLibrary(ADVAPI32_PATH);
  204. if(!g_hAdvapi32)
  205. {
  206. return FALSE;
  207. }
  208. }
  209. if(!g_CryptHashData)
  210. {
  211. g_CryptHashData = (CRYPT_HASH_DATA_FN)GetProcAddress(g_hAdvapi32, CRYPT_HASH_DATA_NAME);
  212. if(!g_CryptHashData)
  213. {
  214. return FALSE;
  215. }
  216. }
  217. return g_CryptHashData(hHash, pbData, dwDataLen, dwFlags);
  218. }
  219. BOOL
  220. WINAPI capiCryptDestroyHash(
  221. HCRYPTHASH hHash)
  222. {
  223. if(!g_hAdvapi32)
  224. {
  225. g_hAdvapi32 = LoadLibrary(ADVAPI32_PATH);
  226. if(!g_hAdvapi32)
  227. {
  228. return FALSE;
  229. }
  230. }
  231. if(!g_CryptDestroyHash)
  232. {
  233. g_CryptDestroyHash = (CRYPT_DESTROY_HASH_FN)GetProcAddress(g_hAdvapi32, CRYPT_DESTROY_HASH_NAME);
  234. if(!g_CryptDestroyHash)
  235. {
  236. return FALSE;
  237. }
  238. }
  239. return g_CryptDestroyHash(hHash);
  240. }
  241. BOOL
  242. WINAPI capiCryptSignHashA(
  243. HCRYPTHASH hHash,
  244. DWORD dwKeySpec,
  245. LPCSTR sDescription,
  246. DWORD dwFlags,
  247. BYTE *pbSignature,
  248. DWORD *pdwSigLen)
  249. {
  250. if(!g_hAdvapi32)
  251. {
  252. g_hAdvapi32 = LoadLibrary(ADVAPI32_PATH);
  253. if(!g_hAdvapi32)
  254. {
  255. return FALSE;
  256. }
  257. }
  258. if(!g_CryptSignHashA)
  259. {
  260. g_CryptSignHashA = (CRYPT_SIGN_HASH_FNA)GetProcAddress(g_hAdvapi32, CRYPT_SIGN_HASH_NAMEA);
  261. if(!g_CryptSignHashA)
  262. {
  263. return FALSE;
  264. }
  265. }
  266. return g_CryptSignHashA(hHash, dwKeySpec, sDescription, dwFlags, pbSignature, pdwSigLen);
  267. }
  268. BOOL
  269. WINAPI capiCryptSignHashW(
  270. HCRYPTHASH hHash,
  271. DWORD dwKeySpec,
  272. LPCWSTR sDescription,
  273. DWORD dwFlags,
  274. BYTE *pbSignature,
  275. DWORD *pdwSigLen)
  276. {
  277. if(!g_hAdvapi32)
  278. {
  279. g_hAdvapi32 = LoadLibrary(ADVAPI32_PATH);
  280. if(!g_hAdvapi32)
  281. {
  282. return FALSE;
  283. }
  284. }
  285. if(!g_CryptSignHashW)
  286. {
  287. g_CryptSignHashW = (CRYPT_SIGN_HASH_FNW)GetProcAddress(g_hAdvapi32, CRYPT_SIGN_HASH_NAMEW);
  288. if(!g_CryptSignHashW)
  289. {
  290. return FALSE;
  291. }
  292. }
  293. return g_CryptSignHashW(hHash, dwKeySpec, sDescription, dwFlags, pbSignature, pdwSigLen);
  294. }
  295. BOOL
  296. WINAPI capiCryptSetHashParam(
  297. HCRYPTHASH hHash,
  298. DWORD dwParam,
  299. BYTE *pbData,
  300. DWORD dwFlags)
  301. {
  302. if(!g_hAdvapi32)
  303. {
  304. g_hAdvapi32 = LoadLibrary(ADVAPI32_PATH);
  305. if(!g_hAdvapi32)
  306. {
  307. return FALSE;
  308. }
  309. }
  310. if(!g_CryptSetHashParam)
  311. {
  312. g_CryptSetHashParam = (CRYPT_SET_HASH_PARAM_FN)GetProcAddress(g_hAdvapi32, CRYPT_SET_HASH_PARAM_NAME);
  313. if(!g_CryptSetHashParam)
  314. {
  315. return FALSE;
  316. }
  317. }
  318. return g_CryptSetHashParam(hHash, dwParam, pbData, dwFlags);
  319. }
  320. #ifdef UNICODE
  321. #define capiCryptSignHash capiCryptSignHashW
  322. #else
  323. #define capiCryptSignHash capiCryptSignHashA
  324. #endif // !UNICODE
  325. BOOL
  326. WINAPI
  327. SigRSAMD5Sign(
  328. PUCHAR pData,
  329. DWORD cbData,
  330. PUCHAR pSigned,
  331. DWORD *pcbSigned,
  332. PctPrivateKey *pKey)
  333. {
  334. MD5_CTX DigCtx;
  335. BSAFE_PRV_KEY *pk = (BSAFE_PRV_KEY *)pKey->pKey;
  336. UCHAR LocalBuffer[300];
  337. UCHAR LocalOutput[300];
  338. unsigned int cbSize;
  339. if(pk->magic != RSA2 && pKey->cbKey == sizeof(HCRYPTPROV))
  340. {
  341. // This isn't a bsafe key, and it's the right size, so it must be a
  342. // CAPI key. This a heuristic.
  343. HCRYPTHASH hHash;
  344. DWORD cbSigned;
  345. HCRYPTPROV hProv = *((HCRYPTPROV *)pKey->pKey);
  346. if(!capiCryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
  347. {
  348. return FALSE;
  349. }
  350. if(!capiCryptHashData(hHash, pData, cbData, 0))
  351. {
  352. capiCryptDestroyHash(hHash);
  353. return FALSE;
  354. }
  355. cbSigned = sizeof(LocalOutput);
  356. if(!capiCryptSignHash(hHash, AT_KEYEXCHANGE, NULL, 0, LocalOutput, &cbSigned))
  357. {
  358. capiCryptDestroyHash(hHash);
  359. return FALSE;
  360. }
  361. capiCryptDestroyHash(hHash);
  362. ReverseMemCopy(pSigned, LocalOutput, cbSigned);
  363. *pcbSigned = cbSigned;
  364. return TRUE;
  365. }
  366. else if(pk->magic != RSA2)
  367. {
  368. // This isn't a bsafe key or a CAPI key, so it must be a WinSock 2
  369. // LSP key.
  370. SSLSIGNATUREFUNC pSignHook;
  371. LPVOID pSignArg;
  372. /* Generate the checksum */
  373. MD5Init(&DigCtx);
  374. MD5Update(&DigCtx, pData, cbData);
  375. MD5Final(&DigCtx);
  376. // Get the prelude data and the hash value.
  377. CopyMemory(LocalBuffer, MD5_PRELUDE, sizeof(MD5_PRELUDE));
  378. CopyMemory(LocalBuffer + sizeof(MD5_PRELUDE), DigCtx.digest, MD5DIGESTLEN);
  379. // Get pointer to callback function.
  380. pSignHook = ((PSCH_CRED_SECRET_WINSOCK2)pKey->pKey)->pSignatureHookFunc;
  381. pSignArg = ((PSCH_CRED_SECRET_WINSOCK2)pKey->pKey)->pSignatureHookArg;
  382. // Invoke the callback function.
  383. if(pSignHook)
  384. {
  385. if(pSignHook(SSL_SIGN_RSA,
  386. pSignArg,
  387. LocalBuffer,
  388. sizeof(MD5_PRELUDE) + MD5DIGESTLEN,
  389. 0,
  390. pSigned,
  391. pcbSigned) != SSL_ERR_OKAY)
  392. {
  393. return FALSE;
  394. }
  395. }
  396. else
  397. {
  398. DebugLog((DEB_ERROR, "Null signature callback function!\n"));
  399. }
  400. // Return success.
  401. return TRUE;
  402. }
  403. cbSize = sizeof(MD5_PRELUDE)+16;
  404. if(pk->datalen > sizeof(LocalBuffer))
  405. {
  406. return FALSE;
  407. }
  408. /* Generate the checksum */
  409. MD5Init(&DigCtx);
  410. MD5Update(&DigCtx, pData, cbData);
  411. MD5Final(&DigCtx);
  412. FillMemory(LocalBuffer, pk->keylen, 0);
  413. ReverseMemCopy(LocalBuffer, DigCtx.digest, 16);
  414. ReverseMemCopy(LocalBuffer+16, MD5_PRELUDE, sizeof(MD5_PRELUDE));
  415. LocalBuffer[cbSize++]=0;
  416. while(cbSize < pk->datalen-1) {
  417. LocalBuffer[cbSize++] = 0xff;
  418. }
  419. /* Make into pkcs block type 1 */
  420. LocalBuffer[pk->datalen-1] = 1;
  421. *pcbSigned = pk->datalen+1;
  422. if(!BSafeDecPrivate(pk, LocalBuffer, LocalOutput))
  423. {
  424. return FALSE;
  425. }
  426. ReverseMemCopy(pSigned, LocalOutput, *pcbSigned);
  427. return TRUE;
  428. }
  429. BOOL
  430. WINAPI
  431. SigRSAMD2Sign(
  432. PUCHAR pData,
  433. DWORD cbData,
  434. PUCHAR pSigned,
  435. DWORD *pcbSigned,
  436. PctPrivateKey *pKey)
  437. {
  438. MD2_CTX DigCtx;
  439. BSAFE_PRV_KEY *pk = (BSAFE_PRV_KEY *)pKey->pKey;
  440. UCHAR LocalBuffer[500];
  441. UCHAR LocalOutput[500];
  442. unsigned int cbSize;
  443. if(pk->magic != RSA2)
  444. {
  445. // This is not a bsafe key, so it must be a CAPI
  446. // key.
  447. HCRYPTHASH hHash;
  448. DWORD cbSigned;
  449. HCRYPTPROV hProv = *((HCRYPTPROV *)pKey->pKey);
  450. if(!capiCryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash))
  451. {
  452. return FALSE;
  453. }
  454. if(!capiCryptHashData(hHash, pData, cbData, 0))
  455. {
  456. capiCryptDestroyHash(hHash);
  457. return FALSE;
  458. }
  459. cbSigned = sizeof(LocalOutput);
  460. if(!capiCryptSignHash(hHash, AT_KEYEXCHANGE, NULL, 0, LocalOutput, &cbSigned))
  461. {
  462. capiCryptDestroyHash(hHash);
  463. return FALSE;
  464. }
  465. capiCryptDestroyHash(hHash);
  466. ReverseMemCopy(pSigned, LocalOutput, cbSigned);
  467. *pcbSigned = cbSigned;
  468. return TRUE;
  469. }
  470. cbSize = sizeof(MD2_PRELUDE)+16;
  471. if(pk->datalen > sizeof(LocalBuffer))
  472. {
  473. return FALSE;
  474. }
  475. //MD2Init(&DigCtx);
  476. FillMemory( &DigCtx, sizeof( DigCtx ), 0 );
  477. MD2Update(&DigCtx, pData, cbData);
  478. MD2Final(&DigCtx);
  479. FillMemory(LocalBuffer, pk->keylen, 0);
  480. ReverseMemCopy(LocalBuffer, DigCtx.state, 16);
  481. ReverseMemCopy(LocalBuffer+16, MD2_PRELUDE, sizeof(MD2_PRELUDE));
  482. LocalBuffer[cbSize++]=0;
  483. while(cbSize < pk->datalen-1) {
  484. LocalBuffer[cbSize++] = 0xff;
  485. }
  486. /* Make into pkcs block type 1 */
  487. LocalBuffer[pk->datalen-1] = 1;
  488. *pcbSigned = pk->datalen+1;
  489. if(!BSafeDecPrivate(pk, LocalBuffer, LocalOutput))
  490. {
  491. return FALSE;
  492. }
  493. ReverseMemCopy(pSigned, LocalOutput, *pcbSigned);
  494. return TRUE;
  495. }
  496. BOOL
  497. WINAPI
  498. SigRSAMD5Verify(
  499. PUCHAR pData,
  500. DWORD cbData,
  501. PUCHAR pSigned,
  502. DWORD cbSigned,
  503. PctPublicKey *pKey)
  504. {
  505. MD5_CTX DigCtx;
  506. BSAFE_PUB_KEY *pk = (BSAFE_PUB_KEY *)pKey->pKey;
  507. UCHAR Buffer[500];
  508. UCHAR SigBuffer[500];
  509. DWORD iLoc;
  510. if(pk->datalen > sizeof(Buffer) || cbSigned != pk->datalen+1)
  511. {
  512. return FALSE;
  513. }
  514. MD5Init(&DigCtx);
  515. MD5Update(&DigCtx, pData, cbData);
  516. MD5Final(&DigCtx);
  517. FillMemory(SigBuffer, pk->keylen, 0);
  518. FillMemory(Buffer, pk->keylen, 0);
  519. ReverseMemCopy(SigBuffer, pSigned, cbSigned);
  520. if(!BSafeEncPublic(pk, SigBuffer, Buffer))
  521. {
  522. return FALSE;
  523. }
  524. ReverseMemCopy(SigBuffer, Buffer, cbSigned);
  525. /* Make sure pkcs block type 1 */
  526. if(SigBuffer[0] != 0 || SigBuffer[1] != 1)
  527. {
  528. return FALSE;
  529. }
  530. for(iLoc = 2; iLoc < pk->datalen; iLoc++ ){
  531. if(!SigBuffer[iLoc])
  532. {
  533. break;
  534. }
  535. if(SigBuffer[iLoc] != 0xff)
  536. {
  537. return FALSE;
  538. }
  539. }
  540. if(iLoc == pk->datalen) return FALSE;
  541. iLoc++; /* skip past separator */
  542. if(memcmp(&SigBuffer[iLoc], MD5_PRELUDE, sizeof(MD5_PRELUDE)) != 0)
  543. {
  544. return FALSE;
  545. }
  546. iLoc += sizeof(MD5_PRELUDE);
  547. if(memcmp(&SigBuffer[iLoc], DigCtx.digest, 16) != 0)
  548. {
  549. return FALSE;
  550. }
  551. return TRUE;
  552. }
  553. BOOL
  554. WINAPI
  555. SigRSAMD2Verify(
  556. PUCHAR pData,
  557. DWORD cbData,
  558. PUCHAR pSigned,
  559. DWORD cbSigned,
  560. PctPublicKey *pKey)
  561. {
  562. MD2_CTX DigCtx;
  563. BSAFE_PUB_KEY *pk = (BSAFE_PUB_KEY *)pKey->pKey;
  564. UCHAR Buffer[500];
  565. UCHAR SigBuffer[500];
  566. DWORD iLoc;
  567. if ((pk->datalen > sizeof(Buffer)) ||
  568. (cbSigned != pk->datalen + 1))
  569. {
  570. return FALSE;
  571. }
  572. // MD2Init(&DigCtx);
  573. FillMemory( &DigCtx, sizeof( DigCtx ), 0 );
  574. MD2Update(&DigCtx, pData, cbData);
  575. MD2Final(&DigCtx);
  576. FillMemory(SigBuffer, pk->keylen, 0);
  577. FillMemory(Buffer, pk->keylen, 0);
  578. ReverseMemCopy(SigBuffer, pSigned, cbSigned);
  579. if(!BSafeEncPublic(pk, SigBuffer, Buffer))
  580. {
  581. return FALSE;
  582. }
  583. ReverseMemCopy(SigBuffer, Buffer, cbSigned);
  584. /* Make sure pkcs block type 1 */
  585. if(SigBuffer[0] != 0 || SigBuffer[1] != 1)
  586. {
  587. return FALSE;
  588. }
  589. for(iLoc = 2; iLoc < pk->datalen; iLoc++ )
  590. {
  591. if(!SigBuffer[iLoc])
  592. {
  593. break;
  594. }
  595. if(SigBuffer[iLoc] != 0xff)
  596. {
  597. return FALSE;
  598. }
  599. }
  600. if(iLoc == pk->datalen)
  601. {
  602. return FALSE;
  603. }
  604. iLoc++; /* skip past separator */
  605. if(memcmp(&SigBuffer[iLoc], MD2_PRELUDE, sizeof(MD2_PRELUDE)) != 0)
  606. {
  607. return FALSE;
  608. }
  609. iLoc += sizeof(MD2_PRELUDE);
  610. if(memcmp(&SigBuffer[iLoc], DigCtx.state, 16) != 0)
  611. {
  612. return FALSE;
  613. }
  614. return TRUE;
  615. }
  616. BOOL
  617. WINAPI
  618. SigRSASHAMD5Sign(
  619. PUCHAR pData, // pointer to hash value
  620. DWORD cbData, // always 36
  621. PUCHAR pSigned,
  622. DWORD *pcbSigned,
  623. PctPrivateKey *pKey)
  624. {
  625. BSAFE_PRV_KEY *pk = (BSAFE_PRV_KEY *)pKey->pKey;
  626. if(pk->magic == RSA2)
  627. {
  628. // BSAFE key
  629. UCHAR LocalBuffer[500];
  630. UCHAR LocalOutput[500];
  631. pk = (BSAFE_PRV_KEY *)pKey;
  632. if(pk->keylen > sizeof(LocalBuffer))
  633. {
  634. return FALSE;
  635. }
  636. FillMemory(LocalBuffer, pk->keylen, 0);
  637. ReverseMemCopy(LocalBuffer, pData, cbData);
  638. LocalBuffer[cbData++] = 0;
  639. while(cbData < pk->datalen-1) {
  640. LocalBuffer[cbData++] = 0xff;
  641. }
  642. /* Make into pkcs block type 1 */
  643. LocalBuffer[pk->datalen-1] = 1;
  644. *pcbSigned = pk->datalen+1;
  645. BSafeDecPrivate(pk, LocalBuffer, LocalOutput);
  646. ReverseMemCopy(pSigned, LocalOutput, *pcbSigned);
  647. return TRUE;
  648. }
  649. else
  650. {
  651. // capiCryptoAPI key
  652. HCRYPTPROV hProv;
  653. HCRYPTHASH hHash;
  654. DWORD dwAlgid;
  655. DWORD i;
  656. DWORD dwT;
  657. // get handle to CSP
  658. hProv = *((HCRYPTPROV *)pKey->pKey);
  659. // create hash object
  660. dwAlgid = ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SSL3SHAMD5;
  661. if(RCRYPT_FAILED(capiCryptCreateHash(hProv, dwAlgid, 0, 0, &hHash)))
  662. {
  663. return FALSE;
  664. }
  665. // set hash value
  666. if(RCRYPT_FAILED(capiCryptSetHashParam(hHash, HP_HASHVAL, pData, 0)))
  667. {
  668. capiCryptDestroyHash(hHash);
  669. return FALSE;
  670. }
  671. // sign hash
  672. if(RCRYPT_FAILED(capiCryptSignHash(hHash,
  673. AT_KEYEXCHANGE,
  674. NULL,
  675. 0,
  676. pSigned,
  677. pcbSigned)))
  678. {
  679. capiCryptDestroyHash(hHash);
  680. return FALSE;
  681. }
  682. // free hash object
  683. capiCryptDestroyHash(hHash);
  684. //Convert to Big-endian
  685. dwT = *pcbSigned;
  686. for( i = 0 ; i < dwT/2 ; i++)
  687. {
  688. BYTE bT = pSigned[i];
  689. pSigned[i] = pSigned[dwT-1-i];
  690. pSigned[dwT-1-i] = bT;
  691. }
  692. return TRUE;
  693. }
  694. }
  695. BOOL
  696. WINAPI
  697. SigRSASHAMD5Verify(
  698. PUCHAR pData, // pointer to hash value
  699. DWORD cbData, // always 36
  700. PUCHAR pSigned,
  701. DWORD cbSigned,
  702. PctPublicKey *pKey)
  703. {
  704. BSAFE_PUB_KEY *pk = (BSAFE_PUB_KEY *)pKey->pKey;
  705. UCHAR Buffer[500];
  706. UCHAR SigBuffer[500];
  707. DWORD iLoc;
  708. if(pk->keylen > sizeof(Buffer) || cbSigned != pk->datalen + 1)
  709. {
  710. return FALSE;
  711. }
  712. FillMemory(SigBuffer, pk->keylen, 0);
  713. FillMemory(Buffer, pk->keylen, 0);
  714. ReverseMemCopy(SigBuffer, pSigned, cbSigned);
  715. BSafeEncPublic(pk, SigBuffer, Buffer);
  716. ReverseMemCopy(SigBuffer, Buffer, cbSigned);
  717. /* Make sure pkcs block type 1 */
  718. if(SigBuffer[0] != 0 || SigBuffer[1] != 1) return FALSE;
  719. for(iLoc = 2; iLoc < pk->datalen; iLoc++ ){
  720. if(!SigBuffer[iLoc]) break;
  721. if(SigBuffer[iLoc] != 0xff) return FALSE;
  722. }
  723. if(iLoc == pk->datalen) return FALSE;
  724. iLoc++; /* skip past separator */
  725. if(memcmp(&SigBuffer[iLoc], pData, cbData) != 0) return FALSE;
  726. return TRUE;
  727. }