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.
 
 
 
 
 
 

1209 lines
30 KiB

//+--------------------------------------------------------------------------
//
// 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 );
}