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.

705 lines
20 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995.
  5. //
  6. // File: pickle.c
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 8-02-95 RichardW Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include <spbase.h>
  18. #include <ssl2msg.h>
  19. #define SSL_OFFSET_OF(t, v) ((DWORD)(ULONG_PTR)&(((t)NULL)->v))
  20. #define SIZEOF(pMessage) (SslRecordSize((PSSL2_MESSAGE_HEADER) pMessage ) )
  21. DWORD
  22. SslRecordSize(
  23. PSSL2_MESSAGE_HEADER pHeader)
  24. {
  25. DWORD Size;
  26. if (pHeader->Byte0 & 0x80)
  27. {
  28. Size = COMBINEBYTES(pHeader->Byte0, pHeader->Byte1) & 0x7FFF;
  29. }
  30. else
  31. {
  32. Size = COMBINEBYTES(pHeader->Byte0, pHeader->Byte1) & 0x3FFF;
  33. }
  34. return(Size);
  35. }
  36. BOOL
  37. Ssl2MapCipherToExternal(
  38. Ssl2_Cipher_Kind FastForm,
  39. PSsl2_Cipher_Tuple pTuple)
  40. {
  41. pTuple->C1 = (UCHAR)((FastForm >> 16) & 0xff);
  42. pTuple->C2 = (UCHAR)((FastForm >> 8) & 0xff);
  43. pTuple->C3 = (UCHAR)(FastForm & 0xff);
  44. return(TRUE);
  45. }
  46. Ssl2_Cipher_Kind
  47. Ssl2MapCipherFromExternal(
  48. PSsl2_Cipher_Tuple pTuple)
  49. {
  50. return SSL_MKFAST(pTuple->C1, pTuple->C2, pTuple->C3);
  51. }
  52. SP_STATUS
  53. Ssl2PackClientHello(
  54. PSsl2_Client_Hello pCanonical,
  55. PSPBuffer pCommOutput)
  56. {
  57. DWORD cbMessage;
  58. PSSL2_CLIENT_HELLO pMessage;
  59. DWORD Size;
  60. PUCHAR pBuffer;
  61. DWORD i;
  62. if(pCanonical == NULL || pCommOutput == NULL)
  63. {
  64. return SP_LOG_RESULT(PCT_INT_INTERNAL_ERROR);
  65. }
  66. pCommOutput->cbData = 0;
  67. pCommOutput->cbData = pCanonical->cbSessionID +
  68. pCanonical->cbChallenge +
  69. pCanonical->cCipherSpecs * sizeof(Ssl2_Cipher_Tuple) +
  70. SSL_OFFSET_OF(PSSL2_CLIENT_HELLO, VariantData);
  71. cbMessage = pCommOutput->cbData - sizeof(SSL2_MESSAGE_HEADER);
  72. /* are we allocating our own memory? */
  73. if(pCommOutput->pvBuffer == NULL)
  74. {
  75. pCommOutput->pvBuffer = SPExternalAlloc(pCommOutput->cbData);
  76. if (NULL == pCommOutput->pvBuffer)
  77. {
  78. return SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY);
  79. }
  80. pCommOutput->cbBuffer = pCommOutput->cbData;
  81. }
  82. if(pCommOutput->cbData > pCommOutput->cbBuffer)
  83. {
  84. // Required buffer size returned in pCommOutput->cbData.
  85. return SP_LOG_RESULT(PCT_INT_BUFF_TOO_SMALL);
  86. }
  87. pMessage = pCommOutput->pvBuffer;
  88. pMessage->MessageId = SSL2_MT_CLIENT_HELLO;
  89. pMessage->VersionMsb = MSBOF(pCanonical->dwVer);
  90. pMessage->VersionLsb = LSBOF(pCanonical->dwVer);
  91. pBuffer = pMessage->VariantData;
  92. cbMessage -= pCanonical->cCipherSpecs * sizeof(Ssl2_Cipher_Tuple);
  93. pCommOutput->cbData -= pCanonical->cCipherSpecs * sizeof(Ssl2_Cipher_Tuple);
  94. Size = 0;
  95. for (i = 0; i < pCanonical->cCipherSpecs ; i++ )
  96. {
  97. if (!Ssl2MapCipherToExternal(pCanonical->CipherSpecs[i],
  98. (PSsl2_Cipher_Tuple) pBuffer) )
  99. {
  100. continue;
  101. }
  102. pBuffer += sizeof(Ssl2_Cipher_Tuple);
  103. Size += sizeof(Ssl2_Cipher_Tuple);
  104. }
  105. cbMessage += Size;
  106. pCommOutput->cbData += Size;
  107. pCommOutput->cbData = cbMessage + 2;
  108. pMessage->Header.Byte0 = MSBOF(cbMessage) | 0x80;
  109. pMessage->Header.Byte1 = LSBOF(cbMessage);
  110. pMessage->CipherSpecsLenMsb = MSBOF(Size);
  111. pMessage->CipherSpecsLenLsb = LSBOF(Size);
  112. pMessage->SessionIdLenMsb = MSBOF(pCanonical->cbSessionID);
  113. pMessage->SessionIdLenLsb = LSBOF(pCanonical->cbSessionID);
  114. if (pCanonical->cbSessionID)
  115. {
  116. CopyMemory( pBuffer,
  117. pCanonical->SessionID,
  118. pCanonical->cbSessionID);
  119. pBuffer += pCanonical->cbSessionID;
  120. }
  121. pMessage->ChallengeLenMsb = MSBOF(pCanonical->cbChallenge);
  122. pMessage->ChallengeLenLsb = LSBOF(pCanonical->cbChallenge);
  123. if (pCanonical->cbChallenge)
  124. {
  125. CopyMemory( pBuffer,
  126. pCanonical->Challenge,
  127. pCanonical->cbChallenge);
  128. }
  129. return(PCT_ERR_OK);
  130. }
  131. SP_STATUS
  132. Ssl2UnpackClientHello(
  133. PSPBuffer pInput,
  134. PSsl2_Client_Hello * ppClient)
  135. {
  136. PSSL2_CLIENT_HELLO pMessage;
  137. DWORD ReportedSize;
  138. DWORD CipherSpecsSize;
  139. DWORD cCipherSpecs;
  140. PSsl2_Client_Hello pCanonical;
  141. PUCHAR pBuffer;
  142. DWORD Size;
  143. DWORD i, dwVer;
  144. pMessage = pInput->pvBuffer;
  145. if(pInput->cbData < 2)
  146. {
  147. pInput->cbData = 2;
  148. return PCT_INT_INCOMPLETE_MSG;
  149. }
  150. ReportedSize = SIZEOF(pMessage);
  151. if ((ReportedSize+2) > pInput->cbData)
  152. {
  153. pInput->cbData = ReportedSize+2;
  154. return PCT_INT_INCOMPLETE_MSG;
  155. }
  156. if(ReportedSize < SSL_OFFSET_OF(PSSL2_CLIENT_HELLO, VariantData))
  157. {
  158. return SP_LOG_RESULT(PCT_ERR_ILLEGAL_MESSAGE);
  159. }
  160. if (pMessage->MessageId != SSL2_MT_CLIENT_HELLO) {
  161. return SP_LOG_RESULT(PCT_ERR_ILLEGAL_MESSAGE);
  162. }
  163. dwVer = COMBINEBYTES(pMessage->VersionMsb, pMessage->VersionLsb);
  164. if (dwVer < 2) //VERSION 2 WILL COMPUTE TO 2 (00:02)
  165. {
  166. return SP_LOG_RESULT(PCT_ERR_ILLEGAL_MESSAGE);
  167. }
  168. CipherSpecsSize = COMBINEBYTES( pMessage->CipherSpecsLenMsb,
  169. pMessage->CipherSpecsLenLsb );
  170. *ppClient = NULL;
  171. /* check that this all fits into the message */
  172. if (SSL_OFFSET_OF(PSSL2_CLIENT_HELLO, VariantData)
  173. - sizeof(SSL2_MESSAGE_HEADER) /* don't count the header */
  174. + CipherSpecsSize
  175. > ReportedSize)
  176. {
  177. return SP_LOG_RESULT(PCT_ERR_ILLEGAL_MESSAGE);
  178. }
  179. cCipherSpecs = CipherSpecsSize / sizeof(Ssl2_Cipher_Tuple);
  180. /* Allocate a buffer for the canonical client hello */
  181. pCanonical = (PSsl2_Client_Hello)SPExternalAlloc(
  182. sizeof(Ssl2_Client_Hello) +
  183. cCipherSpecs * sizeof(UNICipherMap));
  184. if (!pCanonical)
  185. {
  186. return(SP_LOG_RESULT(PCT_INT_INTERNAL_ERROR));
  187. }
  188. pCanonical->dwVer = COMBINEBYTES( pMessage->VersionMsb,
  189. pMessage->VersionLsb );
  190. pBuffer = pMessage->VariantData;
  191. pCanonical->cCipherSpecs = cCipherSpecs;
  192. for (i = 0 ; i < cCipherSpecs ; i++ )
  193. {
  194. pCanonical->CipherSpecs[i] = Ssl2MapCipherFromExternal((PSsl2_Cipher_Tuple)
  195. pBuffer);
  196. pBuffer += sizeof(Ssl2_Cipher_Tuple);
  197. }
  198. Size = COMBINEBYTES( pMessage->SessionIdLenMsb,
  199. pMessage->SessionIdLenLsb );
  200. if (Size <= SSL2_SESSION_ID_LEN)
  201. {
  202. CopyMemory( pCanonical->SessionID, pBuffer, Size);
  203. pBuffer += Size;
  204. }
  205. else
  206. {
  207. SPExternalFree( pCanonical );
  208. return PCT_ERR_ILLEGAL_MESSAGE;
  209. }
  210. pCanonical->cbSessionID = Size;
  211. Size = COMBINEBYTES( pMessage->ChallengeLenMsb,
  212. pMessage->ChallengeLenLsb );
  213. if ((Size > 0) && (Size <= SSL2_MAX_CHALLENGE_LEN))
  214. {
  215. CopyMemory( pCanonical->Challenge, pBuffer, Size );
  216. pBuffer += Size;
  217. }
  218. else
  219. {
  220. SPExternalFree( pCanonical );
  221. return SP_LOG_RESULT(PCT_ERR_ILLEGAL_MESSAGE);
  222. }
  223. pCanonical->cbChallenge = Size;
  224. *ppClient = pCanonical;
  225. pInput->cbData = ReportedSize + sizeof(SSL2_MESSAGE_HEADER);
  226. return( PCT_ERR_OK );
  227. }
  228. SP_STATUS
  229. Ssl2PackServerHello(
  230. PSsl2_Server_Hello pCanonical,
  231. PSPBuffer pCommOutput)
  232. {
  233. DWORD cbMessage;
  234. PSSL2_SERVER_HELLO pMessage;
  235. DWORD Size;
  236. PUCHAR pBuffer;
  237. DWORD i;
  238. if(pCanonical == NULL || pCommOutput == NULL)
  239. {
  240. return SP_LOG_RESULT(PCT_INT_INTERNAL_ERROR);
  241. }
  242. pCommOutput->cbData = 0;
  243. cbMessage = pCanonical->cbConnectionID +
  244. pCanonical->cbCertificate +
  245. pCanonical->cCipherSpecs * sizeof(Ssl2_Cipher_Tuple) +
  246. SSL_OFFSET_OF(PSSL2_SERVER_HELLO, VariantData) -
  247. sizeof(SSL2_MESSAGE_HEADER);
  248. pCommOutput->cbData = cbMessage + 2;
  249. /* are we allocating our own memory? */
  250. if(pCommOutput->pvBuffer == NULL)
  251. {
  252. pCommOutput->pvBuffer = SPExternalAlloc(pCommOutput->cbData);
  253. if (NULL == pCommOutput->pvBuffer)
  254. {
  255. return SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY);
  256. }
  257. pCommOutput->cbBuffer = pCommOutput->cbData;
  258. }
  259. if(pCommOutput->cbData > pCommOutput->cbBuffer)
  260. {
  261. // Required buffer size returned in pCommOutput->cbData.
  262. return SP_LOG_RESULT(PCT_INT_BUFF_TOO_SMALL);
  263. }
  264. pMessage = pCommOutput->pvBuffer;
  265. pMessage->MessageId = SSL2_MT_SERVER_HELLO;
  266. pMessage->ServerVersionMsb = SSL2_SERVER_VERSION_MSB;
  267. pMessage->ServerVersionLsb = SSL2_SERVER_VERSION_LSB;
  268. pMessage->SessionIdHit = (UCHAR) pCanonical->SessionIdHit;
  269. pMessage->CertificateType = (UCHAR) pCanonical->CertificateType;
  270. pBuffer = pMessage->VariantData;
  271. //
  272. // Pack certificate if present
  273. //
  274. pMessage->CertificateLenMsb = MSBOF(pCanonical->cbCertificate);
  275. pMessage->CertificateLenLsb = LSBOF(pCanonical->cbCertificate);
  276. if (pCanonical->cbCertificate)
  277. {
  278. CopyMemory( pBuffer,
  279. pCanonical->pCertificate,
  280. pCanonical->cbCertificate);
  281. pBuffer += pCanonical->cbCertificate ;
  282. }
  283. Size = pCanonical->cCipherSpecs * sizeof(Ssl2_Cipher_Tuple);
  284. for (i = 0; i < pCanonical->cCipherSpecs ; i++ )
  285. {
  286. if (Ssl2MapCipherToExternal(pCanonical->pCipherSpecs[i],
  287. (PSsl2_Cipher_Tuple) pBuffer) )
  288. {
  289. pBuffer += sizeof(Ssl2_Cipher_Tuple);
  290. }
  291. else
  292. {
  293. Size -= sizeof(Ssl2_Cipher_Tuple);
  294. cbMessage -= sizeof(Ssl2_Cipher_Tuple);
  295. }
  296. }
  297. pCommOutput->cbData = cbMessage + 2;
  298. pMessage->Header.Byte0 = MSBOF(cbMessage) | 0x80;
  299. pMessage->Header.Byte1 = LSBOF(cbMessage);
  300. pMessage->CipherSpecsLenMsb = MSBOF(Size);
  301. pMessage->CipherSpecsLenLsb = LSBOF(Size);
  302. pMessage->ConnectionIdLenMsb = MSBOF(pCanonical->cbConnectionID);
  303. pMessage->ConnectionIdLenLsb = LSBOF(pCanonical->cbConnectionID);
  304. if (pCanonical->cbConnectionID)
  305. {
  306. CopyMemory( pBuffer,
  307. pCanonical->ConnectionID,
  308. pCanonical->cbConnectionID);
  309. pBuffer += pCanonical->cbConnectionID;
  310. }
  311. return( PCT_ERR_OK );
  312. }
  313. SP_STATUS
  314. Ssl2UnpackServerHello(
  315. PSPBuffer pInput,
  316. PSsl2_Server_Hello * ppServer)
  317. {
  318. PSsl2_Server_Hello pCanonical;
  319. PSSL2_SERVER_HELLO pMessage;
  320. PUCHAR pBuffer;
  321. DWORD cbCertificate;
  322. DWORD cCipherSpecs;
  323. DWORD cbConnId;
  324. DWORD i;
  325. DWORD ReportedSize;
  326. pMessage = pInput->pvBuffer;
  327. if(pInput->cbData < 2)
  328. {
  329. pInput->cbData = 2;
  330. return PCT_INT_INCOMPLETE_MSG;
  331. }
  332. ReportedSize = SIZEOF(pMessage);
  333. if ((ReportedSize+2) > pInput->cbData)
  334. {
  335. pInput->cbData = ReportedSize+2;
  336. return PCT_INT_INCOMPLETE_MSG;
  337. }
  338. if(ReportedSize + 2 < SSL_OFFSET_OF(PSSL2_SERVER_HELLO, VariantData) )
  339. {
  340. return SP_LOG_RESULT(PCT_ERR_ILLEGAL_MESSAGE);
  341. }
  342. *ppServer = NULL;
  343. //
  344. // Verify Header:
  345. //
  346. if ((pMessage->MessageId != SSL2_MT_SERVER_HELLO) ||
  347. (pMessage->ServerVersionMsb != SSL2_SERVER_VERSION_MSB) ||
  348. (pMessage->ServerVersionLsb != SSL2_SERVER_VERSION_LSB) )
  349. {
  350. return SP_LOG_RESULT(PCT_ERR_ILLEGAL_MESSAGE);
  351. }
  352. cbCertificate = COMBINEBYTES( pMessage->CertificateLenMsb,
  353. pMessage->CertificateLenLsb);
  354. cCipherSpecs = COMBINEBYTES(pMessage->CipherSpecsLenMsb,
  355. pMessage->CipherSpecsLenLsb);
  356. if(cCipherSpecs % sizeof(Ssl2_Cipher_Tuple))
  357. {
  358. return SP_LOG_RESULT(PCT_ERR_ILLEGAL_MESSAGE);
  359. }
  360. cCipherSpecs /= sizeof(Ssl2_Cipher_Tuple);
  361. cbConnId = COMBINEBYTES(pMessage->ConnectionIdLenMsb,
  362. pMessage->ConnectionIdLenLsb);
  363. if(ReportedSize + 2 < SSL_OFFSET_OF(PSSL2_SERVER_HELLO, VariantData) +
  364. cbCertificate +
  365. cCipherSpecs * sizeof(Ssl2_Cipher_Tuple) +
  366. cbConnId)
  367. {
  368. return SP_LOG_RESULT(PCT_ERR_ILLEGAL_MESSAGE);
  369. }
  370. pCanonical = (PSsl2_Server_Hello)SPExternalAlloc(
  371. sizeof(Ssl2_Server_Hello) +
  372. cCipherSpecs * sizeof(Ssl2_Cipher_Kind) +
  373. cbCertificate );
  374. if (!pCanonical)
  375. {
  376. return(SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY));
  377. }
  378. pCanonical->pCertificate = (PUCHAR) (pCanonical + 1);
  379. pCanonical->pCipherSpecs = (PCipherSpec) (pCanonical + 1);
  380. pCanonical->pCertificate = (PUCHAR) (pCanonical->pCipherSpecs + cCipherSpecs);
  381. //
  382. // Expand out:
  383. //
  384. pCanonical->SessionIdHit = (DWORD) pMessage->SessionIdHit;
  385. pCanonical->CertificateType = (DWORD) pMessage->CertificateType;
  386. pCanonical->cbCertificate = cbCertificate;
  387. pCanonical->cCipherSpecs = cCipherSpecs;
  388. pCanonical->cbConnectionID = cbConnId;
  389. pBuffer = pMessage->VariantData;
  390. CopyMemory(pCanonical->pCertificate, pBuffer, cbCertificate);
  391. pBuffer += cbCertificate;
  392. for (i = 0 ; i < cCipherSpecs ; i++ )
  393. {
  394. pCanonical->pCipherSpecs[i] = Ssl2MapCipherFromExternal((PSsl2_Cipher_Tuple)
  395. pBuffer);
  396. pBuffer += sizeof(Ssl2_Cipher_Tuple);
  397. }
  398. if ((cbConnId) && (cbConnId <= SSL2_MAX_CONNECTION_ID_LEN))
  399. {
  400. CopyMemory(pCanonical->ConnectionID, pBuffer, cbConnId);
  401. }
  402. else
  403. {
  404. SPExternalFree(pCanonical);
  405. return SP_LOG_RESULT(PCT_ERR_ILLEGAL_MESSAGE);
  406. }
  407. *ppServer = pCanonical;
  408. pInput->cbData = ReportedSize + sizeof(SSL2_MESSAGE_HEADER);
  409. return( PCT_ERR_OK);
  410. }
  411. SP_STATUS
  412. Ssl2PackClientMasterKey(
  413. PSsl2_Client_Master_Key pCanonical,
  414. PSPBuffer pCommOutput)
  415. {
  416. DWORD cbMessage;
  417. PSSL2_CLIENT_MASTER_KEY pMessage;
  418. PUCHAR pBuffer;
  419. cbMessage = pCanonical->ClearKeyLen +
  420. pCanonical->EncryptedKeyLen +
  421. pCanonical->KeyArgLen +
  422. SSL_OFFSET_OF(PSSL2_CLIENT_MASTER_KEY, VariantData) -
  423. sizeof(SSL2_MESSAGE_HEADER);
  424. pCommOutput->cbData = cbMessage + 2;
  425. /* are we allocating our own memory? */
  426. if(pCommOutput->pvBuffer == NULL)
  427. {
  428. pCommOutput->pvBuffer = SPExternalAlloc(pCommOutput->cbData);
  429. if (NULL == pCommOutput->pvBuffer)
  430. {
  431. return SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY);
  432. }
  433. pCommOutput->cbBuffer = pCommOutput->cbData;
  434. }
  435. if(pCommOutput->cbData > pCommOutput->cbBuffer)
  436. {
  437. // Required buffer size returned in pCommOutput->cbData.
  438. return SP_LOG_RESULT(PCT_INT_BUFF_TOO_SMALL);
  439. }
  440. pMessage = pCommOutput->pvBuffer;
  441. pBuffer = pMessage->VariantData;
  442. pMessage->Header.Byte0 = MSBOF(cbMessage) | 0x80;
  443. pMessage->Header.Byte1 = LSBOF(cbMessage);
  444. pMessage->MessageId = SSL2_MT_CLIENT_MASTER_KEY;
  445. Ssl2MapCipherToExternal(pCanonical->CipherKind, &pMessage->CipherKind);
  446. pMessage->ClearKeyLenMsb = MSBOF(pCanonical->ClearKeyLen);
  447. pMessage->ClearKeyLenLsb = LSBOF(pCanonical->ClearKeyLen);
  448. CopyMemory(pBuffer, pCanonical->ClearKey, pCanonical->ClearKeyLen);
  449. pBuffer += pCanonical->ClearKeyLen;
  450. pMessage->EncryptedKeyLenMsb = MSBOF(pCanonical->EncryptedKeyLen);
  451. pMessage->EncryptedKeyLenLsb = LSBOF(pCanonical->EncryptedKeyLen);
  452. CopyMemory(pBuffer, pCanonical->pbEncryptedKey, pCanonical->EncryptedKeyLen);
  453. pBuffer += pCanonical->EncryptedKeyLen;
  454. pMessage->KeyArgLenMsb = MSBOF(pCanonical->KeyArgLen);
  455. pMessage->KeyArgLenLsb = LSBOF(pCanonical->KeyArgLen);
  456. CopyMemory(pBuffer, pCanonical->KeyArg, pCanonical->KeyArgLen);
  457. return(PCT_ERR_OK);
  458. }
  459. SP_STATUS
  460. Ssl2UnpackClientMasterKey(
  461. PSPBuffer pInput,
  462. PSsl2_Client_Master_Key * ppClient)
  463. {
  464. PSsl2_Client_Master_Key pCanonical;
  465. PSSL2_CLIENT_MASTER_KEY pMessage;
  466. PUCHAR pBuffer;
  467. DWORD ReportedSize;
  468. DWORD EncryptedKeyLen;
  469. pMessage = pInput->pvBuffer;
  470. if(pInput->cbData < 2)
  471. {
  472. pInput->cbData = 2;
  473. return PCT_INT_INCOMPLETE_MSG;
  474. }
  475. ReportedSize = SIZEOF(pMessage);
  476. if ((ReportedSize+2) > pInput->cbData)
  477. {
  478. pInput->cbData = ReportedSize+2;
  479. return PCT_INT_INCOMPLETE_MSG;
  480. }
  481. if(ReportedSize + 2 < SSL_OFFSET_OF(PSSL2_CLIENT_MASTER_KEY, VariantData))
  482. {
  483. return SP_LOG_RESULT(PCT_ERR_ILLEGAL_MESSAGE);
  484. }
  485. *ppClient = NULL;
  486. if ((pMessage->MessageId != SSL2_MT_CLIENT_MASTER_KEY))
  487. {
  488. return SP_LOG_RESULT(PCT_ERR_ILLEGAL_MESSAGE);
  489. }
  490. EncryptedKeyLen = COMBINEBYTES( pMessage->EncryptedKeyLenMsb,
  491. pMessage->EncryptedKeyLenLsb );
  492. if(ReportedSize + 2 < SSL_OFFSET_OF(PSSL2_CLIENT_MASTER_KEY, VariantData) +
  493. EncryptedKeyLen)
  494. {
  495. return SP_LOG_RESULT(PCT_ERR_ILLEGAL_MESSAGE);
  496. }
  497. pCanonical = (PSsl2_Client_Master_Key)SPExternalAlloc(
  498. sizeof(Ssl2_Client_Master_Key) +
  499. EncryptedKeyLen);
  500. if (!pCanonical)
  501. {
  502. return SP_LOG_RESULT( PCT_INT_INTERNAL_ERROR );
  503. }
  504. pCanonical->CipherKind = Ssl2MapCipherFromExternal( &pMessage->CipherKind );
  505. pCanonical->ClearKeyLen = COMBINEBYTES( pMessage->ClearKeyLenMsb,
  506. pMessage->ClearKeyLenLsb );
  507. pCanonical->EncryptedKeyLen = EncryptedKeyLen;
  508. pCanonical->KeyArgLen = COMBINEBYTES( pMessage->KeyArgLenMsb,
  509. pMessage->KeyArgLenLsb );
  510. //
  511. // Validate
  512. //
  513. if ((pCanonical->ClearKeyLen > SSL2_MASTER_KEY_SIZE) ||
  514. (pCanonical->KeyArgLen > SSL2_MAX_KEY_ARGS))
  515. {
  516. SPExternalFree(pCanonical);
  517. return SP_LOG_RESULT(PCT_ERR_ILLEGAL_MESSAGE);
  518. }
  519. if ((SSL_OFFSET_OF(PSSL2_CLIENT_MASTER_KEY, VariantData) -
  520. sizeof(SSL2_MESSAGE_HEADER) +
  521. pCanonical->ClearKeyLen +
  522. pCanonical->EncryptedKeyLen +
  523. pCanonical->KeyArgLen ) !=
  524. ReportedSize)
  525. {
  526. SPExternalFree(pCanonical);
  527. return SP_LOG_RESULT(PCT_ERR_ILLEGAL_MESSAGE);
  528. }
  529. pBuffer = pMessage->VariantData;
  530. CopyMemory(pCanonical->ClearKey, pBuffer, pCanonical->ClearKeyLen );
  531. pBuffer += pCanonical->ClearKeyLen;
  532. pCanonical->pbEncryptedKey = (PBYTE)(pCanonical + 1);
  533. CopyMemory(pCanonical->pbEncryptedKey, pBuffer, pCanonical->EncryptedKeyLen );
  534. pBuffer += pCanonical->EncryptedKeyLen;
  535. CopyMemory( pCanonical->KeyArg, pBuffer, pCanonical->KeyArgLen );
  536. *ppClient = pCanonical;
  537. return( PCT_ERR_OK );
  538. }