|
|
//+--------------------------------------------------------------------------
//
// Copyright (c) 1997-1999 Microsoft Corporation
//
// File:
//
// Contents:
//
// History:
//
//---------------------------------------------------------------------------
#include "precomp.h"
#define EXTENDED_ERROR_CAPABILITY 0x80
///////////////////////////////////////////////////////////////////////////////
VOID CopyBinaryBlob( PBYTE pbBuffer, PBinary_Blob pbbBlob, DWORD * pdwCount ) { *pdwCount = 0;
//
// First copy the wBlobType data;
//
memcpy( pbBuffer, &pbbBlob->wBlobType, sizeof( WORD ) ); pbBuffer += sizeof( WORD ); *pdwCount += sizeof( WORD );
//
// Copy the wBlobLen data
//
memcpy( pbBuffer, &pbbBlob->wBlobLen, sizeof( WORD ) ); pbBuffer += sizeof( WORD ); *pdwCount += sizeof( WORD );
if( 0 == pbbBlob->wBlobLen ) { return; }
//
// Copy the actual data
//
memcpy( pbBuffer, pbbBlob->pBlob, pbbBlob->wBlobLen ); *pdwCount += pbbBlob->wBlobLen;
}
///////////////////////////////////////////////////////////////////////////////
LICENSE_STATUS GetBinaryBlob( PBinary_Blob pBBlob, DWORD dwMsgSize, PBYTE pMessage, PDWORD pcbProcessed ) { PBinary_Blob pBB; LICENSE_STATUS Status;
if(dwMsgSize < 2 * sizeof(WORD)) { return( LICENSE_STATUS_INVALID_INPUT ); }
pBB = ( PBinary_Blob )pMessage; pBBlob->wBlobType = pBB->wBlobType; pBBlob->wBlobLen = pBB->wBlobLen; pBBlob->pBlob = NULL;
*pcbProcessed = 2 * ( sizeof( WORD ) ); if( 0 == pBBlob->wBlobLen ) { return( LICENSE_STATUS_OK ); }
if(dwMsgSize < (2 * sizeof(WORD)) + pBB->wBlobLen) { return( LICENSE_STATUS_INVALID_INPUT ); }
//
// Check that strings are NULL terminated
//
switch (pBB->wBlobType) { case BB_CLIENT_USER_NAME_BLOB: case BB_CLIENT_MACHINE_NAME_BLOB: if ('\0' != pMessage[(2 * sizeof(WORD)) + (pBB->wBlobLen) - 1]) { __try { //
// Handle bug in old client, where length is off by one
//
if ('\0' == pMessage[(2 * sizeof(WORD)) + pBB->wBlobLen]) { pBBlob->wBlobLen++; break; } } __except( EXCEPTION_EXECUTE_HANDLER ) { return( LICENSE_STATUS_INVALID_INPUT ); }
//
// Handle WTB client bug - send wrong data size.
// At this stage of licensing, we don't really care about
// client's machine and user name
//
pMessage[(2 * sizeof(WORD)) + (pBB->wBlobLen) - 1] = '\0'; if(!(pBB->wBlobLen & 0x01)) { //
// Even length, assuming UNICODE, wBlobLen must > 1 to
// come to here
//
pMessage[(2 * sizeof(WORD)) + (pBB->wBlobLen) - 2] = '\0'; } //return( LICENSE_STATUS_INVALID_INPUT );
} break; }
//
// allocate memory for and copy the actual data
//
if( BB_CLIENT_USER_NAME_BLOB == pBB->wBlobType || BB_CLIENT_MACHINE_NAME_BLOB == pBB->wBlobType ) { // WINCE client sends UNICODE, add extra NULL at the end
Status = LicenseMemoryAllocate( ( DWORD )pBBlob->wBlobLen + sizeof(WCHAR), &(pBBlob->pBlob) ); } else { Status = LicenseMemoryAllocate( ( DWORD )pBBlob->wBlobLen, &(pBBlob->pBlob) ); }
if( LICENSE_STATUS_OK != Status ) { return( Status ); } __try { memcpy( pBBlob->pBlob, pMessage + ( 2 * sizeof( WORD ) ), pBBlob->wBlobLen ); } __except( EXCEPTION_EXECUTE_HANDLER ) { LicenseMemoryFree( &pBBlob->pBlob );
return( LICENSE_STATUS_INVALID_INPUT ); }
*pcbProcessed += ( DWORD )pBBlob->wBlobLen;
return( LICENSE_STATUS_OK ); }
///////////////////////////////////////////////////////////////////////////////
VOID FreeBinaryBlob( PBinary_Blob pBlob ) { if( pBlob->pBlob ) { LicenseMemoryFree( &pBlob->pBlob ); pBlob->wBlobLen = 0; }
return; }
///////////////////////////////////////////////////////////////////////////////
LICENSE_STATUS PackHydraServerLicenseRequest( DWORD dwProtocolVersion, PHydra_Server_License_Request pCanonical, PBYTE* ppNetwork, DWORD* pcbNetwork ) { Preamble Header; DWORD i, cbCopied; PBinary_Blob pBlob; LICENSE_STATUS Status = LICENSE_STATUS_OK; PBYTE pNetworkBuf;
ASSERT( pCanonical ); if( ( NULL == pCanonical ) || ( NULL == pcbNetwork ) || ( NULL == ppNetwork ) ) { return( LICENSE_STATUS_INVALID_INPUT ); }
//
// calculate the size needed for network format
//
Header.wMsgSize = (WORD)(sizeof( Preamble ) + LICENSE_RANDOM + sizeof( DWORD ) + sizeof( DWORD ) + pCanonical->ProductInfo.cbCompanyName + sizeof( DWORD ) + pCanonical->ProductInfo.cbProductID + GetBinaryBlobSize( pCanonical->KeyExchngList ) + GetBinaryBlobSize( pCanonical->ServerCert ) + sizeof( DWORD ) + ( pCanonical->ScopeList.dwScopeCount * ( sizeof( WORD ) + sizeof( WORD ) ) ) );
for( i = 0, pBlob = pCanonical->ScopeList.Scopes; i < pCanonical->ScopeList.dwScopeCount; i++ ) { Header.wMsgSize += pBlob->wBlobLen; pBlob++; }
//
// allocate the output buffer
//
Status = LicenseMemoryAllocate( Header.wMsgSize, ppNetwork );
if( LICENSE_STATUS_OK != Status ) { goto PackError; }
*pcbNetwork = Header.wMsgSize; pNetworkBuf = *ppNetwork;
//
// copy the header
//
Header.bMsgType = HS_LICENSE_REQUEST; Header.bVersion = GET_PREAMBLE_VERSION( dwProtocolVersion );
memcpy( pNetworkBuf, &Header, sizeof( Preamble ) ); pNetworkBuf += sizeof( Preamble );
//
// copy the server random number
//
memcpy( pNetworkBuf, pCanonical->ServerRandom, LICENSE_RANDOM ); pNetworkBuf += LICENSE_RANDOM;
//
// copy the product info
//
memcpy( pNetworkBuf, &pCanonical->ProductInfo.dwVersion, sizeof( DWORD ) ); pNetworkBuf += sizeof( DWORD );
memcpy( pNetworkBuf, &pCanonical->ProductInfo.cbCompanyName, sizeof( DWORD ) ); pNetworkBuf += sizeof( DWORD );
memcpy( pNetworkBuf, pCanonical->ProductInfo.pbCompanyName, pCanonical->ProductInfo.cbCompanyName ); pNetworkBuf += pCanonical->ProductInfo.cbCompanyName;
memcpy( pNetworkBuf, &pCanonical->ProductInfo.cbProductID, sizeof( DWORD ) ); pNetworkBuf += sizeof( DWORD );
memcpy( pNetworkBuf, pCanonical->ProductInfo.pbProductID, pCanonical->ProductInfo.cbProductID ); pNetworkBuf += pCanonical->ProductInfo.cbProductID;
//
// copy the key exchange list
//
CopyBinaryBlob( pNetworkBuf, &pCanonical->KeyExchngList, &cbCopied ); pNetworkBuf += cbCopied;
//
// copy the hydra server certificate
//
CopyBinaryBlob( pNetworkBuf, &pCanonical->ServerCert, &cbCopied ); pNetworkBuf += cbCopied;
//
// copy the scope list
//
memcpy( pNetworkBuf, &pCanonical->ScopeList.dwScopeCount, sizeof( DWORD ) ); pNetworkBuf += sizeof( DWORD );
for( i = 0, pBlob = pCanonical->ScopeList.Scopes; i < pCanonical->ScopeList.dwScopeCount; i++ ) { CopyBinaryBlob( pNetworkBuf, pBlob, &cbCopied ); pNetworkBuf += cbCopied; pBlob++; } PackError:
return( Status );
}
///////////////////////////////////////////////////////////////////////////////
LICENSE_STATUS PackHydraServerPlatformChallenge( DWORD dwProtocolVersion, PHydra_Server_Platform_Challenge pCanonical, PBYTE* ppNetwork, DWORD* pcbNetwork ) { Preamble Header; DWORD cbCopied; PBinary_Blob pBlob; LICENSE_STATUS Status = LICENSE_STATUS_OK; PBYTE pNetworkBuf;
ASSERT( pCanonical ); ASSERT( pcbNetwork ); ASSERT( ppNetwork );
if( ( NULL == pCanonical ) || ( NULL == pcbNetwork ) || ( NULL == ppNetwork ) ) { return( LICENSE_STATUS_INVALID_INPUT ); }
//
// calculate the buffer size needed
//
Header.wMsgSize = sizeof( Preamble ) + sizeof( DWORD ) + GetBinaryBlobSize( pCanonical->EncryptedPlatformChallenge ) + LICENSE_MAC_DATA;
//
// allocate the output buffer
//
Status = LicenseMemoryAllocate( Header.wMsgSize, ppNetwork );
if( LICENSE_STATUS_OK != Status ) { goto PackError; }
*pcbNetwork = Header.wMsgSize; pNetworkBuf = *ppNetwork;
//
// copy the header
//
Header.bMsgType = HS_PLATFORM_CHALLENGE; Header.bVersion = GET_PREAMBLE_VERSION( dwProtocolVersion );
memcpy( pNetworkBuf, &Header, sizeof( Preamble ) ); pNetworkBuf += sizeof( Preamble );
//
// copy the connect flag
//
memcpy( pNetworkBuf, &pCanonical->dwConnectFlags, sizeof( DWORD ) ); pNetworkBuf += sizeof( DWORD );
//
// copy the encrypted platform challenge
//
CopyBinaryBlob( pNetworkBuf, &pCanonical->EncryptedPlatformChallenge, &cbCopied ); pNetworkBuf += cbCopied;
//
// copy the MAC
//
memcpy( pNetworkBuf, pCanonical->MACData, LICENSE_MAC_DATA );
PackError:
return( Status ); }
///////////////////////////////////////////////////////////////////////////////
LICENSE_STATUS PackHydraServerNewLicense( DWORD dwProtocolVersion, PHydra_Server_New_License pCanonical, PBYTE* ppNetwork, DWORD* pcbNetwork ) { Preamble Header; DWORD cbCopied; PBinary_Blob pBlob; LICENSE_STATUS Status = LICENSE_STATUS_OK; PBYTE pNetworkBuf;
ASSERT( pCanonical ); ASSERT( pcbNetwork ); ASSERT( ppNetwork );
if( ( NULL == pCanonical ) || ( NULL == pcbNetwork ) || ( NULL == ppNetwork ) ) { return( LICENSE_STATUS_INVALID_INPUT ); }
//
// calculate the buffer size needed
//
Header.wMsgSize = sizeof( Preamble ) + GetBinaryBlobSize( pCanonical->EncryptedNewLicenseInfo ) + LICENSE_MAC_DATA;
//
// allocate the output buffer
//
Status = LicenseMemoryAllocate( Header.wMsgSize, ppNetwork );
if( LICENSE_STATUS_OK != Status ) { goto PackError; }
*pcbNetwork = Header.wMsgSize; pNetworkBuf = *ppNetwork;
//
// copy the header
//
Header.bMsgType = HS_NEW_LICENSE; Header.bVersion = GET_PREAMBLE_VERSION( dwProtocolVersion );
memcpy( pNetworkBuf, &Header, sizeof( Preamble ) ); pNetworkBuf += sizeof( Preamble );
//
// copy the encrypted new license info
//
CopyBinaryBlob( pNetworkBuf, &pCanonical->EncryptedNewLicenseInfo, &cbCopied ); pNetworkBuf += cbCopied;
//
// copy the MAC
//
memcpy( pNetworkBuf, pCanonical->MACData, LICENSE_MAC_DATA ); PackError:
return( Status );
}
///////////////////////////////////////////////////////////////////////////////
LICENSE_STATUS PackHydraServerUpgradeLicense( DWORD dwProtocolVersion, PHydra_Server_Upgrade_License pCanonical, PBYTE* ppNetwork, DWORD* pcbNetwork ) { LICENSE_STATUS Status; PPreamble pHeader;
Status = PackHydraServerNewLicense( dwProtocolVersion, pCanonical, ppNetwork, pcbNetwork );
if( LICENSE_STATUS_OK == Status ) { //
// make this an upgrade license message
//
pHeader = ( PPreamble )*ppNetwork; pHeader->bMsgType = HS_UPGRADE_LICENSE; }
return( Status ); }
///////////////////////////////////////////////////////////////////////////////
LICENSE_STATUS PackHydraServerErrorMessage( DWORD dwProtocolVersion, PLicense_Error_Message pCanonical, PBYTE* ppNetwork, DWORD* pcbNetwork ) { Preamble Header; DWORD cbCopied; PBinary_Blob pBlob; LICENSE_STATUS Status = LICENSE_STATUS_OK; PBYTE pNetworkBuf;
ASSERT( pCanonical ); ASSERT( pcbNetwork ); ASSERT( ppNetwork );
if( ( NULL == pCanonical ) || ( NULL == pcbNetwork ) || ( NULL == ppNetwork ) ) { return( LICENSE_STATUS_INVALID_INPUT ); }
//
// calculate the buffer size needed
//
Header.wMsgSize = sizeof( Preamble ) + sizeof( DWORD ) + sizeof( DWORD ) + GetBinaryBlobSize( pCanonical->bbErrorInfo );
//
// allocate the output buffer
//
Status = LicenseMemoryAllocate( Header.wMsgSize, ppNetwork );
if( LICENSE_STATUS_OK != Status ) { goto PackError; }
*pcbNetwork = Header.wMsgSize; pNetworkBuf = *ppNetwork;
//
// set up preamble
//
Header.bMsgType = GM_ERROR_ALERT; Header.bVersion = GET_PREAMBLE_VERSION( dwProtocolVersion );
memcpy( pNetworkBuf, &Header, sizeof( Preamble ) ); pNetworkBuf += sizeof( Preamble );
//
// copy the error code, state transition and error info
//
memcpy( pNetworkBuf, &pCanonical->dwErrorCode, sizeof( DWORD ) ); pNetworkBuf += sizeof( DWORD );
memcpy( pNetworkBuf, &pCanonical->dwStateTransition, sizeof( DWORD ) ); pNetworkBuf += sizeof( DWORD );
CopyBinaryBlob( pNetworkBuf, &pCanonical->bbErrorInfo, &cbCopied ); PackError:
return( Status ); }
///////////////////////////////////////////////////////////////////////////////
LICENSE_STATUS PackNewLicenseInfo( PNew_License_Info pCanonical, PBYTE* ppNetwork, DWORD* pcbNetwork ) { DWORD cbBufNeeded; PBYTE pNetworkBuf; LICENSE_STATUS Status = LICENSE_STATUS_OK;
ASSERT( pCanonical ); ASSERT( pcbNetwork ); ASSERT( ppNetwork );
if( ( NULL == pCanonical ) || ( NULL == pcbNetwork ) || ( NULL == ppNetwork ) ) { return( LICENSE_STATUS_INVALID_INPUT ); }
//
// calculate the buffer size needed and check that the output
// buffer is large enough
//
cbBufNeeded = 5 * sizeof( DWORD ) + pCanonical->cbScope + pCanonical->cbCompanyName + pCanonical->cbProductID + pCanonical->cbLicenseInfo;
//
// allocate the output buffer
//
Status = LicenseMemoryAllocate( cbBufNeeded, ppNetwork );
if( LICENSE_STATUS_OK != Status ) { goto done; }
*pcbNetwork = cbBufNeeded; pNetworkBuf = *ppNetwork;
//
// start copying the data
//
memcpy( pNetworkBuf, &pCanonical->dwVersion, sizeof( DWORD ) ); pNetworkBuf += sizeof( DWORD );
memcpy( pNetworkBuf, &pCanonical->cbScope, sizeof( DWORD ) ); pNetworkBuf += sizeof( DWORD );
memcpy( pNetworkBuf, pCanonical->pbScope, pCanonical->cbScope ); pNetworkBuf += pCanonical->cbScope;
memcpy( pNetworkBuf, &pCanonical->cbCompanyName, sizeof( DWORD ) ); pNetworkBuf += sizeof( DWORD );
memcpy( pNetworkBuf, pCanonical->pbCompanyName, pCanonical->cbCompanyName ); pNetworkBuf += pCanonical->cbCompanyName;
memcpy( pNetworkBuf, &pCanonical->cbProductID, sizeof( DWORD ) ); pNetworkBuf += sizeof( DWORD );
memcpy( pNetworkBuf, pCanonical->pbProductID, pCanonical->cbProductID ); pNetworkBuf += pCanonical->cbProductID;
memcpy( pNetworkBuf, &pCanonical->cbLicenseInfo, sizeof( DWORD ) ); pNetworkBuf += sizeof( DWORD );
memcpy( pNetworkBuf, pCanonical->pbLicenseInfo, pCanonical->cbLicenseInfo ); pNetworkBuf += pCanonical->cbLicenseInfo;
done:
return( Status ); }
///////////////////////////////////////////////////////////////////////////////
LICENSE_STATUS PackExtendedErrorInfo( UINT32 uiExtendedErrorInfo, Binary_Blob *pbbErrorInfo) { WORD cbBufNeeded; PBYTE pbNetworkBuf; WORD wBlobVersion = BB_ERROR_BLOB_VERSION; WORD wBlobReserved = 0; LICENSE_STATUS Status = LICENSE_STATUS_OK;
if (NULL == pbbErrorInfo) { return( LICENSE_STATUS_INVALID_INPUT ); }
//
// Initialize in case of errors
//
pbbErrorInfo->wBlobLen = 0;
//
// calculate the buffer size needed
//
cbBufNeeded = sizeof(WORD) + sizeof(WORD) + sizeof(UINT32);
//
// allocate the output buffer
//
Status = LicenseMemoryAllocate( cbBufNeeded, &(pbbErrorInfo->pBlob) );
if( LICENSE_STATUS_OK != Status ) { goto done; }
pbbErrorInfo->wBlobLen = cbBufNeeded;
pbNetworkBuf = pbbErrorInfo->pBlob;
//
// start copying the data
//
memcpy( pbNetworkBuf, &wBlobVersion, sizeof( WORD ) ); pbNetworkBuf += sizeof( WORD );
memcpy( pbNetworkBuf, &wBlobReserved, sizeof( WORD ) ); pbNetworkBuf += sizeof( WORD );
memcpy( pbNetworkBuf, &uiExtendedErrorInfo, sizeof( UINT32 ) );
done:
return ( Status ); }
///////////////////////////////////////////////////////////////////////////////
// Functions for unpacking different Hydra Client Messages from
// simple binary blobs to corresponding structure
//
///////////////////////////////////////////////////////////////////////////////
LICENSE_STATUS UnPackHydraClientErrorMessage( PBYTE pbMessage, DWORD cbMessage, PLicense_Error_Message pCanonical, BOOL* pfExtendedError) { DWORD cbUnpacked = 0; LICENSE_STATUS Status = LICENSE_STATUS_OK; PPreamble pHeader; PBYTE pNetwork; DWORD cbProcessed = 0, cbRemainder;
//
// check the input parameters
//
ASSERT( NULL != pbMessage ); ASSERT( 0 < cbMessage ); ASSERT( NULL != pCanonical ); ASSERT( NULL != pfExtendedError );
if( ( NULL == pbMessage ) || ( 0 >= cbMessage ) || ( NULL == pCanonical ) || ( pfExtendedError == NULL)) { return( LICENSE_STATUS_INVALID_INPUT ); }
*pfExtendedError = FALSE;
//
// check the preamble
//
pHeader = ( PPreamble )pbMessage;
if( GM_ERROR_ALERT != pHeader->bMsgType ) { #if DBG
DbgPrint( "UnPackHydraClientErrorMessage: received unexpected message type %c\n", pHeader->bMsgType ); #endif
return( LICENSE_STATUS_INVALID_RESPONSE ); } if(pHeader->bVersion & EXTENDED_ERROR_CAPABILITY) { *pfExtendedError = TRUE; }
//
// do a calculation of the fixed field length
//
cbUnpacked = sizeof( Preamble ) + 2 * sizeof( DWORD );
if( cbMessage < ( WORD )cbUnpacked ) { return( LICENSE_STATUS_INVALID_INPUT ); }
cbRemainder = cbMessage - cbUnpacked;
//
// get the license error structure
//
pNetwork = pbMessage + sizeof( Preamble ); memcpy( &pCanonical->dwErrorCode, pNetwork, sizeof( DWORD ) ); pNetwork += sizeof( DWORD ); memcpy( &pCanonical->dwStateTransition, pNetwork, sizeof( DWORD ) ); pNetwork += sizeof( DWORD );
Status = GetBinaryBlob( &( pCanonical->bbErrorInfo ), cbRemainder, pNetwork, &cbProcessed );
if( LICENSE_STATUS_OK != Status ) { return( Status ); } cbUnpacked += cbProcessed;
ASSERT( pHeader->wMsgSize == ( WORD )cbUnpacked );
return( Status ); }
///////////////////////////////////////////////////////////////////////////////
LICENSE_STATUS UnPackHydraClientLicenseInfo( PBYTE pbMessage, DWORD cbMessage, PHydra_Client_License_Info pCanonical, BOOL* pfExtendedError) { DWORD cbUnpacked = 0; LICENSE_STATUS Status = LICENSE_STATUS_OK; PPreamble pHeader; PBYTE pNetwork; DWORD cbProcessed = 0, cbRemainder = 0;
//
// check the input parameters
//
ASSERT( NULL != pbMessage ); ASSERT( 0 < cbMessage ); ASSERT( NULL != pCanonical ); ASSERT( NULL != pfExtendedError );
if( ( NULL == pbMessage ) || ( 0 >= cbMessage ) || ( NULL == pCanonical ) || ( NULL == pfExtendedError)) { return( LICENSE_STATUS_INVALID_INPUT ); }
*pfExtendedError = FALSE; //
// check the preamble
//
pHeader = ( PPreamble )pbMessage;
if( HC_LICENSE_INFO != pHeader->bMsgType ) { #if DBG
DbgPrint( "UnPackHydraClientLicenseInfo: received unexpected message type %c\n", pHeader->bMsgType ); #endif
return( LICENSE_STATUS_INVALID_RESPONSE ); }
if(pHeader->bVersion & EXTENDED_ERROR_CAPABILITY) { *pfExtendedError = TRUE; }
//
// do a calculation of the fixed field length
//
cbUnpacked = sizeof( Preamble ) + 2 * sizeof( DWORD ) + LICENSE_RANDOM + LICENSE_MAC_DATA;
cbRemainder = cbMessage - cbUnpacked;
if( cbMessage < ( WORD )cbUnpacked ) { return( LICENSE_STATUS_INVALID_INPUT ); }
//
// get the license info structure
//
pNetwork = pbMessage + sizeof( Preamble ); memcpy( &pCanonical->dwPrefKeyExchangeAlg, pNetwork, sizeof( DWORD ) ); pNetwork += sizeof( DWORD );
memcpy( &pCanonical->dwPlatformID, pNetwork, sizeof( DWORD ) ); pNetwork += sizeof( DWORD );
memcpy( &pCanonical->ClientRandom, pNetwork, LICENSE_RANDOM ); pNetwork += LICENSE_RANDOM;
Status = GetBinaryBlob( &pCanonical->EncryptedPreMasterSecret, cbRemainder, pNetwork, &cbProcessed );
if( LICENSE_STATUS_OK != Status ) { if (Status == LICENSE_STATUS_INVALID_INPUT) { Status = LICENSE_STATUS_INVALID_RESPONSE; }
return( Status ); }
pNetwork += cbProcessed; cbUnpacked += cbProcessed;
cbRemainder = cbMessage - cbUnpacked;
Status = GetBinaryBlob( &pCanonical->LicenseInfo, cbRemainder, pNetwork, &cbProcessed );
if( LICENSE_STATUS_OK != Status ) { if (Status == LICENSE_STATUS_INVALID_INPUT) { Status = LICENSE_STATUS_INVALID_RESPONSE; }
return( Status ); } pNetwork += cbProcessed; cbUnpacked += cbProcessed;
cbRemainder = cbMessage- cbUnpacked;
Status = GetBinaryBlob( &pCanonical->EncryptedHWID, cbRemainder, pNetwork, &cbProcessed );
if( LICENSE_STATUS_OK != Status ) { if (Status == LICENSE_STATUS_INVALID_INPUT) { Status = LICENSE_STATUS_INVALID_RESPONSE; }
return( Status ); } pNetwork += cbProcessed; cbUnpacked += cbProcessed;
memcpy( pCanonical->MACData, pNetwork, LICENSE_MAC_DATA );
ASSERT( pHeader->wMsgSize == ( WORD )cbUnpacked );
return( Status ); }
///////////////////////////////////////////////////////////////////////////////
LICENSE_STATUS UnPackHydraClientNewLicenseRequest( PBYTE pbMessage, DWORD cbMessage, PHydra_Client_New_License_Request pCanonical, BOOL* pfExtendedError) { DWORD cbUnpacked = 0; LICENSE_STATUS Status = LICENSE_STATUS_OK; PPreamble pHeader; PBYTE pNetwork; DWORD cbProcessed = 0, cbRemainder = 0;
//
// check the input parameters
//
ASSERT( NULL != pbMessage ); ASSERT( 0 < cbMessage ); ASSERT( NULL != pCanonical ); ASSERT( NULL != pfExtendedError );
if( ( NULL == pbMessage ) || ( 0 >= cbMessage ) || ( NULL == pCanonical ) || ( NULL == pfExtendedError)) { return( LICENSE_STATUS_INVALID_INPUT ); }
*pfExtendedError = FALSE;
//
// check the preamble
//
pHeader = ( PPreamble )pbMessage;
if( HC_NEW_LICENSE_REQUEST != pHeader->bMsgType ) { #if DBG
DbgPrint( "UnPackHydraClientNewLicenseRequest: received unexpected message type %c\n", pHeader->bMsgType ); #endif
return( LICENSE_STATUS_INVALID_RESPONSE ); }
if(pHeader->bVersion & EXTENDED_ERROR_CAPABILITY) { *pfExtendedError = TRUE; }
//
// do a calculation of the fixed field length
//
cbUnpacked = sizeof( Preamble ) + 2 * sizeof( DWORD ) + LICENSE_RANDOM;
cbRemainder = cbMessage - cbUnpacked;
if( cbMessage < ( WORD )cbUnpacked ) { return( LICENSE_STATUS_INVALID_INPUT ); }
//
// get the new license request structure
//
pNetwork = pbMessage + sizeof( Preamble ); memcpy( &pCanonical->dwPrefKeyExchangeAlg, pNetwork, sizeof( DWORD ) ); pNetwork += sizeof( DWORD );
memcpy( &pCanonical->dwPlatformID, pNetwork, sizeof( DWORD ) ); pNetwork += sizeof( DWORD );
memcpy( &pCanonical->ClientRandom, pNetwork, LICENSE_RANDOM ); pNetwork += LICENSE_RANDOM;
Status = GetBinaryBlob( &pCanonical->EncryptedPreMasterSecret, cbRemainder, pNetwork, &cbProcessed );
if( LICENSE_STATUS_OK != Status ) { return( Status ); }
cbUnpacked += cbProcessed; pNetwork += cbProcessed;
cbRemainder = cbMessage - cbUnpacked;
//
// we changed the licensing protocol to include the client user and machine
// name. So to prevent an older client that does not have the user and machine
// name binary blobs from crashing the server, we add this check for the
// message length.
//
if( pHeader->wMsgSize <= cbUnpacked ) { #if DBG
DbgPrint( "UnPackHydraClientNewLicenseRequest: old licensing protocol\n" ); #endif
pCanonical->ClientUserName.pBlob = NULL; pCanonical->ClientMachineName.pBlob = NULL;
//
// make these 2 fields optional for now.
//
return( Status ); } Status = GetBinaryBlob( &pCanonical->ClientUserName, cbRemainder, pNetwork, &cbProcessed );
if( LICENSE_STATUS_OK != Status ) { return( Status ); }
cbUnpacked += cbProcessed; pNetwork += cbProcessed;
cbRemainder = cbMessage - cbUnpacked;
Status = GetBinaryBlob( &pCanonical->ClientMachineName, cbRemainder, pNetwork, &cbProcessed );
if( LICENSE_STATUS_OK != Status ) { return( Status ); }
cbUnpacked += cbProcessed;
ASSERT( pHeader->wMsgSize == ( WORD )cbUnpacked );
return( Status ); }
///////////////////////////////////////////////////////////////////////////////
LICENSE_STATUS UnPackHydraClientPlatformChallengeResponse( PBYTE pbMessage, DWORD cbMessage, PHydra_Client_Platform_Challenge_Response pCanonical, BOOL* pfExtendedError) { DWORD cbUnpacked = 0; LICENSE_STATUS Status = LICENSE_STATUS_OK; PPreamble pHeader; PBYTE pNetwork; DWORD cbProcessed = 0, cbRemainder = 0;
//
// check the input parameters
//
ASSERT( NULL != pbMessage ); ASSERT( 0 < cbMessage ); ASSERT( NULL != pCanonical ); ASSERT( NULL != pfExtendedError );
if( ( NULL == pbMessage ) || ( 0 >= cbMessage ) || ( NULL == pCanonical ) || ( NULL == pfExtendedError )) { return( LICENSE_STATUS_INVALID_INPUT ); }
*pfExtendedError = FALSE; //
// check the preamble
//
pHeader = ( PPreamble )pbMessage;
if( HC_PLATFORM_CHALENGE_RESPONSE != pHeader->bMsgType ) { #if DBG
DbgPrint( "UnPackHydraClientPlatformChallengeResponse: received unexpected message type %c\n", pHeader->bMsgType ); #endif
return( LICENSE_STATUS_INVALID_RESPONSE ); } if(pHeader->bVersion & EXTENDED_ERROR_CAPABILITY) { *pfExtendedError = TRUE; }
//
// do a calculation of the fixed field length
//
cbUnpacked = sizeof( Preamble ) + LICENSE_MAC_DATA;
cbRemainder = cbMessage - cbUnpacked;
if( cbMessage < ( WORD )cbUnpacked ) { return( LICENSE_STATUS_INVALID_INPUT ); }
//
// get the platform challenge response structure
//
pNetwork = pbMessage + sizeof( Preamble );
Status = GetBinaryBlob( &pCanonical->EncryptedChallengeResponse, cbRemainder, pNetwork, &cbProcessed );
if( LICENSE_STATUS_OK != Status ) { return( Status ); }
pNetwork += cbProcessed; cbUnpacked += cbProcessed;
cbRemainder = cbMessage - cbUnpacked;
Status = GetBinaryBlob( &pCanonical->EncryptedHWID, cbRemainder, pNetwork, &cbProcessed );
if( LICENSE_STATUS_OK != Status ) { return( Status ); }
pNetwork += cbProcessed; cbUnpacked += cbProcessed;
memcpy( pCanonical->MACData, pNetwork, LICENSE_MAC_DATA );
ASSERT( pHeader->wMsgSize == ( WORD )cbUnpacked );
return( Status ); }
|