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.

1068 lines
26 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Copyright (c) 1997-1999 Microsoft Corporation
  4. //
  5. // File:
  6. //
  7. // Contents:
  8. //
  9. // History:
  10. //
  11. //---------------------------------------------------------------------------
  12. #include "precomp.h"
  13. ///////////////////////////////////////////////////////////////////////////////
  14. VOID
  15. CopyBinaryBlob(
  16. PBYTE pbBuffer,
  17. PBinary_Blob pbbBlob,
  18. DWORD * pdwCount )
  19. {
  20. *pdwCount = 0;
  21. //
  22. // First copy the wBlobType data;
  23. //
  24. memcpy( pbBuffer, &pbbBlob->wBlobType, sizeof( WORD ) );
  25. pbBuffer += sizeof( WORD );
  26. *pdwCount += sizeof( WORD );
  27. //
  28. // Copy the wBlobLen data
  29. //
  30. memcpy( pbBuffer, &pbbBlob->wBlobLen, sizeof( WORD ) );
  31. pbBuffer += sizeof( WORD );
  32. *pdwCount += sizeof( WORD );
  33. if( 0 == pbbBlob->wBlobLen )
  34. {
  35. return;
  36. }
  37. //
  38. // Copy the actual data
  39. //
  40. memcpy( pbBuffer, pbbBlob->pBlob, pbbBlob->wBlobLen );
  41. *pdwCount += pbbBlob->wBlobLen;
  42. }
  43. ///////////////////////////////////////////////////////////////////////////////
  44. LICENSE_STATUS
  45. GetBinaryBlob(
  46. PBinary_Blob pBBlob,
  47. PBYTE pMessage,
  48. PDWORD pcbProcessed )
  49. {
  50. PBinary_Blob pBB;
  51. LICENSE_STATUS Status;
  52. pBB = ( PBinary_Blob )pMessage;
  53. pBBlob->wBlobType = pBB->wBlobType;
  54. pBBlob->wBlobLen = pBB->wBlobLen;
  55. pBBlob->pBlob = NULL;
  56. *pcbProcessed = 2 * ( sizeof( WORD ) );
  57. if( 0 == pBBlob->wBlobLen )
  58. {
  59. return( LICENSE_STATUS_OK );
  60. }
  61. //
  62. // Check that strings are NULL terminated
  63. //
  64. switch (pBB->wBlobType)
  65. {
  66. case BB_CLIENT_USER_NAME_BLOB:
  67. case BB_CLIENT_MACHINE_NAME_BLOB:
  68. if ('\0' != pMessage[(2 * sizeof(WORD)) + (pBB->wBlobLen) - 1])
  69. {
  70. __try
  71. {
  72. //
  73. // Handle bug in old client, where length is off by one
  74. //
  75. if ('\0' == pMessage[(2 * sizeof(WORD)) + pBB->wBlobLen])
  76. {
  77. pBBlob->wBlobLen++;
  78. break;
  79. }
  80. }
  81. __except( EXCEPTION_EXECUTE_HANDLER )
  82. {
  83. return( LICENSE_STATUS_INVALID_INPUT );
  84. }
  85. //
  86. // Handle WTB client bug - send wrong data size.
  87. // At this stage of licensing, we don't really care about
  88. // client's machine and user name
  89. //
  90. pMessage[(2 * sizeof(WORD)) + (pBB->wBlobLen) - 1] = '\0';
  91. if(!(pBB->wBlobLen & 0x01))
  92. {
  93. //
  94. // Even length, assuming UNICODE, wBlobLen must > 1 to
  95. // come to here
  96. //
  97. pMessage[(2 * sizeof(WORD)) + (pBB->wBlobLen) - 2] = '\0';
  98. }
  99. //return( LICENSE_STATUS_INVALID_INPUT );
  100. }
  101. break;
  102. }
  103. //
  104. // allocate memory for and copy the actual data
  105. //
  106. if( BB_CLIENT_USER_NAME_BLOB == pBB->wBlobType ||
  107. BB_CLIENT_MACHINE_NAME_BLOB == pBB->wBlobType )
  108. {
  109. // WINCE client sends UNICODE, add extra NULL at the end
  110. Status = LicenseMemoryAllocate( ( DWORD )pBBlob->wBlobLen + sizeof(WCHAR), &(pBBlob->pBlob) );
  111. }
  112. else
  113. {
  114. Status = LicenseMemoryAllocate( ( DWORD )pBBlob->wBlobLen, &(pBBlob->pBlob) );
  115. }
  116. if( LICENSE_STATUS_OK != Status )
  117. {
  118. return( Status );
  119. }
  120. __try
  121. {
  122. memcpy( pBBlob->pBlob, pMessage + ( 2 * sizeof( WORD ) ), pBBlob->wBlobLen );
  123. }
  124. __except( EXCEPTION_EXECUTE_HANDLER )
  125. {
  126. LicenseMemoryFree( &pBBlob->pBlob );
  127. return( LICENSE_STATUS_INVALID_INPUT );
  128. }
  129. *pcbProcessed += ( DWORD )pBBlob->wBlobLen;
  130. return( LICENSE_STATUS_OK );
  131. }
  132. ///////////////////////////////////////////////////////////////////////////////
  133. VOID
  134. FreeBinaryBlob(
  135. PBinary_Blob pBlob )
  136. {
  137. if( pBlob->pBlob )
  138. {
  139. LicenseMemoryFree( &pBlob->pBlob );
  140. pBlob->wBlobLen = 0;
  141. }
  142. return;
  143. }
  144. ///////////////////////////////////////////////////////////////////////////////
  145. LICENSE_STATUS
  146. PackHydraServerLicenseRequest(
  147. DWORD dwProtocolVersion,
  148. PHydra_Server_License_Request pCanonical,
  149. PBYTE* ppNetwork,
  150. DWORD* pcbNetwork )
  151. {
  152. Preamble Header;
  153. DWORD i, cbCopied;
  154. PBinary_Blob pBlob;
  155. LICENSE_STATUS Status = LICENSE_STATUS_OK;
  156. PBYTE pNetworkBuf;
  157. ASSERT( pCanonical );
  158. if( ( NULL == pCanonical ) ||
  159. ( NULL == pcbNetwork ) ||
  160. ( NULL == ppNetwork ) )
  161. {
  162. return( LICENSE_STATUS_INVALID_INPUT );
  163. }
  164. //
  165. // calculate the size needed for network format
  166. //
  167. Header.wMsgSize = (WORD)(sizeof( Preamble ) +
  168. LICENSE_RANDOM +
  169. sizeof( DWORD ) +
  170. sizeof( DWORD ) + pCanonical->ProductInfo.cbCompanyName +
  171. sizeof( DWORD ) + pCanonical->ProductInfo.cbProductID +
  172. GetBinaryBlobSize( pCanonical->KeyExchngList ) +
  173. GetBinaryBlobSize( pCanonical->ServerCert ) +
  174. sizeof( DWORD ) +
  175. ( pCanonical->ScopeList.dwScopeCount * ( sizeof( WORD ) + sizeof( WORD ) ) ) );
  176. for( i = 0, pBlob = pCanonical->ScopeList.Scopes;
  177. i < pCanonical->ScopeList.dwScopeCount;
  178. i++ )
  179. {
  180. Header.wMsgSize += pBlob->wBlobLen;
  181. pBlob++;
  182. }
  183. //
  184. // allocate the output buffer
  185. //
  186. Status = LicenseMemoryAllocate( Header.wMsgSize, ppNetwork );
  187. if( LICENSE_STATUS_OK != Status )
  188. {
  189. goto PackError;
  190. }
  191. *pcbNetwork = Header.wMsgSize;
  192. pNetworkBuf = *ppNetwork;
  193. //
  194. // copy the header
  195. //
  196. Header.bMsgType = HS_LICENSE_REQUEST;
  197. Header.bVersion = GET_PREAMBLE_VERSION( dwProtocolVersion );
  198. memcpy( pNetworkBuf, &Header, sizeof( Preamble ) );
  199. pNetworkBuf += sizeof( Preamble );
  200. //
  201. // copy the server random number
  202. //
  203. memcpy( pNetworkBuf, pCanonical->ServerRandom, LICENSE_RANDOM );
  204. pNetworkBuf += LICENSE_RANDOM;
  205. //
  206. // copy the product info
  207. //
  208. memcpy( pNetworkBuf, &pCanonical->ProductInfo.dwVersion, sizeof( DWORD ) );
  209. pNetworkBuf += sizeof( DWORD );
  210. memcpy( pNetworkBuf, &pCanonical->ProductInfo.cbCompanyName, sizeof( DWORD ) );
  211. pNetworkBuf += sizeof( DWORD );
  212. memcpy( pNetworkBuf, pCanonical->ProductInfo.pbCompanyName,
  213. pCanonical->ProductInfo.cbCompanyName );
  214. pNetworkBuf += pCanonical->ProductInfo.cbCompanyName;
  215. memcpy( pNetworkBuf, &pCanonical->ProductInfo.cbProductID, sizeof( DWORD ) );
  216. pNetworkBuf += sizeof( DWORD );
  217. memcpy( pNetworkBuf, pCanonical->ProductInfo.pbProductID,
  218. pCanonical->ProductInfo.cbProductID );
  219. pNetworkBuf += pCanonical->ProductInfo.cbProductID;
  220. //
  221. // copy the key exchange list
  222. //
  223. CopyBinaryBlob( pNetworkBuf, &pCanonical->KeyExchngList, &cbCopied );
  224. pNetworkBuf += cbCopied;
  225. //
  226. // copy the hydra server certificate
  227. //
  228. CopyBinaryBlob( pNetworkBuf, &pCanonical->ServerCert, &cbCopied );
  229. pNetworkBuf += cbCopied;
  230. //
  231. // copy the scope list
  232. //
  233. memcpy( pNetworkBuf, &pCanonical->ScopeList.dwScopeCount, sizeof( DWORD ) );
  234. pNetworkBuf += sizeof( DWORD );
  235. for( i = 0, pBlob = pCanonical->ScopeList.Scopes;
  236. i < pCanonical->ScopeList.dwScopeCount;
  237. i++ )
  238. {
  239. CopyBinaryBlob( pNetworkBuf, pBlob, &cbCopied );
  240. pNetworkBuf += cbCopied;
  241. pBlob++;
  242. }
  243. PackError:
  244. return( Status );
  245. }
  246. ///////////////////////////////////////////////////////////////////////////////
  247. LICENSE_STATUS
  248. PackHydraServerPlatformChallenge(
  249. DWORD dwProtocolVersion,
  250. PHydra_Server_Platform_Challenge pCanonical,
  251. PBYTE* ppNetwork,
  252. DWORD* pcbNetwork )
  253. {
  254. Preamble Header;
  255. DWORD cbCopied;
  256. PBinary_Blob pBlob;
  257. LICENSE_STATUS Status = LICENSE_STATUS_OK;
  258. PBYTE pNetworkBuf;
  259. ASSERT( pCanonical );
  260. ASSERT( pcbNetwork );
  261. ASSERT( ppNetwork );
  262. if( ( NULL == pCanonical ) ||
  263. ( NULL == pcbNetwork ) ||
  264. ( NULL == ppNetwork ) )
  265. {
  266. return( LICENSE_STATUS_INVALID_INPUT );
  267. }
  268. //
  269. // calculate the buffer size needed
  270. //
  271. Header.wMsgSize = sizeof( Preamble ) +
  272. sizeof( DWORD ) +
  273. GetBinaryBlobSize( pCanonical->EncryptedPlatformChallenge ) +
  274. LICENSE_MAC_DATA;
  275. //
  276. // allocate the output buffer
  277. //
  278. Status = LicenseMemoryAllocate( Header.wMsgSize, ppNetwork );
  279. if( LICENSE_STATUS_OK != Status )
  280. {
  281. goto PackError;
  282. }
  283. *pcbNetwork = Header.wMsgSize;
  284. pNetworkBuf = *ppNetwork;
  285. //
  286. // copy the header
  287. //
  288. Header.bMsgType = HS_PLATFORM_CHALLENGE;
  289. Header.bVersion = GET_PREAMBLE_VERSION( dwProtocolVersion );
  290. memcpy( pNetworkBuf, &Header, sizeof( Preamble ) );
  291. pNetworkBuf += sizeof( Preamble );
  292. //
  293. // copy the connect flag
  294. //
  295. memcpy( pNetworkBuf, &pCanonical->dwConnectFlags, sizeof( DWORD ) );
  296. pNetworkBuf += sizeof( DWORD );
  297. //
  298. // copy the encrypted platform challenge
  299. //
  300. CopyBinaryBlob( pNetworkBuf, &pCanonical->EncryptedPlatformChallenge, &cbCopied );
  301. pNetworkBuf += cbCopied;
  302. //
  303. // copy the MAC
  304. //
  305. memcpy( pNetworkBuf, pCanonical->MACData, LICENSE_MAC_DATA );
  306. PackError:
  307. return( Status );
  308. }
  309. ///////////////////////////////////////////////////////////////////////////////
  310. LICENSE_STATUS
  311. PackHydraServerNewLicense(
  312. DWORD dwProtocolVersion,
  313. PHydra_Server_New_License pCanonical,
  314. PBYTE* ppNetwork,
  315. DWORD* pcbNetwork )
  316. {
  317. Preamble Header;
  318. DWORD cbCopied;
  319. PBinary_Blob pBlob;
  320. LICENSE_STATUS Status = LICENSE_STATUS_OK;
  321. PBYTE pNetworkBuf;
  322. ASSERT( pCanonical );
  323. ASSERT( pcbNetwork );
  324. ASSERT( ppNetwork );
  325. if( ( NULL == pCanonical ) ||
  326. ( NULL == pcbNetwork ) ||
  327. ( NULL == ppNetwork ) )
  328. {
  329. return( LICENSE_STATUS_INVALID_INPUT );
  330. }
  331. //
  332. // calculate the buffer size needed
  333. //
  334. Header.wMsgSize = sizeof( Preamble ) +
  335. GetBinaryBlobSize( pCanonical->EncryptedNewLicenseInfo ) +
  336. LICENSE_MAC_DATA;
  337. //
  338. // allocate the output buffer
  339. //
  340. Status = LicenseMemoryAllocate( Header.wMsgSize, ppNetwork );
  341. if( LICENSE_STATUS_OK != Status )
  342. {
  343. goto PackError;
  344. }
  345. *pcbNetwork = Header.wMsgSize;
  346. pNetworkBuf = *ppNetwork;
  347. //
  348. // copy the header
  349. //
  350. Header.bMsgType = HS_NEW_LICENSE;
  351. Header.bVersion = GET_PREAMBLE_VERSION( dwProtocolVersion );
  352. memcpy( pNetworkBuf, &Header, sizeof( Preamble ) );
  353. pNetworkBuf += sizeof( Preamble );
  354. //
  355. // copy the encrypted new license info
  356. //
  357. CopyBinaryBlob( pNetworkBuf, &pCanonical->EncryptedNewLicenseInfo, &cbCopied );
  358. pNetworkBuf += cbCopied;
  359. //
  360. // copy the MAC
  361. //
  362. memcpy( pNetworkBuf, pCanonical->MACData, LICENSE_MAC_DATA );
  363. PackError:
  364. return( Status );
  365. }
  366. ///////////////////////////////////////////////////////////////////////////////
  367. LICENSE_STATUS
  368. PackHydraServerUpgradeLicense(
  369. DWORD dwProtocolVersion,
  370. PHydra_Server_Upgrade_License pCanonical,
  371. PBYTE* ppNetwork,
  372. DWORD* pcbNetwork )
  373. {
  374. LICENSE_STATUS Status;
  375. PPreamble pHeader;
  376. Status = PackHydraServerNewLicense( dwProtocolVersion, pCanonical, ppNetwork, pcbNetwork );
  377. if( LICENSE_STATUS_OK == Status )
  378. {
  379. //
  380. // make this an upgrade license message
  381. //
  382. pHeader = ( PPreamble )*ppNetwork;
  383. pHeader->bMsgType = HS_UPGRADE_LICENSE;
  384. }
  385. return( Status );
  386. }
  387. ///////////////////////////////////////////////////////////////////////////////
  388. LICENSE_STATUS
  389. PackHydraServerErrorMessage(
  390. DWORD dwProtocolVersion,
  391. PLicense_Error_Message pCanonical,
  392. PBYTE* ppNetwork,
  393. DWORD* pcbNetwork )
  394. {
  395. Preamble Header;
  396. DWORD cbCopied;
  397. PBinary_Blob pBlob;
  398. LICENSE_STATUS Status = LICENSE_STATUS_OK;
  399. PBYTE pNetworkBuf;
  400. ASSERT( pCanonical );
  401. ASSERT( pcbNetwork );
  402. ASSERT( ppNetwork );
  403. if( ( NULL == pCanonical ) ||
  404. ( NULL == pcbNetwork ) ||
  405. ( NULL == ppNetwork ) )
  406. {
  407. return( LICENSE_STATUS_INVALID_INPUT );
  408. }
  409. //
  410. // calculate the buffer size needed
  411. //
  412. Header.wMsgSize = sizeof( Preamble ) +
  413. sizeof( DWORD ) +
  414. sizeof( DWORD ) +
  415. GetBinaryBlobSize( pCanonical->bbErrorInfo );
  416. //
  417. // allocate the output buffer
  418. //
  419. Status = LicenseMemoryAllocate( Header.wMsgSize, ppNetwork );
  420. if( LICENSE_STATUS_OK != Status )
  421. {
  422. goto PackError;
  423. }
  424. *pcbNetwork = Header.wMsgSize;
  425. pNetworkBuf = *ppNetwork;
  426. //
  427. // set up preamble
  428. //
  429. Header.bMsgType = GM_ERROR_ALERT;
  430. Header.bVersion = GET_PREAMBLE_VERSION( dwProtocolVersion );
  431. memcpy( pNetworkBuf, &Header, sizeof( Preamble ) );
  432. pNetworkBuf += sizeof( Preamble );
  433. //
  434. // copy the error code, state transition and error info
  435. //
  436. memcpy( pNetworkBuf, &pCanonical->dwErrorCode, sizeof( DWORD ) );
  437. pNetworkBuf += sizeof( DWORD );
  438. memcpy( pNetworkBuf, &pCanonical->dwStateTransition, sizeof( DWORD ) );
  439. pNetworkBuf += sizeof( DWORD );
  440. CopyBinaryBlob( pNetworkBuf, &pCanonical->bbErrorInfo, &cbCopied );
  441. PackError:
  442. return( Status );
  443. }
  444. ///////////////////////////////////////////////////////////////////////////////
  445. LICENSE_STATUS
  446. PackNewLicenseInfo(
  447. PNew_License_Info pCanonical,
  448. PBYTE* ppNetwork,
  449. DWORD* pcbNetwork )
  450. {
  451. DWORD cbBufNeeded;
  452. PBYTE pNetworkBuf;
  453. LICENSE_STATUS Status = LICENSE_STATUS_OK;
  454. ASSERT( pCanonical );
  455. ASSERT( pcbNetwork );
  456. ASSERT( ppNetwork );
  457. if( ( NULL == pCanonical ) ||
  458. ( NULL == pcbNetwork ) ||
  459. ( NULL == ppNetwork ) )
  460. {
  461. return( LICENSE_STATUS_INVALID_INPUT );
  462. }
  463. //
  464. // calculate the buffer size needed and check that the output
  465. // buffer is large enough
  466. //
  467. cbBufNeeded = 5 * sizeof( DWORD ) +
  468. pCanonical->cbScope +
  469. pCanonical->cbCompanyName +
  470. pCanonical->cbProductID +
  471. pCanonical->cbLicenseInfo;
  472. //
  473. // allocate the output buffer
  474. //
  475. Status = LicenseMemoryAllocate( cbBufNeeded, ppNetwork );
  476. if( LICENSE_STATUS_OK != Status )
  477. {
  478. goto done;
  479. }
  480. *pcbNetwork = cbBufNeeded;
  481. pNetworkBuf = *ppNetwork;
  482. //
  483. // start copying the data
  484. //
  485. memcpy( pNetworkBuf, &pCanonical->dwVersion, sizeof( DWORD ) );
  486. pNetworkBuf += sizeof( DWORD );
  487. memcpy( pNetworkBuf, &pCanonical->cbScope, sizeof( DWORD ) );
  488. pNetworkBuf += sizeof( DWORD );
  489. memcpy( pNetworkBuf, pCanonical->pbScope, pCanonical->cbScope );
  490. pNetworkBuf += pCanonical->cbScope;
  491. memcpy( pNetworkBuf, &pCanonical->cbCompanyName, sizeof( DWORD ) );
  492. pNetworkBuf += sizeof( DWORD );
  493. memcpy( pNetworkBuf, pCanonical->pbCompanyName, pCanonical->cbCompanyName );
  494. pNetworkBuf += pCanonical->cbCompanyName;
  495. memcpy( pNetworkBuf, &pCanonical->cbProductID, sizeof( DWORD ) );
  496. pNetworkBuf += sizeof( DWORD );
  497. memcpy( pNetworkBuf, pCanonical->pbProductID, pCanonical->cbProductID );
  498. pNetworkBuf += pCanonical->cbProductID;
  499. memcpy( pNetworkBuf, &pCanonical->cbLicenseInfo, sizeof( DWORD ) );
  500. pNetworkBuf += sizeof( DWORD );
  501. memcpy( pNetworkBuf, pCanonical->pbLicenseInfo, pCanonical->cbLicenseInfo );
  502. pNetworkBuf += pCanonical->cbLicenseInfo;
  503. done:
  504. return( Status );
  505. }
  506. ///////////////////////////////////////////////////////////////////////////////
  507. // Functions for unpacking different Hydra Client Messages from
  508. // simple binary blobs to corresponding structure
  509. //
  510. ///////////////////////////////////////////////////////////////////////////////
  511. LICENSE_STATUS
  512. UnPackHydraClientErrorMessage(
  513. PBYTE pbMessage,
  514. DWORD cbMessage,
  515. PLicense_Error_Message pCanonical )
  516. {
  517. DWORD cbUnpacked = 0;
  518. LICENSE_STATUS Status = LICENSE_STATUS_OK;
  519. PPreamble pHeader;
  520. PBYTE pNetwork;
  521. DWORD cbProcessed = 0;
  522. //
  523. // check the input parameters
  524. //
  525. ASSERT( NULL != pbMessage );
  526. ASSERT( 0 < cbMessage );
  527. ASSERT( NULL != pCanonical );
  528. if( ( NULL == pbMessage ) ||
  529. ( 0 >= cbMessage ) ||
  530. ( NULL == pCanonical ) )
  531. {
  532. return( LICENSE_STATUS_INVALID_INPUT );
  533. }
  534. //
  535. // check the preamble
  536. //
  537. pHeader = ( PPreamble )pbMessage;
  538. if( GM_ERROR_ALERT != pHeader->bMsgType )
  539. {
  540. #if DBG
  541. DbgPrint( "UnPackHydraClientErrorMessage: received unexpected message type %c\n", pHeader->bMsgType );
  542. #endif
  543. return( LICENSE_STATUS_INVALID_RESPONSE );
  544. }
  545. //
  546. // do a calculation of the fixed field length
  547. //
  548. cbUnpacked = sizeof( Preamble ) + 2 * sizeof( DWORD );
  549. ASSERT( pHeader->wMsgSize >= ( WORD )cbUnpacked );
  550. //
  551. // get the license error structure
  552. //
  553. pNetwork = pbMessage + sizeof( Preamble );
  554. memcpy( &pCanonical->dwErrorCode, pNetwork, sizeof( DWORD ) );
  555. pNetwork += sizeof( DWORD );
  556. memcpy( &pCanonical->dwStateTransition, pNetwork, sizeof( DWORD ) );
  557. pNetwork += sizeof( DWORD );
  558. Status = GetBinaryBlob( &( pCanonical->bbErrorInfo ), pNetwork, &cbProcessed );
  559. if( LICENSE_STATUS_OK != Status )
  560. {
  561. return( Status );
  562. }
  563. cbUnpacked += cbProcessed;
  564. ASSERT( pHeader->wMsgSize == ( WORD )cbUnpacked );
  565. return( Status );
  566. }
  567. ///////////////////////////////////////////////////////////////////////////////
  568. LICENSE_STATUS
  569. UnPackHydraClientLicenseInfo(
  570. PBYTE pbMessage,
  571. DWORD cbMessage,
  572. PHydra_Client_License_Info pCanonical )
  573. {
  574. DWORD cbUnpacked = 0;
  575. LICENSE_STATUS Status = LICENSE_STATUS_OK;
  576. PPreamble pHeader;
  577. PBYTE pNetwork;
  578. DWORD cbProcessed = 0;
  579. //
  580. // check the input parameters
  581. //
  582. ASSERT( NULL != pbMessage );
  583. ASSERT( 0 < cbMessage );
  584. ASSERT( NULL != pCanonical );
  585. if( ( NULL == pbMessage ) ||
  586. ( 0 >= cbMessage ) ||
  587. ( NULL == pCanonical ) )
  588. {
  589. return( LICENSE_STATUS_INVALID_INPUT );
  590. }
  591. //
  592. // check the preamble
  593. //
  594. pHeader = ( PPreamble )pbMessage;
  595. if( HC_LICENSE_INFO != pHeader->bMsgType )
  596. {
  597. #if DBG
  598. DbgPrint( "UnPackHydraClientLicenseInfo: received unexpected message type %c\n", pHeader->bMsgType );
  599. #endif
  600. return( LICENSE_STATUS_INVALID_RESPONSE );
  601. }
  602. //
  603. // do a calculation of the fixed field length
  604. //
  605. cbUnpacked = sizeof( Preamble ) +
  606. 2 * sizeof( DWORD ) +
  607. LICENSE_RANDOM +
  608. LICENSE_MAC_DATA;
  609. ASSERT( pHeader->wMsgSize >= ( WORD )cbUnpacked );
  610. //
  611. // get the license info structure
  612. //
  613. pNetwork = pbMessage + sizeof( Preamble );
  614. memcpy( &pCanonical->dwPrefKeyExchangeAlg, pNetwork, sizeof( DWORD ) );
  615. pNetwork += sizeof( DWORD );
  616. memcpy( &pCanonical->dwPlatformID, pNetwork, sizeof( DWORD ) );
  617. pNetwork += sizeof( DWORD );
  618. memcpy( &pCanonical->ClientRandom, pNetwork, LICENSE_RANDOM );
  619. pNetwork += LICENSE_RANDOM;
  620. Status = GetBinaryBlob( &pCanonical->EncryptedPreMasterSecret, pNetwork, &cbProcessed );
  621. if( LICENSE_STATUS_OK != Status )
  622. {
  623. if (Status == LICENSE_STATUS_INVALID_INPUT)
  624. {
  625. Status = LICENSE_STATUS_INVALID_RESPONSE;
  626. }
  627. return( Status );
  628. }
  629. pNetwork += cbProcessed;
  630. cbUnpacked += cbProcessed;
  631. Status = GetBinaryBlob( &pCanonical->LicenseInfo, pNetwork, &cbProcessed );
  632. if( LICENSE_STATUS_OK != Status )
  633. {
  634. if (Status == LICENSE_STATUS_INVALID_INPUT)
  635. {
  636. Status = LICENSE_STATUS_INVALID_RESPONSE;
  637. }
  638. return( Status );
  639. }
  640. pNetwork += cbProcessed;
  641. cbUnpacked += cbProcessed;
  642. Status = GetBinaryBlob( &pCanonical->EncryptedHWID, pNetwork, &cbProcessed );
  643. if( LICENSE_STATUS_OK != Status )
  644. {
  645. if (Status == LICENSE_STATUS_INVALID_INPUT)
  646. {
  647. Status = LICENSE_STATUS_INVALID_RESPONSE;
  648. }
  649. return( Status );
  650. }
  651. pNetwork += cbProcessed;
  652. cbUnpacked += cbProcessed;
  653. memcpy( pCanonical->MACData, pNetwork, LICENSE_MAC_DATA );
  654. ASSERT( pHeader->wMsgSize == ( WORD )cbUnpacked );
  655. return( Status );
  656. }
  657. ///////////////////////////////////////////////////////////////////////////////
  658. LICENSE_STATUS
  659. UnPackHydraClientNewLicenseRequest(
  660. PBYTE pbMessage,
  661. DWORD cbMessage,
  662. PHydra_Client_New_License_Request pCanonical )
  663. {
  664. DWORD cbUnpacked = 0;
  665. LICENSE_STATUS Status = LICENSE_STATUS_OK;
  666. PPreamble pHeader;
  667. PBYTE pNetwork;
  668. DWORD cbProcessed = 0;
  669. //
  670. // check the input parameters
  671. //
  672. ASSERT( NULL != pbMessage );
  673. ASSERT( 0 < cbMessage );
  674. ASSERT( NULL != pCanonical );
  675. if( ( NULL == pbMessage ) ||
  676. ( 0 >= cbMessage ) ||
  677. ( NULL == pCanonical ) )
  678. {
  679. return( LICENSE_STATUS_INVALID_INPUT );
  680. }
  681. //
  682. // check the preamble
  683. //
  684. pHeader = ( PPreamble )pbMessage;
  685. if( HC_NEW_LICENSE_REQUEST != pHeader->bMsgType )
  686. {
  687. #if DBG
  688. DbgPrint( "UnPackHydraClientNewLicenseRequest: received unexpected message type %c\n", pHeader->bMsgType );
  689. #endif
  690. return( LICENSE_STATUS_INVALID_RESPONSE );
  691. }
  692. //
  693. // do a calculation of the fixed field length
  694. //
  695. cbUnpacked = sizeof( Preamble ) +
  696. 2 * sizeof( DWORD ) +
  697. LICENSE_RANDOM;
  698. ASSERT( pHeader->wMsgSize >= ( WORD )cbUnpacked );
  699. //
  700. // get the new license request structure
  701. //
  702. pNetwork = pbMessage + sizeof( Preamble );
  703. memcpy( &pCanonical->dwPrefKeyExchangeAlg, pNetwork, sizeof( DWORD ) );
  704. pNetwork += sizeof( DWORD );
  705. memcpy( &pCanonical->dwPlatformID, pNetwork, sizeof( DWORD ) );
  706. pNetwork += sizeof( DWORD );
  707. memcpy( &pCanonical->ClientRandom, pNetwork, LICENSE_RANDOM );
  708. pNetwork += LICENSE_RANDOM;
  709. Status = GetBinaryBlob( &pCanonical->EncryptedPreMasterSecret, pNetwork, &cbProcessed );
  710. if( LICENSE_STATUS_OK != Status )
  711. {
  712. return( Status );
  713. }
  714. cbUnpacked += cbProcessed;
  715. pNetwork += cbProcessed;
  716. //
  717. // we changed the licensing protocol to include the client user and machine
  718. // name. So to prevent an older client that does not have the user and machine
  719. // name binary blobs from crashing the server, we add this check for the
  720. // message length.
  721. //
  722. if( pHeader->wMsgSize <= cbUnpacked )
  723. {
  724. #if DBG
  725. DbgPrint( "UnPackHydraClientNewLicenseRequest: old licensing protocol\n" );
  726. #endif
  727. pCanonical->ClientUserName.pBlob = NULL;
  728. pCanonical->ClientMachineName.pBlob = NULL;
  729. //
  730. // make these 2 fields optional for now.
  731. //
  732. return( Status );
  733. }
  734. Status = GetBinaryBlob( &pCanonical->ClientUserName, pNetwork, &cbProcessed );
  735. if( LICENSE_STATUS_OK != Status )
  736. {
  737. return( Status );
  738. }
  739. cbUnpacked += cbProcessed;
  740. pNetwork += cbProcessed;
  741. Status = GetBinaryBlob( &pCanonical->ClientMachineName, pNetwork, &cbProcessed );
  742. if( LICENSE_STATUS_OK != Status )
  743. {
  744. return( Status );
  745. }
  746. cbUnpacked += cbProcessed;
  747. ASSERT( pHeader->wMsgSize == ( WORD )cbUnpacked );
  748. return( Status );
  749. }
  750. ///////////////////////////////////////////////////////////////////////////////
  751. LICENSE_STATUS
  752. UnPackHydraClientPlatformChallengeResponse(
  753. PBYTE pbMessage,
  754. DWORD cbMessage,
  755. PHydra_Client_Platform_Challenge_Response pCanonical )
  756. {
  757. DWORD cbUnpacked = 0;
  758. LICENSE_STATUS Status = LICENSE_STATUS_OK;
  759. PPreamble pHeader;
  760. PBYTE pNetwork;
  761. DWORD cbProcessed = 0;
  762. //
  763. // check the input parameters
  764. //
  765. ASSERT( NULL != pbMessage );
  766. ASSERT( 0 < cbMessage );
  767. ASSERT( NULL != pCanonical );
  768. if( ( NULL == pbMessage ) ||
  769. ( 0 >= cbMessage ) ||
  770. ( NULL == pCanonical ) )
  771. {
  772. return( LICENSE_STATUS_INVALID_INPUT );
  773. }
  774. //
  775. // check the preamble
  776. //
  777. pHeader = ( PPreamble )pbMessage;
  778. if( HC_PLATFORM_CHALENGE_RESPONSE != pHeader->bMsgType )
  779. {
  780. #if DBG
  781. DbgPrint( "UnPackHydraClientPlatformChallengeResponse: received unexpected message type %c\n", pHeader->bMsgType );
  782. #endif
  783. return( LICENSE_STATUS_INVALID_RESPONSE );
  784. }
  785. //
  786. // do a calculation of the fixed field length
  787. //
  788. cbUnpacked = sizeof( Preamble ) +
  789. LICENSE_MAC_DATA;
  790. ASSERT( pHeader->wMsgSize >= ( WORD )cbUnpacked );
  791. //
  792. // get the platform challenge response structure
  793. //
  794. pNetwork = pbMessage + sizeof( Preamble );
  795. Status = GetBinaryBlob( &pCanonical->EncryptedChallengeResponse, pNetwork, &cbProcessed );
  796. if( LICENSE_STATUS_OK != Status )
  797. {
  798. return( Status );
  799. }
  800. pNetwork += cbProcessed;
  801. cbUnpacked += cbProcessed;
  802. Status = GetBinaryBlob( &pCanonical->EncryptedHWID, pNetwork, &cbProcessed );
  803. if( LICENSE_STATUS_OK != Status )
  804. {
  805. return( Status );
  806. }
  807. pNetwork += cbProcessed;
  808. cbUnpacked += cbProcessed;
  809. memcpy( pCanonical->MACData, pNetwork, LICENSE_MAC_DATA );
  810. ASSERT( pHeader->wMsgSize == ( WORD )cbUnpacked );
  811. return( Status );
  812. }