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.

2809 lines
81 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995.
  5. //
  6. // File: ssl3msg.c
  7. //
  8. // Contents: Main crypto functions for SSL3.
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 04-16-96 ramas Created.
  15. //
  16. //----------------------------------------------------------------------------
  17. #include <spbase.h>
  18. #if VERIFYHASH
  19. BYTE rgbF[5000];
  20. DWORD ibF = 0;
  21. #endif
  22. //------------------------------------------------------------------------------------------
  23. SP_STATUS WINAPI
  24. Ssl3DecryptHandler(
  25. PSPContext pContext,
  26. PSPBuffer pCommInput,
  27. PSPBuffer pAppOutput)
  28. {
  29. SP_STATUS pctRet = PCT_ERR_OK;
  30. if(pCommInput->cbData == 0)
  31. {
  32. return PCT_INT_INCOMPLETE_MSG;
  33. }
  34. if(!(pContext->State & SP_STATE_CONNECTED) || pContext->Decrypt == NULL)
  35. {
  36. return SP_LOG_RESULT(PCT_INT_ILLEGAL_MSG);
  37. }
  38. switch(*(PBYTE)pCommInput->pvBuffer)
  39. {
  40. case SSL3_CT_HANDSHAKE:
  41. if(pContext->RipeZombie->fProtocol & SP_PROT_CLIENTS)
  42. {
  43. // This should be a HelloRequest message. We should make sure, and
  44. // then completely consume the message.
  45. pctRet = pContext->Decrypt( pContext,
  46. pCommInput, // message
  47. pAppOutput); // Unpacked Message
  48. if(PCT_ERR_OK != pctRet)
  49. {
  50. return pctRet;
  51. }
  52. if(*(PBYTE)pAppOutput->pvBuffer != SSL3_HS_HELLO_REQUEST ||
  53. pAppOutput->cbData != sizeof(SHSH))
  54. {
  55. // This ain't no HelloRequest!
  56. return SP_LOG_RESULT(PCT_INT_ILLEGAL_MSG);
  57. }
  58. }
  59. else
  60. {
  61. // This is probably a ClientHello message. In any case, let the
  62. // caller deal with it (by passing it to the LSA process).
  63. pCommInput->cbData = 0;
  64. }
  65. pAppOutput->cbData = 0;
  66. pContext->State = SSL3_STATE_RENEGOTIATE;
  67. return SP_LOG_RESULT(PCT_INT_RENEGOTIATE);
  68. case SSL3_CT_ALERT:
  69. pctRet = pContext->Decrypt( pContext,
  70. pCommInput,
  71. pAppOutput);
  72. if(PCT_ERR_OK != pctRet)
  73. {
  74. return pctRet;
  75. }
  76. pctRet = ParseAlertMessage(pContext,
  77. (PBYTE)pAppOutput->pvBuffer,
  78. pAppOutput->cbData);
  79. // make sure that APP doesn't see Alert messages...
  80. pAppOutput->cbData = 0;
  81. return pctRet;
  82. case SSL3_CT_APPLICATIONDATA:
  83. pctRet = pContext->Decrypt( pContext,
  84. pCommInput,
  85. pAppOutput);
  86. return pctRet;
  87. default:
  88. return SP_LOG_RESULT(PCT_INT_ILLEGAL_MSG);
  89. }
  90. }
  91. SP_STATUS WINAPI
  92. Ssl3GetHeaderSize(
  93. PSPContext pContext,
  94. PSPBuffer pCommInput,
  95. DWORD * pcbHeaderSize)
  96. {
  97. if(pcbHeaderSize == NULL)
  98. {
  99. return SP_LOG_RESULT(PCT_INT_INTERNAL_ERROR);
  100. }
  101. *pcbHeaderSize = sizeof(SWRAP);
  102. return PCT_ERR_OK;
  103. }
  104. #if DBG
  105. BYTE rgb3Mac[2048];
  106. DWORD ibMac = 0;
  107. #endif
  108. //+---------------------------------------------------------------------------
  109. //
  110. // Function: Ssl3ComputeMac
  111. //
  112. // Synopsis:
  113. //
  114. // Arguments: [pContext] --
  115. // [fReadMac] --
  116. // [pClean] --
  117. // [cContentType] --
  118. // [pbMac] --
  119. // [cbMac]
  120. //
  121. // History: 10-03-97 jbanes Created.
  122. //
  123. // Notes:
  124. //
  125. //----------------------------------------------------------------------------
  126. SP_STATUS
  127. Ssl3ComputeMac(
  128. PSPContext pContext,
  129. BOOL fReadMac,
  130. PSPBuffer pClean,
  131. CHAR cContentType,
  132. PBYTE pbMac,
  133. DWORD cbMac)
  134. {
  135. HCRYPTHASH hHash = 0;
  136. DWORD dwReverseSequence;
  137. WORD wReverseData;
  138. UCHAR rgbDigest[SP_MAX_DIGEST_LEN];
  139. DWORD cbDigest;
  140. BYTE rgbPad[CB_SSL3_MAX_MAC_PAD];
  141. WORD cbPad;
  142. HCRYPTPROV hProv;
  143. HCRYPTKEY hSecret;
  144. DWORD dwSequence;
  145. DWORD dwCapiFlags;
  146. PHashInfo pHashInfo;
  147. SP_STATUS pctRet;
  148. if(fReadMac)
  149. {
  150. hProv = pContext->hReadProv;
  151. hSecret = pContext->hReadMAC;
  152. dwSequence = pContext->ReadCounter;
  153. pHashInfo = pContext->pReadHashInfo;
  154. }
  155. else
  156. {
  157. hProv = pContext->hWriteProv;
  158. hSecret = pContext->hWriteMAC;
  159. dwSequence = pContext->WriteCounter;
  160. pHashInfo = pContext->pWriteHashInfo;
  161. }
  162. dwCapiFlags = pContext->RipeZombie->dwCapiFlags;
  163. if(!hProv)
  164. {
  165. return SP_LOG_RESULT(PCT_INT_INTERNAL_ERROR);
  166. }
  167. // Determine size of pad_1 and pad_2.
  168. if(pHashInfo->aiHash == CALG_MD5)
  169. {
  170. cbPad = CB_SSL3_MD5_MAC_PAD;
  171. }
  172. else
  173. {
  174. cbPad = CB_SSL3_SHA_MAC_PAD;
  175. }
  176. //
  177. // hash(MAC_write_secret + pad_2 +
  178. // hash(MAC_write_secret + pad_1 + seq_num +
  179. // SSLCompressed.type + SSLCompressed.length +
  180. // SSLCompressed.fragment));
  181. //
  182. // Create hash
  183. if(!SchCryptCreateHash(hProv,
  184. pHashInfo->aiHash,
  185. 0,
  186. 0,
  187. &hHash,
  188. dwCapiFlags))
  189. {
  190. SP_LOG_RESULT(GetLastError());
  191. pctRet = PCT_INT_INTERNAL_ERROR;
  192. goto cleanup;
  193. }
  194. // Hash secret
  195. if(!SchCryptHashSessionKey(hHash,
  196. hSecret,
  197. CRYPT_LITTLE_ENDIAN,
  198. dwCapiFlags))
  199. {
  200. SP_LOG_RESULT(GetLastError());
  201. pctRet = PCT_INT_INTERNAL_ERROR;
  202. goto cleanup;
  203. }
  204. // hash pad 1
  205. FillMemory(rgbPad, cbPad, PAD1_CONSTANT);
  206. if(!SchCryptHashData(hHash, rgbPad, cbPad, 0, dwCapiFlags))
  207. {
  208. SP_LOG_RESULT(GetLastError());
  209. pctRet = PCT_INT_INTERNAL_ERROR;
  210. goto cleanup;
  211. }
  212. /* add count */
  213. dwReverseSequence = 0;
  214. if(!SchCryptHashData(hHash,
  215. (PUCHAR)&dwReverseSequence,
  216. sizeof(DWORD),
  217. 0,
  218. dwCapiFlags))
  219. {
  220. SP_LOG_RESULT(GetLastError());
  221. pctRet = PCT_INT_INTERNAL_ERROR;
  222. goto cleanup;
  223. }
  224. dwReverseSequence = htonl(dwSequence);
  225. if(!SchCryptHashData(hHash,
  226. (PUCHAR)&dwReverseSequence,
  227. sizeof(DWORD),
  228. 0,
  229. dwCapiFlags))
  230. {
  231. SP_LOG_RESULT(GetLastError());
  232. pctRet = PCT_INT_INTERNAL_ERROR;
  233. goto cleanup;
  234. }
  235. // Add content type.
  236. if(cContentType != 0)
  237. {
  238. if(!SchCryptHashData(hHash, &cContentType, 1, 0, dwCapiFlags))
  239. {
  240. SP_LOG_RESULT(GetLastError());
  241. pctRet = PCT_INT_INTERNAL_ERROR;
  242. goto cleanup;
  243. }
  244. }
  245. /* add length */
  246. wReverseData = (WORD)pClean->cbData >> 8 | (WORD)pClean->cbData << 8;
  247. if(!SchCryptHashData(hHash,
  248. (PBYTE)&wReverseData,
  249. sizeof(WORD),
  250. 0,
  251. dwCapiFlags))
  252. {
  253. SP_LOG_RESULT(GetLastError());
  254. pctRet = PCT_INT_INTERNAL_ERROR;
  255. goto cleanup;
  256. }
  257. /* add data */
  258. if(!SchCryptHashData(hHash,
  259. pClean->pvBuffer,
  260. pClean->cbData,
  261. 0,
  262. dwCapiFlags))
  263. {
  264. SP_LOG_RESULT(GetLastError());
  265. pctRet = PCT_INT_INTERNAL_ERROR;
  266. goto cleanup;
  267. }
  268. #if VERIFYHASH
  269. if(ibMac > 1800) ibMac = 0;
  270. CopyMemory(&rgb3Mac[ibMac], (BYTE *)&dw32High, sizeof(DWORD));
  271. ibMac += sizeof(DWORD);
  272. CopyMemory(&rgb3Mac[ibMac], (BYTE *)&dwReverseSeq, sizeof(DWORD));
  273. ibMac += sizeof(DWORD);
  274. CopyMemory(&rgb3Mac[ibMac], (BYTE *)&wDataReverse, sizeof(WORD));
  275. ibMac += sizeof(WORD);
  276. if(wData < 50)
  277. {
  278. CopyMemory(&rgb3Mac[ibMac], (PUCHAR)pClean->pvBuffer, wData);
  279. ibMac += wData;
  280. }
  281. #endif
  282. // Get inner hash value.
  283. cbDigest = sizeof(rgbDigest);
  284. if(!SchCryptGetHashParam(hHash,
  285. HP_HASHVAL,
  286. rgbDigest,
  287. &cbDigest,
  288. 0,
  289. dwCapiFlags))
  290. {
  291. SP_LOG_RESULT(GetLastError());
  292. pctRet = PCT_INT_INTERNAL_ERROR;
  293. goto cleanup;
  294. }
  295. SP_ASSERT(pHashInfo->cbCheckSum == cbDigest);
  296. SchCryptDestroyHash(hHash, dwCapiFlags);
  297. hHash = 0;
  298. #if VERIFYHASH
  299. CopyMemory(&rgb3Mac[ibMac], rgbDigest, pHashInfo->cbCheckSum);
  300. ibMac += pHashInfo->cbCheckSum;
  301. #endif
  302. // Create hash
  303. if(!SchCryptCreateHash(hProv,
  304. pHashInfo->aiHash,
  305. 0,
  306. 0,
  307. &hHash,
  308. dwCapiFlags))
  309. {
  310. SP_LOG_RESULT(GetLastError());
  311. pctRet = PCT_INT_INTERNAL_ERROR;
  312. goto cleanup;
  313. }
  314. // Hash secret
  315. if(!SchCryptHashSessionKey(hHash,
  316. hSecret,
  317. CRYPT_LITTLE_ENDIAN,
  318. dwCapiFlags))
  319. {
  320. SP_LOG_RESULT(GetLastError());
  321. pctRet = PCT_INT_INTERNAL_ERROR;
  322. goto cleanup;
  323. }
  324. // hash pad 2
  325. FillMemory(rgbPad, cbPad, PAD2_CONSTANT);
  326. if(!SchCryptHashData(hHash, rgbPad, cbPad, 0, dwCapiFlags))
  327. {
  328. SP_LOG_RESULT(GetLastError());
  329. pctRet = PCT_INT_INTERNAL_ERROR;
  330. goto cleanup;
  331. }
  332. if(!SchCryptHashData(hHash, rgbDigest, cbDigest, 0, dwCapiFlags))
  333. {
  334. SP_LOG_RESULT(GetLastError());
  335. pctRet = PCT_INT_INTERNAL_ERROR;
  336. goto cleanup;
  337. }
  338. // Get outer hash value.
  339. cbDigest = sizeof(rgbDigest);
  340. if(!SchCryptGetHashParam(hHash,
  341. HP_HASHVAL,
  342. rgbDigest,
  343. &cbDigest,
  344. 0,
  345. dwCapiFlags))
  346. {
  347. SP_LOG_RESULT(GetLastError());
  348. pctRet = PCT_INT_INTERNAL_ERROR;
  349. goto cleanup;
  350. }
  351. SP_ASSERT(pHashInfo->cbCheckSum == cbDigest);
  352. SchCryptDestroyHash(hHash, dwCapiFlags);
  353. hHash = 0;
  354. #if VERIFYHASH
  355. CopyMemory(&rgb3Mac[ibMac], rgbDigest, pHashInfo->cbCheckSum);
  356. ibMac += pHashInfo->cbCheckSum;
  357. #endif
  358. CopyMemory(pbMac, rgbDigest, cbDigest);
  359. pctRet = PCT_ERR_OK;
  360. cleanup:
  361. if(hHash)
  362. {
  363. SchCryptDestroyHash(hHash, dwCapiFlags);
  364. }
  365. return pctRet;
  366. }
  367. //+---------------------------------------------------------------------------
  368. //
  369. // Function: Ssl3BuildFinishMessage
  370. //
  371. // Synopsis:
  372. //
  373. // Arguments: [pContext] --
  374. // [pbMd5Digest] --
  375. // [pbSHADigest] --
  376. // [fClient] --
  377. //
  378. // History: 10-03-97 jbanes Added server-side CAPI integration.
  379. //
  380. // Notes:
  381. //
  382. //----------------------------------------------------------------------------
  383. SP_STATUS
  384. Ssl3BuildFinishMessage(
  385. PSPContext pContext,
  386. BYTE *pbMd5Digest,
  387. BYTE *pbSHADigest,
  388. BOOL fClient)
  389. {
  390. BYTE rgbPad1[CB_SSL3_MAX_MAC_PAD];
  391. BYTE rgbPad2[CB_SSL3_MAX_MAC_PAD];
  392. BYTE szClnt[] = "CLNT";
  393. BYTE szSrvr[] = "SRVR";
  394. DWORD cbMessage;
  395. HCRYPTHASH hHash = 0;
  396. DWORD cbDigest;
  397. SP_STATUS pctRet;
  398. //
  399. // Compute the two hash values as follows:
  400. //
  401. // enum { client(0x434c4e54), server(0x53525652) } Sender;
  402. // enum { client("CLNT"), server("SRVR") } Sender;
  403. //
  404. // struct {
  405. // opaque md5_hash[16];
  406. // opaque sha_hash[20];
  407. // } Finished;
  408. //
  409. // md5_hash - MD5(master_secret + pad2 + MD5(handshake_messages +
  410. // Sender + master_secret + pad1))
  411. //
  412. // sha_hash - SHA(master_secret + pad2 + SHA(handshake_messages +
  413. // Sender + master_secret + pad1))
  414. //
  415. // pad_1 - The character 0x36 repeated 48 times for MD5 or
  416. // 40 times for SHA.
  417. //
  418. // pad_2 - The character 0x5c repeated the same number of times.
  419. //
  420. FillMemory(rgbPad1, sizeof(rgbPad1), PAD1_CONSTANT);
  421. FillMemory(rgbPad2, sizeof(rgbPad2), PAD2_CONSTANT);
  422. // Make local copy of the handshake_messages MD5 hash object
  423. if(!SchCryptDuplicateHash(pContext->hMd5Handshake,
  424. NULL,
  425. 0,
  426. &hHash,
  427. pContext->RipeZombie->dwCapiFlags))
  428. {
  429. SP_LOG_RESULT(GetLastError());
  430. pctRet = PCT_INT_INTERNAL_ERROR;
  431. goto cleanup;
  432. }
  433. // Add rest of stuff to local MD5 hash object.
  434. if(!SchCryptHashData(hHash,
  435. fClient ? szClnt : szSrvr,
  436. 4,
  437. 0,
  438. pContext->RipeZombie->dwCapiFlags))
  439. {
  440. SP_LOG_RESULT(GetLastError());
  441. pctRet = PCT_INT_INTERNAL_ERROR;
  442. goto cleanup;
  443. }
  444. if(!SchCryptHashSessionKey(hHash,
  445. pContext->RipeZombie->hMasterKey,
  446. CRYPT_LITTLE_ENDIAN,
  447. pContext->RipeZombie->dwCapiFlags))
  448. {
  449. SP_LOG_RESULT(GetLastError());
  450. pctRet = PCT_INT_INTERNAL_ERROR;
  451. goto cleanup;
  452. }
  453. if(!SchCryptHashData(hHash,
  454. rgbPad1,
  455. CB_SSL3_MD5_MAC_PAD,
  456. 0,
  457. pContext->RipeZombie->dwCapiFlags))
  458. {
  459. SP_LOG_RESULT(GetLastError());
  460. pctRet = PCT_INT_INTERNAL_ERROR;
  461. goto cleanup;
  462. }
  463. cbDigest = CB_MD5_DIGEST_LEN;
  464. if(!SchCryptGetHashParam(hHash,
  465. HP_HASHVAL,
  466. pbMd5Digest,
  467. &cbDigest,
  468. 0,
  469. pContext->RipeZombie->dwCapiFlags))
  470. {
  471. SP_LOG_RESULT(GetLastError());
  472. pctRet = PCT_INT_INTERNAL_ERROR;
  473. goto cleanup;
  474. }
  475. SchCryptDestroyHash(hHash, pContext->RipeZombie->dwCapiFlags);
  476. hHash = 0;
  477. // Compute "parent" MD5 hash
  478. if(!SchCryptCreateHash(pContext->RipeZombie->hMasterProv,
  479. CALG_MD5,
  480. 0,
  481. 0,
  482. &hHash,
  483. pContext->RipeZombie->dwCapiFlags))
  484. {
  485. SP_LOG_RESULT(GetLastError());
  486. pctRet = PCT_INT_INTERNAL_ERROR;
  487. goto cleanup;
  488. }
  489. if(!SchCryptHashSessionKey(hHash,
  490. pContext->RipeZombie->hMasterKey,
  491. CRYPT_LITTLE_ENDIAN,
  492. pContext->RipeZombie->dwCapiFlags))
  493. {
  494. SP_LOG_RESULT(GetLastError());
  495. pctRet = PCT_INT_INTERNAL_ERROR;
  496. goto cleanup;
  497. }
  498. if(!SchCryptHashData(hHash,
  499. rgbPad2,
  500. CB_SSL3_MD5_MAC_PAD,
  501. 0,
  502. pContext->RipeZombie->dwCapiFlags))
  503. {
  504. SP_LOG_RESULT(GetLastError());
  505. pctRet = PCT_INT_INTERNAL_ERROR;
  506. goto cleanup;
  507. }
  508. if(!SchCryptHashData(hHash,
  509. pbMd5Digest,
  510. CB_MD5_DIGEST_LEN,
  511. 0,
  512. pContext->RipeZombie->dwCapiFlags))
  513. {
  514. SP_LOG_RESULT(GetLastError());
  515. pctRet = PCT_INT_INTERNAL_ERROR;
  516. goto cleanup;
  517. }
  518. cbDigest = CB_MD5_DIGEST_LEN;
  519. if(!SchCryptGetHashParam(hHash,
  520. HP_HASHVAL,
  521. pbMd5Digest,
  522. &cbDigest,
  523. 0,
  524. pContext->RipeZombie->dwCapiFlags))
  525. {
  526. SP_LOG_RESULT(GetLastError());
  527. pctRet = PCT_INT_INTERNAL_ERROR;
  528. goto cleanup;
  529. }
  530. SchCryptDestroyHash(hHash, pContext->RipeZombie->dwCapiFlags);
  531. hHash = 0;
  532. // Build SHA Hash
  533. // Make local copy of the handshake_messages SHA hash object
  534. if(!SchCryptDuplicateHash(pContext->hShaHandshake,
  535. NULL,
  536. 0,
  537. &hHash,
  538. pContext->RipeZombie->dwCapiFlags))
  539. {
  540. SP_LOG_RESULT(GetLastError());
  541. pctRet = PCT_INT_INTERNAL_ERROR;
  542. goto cleanup;
  543. }
  544. // SHA(handshake_messages + Sender + master_secret + pad1)
  545. if(!SchCryptHashData(hHash,
  546. fClient ? szClnt : szSrvr,
  547. 4,
  548. 0,
  549. pContext->RipeZombie->dwCapiFlags))
  550. {
  551. SP_LOG_RESULT(GetLastError());
  552. pctRet = PCT_INT_INTERNAL_ERROR;
  553. goto cleanup;
  554. }
  555. if(!SchCryptHashSessionKey(hHash,
  556. pContext->RipeZombie->hMasterKey,
  557. CRYPT_LITTLE_ENDIAN,
  558. pContext->RipeZombie->dwCapiFlags))
  559. {
  560. SP_LOG_RESULT(GetLastError());
  561. pctRet = PCT_INT_INTERNAL_ERROR;
  562. goto cleanup;
  563. }
  564. if(!SchCryptHashData(hHash,
  565. rgbPad1,
  566. CB_SSL3_SHA_MAC_PAD,
  567. 0,
  568. pContext->RipeZombie->dwCapiFlags))
  569. {
  570. SP_LOG_RESULT(GetLastError());
  571. pctRet = PCT_INT_INTERNAL_ERROR;
  572. goto cleanup;
  573. }
  574. cbDigest = A_SHA_DIGEST_LEN;
  575. if(!SchCryptGetHashParam(hHash,
  576. HP_HASHVAL,
  577. pbSHADigest,
  578. &cbDigest,
  579. 0,
  580. pContext->RipeZombie->dwCapiFlags))
  581. {
  582. SP_LOG_RESULT(GetLastError());
  583. pctRet = PCT_INT_INTERNAL_ERROR;
  584. goto cleanup;
  585. }
  586. SchCryptDestroyHash(hHash, pContext->RipeZombie->dwCapiFlags);
  587. hHash = 0;
  588. // SHA(master_secret + pad2 + SHA-hash);
  589. if(!SchCryptCreateHash(pContext->RipeZombie->hMasterProv,
  590. CALG_SHA,
  591. 0,
  592. 0,
  593. &hHash,
  594. pContext->RipeZombie->dwCapiFlags))
  595. {
  596. SP_LOG_RESULT(GetLastError());
  597. pctRet = PCT_INT_INTERNAL_ERROR;
  598. goto cleanup;
  599. }
  600. if(!SchCryptHashSessionKey(hHash,
  601. pContext->RipeZombie->hMasterKey,
  602. CRYPT_LITTLE_ENDIAN,
  603. pContext->RipeZombie->dwCapiFlags))
  604. {
  605. SP_LOG_RESULT(GetLastError());
  606. pctRet = PCT_INT_INTERNAL_ERROR;
  607. goto cleanup;
  608. }
  609. if(!SchCryptHashData(hHash,
  610. rgbPad2,
  611. CB_SSL3_SHA_MAC_PAD,
  612. 0,
  613. pContext->RipeZombie->dwCapiFlags))
  614. {
  615. SP_LOG_RESULT(GetLastError());
  616. pctRet = PCT_INT_INTERNAL_ERROR;
  617. goto cleanup;
  618. }
  619. if(!SchCryptHashData(hHash,
  620. pbSHADigest,
  621. A_SHA_DIGEST_LEN,
  622. 0,
  623. pContext->RipeZombie->dwCapiFlags))
  624. {
  625. SP_LOG_RESULT(GetLastError());
  626. pctRet = PCT_INT_INTERNAL_ERROR;
  627. goto cleanup;
  628. }
  629. cbDigest = A_SHA_DIGEST_LEN;
  630. if(!SchCryptGetHashParam(hHash,
  631. HP_HASHVAL,
  632. pbSHADigest,
  633. &cbDigest,
  634. 0,
  635. pContext->RipeZombie->dwCapiFlags))
  636. {
  637. SP_LOG_RESULT(GetLastError());
  638. pctRet = PCT_INT_INTERNAL_ERROR;
  639. goto cleanup;
  640. }
  641. SchCryptDestroyHash(hHash, pContext->RipeZombie->dwCapiFlags);
  642. hHash = 0;
  643. pctRet = PCT_ERR_OK;
  644. cleanup:
  645. if(hHash)
  646. {
  647. SchCryptDestroyHash(hHash, pContext->RipeZombie->dwCapiFlags);
  648. }
  649. return pctRet;
  650. }
  651. /*****************************************************************************/
  652. DWORD Ssl3CiphertextLen(
  653. PSPContext pContext,
  654. DWORD cbMessage,
  655. BOOL fClientIsSender)
  656. {
  657. DWORD cbBlock;
  658. // Abort early if we're not encrypting.
  659. if(pContext->pWriteCipherInfo == NULL)
  660. {
  661. // Add record header length.
  662. cbMessage += sizeof(SWRAP);
  663. return cbMessage;
  664. }
  665. // Add MAC length.
  666. cbMessage += pContext->pWriteHashInfo->cbCheckSum;
  667. // Add padding if we're using a block cipher.
  668. cbBlock = pContext->pWriteCipherInfo->dwBlockSize;
  669. if(cbBlock > 1)
  670. {
  671. cbMessage += cbBlock - cbMessage % cbBlock;
  672. }
  673. // Add record header length.
  674. cbMessage += sizeof(SWRAP);
  675. return cbMessage;
  676. }
  677. //+---------------------------------------------------------------------------
  678. //
  679. // Function: Ssl3EncryptRaw
  680. //
  681. // Synopsis: Perform the MAC and encryption steps on an SSL3 record.
  682. //
  683. // Arguments: [pContext] -- Schannel context.
  684. // [pAppInput] -- Data to be encrypted.
  685. // [pCommOutput] -- (output) Encrypted SSL3 record.
  686. // [bContentType] -- SSL3 context type.
  687. //
  688. // History: 10-22-97 jbanes CAPI integrated.
  689. //
  690. // Notes: This function doesn't touch the header portion of the SSL3
  691. // record. This is handle by the calling function.
  692. //
  693. //----------------------------------------------------------------------------
  694. SP_STATUS WINAPI
  695. Ssl3EncryptRaw(
  696. PSPContext pContext,
  697. PSPBuffer pAppInput,
  698. PSPBuffer pCommOutput,
  699. BYTE bContentType)
  700. {
  701. SP_STATUS pctRet;
  702. SPBuffer Clean;
  703. SPBuffer Encrypted;
  704. DWORD cbBlock;
  705. DWORD cbPadding;
  706. PUCHAR pbMAC = NULL;
  707. BOOL fIsClient = FALSE;
  708. DWORD cbBuffExpected;
  709. if((pContext == NULL) ||
  710. (pContext->RipeZombie == NULL) ||
  711. (pContext->pWriteHashInfo == NULL) ||
  712. (pContext->pWriteCipherInfo == NULL) ||
  713. (pAppInput == NULL) ||
  714. (pCommOutput == NULL) ||
  715. (pAppInput->pvBuffer == NULL) ||
  716. (pCommOutput->pvBuffer == NULL))
  717. {
  718. return SP_LOG_RESULT(PCT_INT_INTERNAL_ERROR);
  719. }
  720. if(pAppInput->cbData > pAppInput->cbBuffer)
  721. {
  722. return SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY);
  723. }
  724. fIsClient = ( 0 != (pContext->RipeZombie->fProtocol & SP_PROT_SSL3TLS1_CLIENTS));
  725. cbBuffExpected = Ssl3CiphertextLen(pContext, pAppInput->cbData, fIsClient);
  726. if(cbBuffExpected == 0)
  727. {
  728. return SP_LOG_RESULT(PCT_INT_INTERNAL_ERROR);
  729. }
  730. if(pCommOutput->cbBuffer < cbBuffExpected)
  731. {
  732. return SP_LOG_RESULT(PCT_INT_BUFF_TOO_SMALL);
  733. }
  734. Clean.cbData = pAppInput->cbData;
  735. Clean.pvBuffer = (PUCHAR)pCommOutput->pvBuffer + sizeof(SWRAP);
  736. Clean.cbBuffer = pCommOutput->cbBuffer - sizeof(SWRAP);
  737. /* Move data out of the way if necessary */
  738. if(Clean.pvBuffer != pAppInput->pvBuffer)
  739. {
  740. DebugLog((DEB_WARN, "SSL3EncryptRaw: Unnecessary Move, performance hog\n"));
  741. MoveMemory(Clean.pvBuffer,
  742. pAppInput->pvBuffer,
  743. pAppInput->cbData);
  744. }
  745. // Transfer the write key over from the application process.
  746. if(pContext->hWriteKey == 0 &&
  747. pContext->pWriteCipherInfo->aiCipher != CALG_NULLCIPHER)
  748. {
  749. DebugLog((DEB_TRACE, "Transfer write key from user process.\n"));
  750. pctRet = SPGetUserKeys(pContext, SCH_FLAG_WRITE_KEY);
  751. if(pctRet != PCT_ERR_OK)
  752. {
  753. return SP_LOG_RESULT(pctRet);
  754. }
  755. }
  756. // Compute MAC and add it to end of message.
  757. pbMAC = (PUCHAR)Clean.pvBuffer + Clean.cbData;
  758. if(pContext->RipeZombie->fProtocol & SP_PROT_SSL3)
  759. {
  760. pctRet = Ssl3ComputeMac(pContext,
  761. FALSE,
  762. &Clean,
  763. bContentType,
  764. pbMAC,
  765. pContext->pWriteHashInfo->cbCheckSum);
  766. if(pctRet != PCT_ERR_OK)
  767. {
  768. return pctRet;
  769. }
  770. }
  771. else
  772. {
  773. pctRet = Tls1ComputeMac(pContext,
  774. FALSE,
  775. &Clean,
  776. bContentType,
  777. pbMAC,
  778. pContext->pWriteHashInfo->cbCheckSum);
  779. if(pctRet != PCT_ERR_OK)
  780. {
  781. return pctRet;
  782. }
  783. }
  784. Clean.cbData += pContext->pWriteHashInfo->cbCheckSum;
  785. pContext->WriteCounter++;
  786. // Add block cipher padding to end of message.
  787. cbBlock = pContext->pWriteCipherInfo->dwBlockSize;
  788. if(cbBlock > 1)
  789. {
  790. // This is a block cipher.
  791. cbPadding = cbBlock - Clean.cbData % cbBlock;
  792. FillMemory((PUCHAR)Clean.pvBuffer + Clean.cbData,
  793. cbPadding,
  794. (UCHAR)(cbPadding - 1));
  795. Clean.cbData += cbPadding;
  796. }
  797. SP_ASSERT(Clean.cbData <= Clean.cbBuffer);
  798. Encrypted.cbData = Clean.cbData;
  799. Encrypted.pvBuffer = Clean.pvBuffer;
  800. Encrypted.cbBuffer = Clean.cbBuffer;
  801. // Encrypt message.
  802. if(pContext->pWriteCipherInfo->aiCipher != CALG_NULLCIPHER)
  803. {
  804. if(!SchCryptEncrypt(pContext->hWriteKey,
  805. 0, FALSE, 0,
  806. Encrypted.pvBuffer,
  807. &Encrypted.cbData,
  808. Encrypted.cbBuffer,
  809. pContext->RipeZombie->dwCapiFlags))
  810. {
  811. SP_LOG_RESULT(GetLastError());
  812. return PCT_INT_INTERNAL_ERROR;
  813. }
  814. }
  815. pCommOutput->cbData = Encrypted.cbData + sizeof(SWRAP);
  816. return PCT_ERR_OK;
  817. }
  818. //+---------------------------------------------------------------------------
  819. //
  820. // Function: Ssl3EncryptMessage
  821. //
  822. // Synopsis: Encode a block of data as an SSL3 record.
  823. //
  824. // Arguments: [pContext] -- Schannel context.
  825. // [pAppInput] -- Data to be encrypted.
  826. // [pCommOutput] -- (output) Completed SSL3 record.
  827. //
  828. // History: 10-22-97 jbanes CAPI integrated.
  829. //
  830. // Notes: An SSL3 record is formatted as:
  831. //
  832. // BYTE header[5];
  833. // BYTE data[pAppInput->cbData];
  834. // BYTE mac[mac_size];
  835. // BYTE padding[padding_size];
  836. //
  837. //----------------------------------------------------------------------------
  838. SP_STATUS WINAPI
  839. Ssl3EncryptMessage( PSPContext pContext,
  840. PSPBuffer pAppInput,
  841. PSPBuffer pCommOutput)
  842. {
  843. DWORD cbMessage;
  844. SP_STATUS pctRet;
  845. SP_BEGIN("Ssl3EncryptMessage");
  846. if((pContext == NULL) ||
  847. (pContext->RipeZombie == NULL) ||
  848. (pAppInput == NULL) ||
  849. (pCommOutput == NULL) ||
  850. (pCommOutput->pvBuffer == NULL))
  851. {
  852. return SP_LOG_RESULT(PCT_INT_INTERNAL_ERROR);
  853. }
  854. DebugLog((DEB_TRACE, "Input: cbData:0x%x, cbBuffer:0x%x, pvBuffer:0x%8.8x\n",
  855. pAppInput->cbData,
  856. pAppInput->cbBuffer,
  857. pAppInput->pvBuffer));
  858. DebugLog((DEB_TRACE, "Output: cbData:0x%x, cbBuffer:0x%x, pvBuffer:0x%8.8x\n",
  859. pCommOutput->cbData,
  860. pCommOutput->cbBuffer,
  861. pCommOutput->pvBuffer));
  862. // Compute encrypted message size.
  863. cbMessage = Ssl3CiphertextLen(pContext, pAppInput->cbData, TRUE);
  864. pctRet = Ssl3EncryptRaw(pContext, pAppInput, pCommOutput, SSL3_CT_APPLICATIONDATA);
  865. if(pctRet != PCT_ERR_OK)
  866. {
  867. SP_RETURN(SP_LOG_RESULT(pctRet));
  868. }
  869. SetWrapNoEncrypt(pCommOutput->pvBuffer,
  870. SSL3_CT_APPLICATIONDATA,
  871. cbMessage - sizeof(SWRAP));
  872. if(pContext->RipeZombie->fProtocol & SP_PROT_TLS1)
  873. {
  874. ((PUCHAR)pCommOutput->pvBuffer)[02] = TLS1_CLIENT_VERSION_LSB;
  875. }
  876. DebugLog((DEB_TRACE, "Output: cbData:0x%x, cbBuffer:0x%x, pvBuffer:0x%8.8x\n",
  877. pCommOutput->cbData,
  878. pCommOutput->cbBuffer,
  879. pCommOutput->pvBuffer));
  880. SP_RETURN(PCT_ERR_OK);
  881. }
  882. //+---------------------------------------------------------------------------
  883. //
  884. // Function: Ssl3DecryptMessage
  885. //
  886. // Synopsis: Decode an SSL3 record.
  887. //
  888. // Arguments: [pContext] -- Schannel context.
  889. // [pMessage] -- Data from the remote party.
  890. // [pAppOutput] -- (output) Decrypted data.
  891. //
  892. // History: 10-22-97 jbanes CAPI integrated.
  893. //
  894. // Notes: The number of input data bytes consumed by this function
  895. // is returned in pMessage->cbData.
  896. //
  897. //----------------------------------------------------------------------------
  898. SP_STATUS WINAPI
  899. Ssl3DecryptMessage( PSPContext pContext,
  900. PSPBuffer pMessage,
  901. PSPBuffer pAppOutput)
  902. {
  903. SP_STATUS pctRet;
  904. SPBuffer Clean;
  905. SPBuffer Encrypted;
  906. UCHAR rgbDigest[SP_MAX_DIGEST_LEN];
  907. PUCHAR pbMAC;
  908. DWORD dwLength, cbActualData;
  909. SWRAP *pswrap = pMessage->pvBuffer;
  910. DWORD dwVersion;
  911. DWORD cbBlock;
  912. DWORD cbPadding;
  913. SP_BEGIN("Ssl3DecryptMessage");
  914. if((pContext == NULL) ||
  915. (pContext->pReadCipherInfo == NULL) ||
  916. (pContext->RipeZombie == NULL) ||
  917. (pAppOutput == NULL) ||
  918. (pMessage == NULL) ||
  919. (pMessage->pvBuffer == NULL))
  920. {
  921. SP_RETURN(SP_LOG_RESULT(PCT_INT_INTERNAL_ERROR));
  922. }
  923. /* First determine the length of data, the length of padding,
  924. * and the location of data, and the location of MAC */
  925. cbActualData = pMessage->cbData;
  926. pMessage->cbData = sizeof(SWRAP); /* minimum amount of data we need */
  927. if(cbActualData < sizeof(SWRAP))
  928. {
  929. SP_RETURN(PCT_INT_INCOMPLETE_MSG);
  930. }
  931. dwVersion = COMBINEBYTES(pswrap->bMajor, pswrap->bMinor);
  932. if(dwVersion != SSL3_CLIENT_VERSION && dwVersion != TLS1_CLIENT_VERSION)
  933. {
  934. SP_RETURN(SP_LOG_RESULT(PCT_INT_ILLEGAL_MSG));
  935. }
  936. dwLength = COMBINEBYTES(pswrap->bcbMSBSize, pswrap->bcbLSBSize);
  937. Encrypted.pvBuffer = (PUCHAR)pMessage->pvBuffer + sizeof(SWRAP);
  938. Encrypted.cbBuffer = pMessage->cbBuffer - sizeof(SWRAP);
  939. pMessage->cbData += dwLength ;
  940. if(pMessage->cbData > cbActualData)
  941. {
  942. SP_RETURN(PCT_INT_INCOMPLETE_MSG);
  943. }
  944. Encrypted.cbData = dwLength; /* encrypted data size */
  945. SP_ASSERT(Encrypted.cbData != 0);
  946. /* check to see if we have a block size violation */
  947. if(Encrypted.cbData % pContext->pReadCipherInfo->dwBlockSize)
  948. {
  949. SP_RETURN(SP_LOG_RESULT(PCT_INT_MSG_ALTERED));
  950. }
  951. // Transfer the read key over from the application process.
  952. if(pContext->hReadKey == 0 &&
  953. pContext->pReadCipherInfo->aiCipher != CALG_NULLCIPHER)
  954. {
  955. DebugLog((DEB_TRACE, "Transfer read key from user process.\n"));
  956. pctRet = SPGetUserKeys(pContext, SCH_FLAG_READ_KEY);
  957. if(pctRet != PCT_ERR_OK)
  958. {
  959. return SP_LOG_RESULT(pctRet);
  960. }
  961. }
  962. // Decrypt message.
  963. if(pContext->pReadCipherInfo->aiCipher != CALG_NULLCIPHER)
  964. {
  965. if(!SchCryptDecrypt(pContext->hReadKey,
  966. 0, FALSE, 0,
  967. Encrypted.pvBuffer,
  968. &Encrypted.cbData,
  969. pContext->RipeZombie->dwCapiFlags))
  970. {
  971. SP_LOG_RESULT(GetLastError());
  972. SP_RETURN(PCT_INT_INTERNAL_ERROR);
  973. }
  974. }
  975. // Remove block cipher padding.
  976. cbBlock = pContext->pReadCipherInfo->dwBlockSize;
  977. if(cbBlock > 1)
  978. {
  979. // This is a block cipher.
  980. cbPadding = *((PUCHAR)Encrypted.pvBuffer + Encrypted.cbData - 1) + 1;
  981. if(pContext->RipeZombie->fProtocol & SP_PROT_SSL3)
  982. {
  983. if(cbPadding > cbBlock || cbPadding >= Encrypted.cbData)
  984. {
  985. // Invalid pad size.
  986. DebugLog((DEB_WARN, "FINISHED Message: Padding Invalid\n"));
  987. SP_RETURN(SP_LOG_RESULT(PCT_INT_MSG_ALTERED));
  988. }
  989. }
  990. else
  991. {
  992. if(cbPadding > 256 || cbPadding >= Encrypted.cbData)
  993. {
  994. // Invalid pad size.
  995. DebugLog((DEB_WARN, "FINISHED Message: Padding Invalid\n"));
  996. SP_RETURN(SP_LOG_RESULT(PCT_INT_MSG_ALTERED));
  997. }
  998. }
  999. Encrypted.cbData -= cbPadding;
  1000. }
  1001. if(Encrypted.cbData < pContext->pReadHashInfo->cbCheckSum)
  1002. {
  1003. SP_RETURN(SP_LOG_RESULT(PCT_INT_MSG_ALTERED));
  1004. }
  1005. // Validate MAC.
  1006. Clean.pvBuffer = Encrypted.pvBuffer;
  1007. Clean.cbData = Encrypted.cbData - pContext->pReadHashInfo->cbCheckSum;
  1008. Clean.cbBuffer = Clean.cbData;
  1009. if(pContext->RipeZombie->fProtocol & SP_PROT_SSL3)
  1010. {
  1011. pctRet = Ssl3ComputeMac(pContext,
  1012. TRUE,
  1013. &Clean,
  1014. pswrap->bCType,
  1015. rgbDigest,
  1016. sizeof(rgbDigest));
  1017. if(pctRet != PCT_ERR_OK)
  1018. {
  1019. return pctRet;
  1020. }
  1021. }
  1022. else
  1023. {
  1024. pctRet = Tls1ComputeMac(pContext,
  1025. TRUE,
  1026. &Clean,
  1027. pswrap->bCType,
  1028. rgbDigest,
  1029. sizeof(rgbDigest));
  1030. if(pctRet != PCT_ERR_OK)
  1031. {
  1032. return pctRet;
  1033. }
  1034. }
  1035. pContext->ReadCounter++;
  1036. pbMAC = (PUCHAR)Clean.pvBuffer + Clean.cbData;
  1037. if(memcmp(rgbDigest, pbMAC, pContext->pReadHashInfo->cbCheckSum))
  1038. {
  1039. DebugLog((DEB_WARN, "FINISHED Message: Checksum Invalid\n"));
  1040. if(pContext->RipeZombie->fProtocol & SP_PROT_TLS1)
  1041. {
  1042. SetTls1Alert(pContext, TLS1_ALERT_FATAL, TLS1_ALERT_BAD_RECORD_MAC);
  1043. }
  1044. SP_RETURN(SP_LOG_RESULT(SEC_E_MESSAGE_ALTERED));
  1045. }
  1046. if(pAppOutput->pvBuffer != Clean.pvBuffer)
  1047. {
  1048. CopyMemory(pAppOutput->pvBuffer, Clean.pvBuffer, Clean.cbData);
  1049. }
  1050. pAppOutput->cbData = Clean.cbData;
  1051. SP_RETURN(PCT_ERR_OK);
  1052. }
  1053. /*****************************************************************************/
  1054. // Create an encrypted Finish message, adding it to the end of the
  1055. // specified buffer object.
  1056. //
  1057. SP_STATUS SPBuildS3FinalFinish(PSPContext pContext, PSPBuffer pBuffer, BOOL fClient)
  1058. {
  1059. PBYTE pbMessage = (PBYTE)pBuffer->pvBuffer + pBuffer->cbData;
  1060. DWORD cbFinished;
  1061. SP_STATUS pctRet;
  1062. DWORD cbDataOut;
  1063. BYTE rgbMd5Digest[CB_MD5_DIGEST_LEN];
  1064. BYTE rgbSHADigest[CB_SHA_DIGEST_LEN];
  1065. // Build Finished message body.
  1066. pctRet = Ssl3BuildFinishMessage(pContext, rgbMd5Digest, rgbSHADigest, fClient);
  1067. if(pctRet != PCT_ERR_OK)
  1068. {
  1069. return pctRet;
  1070. }
  1071. CopyMemory(pbMessage + sizeof(SWRAP) + sizeof(SHSH),
  1072. rgbMd5Digest,
  1073. CB_MD5_DIGEST_LEN);
  1074. CopyMemory(pbMessage + sizeof(SWRAP) + sizeof(SHSH) + CB_MD5_DIGEST_LEN,
  1075. rgbSHADigest,
  1076. CB_SHA_DIGEST_LEN);
  1077. // Build Finished handshake header.
  1078. SetHandshake(pbMessage + sizeof(SWRAP),
  1079. SSL3_HS_FINISHED,
  1080. NULL,
  1081. CB_MD5_DIGEST_LEN + CB_SHA_DIGEST_LEN);
  1082. cbFinished = sizeof(SHSH) + CB_MD5_DIGEST_LEN + CB_SHA_DIGEST_LEN;
  1083. // Update handshake hash objects.
  1084. pctRet = UpdateHandshakeHash(pContext,
  1085. pbMessage + sizeof(SWRAP),
  1086. cbFinished,
  1087. FALSE);
  1088. if(pctRet != PCT_ERR_OK)
  1089. {
  1090. return(pctRet);
  1091. }
  1092. // Add record header and encrypt message.
  1093. pctRet = SPSetWrap(pContext,
  1094. pbMessage,
  1095. SSL3_CT_HANDSHAKE,
  1096. cbFinished,
  1097. fClient,
  1098. &cbDataOut);
  1099. if(pctRet != PCT_ERR_OK)
  1100. {
  1101. return pctRet;
  1102. }
  1103. // Update buffer length.
  1104. pBuffer->cbData += cbDataOut;
  1105. SP_ASSERT(pBuffer->cbData <= pBuffer->cbBuffer);
  1106. return PCT_ERR_OK;
  1107. }
  1108. SP_STATUS
  1109. SPSetWrap(
  1110. PSPContext pContext,
  1111. PUCHAR pbMessage,
  1112. UCHAR bContentType,
  1113. DWORD cbPayload,
  1114. BOOL fClient,
  1115. DWORD *pcbDataOut)
  1116. {
  1117. SWRAP *pswrap = (SWRAP *)pbMessage;
  1118. DWORD cbMessage;
  1119. SP_STATUS pctRet = PCT_ERR_OK;
  1120. // Compute size of encrypted message.
  1121. cbMessage = Ssl3CiphertextLen(pContext, cbPayload, fClient);
  1122. if(pContext->pWriteHashInfo)
  1123. {
  1124. SPBuffer Clean;
  1125. SPBuffer Encrypted;
  1126. Clean.pvBuffer = pbMessage + sizeof(SWRAP);
  1127. Clean.cbBuffer = cbMessage;
  1128. Clean.cbData = cbPayload;
  1129. Encrypted.pvBuffer = pbMessage;
  1130. Encrypted.cbBuffer = cbMessage;
  1131. Encrypted.cbData = cbPayload + sizeof(SWRAP);
  1132. pctRet = Ssl3EncryptRaw(pContext, &Clean, &Encrypted, bContentType);
  1133. cbMessage = Encrypted.cbData;
  1134. }
  1135. ZeroMemory(pswrap, sizeof(SWRAP));
  1136. pswrap->bCType = bContentType;
  1137. pswrap->bMajor = SSL3_CLIENT_VERSION_MSB;
  1138. if(pContext->RipeZombie->fProtocol & SP_PROT_SSL3)
  1139. {
  1140. pswrap->bMinor = (UCHAR)SSL3_CLIENT_VERSION_LSB;
  1141. }
  1142. else
  1143. {
  1144. pswrap->bMinor = (UCHAR)TLS1_CLIENT_VERSION_LSB;
  1145. }
  1146. pswrap->bcbMSBSize = MSBOF(cbMessage - sizeof(SWRAP));
  1147. pswrap->bcbLSBSize = LSBOF(cbMessage - sizeof(SWRAP));
  1148. if(pcbDataOut != NULL)
  1149. {
  1150. *pcbDataOut = cbMessage;
  1151. }
  1152. return(pctRet);
  1153. }
  1154. void
  1155. SetWrapNoEncrypt(
  1156. PUCHAR pbMessage,
  1157. UCHAR bContentType,
  1158. DWORD cbPayload)
  1159. {
  1160. SWRAP *pswrap = (SWRAP *)pbMessage;
  1161. ZeroMemory(pswrap, sizeof(SWRAP));
  1162. pswrap->bCType = bContentType;
  1163. pswrap->bMajor = SSL3_CLIENT_VERSION_MSB;
  1164. pswrap->bMinor = SSL3_CLIENT_VERSION_LSB;
  1165. pswrap->bcbMSBSize = MSBOF(cbPayload);
  1166. pswrap->bcbLSBSize = LSBOF(cbPayload);
  1167. }
  1168. void SetHandshake(PUCHAR pb, BYTE bHandshake, PUCHAR pbData, DWORD dwSize)
  1169. {
  1170. SHSH *pshsh = (SHSH *) pb;
  1171. FillMemory(pshsh, sizeof(SHSH), 0);
  1172. pshsh->typHS = bHandshake;
  1173. pshsh->bcbMSB = MSBOF(dwSize) ;
  1174. pshsh->bcbLSB = LSBOF(dwSize) ;
  1175. if(NULL != pbData)
  1176. {
  1177. CopyMemory( pb + sizeof(SHSH) , pbData, dwSize);
  1178. }
  1179. }
  1180. //+---------------------------------------------------------------------------
  1181. //
  1182. // Function: UpdateHandshakeHash
  1183. //
  1184. // Synopsis:
  1185. //
  1186. // Arguments: [pContext] --
  1187. // [pb] --
  1188. // [dwcb] --
  1189. // [fInit] --
  1190. //
  1191. // History: 10-03-97 jbanes Added server-side CAPI integration.
  1192. //
  1193. // Notes:
  1194. //
  1195. //----------------------------------------------------------------------------
  1196. SP_STATUS
  1197. UpdateHandshakeHash(
  1198. PSPContext pContext,
  1199. PUCHAR pb,
  1200. DWORD dwcb,
  1201. BOOL fInit)
  1202. {
  1203. if(pContext->RipeZombie->hMasterProv == 0)
  1204. {
  1205. return SP_LOG_RESULT(PCT_INT_INTERNAL_ERROR);
  1206. }
  1207. if(fInit)
  1208. {
  1209. DebugLog((DEB_TRACE, "UpdateHandshakeHash: initializing\n"));
  1210. if(pContext->hMd5Handshake)
  1211. {
  1212. SchCryptDestroyHash(pContext->hMd5Handshake,
  1213. pContext->RipeZombie->dwCapiFlags);
  1214. pContext->hMd5Handshake = 0;
  1215. }
  1216. if(!SchCryptCreateHash(pContext->RipeZombie->hMasterProv,
  1217. CALG_MD5, 0, 0,
  1218. &pContext->hMd5Handshake,
  1219. pContext->RipeZombie->dwCapiFlags))
  1220. {
  1221. SP_LOG_RESULT(GetLastError());
  1222. return PCT_INT_INTERNAL_ERROR;
  1223. }
  1224. if(pContext->hShaHandshake)
  1225. {
  1226. SchCryptDestroyHash(pContext->hShaHandshake,
  1227. pContext->RipeZombie->dwCapiFlags);
  1228. pContext->hShaHandshake = 0;
  1229. }
  1230. if(!SchCryptCreateHash(pContext->RipeZombie->hMasterProv,
  1231. CALG_SHA, 0, 0,
  1232. &pContext->hShaHandshake,
  1233. pContext->RipeZombie->dwCapiFlags))
  1234. {
  1235. SP_LOG_RESULT(GetLastError());
  1236. return PCT_INT_INTERNAL_ERROR;
  1237. }
  1238. }
  1239. if(pContext->hMd5Handshake == 0 || pContext->hShaHandshake == 0)
  1240. {
  1241. return SP_LOG_RESULT(PCT_INT_INTERNAL_ERROR);
  1242. }
  1243. if(dwcb && NULL != pb)
  1244. {
  1245. DebugLog((DEB_TRACE, "UpdateHandshakeHash: %d bytes\n", dwcb));
  1246. if(!SchCryptHashData(pContext->hMd5Handshake,
  1247. pb, dwcb, 0,
  1248. pContext->RipeZombie->dwCapiFlags))
  1249. {
  1250. SP_LOG_RESULT(GetLastError());
  1251. return PCT_INT_INTERNAL_ERROR;
  1252. }
  1253. if(!SchCryptHashData(pContext->hShaHandshake,
  1254. pb, dwcb, 0,
  1255. pContext->RipeZombie->dwCapiFlags))
  1256. {
  1257. SP_LOG_RESULT(GetLastError());
  1258. return PCT_INT_INTERNAL_ERROR;
  1259. }
  1260. }
  1261. #if VERIFYHASH
  1262. CopyMemory(&rgbF[ibF], pb, dwcb);
  1263. ibF += dwcb;
  1264. #endif
  1265. return PCT_ERR_OK;
  1266. }
  1267. //+---------------------------------------------------------------------------
  1268. //
  1269. // Function: Tls1ComputeCertVerifyHashes
  1270. //
  1271. // Synopsis: Compute the hashes contained by a TLS
  1272. // CertificateVerify message.
  1273. //
  1274. // Arguments: [pContext] -- Schannel context.
  1275. // [pbHash] --
  1276. // [cbHash] --
  1277. //
  1278. // History: 10-14-97 jbanes Created.
  1279. //
  1280. // Notes: The data generated by this routine is always 36 bytes in
  1281. // length, and consists of an MD5 hash followed by an SHA
  1282. // hash.
  1283. //
  1284. // The hash values are computed as:
  1285. //
  1286. // md5_hash = MD5(handshake_messages);
  1287. //
  1288. // sha_hash = SHA(handshake_messages);
  1289. //
  1290. //----------------------------------------------------------------------------
  1291. SP_STATUS
  1292. Tls1ComputeCertVerifyHashes(
  1293. PSPContext pContext, // in
  1294. PBYTE pbMD5, // out
  1295. PBYTE pbSHA) // out
  1296. {
  1297. HCRYPTHASH hHash = 0;
  1298. DWORD cbData;
  1299. if((pContext == NULL) ||
  1300. (pContext->RipeZombie == NULL))
  1301. {
  1302. return SP_LOG_RESULT(PCT_INT_INTERNAL_ERROR);
  1303. }
  1304. if(pbMD5 != NULL)
  1305. {
  1306. // md5_hash = MD5(handshake_messages);
  1307. if(!SchCryptDuplicateHash(pContext->hMd5Handshake,
  1308. NULL,
  1309. 0,
  1310. &hHash,
  1311. pContext->RipeZombie->dwCapiFlags))
  1312. {
  1313. SP_LOG_RESULT(GetLastError());
  1314. return PCT_INT_INTERNAL_ERROR;
  1315. }
  1316. cbData = CB_MD5_DIGEST_LEN;
  1317. if(!SchCryptGetHashParam(hHash,
  1318. HP_HASHVAL,
  1319. pbMD5,
  1320. &cbData,
  1321. 0,
  1322. pContext->RipeZombie->dwCapiFlags))
  1323. {
  1324. SP_LOG_RESULT(GetLastError());
  1325. SchCryptDestroyHash(hHash, pContext->RipeZombie->dwCapiFlags);
  1326. return PCT_INT_INTERNAL_ERROR;
  1327. }
  1328. SP_ASSERT(cbData == CB_MD5_DIGEST_LEN);
  1329. if(!SchCryptDestroyHash(hHash, pContext->RipeZombie->dwCapiFlags))
  1330. {
  1331. SP_LOG_RESULT(GetLastError());
  1332. }
  1333. }
  1334. if(pbSHA != NULL)
  1335. {
  1336. // sha_hash = SHA(handshake_messages);
  1337. if(!SchCryptDuplicateHash(pContext->hShaHandshake,
  1338. NULL,
  1339. 0,
  1340. &hHash,
  1341. pContext->RipeZombie->dwCapiFlags))
  1342. {
  1343. SP_LOG_RESULT(GetLastError());
  1344. return PCT_INT_INTERNAL_ERROR;
  1345. }
  1346. cbData = CB_SHA_DIGEST_LEN;
  1347. if(!SchCryptGetHashParam(hHash,
  1348. HP_HASHVAL, pbSHA,
  1349. &cbData,
  1350. 0,
  1351. pContext->RipeZombie->dwCapiFlags))
  1352. {
  1353. SP_LOG_RESULT(GetLastError());
  1354. SchCryptDestroyHash(hHash, pContext->RipeZombie->dwCapiFlags);
  1355. return PCT_INT_INTERNAL_ERROR;
  1356. }
  1357. SP_ASSERT(cbData == CB_SHA_DIGEST_LEN);
  1358. if(!SchCryptDestroyHash(hHash, pContext->RipeZombie->dwCapiFlags))
  1359. {
  1360. SP_LOG_RESULT(GetLastError());
  1361. }
  1362. }
  1363. return PCT_ERR_OK;
  1364. }
  1365. //+---------------------------------------------------------------------------
  1366. //
  1367. // Function: Ssl3ComputeCertVerifyHashes
  1368. //
  1369. // Synopsis: Compute the hashes contained by an SSL3
  1370. // CertificateVerify message.
  1371. //
  1372. // Arguments: [pContext] -- Schannel context.
  1373. // [pbHash] --
  1374. // [cbHash] --
  1375. //
  1376. // History: 10-14-97 jbanes Added CAPI integration.
  1377. //
  1378. // Notes: The data generated by this routine is always 36 bytes in
  1379. // length, and consists of an MD5 hash followed by an SHA
  1380. // hash.
  1381. //
  1382. // The hash values are computed as follows:
  1383. //
  1384. // md5_hash = MD5(master_secret + pad2 +
  1385. // MD5(handshake_messages + master_secret +
  1386. // pad1));
  1387. //
  1388. // sha_hash = SHA(master_secret + pad2 +
  1389. // SHA(handshake_messages + master_secret +
  1390. // pad1));
  1391. //
  1392. //----------------------------------------------------------------------------
  1393. SP_STATUS
  1394. Ssl3ComputeCertVerifyHashes(
  1395. PSPContext pContext, // in
  1396. PBYTE pbMD5, // out
  1397. PBYTE pbSHA) // out
  1398. {
  1399. BYTE rgbPad1[CB_SSL3_MAX_MAC_PAD];
  1400. BYTE rgbPad2[CB_SSL3_MAX_MAC_PAD];
  1401. HCRYPTHASH hHash = 0;
  1402. DWORD cbData;
  1403. SP_STATUS pctRet;
  1404. FillMemory(rgbPad1, sizeof(rgbPad1), PAD1_CONSTANT);
  1405. FillMemory(rgbPad2, sizeof(rgbPad2), PAD2_CONSTANT);
  1406. if(pbMD5 != NULL)
  1407. {
  1408. //
  1409. // CertificateVerify.signature.md5_hash = MD5(master_secret + pad2 +
  1410. // MD5(handshake_messages + master_secret + pad1));
  1411. //
  1412. // Compute inner hash.
  1413. if(!SchCryptDuplicateHash(pContext->hMd5Handshake,
  1414. NULL,
  1415. 0,
  1416. &hHash,
  1417. pContext->RipeZombie->dwCapiFlags))
  1418. {
  1419. SP_LOG_RESULT(GetLastError());
  1420. pctRet = PCT_INT_INTERNAL_ERROR;
  1421. goto cleanup;
  1422. }
  1423. if(!SchCryptHashSessionKey(hHash,
  1424. pContext->RipeZombie->hMasterKey,
  1425. CRYPT_LITTLE_ENDIAN,
  1426. pContext->RipeZombie->dwCapiFlags))
  1427. {
  1428. SP_LOG_RESULT(GetLastError());
  1429. pctRet = PCT_INT_INTERNAL_ERROR;
  1430. goto cleanup;
  1431. }
  1432. if(!SchCryptHashData(hHash,
  1433. rgbPad1,
  1434. CB_SSL3_MD5_MAC_PAD,
  1435. 0,
  1436. pContext->RipeZombie->dwCapiFlags))
  1437. {
  1438. SP_LOG_RESULT(GetLastError());
  1439. pctRet = PCT_INT_INTERNAL_ERROR;
  1440. goto cleanup;
  1441. }
  1442. cbData = CB_MD5_DIGEST_LEN;
  1443. if(!SchCryptGetHashParam(hHash,
  1444. HP_HASHVAL,
  1445. pbMD5,
  1446. &cbData,
  1447. 0,
  1448. pContext->RipeZombie->dwCapiFlags))
  1449. {
  1450. SP_LOG_RESULT(GetLastError());
  1451. pctRet = PCT_INT_INTERNAL_ERROR;
  1452. goto cleanup;
  1453. }
  1454. SP_ASSERT(cbData == CB_MD5_DIGEST_LEN);
  1455. if(!SchCryptDestroyHash(hHash, pContext->RipeZombie->dwCapiFlags))
  1456. {
  1457. SP_LOG_RESULT(GetLastError());
  1458. }
  1459. hHash = 0;
  1460. // Compute outer hash.
  1461. if(!SchCryptCreateHash(pContext->RipeZombie->hMasterProv,
  1462. CALG_MD5,
  1463. 0,
  1464. 0,
  1465. &hHash,
  1466. pContext->RipeZombie->dwCapiFlags))
  1467. {
  1468. SP_LOG_RESULT(GetLastError());
  1469. pctRet = PCT_INT_INTERNAL_ERROR;
  1470. goto cleanup;
  1471. }
  1472. if(!SchCryptHashSessionKey(hHash,
  1473. pContext->RipeZombie->hMasterKey,
  1474. CRYPT_LITTLE_ENDIAN,
  1475. pContext->RipeZombie->dwCapiFlags))
  1476. {
  1477. SP_LOG_RESULT(GetLastError());
  1478. pctRet = PCT_INT_INTERNAL_ERROR;
  1479. goto cleanup;
  1480. }
  1481. if(!SchCryptHashData(hHash,
  1482. rgbPad2,
  1483. CB_SSL3_MD5_MAC_PAD,
  1484. 0,
  1485. pContext->RipeZombie->dwCapiFlags))
  1486. {
  1487. SP_LOG_RESULT(GetLastError());
  1488. pctRet = PCT_INT_INTERNAL_ERROR;
  1489. goto cleanup;
  1490. }
  1491. if(!SchCryptHashData(hHash,
  1492. pbMD5,
  1493. CB_MD5_DIGEST_LEN,
  1494. 0,
  1495. pContext->RipeZombie->dwCapiFlags))
  1496. {
  1497. SP_LOG_RESULT(GetLastError());
  1498. pctRet = PCT_INT_INTERNAL_ERROR;
  1499. goto cleanup;
  1500. }
  1501. cbData = CB_MD5_DIGEST_LEN;
  1502. if(!SchCryptGetHashParam(hHash,
  1503. HP_HASHVAL,
  1504. pbMD5,
  1505. &cbData,
  1506. 0,
  1507. pContext->RipeZombie->dwCapiFlags))
  1508. {
  1509. SP_LOG_RESULT(GetLastError());
  1510. pctRet = PCT_INT_INTERNAL_ERROR;
  1511. goto cleanup;
  1512. }
  1513. SP_ASSERT(cbData == CB_MD5_DIGEST_LEN);
  1514. if(!SchCryptDestroyHash(hHash, pContext->RipeZombie->dwCapiFlags))
  1515. {
  1516. SP_LOG_RESULT(GetLastError());
  1517. }
  1518. hHash = 0;
  1519. }
  1520. if(pbSHA != NULL)
  1521. {
  1522. //
  1523. // CertificateVerify.signature.sha_hash = SHA(master_secret + pad2 +
  1524. // SHA(handshake_messages + master_secret + pad1));
  1525. //
  1526. // Compute inner hash.
  1527. if(!SchCryptDuplicateHash(pContext->hShaHandshake,
  1528. NULL,
  1529. 0,
  1530. &hHash,
  1531. pContext->RipeZombie->dwCapiFlags))
  1532. {
  1533. SP_LOG_RESULT(GetLastError());
  1534. pctRet = PCT_INT_INTERNAL_ERROR;
  1535. goto cleanup;
  1536. }
  1537. if(!SchCryptHashSessionKey(hHash,
  1538. pContext->RipeZombie->hMasterKey,
  1539. CRYPT_LITTLE_ENDIAN,
  1540. pContext->RipeZombie->dwCapiFlags))
  1541. {
  1542. SP_LOG_RESULT(GetLastError());
  1543. pctRet = PCT_INT_INTERNAL_ERROR;
  1544. goto cleanup;
  1545. }
  1546. if(!SchCryptHashData(hHash,
  1547. rgbPad1,
  1548. CB_SSL3_SHA_MAC_PAD,
  1549. 0,
  1550. pContext->RipeZombie->dwCapiFlags))
  1551. {
  1552. SP_LOG_RESULT(GetLastError());
  1553. pctRet = PCT_INT_INTERNAL_ERROR;
  1554. goto cleanup;
  1555. }
  1556. cbData = CB_SHA_DIGEST_LEN;
  1557. if(!SchCryptGetHashParam(hHash,
  1558. HP_HASHVAL,
  1559. pbSHA,
  1560. &cbData,
  1561. 0,
  1562. pContext->RipeZombie->dwCapiFlags))
  1563. {
  1564. SP_LOG_RESULT(GetLastError());
  1565. pctRet = PCT_INT_INTERNAL_ERROR;
  1566. goto cleanup;
  1567. }
  1568. SP_ASSERT(cbData == CB_SHA_DIGEST_LEN);
  1569. if(!SchCryptDestroyHash(hHash, pContext->RipeZombie->dwCapiFlags))
  1570. {
  1571. SP_LOG_RESULT(GetLastError());
  1572. }
  1573. hHash = 0;
  1574. // Compute outer hash.
  1575. if(!SchCryptCreateHash(pContext->RipeZombie->hMasterProv,
  1576. CALG_SHA,
  1577. 0,
  1578. 0,
  1579. &hHash,
  1580. pContext->RipeZombie->dwCapiFlags))
  1581. {
  1582. SP_LOG_RESULT(GetLastError());
  1583. pctRet = PCT_INT_INTERNAL_ERROR;
  1584. goto cleanup;
  1585. }
  1586. if(!SchCryptHashSessionKey(hHash,
  1587. pContext->RipeZombie->hMasterKey,
  1588. CRYPT_LITTLE_ENDIAN,
  1589. pContext->RipeZombie->dwCapiFlags))
  1590. {
  1591. SP_LOG_RESULT(GetLastError());
  1592. pctRet = PCT_INT_INTERNAL_ERROR;
  1593. goto cleanup;
  1594. }
  1595. if(!SchCryptHashData(hHash,
  1596. rgbPad2,
  1597. CB_SSL3_SHA_MAC_PAD,
  1598. 0,
  1599. pContext->RipeZombie->dwCapiFlags))
  1600. {
  1601. SP_LOG_RESULT(GetLastError());
  1602. pctRet = PCT_INT_INTERNAL_ERROR;
  1603. goto cleanup;
  1604. }
  1605. if(!SchCryptHashData(hHash,
  1606. pbSHA,
  1607. CB_SHA_DIGEST_LEN,
  1608. 0,
  1609. pContext->RipeZombie->dwCapiFlags))
  1610. {
  1611. SP_LOG_RESULT(GetLastError());
  1612. pctRet = PCT_INT_INTERNAL_ERROR;
  1613. goto cleanup;
  1614. }
  1615. cbData = CB_SHA_DIGEST_LEN;
  1616. if(!SchCryptGetHashParam(hHash,
  1617. HP_HASHVAL,
  1618. pbSHA,
  1619. &cbData,
  1620. 0,
  1621. pContext->RipeZombie->dwCapiFlags))
  1622. {
  1623. SP_LOG_RESULT(GetLastError());
  1624. pctRet = PCT_INT_INTERNAL_ERROR;
  1625. goto cleanup;
  1626. }
  1627. SP_ASSERT(cbData == CB_SHA_DIGEST_LEN);
  1628. if(!SchCryptDestroyHash(hHash, pContext->RipeZombie->dwCapiFlags))
  1629. {
  1630. SP_LOG_RESULT(GetLastError());
  1631. }
  1632. hHash = 0;
  1633. }
  1634. pctRet = PCT_ERR_OK;
  1635. cleanup:
  1636. if(hHash)
  1637. {
  1638. SchCryptDestroyHash(hHash, pContext->RipeZombie->dwCapiFlags);
  1639. }
  1640. return pctRet;
  1641. }
  1642. SP_STATUS Ssl3HandleCCS(PSPContext pContext,
  1643. PUCHAR pb,
  1644. DWORD cbMessage)
  1645. {
  1646. SP_STATUS pctRet = PCT_ERR_OK;
  1647. BOOL fSender =
  1648. (0 == (pContext->RipeZombie->fProtocol & SP_PROT_SSL3TLS1_CLIENTS)) ;
  1649. SP_BEGIN("Ssl3HandleCCS");
  1650. if(cbMessage != 1 || pb[0] != 0x1)
  1651. {
  1652. pctRet = SP_LOG_RESULT(PCT_ERR_ILLEGAL_MESSAGE);
  1653. SP_RETURN(pctRet);
  1654. }
  1655. // We always zero out the read counter on receipt
  1656. // of a change cipher spec message.
  1657. pContext->ReadCounter = 0;
  1658. // Move pending ciphers to real ciphers
  1659. pctRet = ContextInitCiphers(pContext, TRUE, FALSE);
  1660. if(pctRet != PCT_ERR_OK)
  1661. {
  1662. SP_RETURN(pctRet);
  1663. }
  1664. if(pContext->RipeZombie->fProtocol & SP_PROT_SSL3)
  1665. {
  1666. pctRet = Ssl3MakeReadSessionKeys(pContext);
  1667. }
  1668. else
  1669. {
  1670. pctRet = Tls1MakeReadSessionKeys(pContext);
  1671. }
  1672. if(pctRet != PCT_ERR_OK)
  1673. {
  1674. SP_RETURN(pctRet);
  1675. }
  1676. if(fSender)
  1677. {
  1678. pContext->wS3CipherSuiteClient = (WORD)UniAvailableCiphers[pContext->dwPendingCipherSuiteIndex].CipherKind;
  1679. pContext->State = SSL3_STATE_CHANGE_CIPHER_SPEC_SERVER;
  1680. }
  1681. else
  1682. {
  1683. pContext->wS3CipherSuiteServer = (WORD)UniAvailableCiphers[pContext->dwPendingCipherSuiteIndex].CipherKind;
  1684. pContext->State = SSL3_STATE_CHANGE_CIPHER_SPEC_CLIENT;
  1685. }
  1686. SP_RETURN(PCT_ERR_OK);
  1687. }
  1688. /*****************************************************************************/
  1689. // Create a (possibly encrypted) ChangeCipherSpec and an encrypted
  1690. // Finish message, adding them to the end of the specified buffer object.
  1691. //
  1692. SP_STATUS
  1693. BuildCCSAndFinishMessage(
  1694. PSPContext pContext,
  1695. PSPBuffer pBuffer,
  1696. BOOL fClient)
  1697. {
  1698. SP_STATUS pctRet;
  1699. PBYTE pbMessage = (PBYTE)pBuffer->pvBuffer + pBuffer->cbData;
  1700. DWORD cbDataOut;
  1701. // Build ChangeCipherSpec message body.
  1702. *(pbMessage + sizeof(SWRAP)) = 0x1;
  1703. // Add record header and encrypt message.
  1704. pctRet = SPSetWrap(pContext,
  1705. pbMessage,
  1706. SSL3_CT_CHANGE_CIPHER_SPEC,
  1707. 1,
  1708. fClient,
  1709. &cbDataOut);
  1710. if(pctRet != PCT_ERR_OK)
  1711. return(pctRet);
  1712. // Update buffer length.
  1713. pBuffer->cbData += cbDataOut;
  1714. SP_ASSERT(pBuffer->cbData <= pBuffer->cbBuffer);
  1715. // Update cipher suites.
  1716. pContext->WriteCounter = 0;
  1717. pctRet = ContextInitCiphers(pContext, FALSE, TRUE);
  1718. if(pctRet != PCT_ERR_OK)
  1719. {
  1720. return(pctRet);
  1721. }
  1722. if(pContext->RipeZombie->fProtocol & SP_PROT_SSL3)
  1723. {
  1724. pctRet = Ssl3MakeWriteSessionKeys(pContext);
  1725. }
  1726. else
  1727. {
  1728. pctRet = Tls1MakeWriteSessionKeys(pContext);
  1729. }
  1730. if(pctRet != PCT_ERR_OK)
  1731. {
  1732. return(pctRet);
  1733. }
  1734. if(fClient)
  1735. {
  1736. pContext->wS3CipherSuiteClient = (WORD)UniAvailableCiphers[pContext->dwPendingCipherSuiteIndex].CipherKind;
  1737. }
  1738. else
  1739. {
  1740. pContext->wS3CipherSuiteServer = (WORD)UniAvailableCiphers[pContext->dwPendingCipherSuiteIndex].CipherKind;
  1741. }
  1742. // Build Finish message.
  1743. if(pContext->RipeZombie->fProtocol & SP_PROT_SSL3)
  1744. {
  1745. pctRet = SPBuildS3FinalFinish(pContext, pBuffer, fClient);
  1746. }
  1747. else
  1748. {
  1749. pctRet = SPBuildTls1FinalFinish(pContext, pBuffer, fClient);
  1750. }
  1751. return pctRet;
  1752. }
  1753. SP_STATUS
  1754. Ssl3SelectCipher
  1755. (
  1756. PSPContext pContext,
  1757. WORD wCipher
  1758. )
  1759. {
  1760. SP_STATUS pctRet=PCT_ERR_ILLEGAL_MESSAGE;
  1761. DWORD i;
  1762. PCipherInfo pCipherInfo = NULL;
  1763. PHashInfo pHashInfo = NULL;
  1764. PKeyExchangeInfo pExchInfo = NULL;
  1765. pContext->dwPendingCipherSuiteIndex = 0;
  1766. for(i = 0; i < UniNumCiphers; i++)
  1767. {
  1768. // Is this an SSL3 cipher suite?
  1769. if(!(UniAvailableCiphers[i].fProt & pContext->RipeZombie->fProtocol))
  1770. {
  1771. continue;
  1772. }
  1773. // Is this the right cipher suite?
  1774. if(UniAvailableCiphers[i].CipherKind != wCipher)
  1775. {
  1776. continue;
  1777. }
  1778. pCipherInfo = GetCipherInfo(UniAvailableCiphers[i].aiCipher, UniAvailableCiphers[i].dwStrength);
  1779. pHashInfo = GetHashInfo(UniAvailableCiphers[i].aiHash);
  1780. pExchInfo = GetKeyExchangeInfo(UniAvailableCiphers[i].KeyExch);
  1781. if(!IsCipherAllowed(pContext,
  1782. pCipherInfo,
  1783. pContext->RipeZombie->fProtocol,
  1784. pContext->RipeZombie->dwCF))
  1785. {
  1786. continue;
  1787. }
  1788. if(!IsHashAllowed(pContext, pHashInfo, pContext->RipeZombie->fProtocol))
  1789. {
  1790. continue;
  1791. }
  1792. if(!IsExchAllowed(pContext, pExchInfo, pContext->RipeZombie->fProtocol))
  1793. {
  1794. continue;
  1795. }
  1796. if(pContext->RipeZombie->fProtocol & SP_PROT_SSL3TLS1_SERVERS)
  1797. {
  1798. // Determine the credentials (and CSP) to use, based on the
  1799. // key exchange algorithm.
  1800. pctRet = SPPickClientCertificate(pContext,
  1801. UniAvailableCiphers[i].KeyExch);
  1802. if(pctRet != PCT_ERR_OK)
  1803. {
  1804. continue;
  1805. }
  1806. }
  1807. pContext->RipeZombie->dwCipherSuiteIndex = i;
  1808. pContext->RipeZombie->aiCipher = UniAvailableCiphers[i].aiCipher;
  1809. pContext->RipeZombie->dwStrength = UniAvailableCiphers[i].dwStrength;
  1810. pContext->RipeZombie->aiHash = UniAvailableCiphers[i].aiHash;
  1811. pContext->RipeZombie->SessExchSpec = UniAvailableCiphers[i].KeyExch;
  1812. return ContextInitCiphersFromCache(pContext);
  1813. }
  1814. return(SP_LOG_RESULT(PCT_ERR_ILLEGAL_MESSAGE));
  1815. }
  1816. // Server side cipher selection
  1817. SP_STATUS
  1818. Ssl3SelectCipherEx(
  1819. PSPContext pContext,
  1820. DWORD *pCipherSpecs,
  1821. DWORD cCipherSpecs)
  1822. {
  1823. DWORD i, j;
  1824. SP_STATUS pctRet;
  1825. PCipherInfo pCipherInfo = NULL;
  1826. PHashInfo pHashInfo = NULL;
  1827. PKeyExchangeInfo pExchInfo = NULL;
  1828. PSPCredential pCred = NULL;
  1829. BOOL fFound;
  1830. pContext->dwPendingCipherSuiteIndex = 0;
  1831. // Loop through the supported SSL3 cipher suites.
  1832. for(i = 0; i < UniNumCiphers; i++)
  1833. {
  1834. // Is this an SSL3 cipher suite?
  1835. if(!(UniAvailableCiphers[i].fProt & pContext->RipeZombie->fProtocol))
  1836. {
  1837. continue;
  1838. }
  1839. pCipherInfo = GetCipherInfo(UniAvailableCiphers[i].aiCipher,
  1840. UniAvailableCiphers[i].dwStrength);
  1841. pHashInfo = GetHashInfo(UniAvailableCiphers[i].aiHash);
  1842. pExchInfo = GetKeyExchangeInfo(UniAvailableCiphers[i].KeyExch);
  1843. // Do we currently support this hash and key exchange algorithm?
  1844. if(!IsHashAllowed(pContext, pHashInfo, pContext->RipeZombie->fProtocol))
  1845. {
  1846. DebugLog((DEB_TRACE, "Cipher %d - hash not supported\n", i));
  1847. continue;
  1848. }
  1849. if(!IsExchAllowed(pContext, pExchInfo, pContext->RipeZombie->fProtocol))
  1850. {
  1851. DebugLog((DEB_TRACE, "Cipher %d - exch not supported\n", i));
  1852. continue;
  1853. }
  1854. // Do we have an appropriate certificate?
  1855. if(pContext->RipeZombie->fProtocol & SP_PROT_SSL3TLS1_SERVERS)
  1856. {
  1857. pctRet = SPPickServerCertificate(pContext,
  1858. UniAvailableCiphers[i].KeyExch);
  1859. if(pctRet != PCT_ERR_OK)
  1860. {
  1861. DebugLog((DEB_TRACE, "Cipher %d - certificate %d not found\n",
  1862. i, UniAvailableCiphers[i].KeyExch));
  1863. continue;
  1864. }
  1865. }
  1866. pCred = pContext->RipeZombie->pActiveServerCred;
  1867. // Do we support this encryption algorithm/key length?
  1868. if(!IsCipherSuiteAllowed(pContext,
  1869. pCipherInfo,
  1870. pContext->RipeZombie->fProtocol,
  1871. pCred->dwCF,
  1872. UniAvailableCiphers[i].dwFlags))
  1873. {
  1874. DebugLog((DEB_TRACE, "Cipher %d - cipher not supported\n", i));
  1875. continue;
  1876. }
  1877. // Is this cipher suite supported by the client?
  1878. for(fFound = FALSE, j = 0; j < cCipherSpecs; j++)
  1879. {
  1880. if(UniAvailableCiphers[i].CipherKind == pCipherSpecs[j])
  1881. {
  1882. fFound = TRUE;
  1883. break;
  1884. }
  1885. }
  1886. if(!fFound)
  1887. {
  1888. DebugLog((DEB_TRACE, "Cipher %d - not supported by client\n", i));
  1889. continue;
  1890. }
  1891. if(UniAvailableCiphers[i].KeyExch == SP_EXCH_RSA_PKCS1)
  1892. {
  1893. // This is an RSA cipher suite, so make sure that the
  1894. // CSP supports it.
  1895. if(!IsAlgSupportedCapi(pContext->RipeZombie->fProtocol,
  1896. UniAvailableCiphers + i,
  1897. pCred->pCapiAlgs,
  1898. pCred->cCapiAlgs))
  1899. {
  1900. DebugLog((DEB_TRACE, "Cipher %d - not supported by csp\n", i));
  1901. continue;
  1902. }
  1903. }
  1904. if(UniAvailableCiphers[i].KeyExch == SP_EXCH_DH_PKCS3)
  1905. {
  1906. // This is a DH cipher suite, so make sure that the
  1907. // CSP supports it.
  1908. if(!IsAlgSupportedCapi(pContext->RipeZombie->fProtocol,
  1909. UniAvailableCiphers + i,
  1910. pCred->pCapiAlgs,
  1911. pCred->cCapiAlgs))
  1912. {
  1913. DebugLog((DEB_TRACE, "Cipher %d - not supported by csp\n", i));
  1914. continue;
  1915. }
  1916. }
  1917. // Use this cipher.
  1918. pContext->RipeZombie->dwCipherSuiteIndex = i;
  1919. pContext->RipeZombie->aiCipher = UniAvailableCiphers[i].aiCipher;
  1920. pContext->RipeZombie->dwStrength = UniAvailableCiphers[i].dwStrength;
  1921. pContext->RipeZombie->aiHash = UniAvailableCiphers[i].aiHash;
  1922. pContext->RipeZombie->SessExchSpec = UniAvailableCiphers[i].KeyExch;
  1923. pContext->RipeZombie->dwCF = pCred->dwCF;
  1924. return ContextInitCiphersFromCache(pContext);
  1925. }
  1926. LogCipherMismatchEvent();
  1927. return SP_LOG_RESULT(PCT_ERR_SPECS_MISMATCH);
  1928. }
  1929. /*****************************************************************************/
  1930. VOID ComputeServerExchangeHashes(
  1931. PSPContext pContext,
  1932. PBYTE pbServerParams, // in
  1933. INT iServerParamsLen, // in
  1934. PBYTE pbMd5HashVal, // out
  1935. PBYTE pbShaHashVal) // out
  1936. {
  1937. MD5_CTX Md5Hash;
  1938. A_SHA_CTX ShaHash;
  1939. //
  1940. // md5_hash = MD5(ClientHello.random + ServerHello.random + ServerParams);
  1941. //
  1942. // sha_hash = SHA(ClientHello.random + ServerHello.random + ServerParams);
  1943. //
  1944. MD5Init(&Md5Hash);
  1945. MD5Update(&Md5Hash, pContext->rgbS3CRandom, 32);
  1946. MD5Update(&Md5Hash, pContext->rgbS3SRandom, 32);
  1947. MD5Update(&Md5Hash, pbServerParams, iServerParamsLen);
  1948. MD5Final(&Md5Hash);
  1949. CopyMemory(pbMd5HashVal, Md5Hash.digest, 16);
  1950. A_SHAInit(&ShaHash);
  1951. A_SHAUpdate(&ShaHash, pContext->rgbS3CRandom, 32);
  1952. A_SHAUpdate(&ShaHash, pContext->rgbS3SRandom, 32);
  1953. A_SHAUpdate(&ShaHash, pbServerParams, iServerParamsLen);
  1954. A_SHAFinal(&ShaHash, pbShaHashVal);
  1955. }
  1956. SP_STATUS
  1957. UnwrapSsl3Message(
  1958. PSPContext pContext,
  1959. PSPBuffer pMsgInput)
  1960. {
  1961. SPBuffer Encrypted;
  1962. SPBuffer Clean;
  1963. SP_STATUS pctRet;
  1964. SWRAP *pswrap = (SWRAP *)pMsgInput->pvBuffer;
  1965. PBYTE pbMsg = (PBYTE)pMsgInput->pvBuffer;
  1966. //
  1967. // Validate 5 byte header.
  1968. //
  1969. // ProtocolVersion version;
  1970. if(COMBINEBYTES(pbMsg[1], pbMsg[2]) < SSL3_CLIENT_VERSION)
  1971. {
  1972. pctRet = SP_LOG_RESULT(PCT_ERR_ILLEGAL_MESSAGE);
  1973. }
  1974. if(COMBINEBYTES(pswrap->bcbMSBSize, pswrap->bcbLSBSize) <
  1975. pContext->pReadHashInfo->cbCheckSum)
  1976. {
  1977. return(PCT_ERR_ILLEGAL_MESSAGE);
  1978. }
  1979. Encrypted.pvBuffer = pMsgInput->pvBuffer;
  1980. Encrypted.cbBuffer = pMsgInput->cbBuffer;
  1981. Encrypted.cbData = pMsgInput->cbData;
  1982. Clean.pvBuffer = (PUCHAR)pMsgInput->pvBuffer + sizeof(SWRAP);
  1983. pctRet = Ssl3DecryptMessage(pContext, &Encrypted, &Clean);
  1984. if(pctRet == PCT_ERR_OK)
  1985. {
  1986. pswrap->bcbMSBSize = MSBOF(Clean.cbData);
  1987. pswrap->bcbLSBSize = LSBOF(Clean.cbData);
  1988. }
  1989. return(pctRet);
  1990. }
  1991. SP_STATUS
  1992. ParseAlertMessage(
  1993. PSPContext pContext,
  1994. PUCHAR pbAlertMsg,
  1995. DWORD cbMessage
  1996. )
  1997. {
  1998. SP_STATUS pctRet=PCT_ERR_OK;
  1999. if(cbMessage != 2)
  2000. {
  2001. return SP_LOG_RESULT(PCT_ERR_ILLEGAL_MESSAGE);
  2002. }
  2003. if(pbAlertMsg[0] != SSL3_ALERT_WARNING && pbAlertMsg[0] != SSL3_ALERT_FATAL)
  2004. {
  2005. return SP_LOG_RESULT(PCT_ERR_ILLEGAL_MESSAGE);
  2006. }
  2007. DebugLog((DEB_WARN, "AlertMessage, Alert Level - %lx\n", (DWORD)pbAlertMsg[0]));
  2008. DebugLog((DEB_WARN, "AlertMessage, Alert Description - %lx\n", (DWORD)pbAlertMsg[1]));
  2009. if(pbAlertMsg[0] == SSL3_ALERT_WARNING)
  2010. {
  2011. switch(pbAlertMsg[1])
  2012. {
  2013. case SSL3_ALERT_NO_CERTIFICATE:
  2014. DebugLog((DEB_TRACE, "no_certificate alert\n"));
  2015. pContext->State = SSL3_STATE_NO_CERT_ALERT;
  2016. pctRet = PCT_ERR_OK;
  2017. break;
  2018. case SSL3_ALERT_CLOSE_NOTIFY:
  2019. DebugLog((DEB_TRACE, "close_notify alert\n"));
  2020. pctRet = SEC_I_CONTEXT_EXPIRED;
  2021. break;
  2022. default:
  2023. DebugLog((DEB_TRACE, "Ignoring warning alert\n"));
  2024. pctRet = PCT_ERR_OK;
  2025. break;
  2026. }
  2027. }
  2028. else
  2029. {
  2030. switch(pbAlertMsg[1])
  2031. {
  2032. case SSL3_ALERT_UNEXPECTED_MESSAGE:
  2033. DebugLog((DEB_TRACE, "unexpected_message alert\n"));
  2034. pctRet = SP_LOG_RESULT(SEC_E_ILLEGAL_MESSAGE);
  2035. break;
  2036. case TLS1_ALERT_BAD_RECORD_MAC:
  2037. DebugLog((DEB_TRACE, "bad_record_mac alert\n"));
  2038. pctRet = SP_LOG_RESULT(SEC_E_MESSAGE_ALTERED);
  2039. break;
  2040. case TLS1_ALERT_DECRYPTION_FAILED:
  2041. DebugLog((DEB_TRACE, "decryption_failed alert\n"));
  2042. pctRet = SP_LOG_RESULT(SEC_E_DECRYPT_FAILURE);
  2043. break;
  2044. case TLS1_ALERT_RECORD_OVERFLOW:
  2045. DebugLog((DEB_TRACE, "record_overflow alert\n"));
  2046. pctRet = SP_LOG_RESULT(SEC_E_ILLEGAL_MESSAGE);
  2047. break;
  2048. case SSL3_ALERT_DECOMPRESSION_FAIL:
  2049. DebugLog((DEB_TRACE, "decompression_fail alert\n"));
  2050. pctRet = SP_LOG_RESULT(SEC_E_MESSAGE_ALTERED);
  2051. break;
  2052. case SSL3_ALERT_HANDSHAKE_FAILURE:
  2053. DebugLog((DEB_TRACE, "handshake_failure alert\n"));
  2054. pctRet = SP_LOG_RESULT(SEC_E_ILLEGAL_MESSAGE);
  2055. break;
  2056. case TLS1_ALERT_BAD_CERTIFICATE:
  2057. DebugLog((DEB_TRACE, "bad_certificate alert\n"));
  2058. pctRet = SP_LOG_RESULT(SEC_E_CERT_UNKNOWN);
  2059. break;
  2060. case TLS1_ALERT_UNSUPPORTED_CERT:
  2061. DebugLog((DEB_TRACE, "unsupported_cert alert\n"));
  2062. pctRet = SP_LOG_RESULT(SEC_E_CERT_UNKNOWN);
  2063. break;
  2064. case TLS1_ALERT_CERTIFICATE_REVOKED:
  2065. DebugLog((DEB_TRACE, "certificate_revoked alert\n"));
  2066. pctRet = SP_LOG_RESULT(CRYPT_E_REVOKED);
  2067. break;
  2068. case TLS1_ALERT_CERTIFICATE_EXPIRED:
  2069. DebugLog((DEB_TRACE, "certificate_expired alert\n"));
  2070. pctRet = SP_LOG_RESULT(SEC_E_CERT_EXPIRED);
  2071. break;
  2072. case TLS1_ALERT_CERTIFICATE_UNKNOWN:
  2073. DebugLog((DEB_TRACE, "certificate_unknown alert\n"));
  2074. pctRet = SP_LOG_RESULT(SEC_E_CERT_UNKNOWN);
  2075. break;
  2076. case SSL3_ALERT_ILLEGAL_PARAMETER:
  2077. DebugLog((DEB_TRACE, "illegal_parameter alert\n"));
  2078. pctRet = SP_LOG_RESULT(SEC_E_ILLEGAL_MESSAGE);
  2079. break;
  2080. case TLS1_ALERT_UNKNOWN_CA:
  2081. DebugLog((DEB_TRACE, "unknown_ca alert\n"));
  2082. pctRet = SP_LOG_RESULT(SEC_E_UNTRUSTED_ROOT);
  2083. break;
  2084. case TLS1_ALERT_ACCESS_DENIED:
  2085. DebugLog((DEB_TRACE, "access_denied alert\n"));
  2086. pctRet = SP_LOG_RESULT(SEC_E_LOGON_DENIED);
  2087. break;
  2088. case TLS1_ALERT_DECODE_ERROR:
  2089. DebugLog((DEB_TRACE, "decode_error alert\n"));
  2090. pctRet = SP_LOG_RESULT(SEC_E_ILLEGAL_MESSAGE);
  2091. break;
  2092. case TLS1_ALERT_DECRYPT_ERROR:
  2093. DebugLog((DEB_TRACE, "decrypt_error alert\n"));
  2094. pctRet = SP_LOG_RESULT(SEC_E_DECRYPT_FAILURE);
  2095. break;
  2096. case TLS1_ALERT_EXPORT_RESTRICTION:
  2097. DebugLog((DEB_TRACE, "export_restriction alert\n"));
  2098. pctRet = SP_LOG_RESULT(SEC_E_ILLEGAL_MESSAGE);
  2099. break;
  2100. case TLS1_ALERT_PROTOCOL_VERSION:
  2101. DebugLog((DEB_TRACE, "protocol_version alert\n"));
  2102. pctRet = SP_LOG_RESULT(SEC_E_UNSUPPORTED_FUNCTION);
  2103. break;
  2104. case TLS1_ALERT_INSUFFIENT_SECURITY:
  2105. DebugLog((DEB_TRACE, "insuffient_security alert\n"));
  2106. pctRet = SP_LOG_RESULT(SEC_E_ALGORITHM_MISMATCH);
  2107. break;
  2108. case TLS1_ALERT_INTERNAL_ERROR:
  2109. DebugLog((DEB_TRACE, "internal_error alert\n"));
  2110. pctRet = SP_LOG_RESULT(SEC_E_INTERNAL_ERROR);
  2111. break;
  2112. default:
  2113. DebugLog((DEB_TRACE, "Unknown fatal alert\n"));
  2114. pctRet = SP_LOG_RESULT(SEC_E_ILLEGAL_MESSAGE);
  2115. break;
  2116. }
  2117. }
  2118. return pctRet;
  2119. }
  2120. void BuildAlertMessage(PBYTE pbAlertMsg, UCHAR bAlertLevel, UCHAR bAlertDesc)
  2121. {
  2122. ALRT *palrt = (ALRT *) pbAlertMsg;
  2123. FillMemory(palrt, sizeof(ALRT), 0);
  2124. palrt->bCType = SSL3_CT_ALERT;
  2125. palrt->bMajor = SSL3_CLIENT_VERSION_MSB;
  2126. // palrt->bMinor = SSL3_CLIENT_VERSION_LSB; DONE by FillMemory
  2127. // palrt->bcbMSBSize = 0; Done by FillMemory
  2128. palrt->bcbLSBSize = 2;
  2129. palrt->bAlertLevel = bAlertLevel;
  2130. palrt->bAlertDesc = bAlertDesc ;
  2131. }
  2132. SP_STATUS SPPacketSplit(BYTE bContentType, PSPBuffer pPlain)
  2133. //Now let's us see whether we have the FULL-handshake
  2134. {
  2135. SP_STATUS pctRet = PCT_ERR_OK;
  2136. PBYTE pb;
  2137. DWORD cb;
  2138. pb = pPlain->pvBuffer;
  2139. switch(bContentType)
  2140. {
  2141. case SSL3_CT_HANDSHAKE:
  2142. if(pPlain->cbData >= sizeof(SHSH))
  2143. {
  2144. cb = ((INT)pb[1] << 16) + ((INT)pb[2] << 8) + (INT)pb[3];
  2145. cb += sizeof(SHSH);
  2146. if( cb > pPlain->cbData)
  2147. {
  2148. return(PCT_INT_INCOMPLETE_MSG);
  2149. }
  2150. }
  2151. else
  2152. return(PCT_INT_INCOMPLETE_MSG);
  2153. break;
  2154. case SSL3_CT_ALERT:
  2155. if(pPlain->cbData != 2)
  2156. return(PCT_INT_INCOMPLETE_MSG);
  2157. break;
  2158. case SSL3_CT_CHANGE_CIPHER_SPEC:
  2159. if(pPlain->cbData != 1)
  2160. return(PCT_INT_INTERNAL_ERROR);
  2161. default:
  2162. break;
  2163. }
  2164. return(pctRet);
  2165. }
  2166. /*****************************************************************************/
  2167. // Create an encrypted Finish message, adding it to the end of the
  2168. // specified buffer object.
  2169. //
  2170. SP_STATUS SPBuildTls1FinalFinish(PSPContext pContext, PSPBuffer pBuffer, BOOL fClient)
  2171. {
  2172. PBYTE pbMessage = (PBYTE)pBuffer->pvBuffer + pBuffer->cbData;
  2173. DWORD cbFinished;
  2174. SP_STATUS pctRet;
  2175. DWORD cbDataOut;
  2176. BYTE rgbDigest[CB_TLS1_VERIFYDATA];
  2177. // Build Finished message body.
  2178. pctRet = Tls1BuildFinishMessage(pContext, rgbDigest, sizeof(rgbDigest), fClient);
  2179. if(pctRet != PCT_ERR_OK)
  2180. {
  2181. return pctRet;
  2182. }
  2183. CopyMemory(pbMessage + sizeof(SWRAP) + sizeof(SHSH),
  2184. rgbDigest,
  2185. CB_TLS1_VERIFYDATA);
  2186. // Build Finished handshake header.
  2187. SetHandshake(pbMessage + sizeof(SWRAP),
  2188. SSL3_HS_FINISHED,
  2189. NULL,
  2190. CB_TLS1_VERIFYDATA);
  2191. cbFinished = sizeof(SHSH) + CB_TLS1_VERIFYDATA;
  2192. // Update handshake hash objects.
  2193. pctRet = UpdateHandshakeHash(pContext,
  2194. pbMessage + sizeof(SWRAP),
  2195. cbFinished,
  2196. FALSE);
  2197. if(pctRet != PCT_ERR_OK)
  2198. {
  2199. return(pctRet);
  2200. }
  2201. // Add record header and encrypt message.
  2202. pctRet = SPSetWrap(pContext,
  2203. pbMessage,
  2204. SSL3_CT_HANDSHAKE,
  2205. cbFinished,
  2206. fClient,
  2207. &cbDataOut);
  2208. if(pctRet != PCT_ERR_OK)
  2209. {
  2210. return(pctRet);
  2211. }
  2212. // Update buffer length .
  2213. pBuffer->cbData += cbDataOut;
  2214. SP_ASSERT(pBuffer->cbData <= pBuffer->cbBuffer);
  2215. return pctRet;
  2216. }
  2217. //+---------------------------------------------------------------------------
  2218. //
  2219. // Function: Tls1BuildFinishMessage
  2220. //
  2221. // Synopsis: Compute a TLS MAC for the specified message.
  2222. //
  2223. // Arguments: [pContext] -- Schannel context.
  2224. // [pbVerifyData] -- Verify data buffer.
  2225. // [cbVerifyData] -- Length of verify data buffer.
  2226. // [fClient] -- Client-generated Finished?
  2227. //
  2228. // History: 10-13-97 jbanes Created.
  2229. //
  2230. // Notes: The Finished message is computed using the following formula:
  2231. //
  2232. // verify_data = PRF(master_secret, finished_label,
  2233. // MD5(handshake_messages) +
  2234. // SHA-1(handshake_messages)) [0..11];
  2235. //
  2236. //----------------------------------------------------------------------------
  2237. SP_STATUS
  2238. Tls1BuildFinishMessage(
  2239. PSPContext pContext, // in
  2240. PBYTE pbVerifyData, // out
  2241. DWORD cbVerifyData, // in
  2242. BOOL fClient) // in
  2243. {
  2244. PBYTE pbLabel;
  2245. DWORD cbLabel;
  2246. UCHAR rgbData[CB_MD5_DIGEST_LEN + CB_SHA_DIGEST_LEN];
  2247. DWORD cbData;
  2248. HCRYPTHASH hHash = 0;
  2249. CRYPT_DATA_BLOB Data;
  2250. SP_STATUS pctRet;
  2251. if(cbVerifyData < CB_TLS1_VERIFYDATA)
  2252. {
  2253. return SP_LOG_RESULT(PCT_INT_BUFF_TOO_SMALL);
  2254. }
  2255. if(fClient)
  2256. {
  2257. pbLabel = TLS1_LABEL_CLIENTFINISHED;
  2258. }
  2259. else
  2260. {
  2261. pbLabel = TLS1_LABEL_SERVERFINISHED;
  2262. }
  2263. cbLabel = CB_TLS1_LABEL_FINISHED;
  2264. // Get the MD5 hash of the handshake messages so far.
  2265. if(!SchCryptDuplicateHash(pContext->hMd5Handshake,
  2266. NULL,
  2267. 0,
  2268. &hHash,
  2269. pContext->RipeZombie->dwCapiFlags))
  2270. {
  2271. SP_LOG_RESULT(GetLastError());
  2272. pctRet = PCT_INT_INTERNAL_ERROR;
  2273. goto error;
  2274. }
  2275. cbData = CB_MD5_DIGEST_LEN;
  2276. if(!SchCryptGetHashParam(hHash,
  2277. HP_HASHVAL,
  2278. rgbData,
  2279. &cbData,
  2280. 0,
  2281. pContext->RipeZombie->dwCapiFlags))
  2282. {
  2283. SP_LOG_RESULT(GetLastError());
  2284. pctRet = PCT_INT_INTERNAL_ERROR;
  2285. goto error;
  2286. }
  2287. if(!SchCryptDestroyHash(hHash, pContext->RipeZombie->dwCapiFlags))
  2288. {
  2289. SP_LOG_RESULT(GetLastError());
  2290. }
  2291. hHash = 0;
  2292. // Get the SHA hash of the handshake messages so far.
  2293. if(!SchCryptDuplicateHash(pContext->hShaHandshake,
  2294. NULL,
  2295. 0,
  2296. &hHash,
  2297. pContext->RipeZombie->dwCapiFlags))
  2298. {
  2299. SP_LOG_RESULT(GetLastError());
  2300. pctRet = PCT_INT_INTERNAL_ERROR;
  2301. goto error;
  2302. }
  2303. cbData = A_SHA_DIGEST_LEN;
  2304. if(!SchCryptGetHashParam(hHash,
  2305. HP_HASHVAL,
  2306. rgbData + CB_MD5_DIGEST_LEN,
  2307. &cbData,
  2308. 0,
  2309. pContext->RipeZombie->dwCapiFlags))
  2310. {
  2311. SP_LOG_RESULT(GetLastError());
  2312. pctRet = PCT_INT_INTERNAL_ERROR;
  2313. goto error;
  2314. }
  2315. cbData = CB_MD5_DIGEST_LEN + CB_SHA_DIGEST_LEN;
  2316. if(!SchCryptDestroyHash(hHash, pContext->RipeZombie->dwCapiFlags))
  2317. {
  2318. SP_LOG_RESULT(GetLastError());
  2319. }
  2320. hHash = 0;
  2321. // Compute the PRF
  2322. if(!SchCryptCreateHash(pContext->RipeZombie->hMasterProv,
  2323. CALG_TLS1PRF,
  2324. pContext->RipeZombie->hMasterKey,
  2325. 0,
  2326. &hHash,
  2327. pContext->RipeZombie->dwCapiFlags))
  2328. {
  2329. SP_LOG_RESULT(GetLastError());
  2330. pctRet = PCT_INT_INTERNAL_ERROR;
  2331. goto error;
  2332. }
  2333. Data.pbData = pbLabel;
  2334. Data.cbData = cbLabel;
  2335. if(!SchCryptSetHashParam(hHash,
  2336. HP_TLS1PRF_LABEL,
  2337. (PBYTE)&Data,
  2338. 0,
  2339. pContext->RipeZombie->dwCapiFlags))
  2340. {
  2341. SP_LOG_RESULT(GetLastError());
  2342. pctRet = PCT_INT_INTERNAL_ERROR;
  2343. goto error;
  2344. }
  2345. Data.pbData = rgbData;
  2346. Data.cbData = cbData;
  2347. if(!SchCryptSetHashParam(hHash,
  2348. HP_TLS1PRF_SEED,
  2349. (PBYTE)&Data,
  2350. 0,
  2351. pContext->RipeZombie->dwCapiFlags))
  2352. {
  2353. SP_LOG_RESULT(GetLastError());
  2354. pctRet = PCT_INT_INTERNAL_ERROR;
  2355. goto error;
  2356. }
  2357. if(!SchCryptGetHashParam(hHash,
  2358. HP_HASHVAL,
  2359. pbVerifyData,
  2360. &cbVerifyData,
  2361. 0,
  2362. pContext->RipeZombie->dwCapiFlags))
  2363. {
  2364. SP_LOG_RESULT(GetLastError());
  2365. pctRet = PCT_INT_INTERNAL_ERROR;
  2366. goto error;
  2367. }
  2368. pctRet = PCT_ERR_OK;
  2369. error:
  2370. if(hHash)
  2371. {
  2372. if(!SchCryptDestroyHash(hHash, pContext->RipeZombie->dwCapiFlags))
  2373. {
  2374. SP_LOG_RESULT(GetLastError());
  2375. }
  2376. }
  2377. return pctRet;
  2378. }
  2379. SP_STATUS
  2380. SPBuildTlsAlertMessage(
  2381. PSPContext pContext, // in
  2382. PSPBuffer pCommOutput)
  2383. {
  2384. PBYTE pbMessage = NULL;
  2385. DWORD cbMessage;
  2386. BOOL fAllocated = FALSE;
  2387. SP_STATUS pctRet;
  2388. DWORD cbDataOut;
  2389. SP_BEGIN("SPBuildTlsAlertMessage");
  2390. cbMessage = sizeof(SWRAP) +
  2391. CB_SSL3_ALERT_ONLY +
  2392. SP_MAX_DIGEST_LEN +
  2393. SP_MAX_BLOCKCIPHER_SIZE;
  2394. if(pContext->State != TLS1_STATE_ERROR)
  2395. {
  2396. SP_RETURN(SP_LOG_RESULT(PCT_INT_INTERNAL_ERROR));
  2397. }
  2398. if(pCommOutput->pvBuffer)
  2399. {
  2400. // Application has allocated memory.
  2401. if(pCommOutput->cbBuffer < cbMessage)
  2402. {
  2403. pCommOutput->cbData = cbMessage;
  2404. return SP_LOG_RESULT(PCT_INT_BUFF_TOO_SMALL);
  2405. }
  2406. fAllocated = TRUE;
  2407. }
  2408. else
  2409. {
  2410. // Schannel is to allocate memory.
  2411. pCommOutput->cbBuffer = cbMessage;
  2412. pCommOutput->pvBuffer = SPExternalAlloc(cbMessage);
  2413. if(pCommOutput->pvBuffer == NULL)
  2414. {
  2415. SP_RETURN(SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY));
  2416. }
  2417. }
  2418. pCommOutput->cbData = 0;
  2419. pbMessage = (PBYTE)pCommOutput->pvBuffer;
  2420. // Build alert message.
  2421. BuildAlertMessage(pbMessage,
  2422. pContext->bAlertLevel,
  2423. pContext->bAlertNumber);
  2424. #if DBG
  2425. DBG_HEX_STRING(DEB_TRACE, pbMessage, sizeof(ALRT));
  2426. #endif
  2427. // Build record header and encrypt message.
  2428. pctRet = SPSetWrap(pContext,
  2429. pbMessage,
  2430. SSL3_CT_ALERT,
  2431. CB_SSL3_ALERT_ONLY,
  2432. pContext->dwProtocol & SP_PROT_SSL3TLS1_CLIENTS,
  2433. &cbDataOut);
  2434. if(pctRet != PCT_ERR_OK)
  2435. {
  2436. if(!fAllocated)
  2437. {
  2438. SPExternalFree(pCommOutput->pvBuffer);
  2439. pCommOutput->pvBuffer = NULL;
  2440. }
  2441. SP_RETURN(SP_LOG_RESULT(pctRet));
  2442. }
  2443. // Update buffer length.
  2444. pCommOutput->cbData = cbDataOut;
  2445. SP_ASSERT(pCommOutput->cbData <= pCommOutput->cbBuffer);
  2446. SP_RETURN(PCT_ERR_OK);
  2447. }
  2448. void
  2449. SetTls1Alert(
  2450. PSPContext pContext,
  2451. BYTE bAlertLevel,
  2452. BYTE bAlertNumber)
  2453. {
  2454. pContext->State = TLS1_STATE_ERROR;
  2455. pContext->bAlertLevel = bAlertLevel;
  2456. pContext->bAlertNumber = bAlertNumber;
  2457. }