windows-nt/Source/XPSP1/NT/termsrv/common/license/hclient/liclient/hcpack.c

1667 lines
48 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1997.
//
// File: hcpack.c
//
// Contents: Functions that are used to pack and unpack different messages
//
// Classes:
//
// Functions: PackHydraClientNewLicenseRequest
// PackHydraClientKeyExchangeInfo
// PackHydraClientLicenseInfo
// PackHydraClientPlatformInfo
// PackHydraClientPlatformChallengeResponse
// PackLicenseErrorMessage
// UnPackLicenseErrorMessage
// UnpackHydraServerLicenseRequest
// UnPackHydraServerPlatformChallenge
// UnPackHydraServerNewLicense
// UnPackHydraServerUpgradeLicense
// UnpackHydraServerCertificate
//
// History: 12-19-97 v-sbhatt Created
//
//----------------------------------------------------------------------------
//
//Includes
//
#include "windows.h"
#ifndef OS_WINCE
#include "stdio.h"
#endif // OS_WINCE
#include "stdlib.h"
#include <tchar.h>
#ifdef OS_WINCE
#include <wincelic.h>
#endif //OS_WINCE
#include "license.h"
#include "hcpack.h"
#include "licdbg.h"
#define INVALID_INPUT_RETURN lsReturn = LICENSE_STATUS_INVALID_INPUT; LS_LOG_RESULT(lsReturn); goto ErrorReturn
#define EXTENDED_ERROR_CAPABILITY 0x80
//Copies a binary blob into a byte buffer. Does not check for any abnormal
//condition. After copying buffer points to the end of the blob
static VOID CopyBinaryBlob(
BYTE FAR * pbBuffer,
PBinary_Blob pbbBlob,
DWORD FAR * 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( (pbbBlob->wBlobLen >0) && (pbbBlob->pBlob != NULL) )
{
//Copy the actual data
memcpy(pbBuffer, pbbBlob->pBlob, pbbBlob->wBlobLen);
pbBuffer += pbbBlob->wBlobLen;
*pdwCount += pbbBlob->wBlobLen;
}
}
//Function implementation
/***************************************************************************************
* Function : PackHydraClientNewLicenseRequest
* Purpose : This function takes a pointer to a Hydra_Client_New_License_Request
* structure and copies the data to the buffer pointed by pbBuffer.
* pcbBuffer should point the size of the buffer pointed by pbBuffer.
* After the function returns, pcbBuffer contains the no. of bytes copied
* in the buffer. If pbBuffer is NULL, the fucntion returns the size of
* the pbBuffer to be allocated.
* Returns : LICENSE_STATUS
****************************************************************************************/
LICENSE_STATUS
PackHydraClientNewLicenseRequest(
IN PHydra_Client_New_License_Request pCanonical,
IN BOOL fExtendedError,
OUT BYTE FAR * pbBuffer,
IN OUT DWORD FAR * pcbBuffer
)
{
LICENSE_STATUS lsReturn = LICENSE_STATUS_OK;
BYTE FAR * pbTemp = NULL;
DWORD dwCount = 0;
Preamble Header;
LS_BEGIN(TEXT("PackHydraClientNewLicenseRequest"));
//Check if the inputs are valid or not!
if(pCanonical == NULL)
{
INVALID_INPUT_RETURN;;
}
if( pbBuffer == NULL && pcbBuffer == NULL )
{
INVALID_INPUT_RETURN;;
}
//Initialize Message Header
Header.bMsgType = HC_NEW_LICENSE_REQUEST;
Header.bVersion = PREAMBLE_VERSION_3_0;
if( fExtendedError == TRUE)
{
Header.bVersion |= EXTENDED_ERROR_CAPABILITY;
}
Header.wMsgSize = 0;
//Calculate the size of the message and place the data in Header.wMsgSize.
//Start with Preamble size
Header.wMsgSize += sizeof(Preamble);
//dwPrefKeyExchangeAlg
Header.wMsgSize += sizeof(pCanonical->dwPrefKeyExchangeAlg);
//dwPlatformID
Header.wMsgSize += sizeof(pCanonical->dwPlatformID);
//Client Random
Header.wMsgSize += LICENSE_RANDOM;
//EncryptedPreMasterSecret
Header.wMsgSize += sizeof(pCanonical->EncryptedPreMasterSecret.wBlobType) +
sizeof(pCanonical->EncryptedPreMasterSecret.wBlobLen) +
pCanonical->EncryptedPreMasterSecret.wBlobLen;
//
// client user name and machine name
//
Header.wMsgSize += sizeof(pCanonical->ClientUserName.wBlobType) +
sizeof(pCanonical->ClientUserName.wBlobLen) +
pCanonical->ClientUserName.wBlobLen;
Header.wMsgSize += sizeof(pCanonical->ClientMachineName.wBlobType) +
sizeof(pCanonical->ClientMachineName.wBlobLen) +
pCanonical->ClientMachineName.wBlobLen;
if(pbBuffer == NULL)
{
*pcbBuffer = (DWORD)Header.wMsgSize;
LS_RETURN(lsReturn);
goto CommonReturn;
}
else if(*pcbBuffer < (DWORD)Header.wMsgSize)
{
lsReturn = LICENSE_STATUS_INSUFFICIENT_BUFFER;
LS_RETURN(lsReturn);
goto ErrorReturn;
}
pbTemp = pbBuffer;
*pcbBuffer = 0;
//Now start copying different members of the New License structure to the
//buffer specified by the caller
//first copy the Header into the buffer
memcpy(pbTemp, &Header, sizeof(Preamble));
pbTemp += sizeof(Preamble);
*pcbBuffer += sizeof(Preamble);
//Copy the dwPrefKeyExchangeAlg parameter
memcpy(pbTemp, &pCanonical->dwPrefKeyExchangeAlg, sizeof(pCanonical->dwPrefKeyExchangeAlg));
pbTemp += sizeof(pCanonical->dwPrefKeyExchangeAlg);
*pcbBuffer += sizeof(pCanonical->dwPrefKeyExchangeAlg);
//Copy PlatformID;
memcpy(pbTemp, &pCanonical->dwPlatformID, sizeof(pCanonical->dwPlatformID));
pbTemp += sizeof(pCanonical->dwPlatformID);
*pcbBuffer += sizeof(pCanonical->dwPlatformID);
//Copy ClientRandom
memcpy(pbTemp, pCanonical->ClientRandom, LICENSE_RANDOM);
pbTemp += LICENSE_RANDOM;
*pcbBuffer += LICENSE_RANDOM;
//Copy EncryptedPreMasterSecret Blob
CopyBinaryBlob(pbTemp, &pCanonical->EncryptedPreMasterSecret, &dwCount);
pbTemp += dwCount;
*pcbBuffer += dwCount;
//
// copy client user name
//
CopyBinaryBlob(pbTemp, &pCanonical->ClientUserName, &dwCount);
pbTemp += dwCount;
*pcbBuffer += dwCount;
//
// copy client machine name
//
CopyBinaryBlob(pbTemp, &pCanonical->ClientMachineName, &dwCount);
pbTemp += dwCount;
*pcbBuffer += dwCount;
LS_LOG_RESULT(lsReturn);
CommonReturn:
//return lsReturn;
LS_RETURN(lsReturn);
ErrorReturn:
goto CommonReturn;
}
/***************************************************************************************
* Function : PackHydraClientLicenseInfo
* Purpose : This function takes a pointer to a Hydra_Client_License_Info structure
* and copies the data to the buffer pointed by pbBuffer. pcbBuffer
* should point the size of the buffer pointed by pbBuffer. After the
* function returns, pcbBuffer contains the no. of bytes copied in the
* buffer. If pbBuffer is NULL, the fucntion returns the size of the
* pbBuffer to be allocated
* Returns : LICENSE_STATUS
****************************************************************************************/
LICENSE_STATUS
PackHydraClientLicenseInfo(
IN PHydra_Client_License_Info pCanonical,
IN BOOL fExtendedError,
OUT BYTE FAR * pbBuffer,
IN OUT DWORD FAR * pcbBuffer
)
{
LICENSE_STATUS lsReturn = LICENSE_STATUS_OK;
BYTE FAR * pbTemp; //To be used while copying the data
Preamble Header;
DWORD dwCount = 0;
//Check if the inputs are valid or not!
LS_BEGIN(TEXT("PackHydraClientLicenseInfo\n"));
if(pCanonical == NULL)
{
INVALID_INPUT_RETURN;
}
if( pbBuffer == NULL && pcbBuffer == NULL )
{
INVALID_INPUT_RETURN;
}
//Initialize Message Header
Header.bMsgType = HC_LICENSE_INFO;
Header.bVersion = PREAMBLE_VERSION_3_0;
if(fExtendedError == TRUE)
{
Header.bVersion |= EXTENDED_ERROR_CAPABILITY;
}
Header.wMsgSize = 0;
//Calculate the size of the message and place the data in Header.wMsgSize.
//Start with Preamble size
Header.wMsgSize += sizeof(Preamble);
//dwPrefKeyExchangeAlg
Header.wMsgSize += sizeof(pCanonical->dwPrefKeyExchangeAlg);
//dwPlatformID
Header.wMsgSize += sizeof(pCanonical->dwPlatformID);
//ClientRandom
Header.wMsgSize += LICENSE_RANDOM;
//EncryptedPreMasterSecret
Header.wMsgSize += sizeof(pCanonical->EncryptedPreMasterSecret.wBlobType) +
sizeof(pCanonical->EncryptedPreMasterSecret.wBlobLen) +
pCanonical->EncryptedPreMasterSecret.wBlobLen;
//Add the license Info
Header.wMsgSize += sizeof(pCanonical->LicenseInfo.wBlobType) +
sizeof(pCanonical->LicenseInfo.wBlobLen) +
pCanonical->LicenseInfo.wBlobLen;
//Encrypted HWID
Header.wMsgSize += sizeof(pCanonical->EncryptedHWID.wBlobType) +
sizeof(pCanonical->EncryptedHWID.wBlobLen) +
pCanonical->EncryptedHWID.wBlobLen;
//MACData
Header.wMsgSize += LICENSE_MAC_DATA;
//If the input buffer is null, inform the user to allocate a buffer of size
//*pcbBuffer!
if(pbBuffer == NULL)
{
*pcbBuffer = (DWORD)Header.wMsgSize;
LS_LOG_RESULT(lsReturn);
goto CommonReturn;
}
//else, check if the allocated buffer size is more than the required!
else if(*pcbBuffer < (DWORD)Header.wMsgSize)
{
lsReturn = LICENSE_STATUS_INSUFFICIENT_BUFFER;
LS_LOG_RESULT(lsReturn);
goto ErrorReturn;
}
pbTemp = pbBuffer;
*pcbBuffer = 0;
//Now start copying different members of the New License structure to the
//buffer specified by the caller
//first copy the Header into the buffer
memcpy(pbTemp, &Header, sizeof(Preamble));
pbTemp += sizeof(Preamble);
*pcbBuffer += sizeof(Preamble);
//Copy the dwPrefKeyExchangeAlg parameter
memcpy(pbTemp, &pCanonical->dwPrefKeyExchangeAlg, sizeof(pCanonical->dwPrefKeyExchangeAlg));
pbTemp += sizeof(pCanonical->dwPrefKeyExchangeAlg);
*pcbBuffer += sizeof(pCanonical->dwPrefKeyExchangeAlg);
//Copy the dwPlatformID
memcpy(pbTemp, &pCanonical->dwPlatformID, sizeof(pCanonical->dwPlatformID));
pbTemp += sizeof(pCanonical->dwPlatformID);
*pcbBuffer += sizeof(pCanonical->dwPlatformID);
//Copy ClientRandom
memcpy(pbTemp, pCanonical->ClientRandom, LICENSE_RANDOM);
pbTemp += LICENSE_RANDOM;
*pcbBuffer += LICENSE_RANDOM;
//Copy EncryptedPreMasterSecret Blob
CopyBinaryBlob(pbTemp, &pCanonical->EncryptedPreMasterSecret, &dwCount);
pbTemp += dwCount;
*pcbBuffer += dwCount;
//Copy LicenseInfo
CopyBinaryBlob(pbTemp, &pCanonical->LicenseInfo, &dwCount);
pbTemp += dwCount;
*pcbBuffer += dwCount;
//Copy EncryptedHWID
CopyBinaryBlob(pbTemp, &pCanonical->EncryptedHWID, &dwCount);
pbTemp += dwCount;
*pcbBuffer += dwCount;
//Copy MACData
memcpy(pbTemp, pCanonical->MACData, LICENSE_MAC_DATA);
pbTemp += LICENSE_MAC_DATA;
*pcbBuffer += LICENSE_MAC_DATA;
LS_LOG_RESULT(lsReturn);
CommonReturn:
//return lsReturn;
LS_RETURN(lsReturn);
ErrorReturn:
goto CommonReturn;
}
/****************************************************************************************
* Function : PackHydraClientPlatformChallengeResponse
* Purpose : This function takes a pointer to a Hydra_Client_Platform_Info structure
* and copies the data to the buffer pointed by pbBuffer. pcbBuffer should
* point the size of the buffer pointed by pbBuffer. After the function
* returns, pcbBuffer contains the no. of bytes copied in the buffer.
* If pbBuffer is NULL, the fucntion returns the size of the pbBuffer to
* be allocated
* Returns : LICENSE_STATUS
******************************************************************************************/
LICENSE_STATUS
PackHydraClientPlatformChallengeResponse(
IN PHydra_Client_Platform_Challenge_Response pCanonical,
IN BOOL fExtendedError,
OUT BYTE FAR * pbBuffer,
IN OUT DWORD FAR * pcbBuffer
)
{
LICENSE_STATUS lsReturn = LICENSE_STATUS_OK;
BYTE FAR * pbTemp; //To be used while copying the data
Preamble Header;
DWORD dwCount = 0;
//Check if the inputs are valid or not!
LS_BEGIN(TEXT("PackHydraClientPlatformChallengeResponse\n"));
if(pCanonical == NULL)
{
INVALID_INPUT_RETURN;
}
if( pbBuffer == NULL && pcbBuffer == NULL )
{
INVALID_INPUT_RETURN;
}
//Initialize Message Header
Header.bMsgType = HC_PLATFORM_CHALENGE_RESPONSE;
Header.bVersion = PREAMBLE_VERSION_3_0;
if(fExtendedError == TRUE)
{
Header.bVersion |= EXTENDED_ERROR_CAPABILITY;
}
Header.wMsgSize = 0;
//Calculate the size of the message and place the data in Header.wMsgSize.
//Start with Preamble size
Header.wMsgSize += sizeof(Preamble);
//EncryptedChallengeResponse
Header.wMsgSize += sizeof(pCanonical->EncryptedChallengeResponse.wBlobType) +
sizeof(pCanonical->EncryptedChallengeResponse.wBlobLen) +
pCanonical->EncryptedChallengeResponse.wBlobLen;
//Encrypted HWID
Header.wMsgSize += sizeof(pCanonical->EncryptedHWID.wBlobType) +
sizeof(pCanonical->EncryptedHWID.wBlobLen) +
pCanonical->EncryptedHWID.wBlobLen;
//MACData
Header.wMsgSize += LICENSE_MAC_DATA;
if(pbBuffer == NULL)
{
*pcbBuffer = (DWORD)Header.wMsgSize;
LS_LOG_RESULT(lsReturn);
goto CommonReturn;
}
else if(*pcbBuffer < (DWORD)Header.wMsgSize)
{
lsReturn = LICENSE_STATUS_INSUFFICIENT_BUFFER;
LS_LOG_RESULT(lsReturn);
goto ErrorReturn;
}
pbTemp = pbBuffer;
*pcbBuffer = 0;
//Now start copying different members of the New License structure to the
//buffer specified by the caller
//first copy the Header into the buffer
memcpy(pbTemp, &Header, sizeof(Preamble));
pbTemp += sizeof(Preamble);
*pcbBuffer += sizeof(Preamble);
//Copy LicenseInfo
CopyBinaryBlob(pbTemp, &pCanonical->EncryptedChallengeResponse, &dwCount);
pbTemp += dwCount;
*pcbBuffer += dwCount;
//Copy EncryptedHWID
CopyBinaryBlob(pbTemp, &pCanonical->EncryptedHWID, &dwCount);
pbTemp += dwCount;
*pcbBuffer += dwCount;
//Copy MACData
memcpy(pbTemp, pCanonical->MACData, LICENSE_MAC_DATA);
pbTemp += LICENSE_MAC_DATA;
//CopyBinaryBlob(pbTemp, &pCanonical->MACData, &dwCount);
*pcbBuffer += LICENSE_MAC_DATA;
LS_LOG_RESULT(lsReturn);
CommonReturn:
//return lsReturn;
LS_RETURN(lsReturn);
ErrorReturn:
goto CommonReturn;
}
/****************************************************************************************
* Funtion : PackLicenseErrorMessage
* Purpose : This function takes a pointer to a License_Error_Message structure
* and copies the data to the buffer pointed by pbBuffer. pcbBuffer should
* point the size of the buffer pointed by pbBuffer. After the function
* returns, pcbBuffer contains the no. of bytes copied in the buffer.
* If pbBuffer is NULL, the fucntion returns the size of the pbBuffer to
* be allocated
* Return : LICENSE_STATUS
*****************************************************************************************/
LICENSE_STATUS
PackLicenseErrorMessage(
IN PLicense_Error_Message pCanonical,
IN BOOL fExtendedError,
OUT BYTE FAR * pbBuffer,
IN OUT DWORD FAR * pcbBuffer
)
{
LICENSE_STATUS lsReturn = LICENSE_STATUS_OK;
BYTE FAR * pbTemp; //To be used while copying the data
Preamble Header;
DWORD dwCount = 0;
LS_BEGIN(TEXT("PackLicenseErrorMessage\n"));
//Check if the inputs are valid or not!
if(pCanonical == NULL)
{
INVALID_INPUT_RETURN;
}
if( pbBuffer == NULL && pcbBuffer == NULL )
{
INVALID_INPUT_RETURN;
}
//Initialize Message Header
Header.bMsgType = GM_ERROR_ALERT;
Header.bVersion = PREAMBLE_VERSION_3_0;
if(fExtendedError == TRUE)
{
Header.bVersion |= EXTENDED_ERROR_CAPABILITY;
}
Header.wMsgSize = 0;
//Calculate the size of the message and place the data in Header.wMsgSize.
//Start with Preamble size
Header.wMsgSize += sizeof(Preamble);
//dwErrorCode
Header.wMsgSize += sizeof(pCanonical->dwErrorCode);
//dwStateTransition
Header.wMsgSize += sizeof(pCanonical->dwStateTransition);
//bbErrorInfo
Header.wMsgSize += sizeof(pCanonical->bbErrorInfo.wBlobType) +
sizeof(pCanonical->bbErrorInfo.wBlobLen) +
pCanonical->bbErrorInfo.wBlobLen;
if(pbBuffer == NULL)
{
*pcbBuffer = (DWORD)Header.wMsgSize;
LS_LOG_RESULT(lsReturn);
goto CommonReturn;
}
else if(*pcbBuffer < (DWORD)Header.wMsgSize)
{
lsReturn = LICENSE_STATUS_INSUFFICIENT_BUFFER;
LS_LOG_RESULT(lsReturn);
goto ErrorReturn;
}
pbTemp = pbBuffer;
*pcbBuffer = 0;
//Now start copying different members of the New License structure to the
//buffer specified by the caller
//first copy the Header into the buffer
memcpy(pbTemp, &Header, sizeof(Preamble));
pbTemp += sizeof(Preamble);
*pcbBuffer += sizeof(Preamble);
//Copy dwErrorCode
memcpy(pbTemp, &pCanonical->dwErrorCode, sizeof(pCanonical->dwErrorCode));
pbTemp += sizeof(pCanonical->dwErrorCode);
*pcbBuffer += sizeof(pCanonical->dwErrorCode);
//Copy dwStateTransition
memcpy(pbTemp, &pCanonical->dwStateTransition, sizeof(pCanonical->dwStateTransition));
pbTemp += sizeof(pCanonical->dwStateTransition);
*pcbBuffer += sizeof(pCanonical->dwStateTransition);
//Copy bbErrorInfo
CopyBinaryBlob(pbTemp, &pCanonical->bbErrorInfo, &dwCount);
pbTemp += dwCount;
*pcbBuffer += dwCount;
LS_LOG_RESULT(lsReturn);
CommonReturn:
LS_RETURN(lsReturn);
//return lsReturn;
ErrorReturn:
goto CommonReturn;
}
/****************************************************************************************
* Function : UnpackLicenseErrorMessage
* Purpose : To unpack a binary blob into a License_Error_Message structure.
* Note : The caller should initialize the pointer. All the necessary allocation is
* done by the function itself.
* The caller should free all the memory components once it is no longer needed.
* Return : License_Status
*****************************************************************************************/
LICENSE_STATUS
UnPackLicenseErrorMessage(
IN BYTE FAR * pbMessage,
IN DWORD cbMessage,
OUT PLicense_Error_Message pCanonical
)
{
LICENSE_STATUS lsReturn = LICENSE_STATUS_OK;
BYTE FAR * pbTemp;
DWORD dwTemp;
DWORD dwSize;
LS_BEGIN(TEXT("UnpackLicenseErrorMessage\n"));
if(pbMessage == NULL)
{
INVALID_INPUT_RETURN;
}
if(pCanonical == NULL)
{
INVALID_INPUT_RETURN;
}
//Memset pCanonical structure to zero
memset(pCanonical, 0x00, sizeof(License_Error_Message));
LS_DUMPSTRING(cbMessage, pbMessage);
pbTemp = pbMessage;
dwTemp = cbMessage;
if (dwTemp < 2 * sizeof(DWORD))
{
INVALID_INPUT_RETURN;
}
//Assign dwErrorCode
pCanonical->dwErrorCode = *( UNALIGNED DWORD* )pbTemp;
pbTemp += sizeof(DWORD);
dwTemp -= sizeof(DWORD);
//Assign dwStateTransition
pCanonical->dwStateTransition = *( UNALIGNED DWORD* )pbTemp;
pbTemp += sizeof(DWORD);
dwTemp -= sizeof(DWORD);
if (dwTemp < 2 * sizeof(WORD))
{
INVALID_INPUT_RETURN;
}
pCanonical->bbErrorInfo.wBlobType = *( UNALIGNED WORD* )pbTemp;
pbTemp += sizeof(WORD);
dwTemp -= sizeof(WORD);
pCanonical->bbErrorInfo.wBlobLen = *( UNALIGNED WORD* )pbTemp;
pbTemp += sizeof(WORD);
dwTemp -= sizeof(WORD);
dwSize = pCanonical->bbErrorInfo.wBlobLen;
if(dwSize > dwTemp)
{
INVALID_INPUT_RETURN;
}
if(pCanonical->bbErrorInfo.wBlobLen>0)
{
if( NULL == (pCanonical->bbErrorInfo.pBlob = (BYTE FAR *)malloc(pCanonical->bbErrorInfo.wBlobLen)) )
{
pCanonical->bbErrorInfo.wBlobLen = 0;
lsReturn = LICENSE_STATUS_OUT_OF_MEMORY;
LS_LOG_RESULT(lsReturn);
goto ErrorReturn;
}
memset(pCanonical->bbErrorInfo.pBlob, 0x00, pCanonical->bbErrorInfo.wBlobLen);
memcpy(pCanonical->bbErrorInfo.pBlob, pbTemp, pCanonical->bbErrorInfo.wBlobLen);
}
else
{
pCanonical->bbErrorInfo.pBlob = NULL;
}
LS_LOG_RESULT(lsReturn);
ErrorReturn:
LS_RETURN(lsReturn);
}
/****************************************************************************************
* Function : UnpackHydraServerLicenseRequest
* Purpose : To unpack a binary blob into a Hydra_Server_License_Request structure.
* Note : The caller should initialize the output pointer. All the necessary
* allocation for different structure components is done by the function itself.
* The caller should free all the memory components once it is no longer needed.
* Return : License_Status
*****************************************************************************************/
LICENSE_STATUS
UnpackHydraServerLicenseRequest(
IN BYTE FAR * pbMessage,
IN DWORD cbMessage,
OUT PHydra_Server_License_Request pCanonical
)
{
LICENSE_STATUS lsReturn = LICENSE_STATUS_OK;
BYTE FAR *pbTemp = NULL;
DWORD dwTemp = 0;
DWORD i = 0;
LS_BEGIN(TEXT("UnpackHydraServerLicenseRequest\n"));
if(pbMessage == NULL)
{
INVALID_INPUT_RETURN;
}
if(pCanonical == NULL)
{
INVALID_INPUT_RETURN;
}
LS_DUMPSTRING(cbMessage, pbMessage);
pbTemp = pbMessage;
dwTemp = cbMessage;
if (dwTemp < LICENSE_RANDOM)
{
INVALID_INPUT_RETURN;
}
//Copy Server Random
memcpy(pCanonical->ServerRandom, pbTemp, LICENSE_RANDOM);
pbTemp += LICENSE_RANDOM;
dwTemp -= LICENSE_RANDOM;
if (dwTemp < 2 * sizeof(DWORD))
{
INVALID_INPUT_RETURN;
}
//Copy the ProductInfo structure
pCanonical->ProductInfo.dwVersion = *( UNALIGNED DWORD* )pbTemp;
pbTemp += sizeof(DWORD);
dwTemp -= sizeof(DWORD);
pCanonical->ProductInfo.cbCompanyName = *( UNALIGNED DWORD* )pbTemp;
pbTemp += sizeof(DWORD);
dwTemp -= sizeof(DWORD);
if(pCanonical->ProductInfo.cbCompanyName>0)
{
if(dwTemp < pCanonical->ProductInfo.cbCompanyName)
{
INVALID_INPUT_RETURN;
}
if( NULL == (pCanonical->ProductInfo.pbCompanyName = (BYTE FAR *)malloc(pCanonical->ProductInfo.cbCompanyName)) )
{
pCanonical->ProductInfo.cbCompanyName = 0;
lsReturn = LICENSE_STATUS_OUT_OF_MEMORY;
LS_LOG_RESULT(lsReturn);
goto ErrorReturn;
}
memcpy(pCanonical->ProductInfo.pbCompanyName, pbTemp, pCanonical->ProductInfo.cbCompanyName);
pbTemp += pCanonical->ProductInfo.cbCompanyName;
dwTemp -= pCanonical->ProductInfo.cbCompanyName;
}
if(dwTemp < sizeof(DWORD))
{
INVALID_INPUT_RETURN;
}
pCanonical->ProductInfo.cbProductID = *( UNALIGNED DWORD* )pbTemp;
pbTemp += sizeof(DWORD);
dwTemp -= sizeof(DWORD);
if(pCanonical->ProductInfo.cbProductID>0)
{
if(dwTemp < pCanonical->ProductInfo.cbProductID)
{
INVALID_INPUT_RETURN;
}
if( NULL == (pCanonical->ProductInfo.pbProductID = (BYTE FAR *)malloc(pCanonical->ProductInfo.cbProductID)) )
{
pCanonical->ProductInfo.cbProductID = 0;
lsReturn = LICENSE_STATUS_OUT_OF_MEMORY;
LS_LOG_RESULT(lsReturn);
goto ErrorReturn;
}
memcpy(pCanonical->ProductInfo.pbProductID, pbTemp, pCanonical->ProductInfo.cbProductID);
pbTemp += pCanonical->ProductInfo.cbProductID;
dwTemp -= pCanonical->ProductInfo.cbProductID;
}
if(dwTemp < sizeof(WORD)*2)
{
INVALID_INPUT_RETURN;
}
//Copy KeyExchngList
pCanonical->KeyExchngList.wBlobType = *( UNALIGNED WORD* )pbTemp;
pbTemp += sizeof(WORD);
dwTemp -= sizeof(WORD);
pCanonical->KeyExchngList.wBlobLen = *( UNALIGNED WORD* )pbTemp;
pbTemp += sizeof(WORD);
dwTemp -= sizeof(WORD);
if( pCanonical->KeyExchngList.wBlobLen > 0 )
{
if(dwTemp < pCanonical->KeyExchngList.wBlobLen)
{
INVALID_INPUT_RETURN;
}
if( NULL == (pCanonical->KeyExchngList.pBlob = (BYTE FAR *)malloc(pCanonical->KeyExchngList.wBlobLen)) )
{
pCanonical->KeyExchngList.wBlobLen = 0;
lsReturn = LICENSE_STATUS_OUT_OF_MEMORY;
LS_LOG_RESULT(lsReturn);
goto ErrorReturn;
}
memcpy(pCanonical->KeyExchngList.pBlob, pbTemp, pCanonical->KeyExchngList.wBlobLen);
pbTemp += pCanonical->KeyExchngList.wBlobLen;
dwTemp -= pCanonical->KeyExchngList.wBlobLen;
}
if(dwTemp < sizeof(WORD)*2)
{
INVALID_INPUT_RETURN;
}
//Copy ServerCert
pCanonical->ServerCert.wBlobType = *( UNALIGNED WORD* )pbTemp;
pbTemp += sizeof(WORD);
dwTemp -= sizeof(WORD);
pCanonical->ServerCert.wBlobLen = *( UNALIGNED WORD* )pbTemp;
pbTemp += sizeof(WORD);
dwTemp -= sizeof(WORD);
if(pCanonical->ServerCert.wBlobLen >0)
{
if(dwTemp < pCanonical->ServerCert.wBlobLen)
{
INVALID_INPUT_RETURN;
}
if( NULL == (pCanonical->ServerCert.pBlob = (BYTE FAR *)malloc(pCanonical->ServerCert.wBlobLen)) )
{
pCanonical->ServerCert.wBlobLen = 0;
lsReturn = LICENSE_STATUS_OUT_OF_MEMORY;
LS_LOG_RESULT(lsReturn);
goto ErrorReturn;
}
memcpy(pCanonical->ServerCert.pBlob, pbTemp, pCanonical->ServerCert.wBlobLen);
pbTemp += pCanonical->ServerCert.wBlobLen;
dwTemp -= pCanonical->ServerCert.wBlobLen;
}
if(dwTemp < sizeof(DWORD))
{
INVALID_INPUT_RETURN;
}
//Copy the scopelist
pCanonical->ScopeList.dwScopeCount = *( UNALIGNED DWORD* )pbTemp;
pbTemp += sizeof( DWORD );
dwTemp -= sizeof( DWORD );
if(dwTemp < pCanonical->ScopeList.dwScopeCount*sizeof(Binary_Blob))
{
pCanonical->ScopeList.dwScopeCount = 0;
INVALID_INPUT_RETURN;
}
if( NULL == (pCanonical->ScopeList.Scopes = (PBinary_Blob)malloc(pCanonical->ScopeList.dwScopeCount*sizeof(Binary_Blob))) )
{
pCanonical->ScopeList.dwScopeCount = 0;
lsReturn = LICENSE_STATUS_OUT_OF_MEMORY;
LS_LOG_RESULT(lsReturn);
goto ErrorReturn;
}
memset(pCanonical->ScopeList.Scopes, 0x00, pCanonical->ScopeList.dwScopeCount*sizeof(Binary_Blob));
for(i = 0; i<pCanonical->ScopeList.dwScopeCount; i++ )
{
if(dwTemp < sizeof(WORD)*2)
{
pCanonical->ScopeList.dwScopeCount = i;
INVALID_INPUT_RETURN;
}
pCanonical->ScopeList.Scopes[i].wBlobType = *( UNALIGNED WORD* )pbTemp;
pbTemp += sizeof(WORD);
dwTemp -= sizeof(WORD);
pCanonical->ScopeList.Scopes[i].wBlobLen = *( UNALIGNED WORD* )pbTemp;
pbTemp += sizeof(WORD);
dwTemp -= sizeof(WORD);
if(dwTemp < pCanonical->ScopeList.Scopes[i].wBlobLen)
{
pCanonical->ScopeList.dwScopeCount = i;
INVALID_INPUT_RETURN;
}
if( NULL ==(pCanonical->ScopeList.Scopes[i].pBlob = (BYTE FAR *)malloc(pCanonical->ScopeList.Scopes[i].wBlobLen)) )
{
pCanonical->ScopeList.Scopes[i].wBlobLen = 0;
lsReturn = LICENSE_STATUS_OUT_OF_MEMORY;
LS_LOG_RESULT(lsReturn);
goto ErrorReturn;
}
memcpy(pCanonical->ScopeList.Scopes[i].pBlob, pbTemp, pCanonical->ScopeList.Scopes[i].wBlobLen);
pbTemp += pCanonical->ScopeList.Scopes[i].wBlobLen;
dwTemp -= pCanonical->ScopeList.Scopes[i].wBlobLen;
}
LS_LOG_RESULT(lsReturn);
LS_RETURN(lsReturn);
ErrorReturn:
if (pCanonical)
{
if(pCanonical->ProductInfo.pbCompanyName)
{
free(pCanonical->ProductInfo.pbCompanyName);
pCanonical->ProductInfo.pbCompanyName = NULL;
}
if(pCanonical->ProductInfo.pbProductID)
{
free(pCanonical->ProductInfo.pbProductID);
pCanonical->ProductInfo.pbProductID = NULL;
}
if(pCanonical->KeyExchngList.pBlob)
{
free(pCanonical->KeyExchngList.pBlob);
pCanonical->KeyExchngList.pBlob = NULL;
}
if(pCanonical->ServerCert.pBlob)
{
free(pCanonical->ServerCert.pBlob);
pCanonical->ServerCert.pBlob = NULL;
}
for(i = 0; i<pCanonical->ScopeList.dwScopeCount; i++ )
{
if(pCanonical->ScopeList.Scopes[i].pBlob)
{
free(pCanonical->ScopeList.Scopes[i].pBlob);
pCanonical->ScopeList.Scopes[i].pBlob = NULL;
}
}
if(pCanonical->ScopeList.Scopes)
{
free(pCanonical->ScopeList.Scopes);
pCanonical->ScopeList.Scopes = NULL;
}
}
LS_RETURN(lsReturn);
}
/****************************************************************************************
* Function : UnpackHydraPlatformChallenge
* Purpose : To unpack a binary blob into a Hydra_Server_Platform_Challenge structure.
* Note : The caller should initialize the output pointer. All the necessary
* allocation for different structure components is done by the function itself.
* The caller should free all the memory components once it is no longer needed.
* Return : License_Status
*****************************************************************************************/
LICENSE_STATUS
UnPackHydraServerPlatformChallenge(
IN BYTE FAR * pbMessage,
IN DWORD cbMessage,
OUT PHydra_Server_Platform_Challenge pCanonical
)
{
LICENSE_STATUS lsReturn = LICENSE_STATUS_OK;
BYTE FAR * pbTemp = NULL;
DWORD dwTemp = 0;
LS_BEGIN(TEXT("UnpackHydraServerPlatformChallenge\n"));
if(pbMessage == NULL)
{
INVALID_INPUT_RETURN;
}
if(pCanonical == NULL)
{
INVALID_INPUT_RETURN;
}
LS_DUMPSTRING(cbMessage, pbMessage);
pbTemp = pbMessage;
dwTemp = cbMessage;
if (dwTemp < sizeof(DWORD))
{
INVALID_INPUT_RETURN;
}
//Assign dwConnectFlags
pCanonical->dwConnectFlags = *( UNALIGNED DWORD* )pbTemp;
pbTemp += sizeof(DWORD);
dwTemp -= sizeof(DWORD);
if (dwTemp < 2 * sizeof(WORD))
{
INVALID_INPUT_RETURN;
}
//Assign EncryptedPlatformChallenge
pCanonical->EncryptedPlatformChallenge.wBlobType = *( UNALIGNED WORD* )pbTemp;
pbTemp += sizeof(WORD);
dwTemp -= sizeof(WORD);
pCanonical->EncryptedPlatformChallenge.wBlobLen = *( UNALIGNED WORD* )pbTemp;
pbTemp += sizeof(WORD);
dwTemp -= sizeof(WORD);
if(pCanonical->EncryptedPlatformChallenge.wBlobLen >0)
{
if (dwTemp < pCanonical->EncryptedPlatformChallenge.wBlobLen)
{
INVALID_INPUT_RETURN;
}
if( NULL == (pCanonical->EncryptedPlatformChallenge.pBlob = (BYTE FAR *)malloc(pCanonical->EncryptedPlatformChallenge.wBlobLen)) )
{
pCanonical->EncryptedPlatformChallenge.wBlobLen = 0;
lsReturn = LICENSE_STATUS_OUT_OF_MEMORY;
LS_LOG_RESULT(lsReturn);
goto ErrorReturn;
}
memcpy(pCanonical->EncryptedPlatformChallenge.pBlob, pbTemp, pCanonical->EncryptedPlatformChallenge.wBlobLen);
pbTemp += pCanonical->EncryptedPlatformChallenge.wBlobLen;
dwTemp -= pCanonical->EncryptedPlatformChallenge.wBlobLen;
}
if(dwTemp < LICENSE_MAC_DATA)
{
INVALID_INPUT_RETURN;
}
//Assign MACData
memcpy(pCanonical->MACData, pbTemp, LICENSE_MAC_DATA);
pbTemp += LICENSE_MAC_DATA;
dwTemp -= LICENSE_MAC_DATA;
LS_LOG_RESULT(lsReturn);
LS_RETURN(lsReturn);
ErrorReturn:
if (pCanonical)
{
if(pCanonical->EncryptedPlatformChallenge.pBlob)
{
free(pCanonical->EncryptedPlatformChallenge.pBlob);
pCanonical->EncryptedPlatformChallenge.pBlob = NULL;
}
}
LS_RETURN(lsReturn);
}
/****************************************************************************************
* Function : UnpackHydraServerNewLicense
* Purpose : To unpack a binary blob into a Hydra_Server_New_License structure.
* Note : The caller should initialize the output pointer. All the necessary
* allocation for different structure components is done by the function itself.
* The caller should free all the memory components once it is no longer needed.
* Return : License_Status
*****************************************************************************************/
LICENSE_STATUS
UnPackHydraServerNewLicense(
IN BYTE FAR * pbMessage,
IN DWORD cbMessage,
OUT PHydra_Server_New_License pCanonical
)
{
LICENSE_STATUS lsReturn = LICENSE_STATUS_OK;
BYTE FAR * pbTemp = NULL;
DWORD dwTemp = 0;
LS_BEGIN(TEXT("UnpackHydraServerNewLicense\n"));
if( (pbMessage == NULL) || (pCanonical == NULL ) )
{
INVALID_INPUT_RETURN;
}
memset(pCanonical, 0x00, sizeof(Hydra_Server_New_License));
LS_DUMPSTRING(cbMessage, pbMessage);
pbTemp = pbMessage;
dwTemp = cbMessage;
if (dwTemp < 2 * sizeof(WORD))
{
INVALID_INPUT_RETURN;
}
//Assign EncryptedNewLicenseInfo
pCanonical->EncryptedNewLicenseInfo.wBlobType = *( UNALIGNED WORD* )pbTemp;
pbTemp += sizeof(WORD);
dwTemp -= sizeof(WORD);
pCanonical->EncryptedNewLicenseInfo.wBlobLen = *( UNALIGNED WORD* )pbTemp;
pbTemp += sizeof(WORD);
dwTemp -= sizeof(WORD);
if(pCanonical->EncryptedNewLicenseInfo.wBlobLen > 0)
{
if (dwTemp < pCanonical->EncryptedNewLicenseInfo.wBlobLen)
{
INVALID_INPUT_RETURN;
}
if( NULL == (pCanonical->EncryptedNewLicenseInfo.pBlob = (BYTE FAR *)malloc(pCanonical->EncryptedNewLicenseInfo.wBlobLen)) )
{
pCanonical->EncryptedNewLicenseInfo.wBlobLen = 0;
lsReturn = LICENSE_STATUS_OUT_OF_MEMORY;
LS_LOG_RESULT(lsReturn);
goto ErrorReturn;
}
memcpy(pCanonical->EncryptedNewLicenseInfo.pBlob, pbTemp, pCanonical->EncryptedNewLicenseInfo.wBlobLen);
pbTemp += pCanonical->EncryptedNewLicenseInfo.wBlobLen;
dwTemp -= pCanonical->EncryptedNewLicenseInfo.wBlobLen;
}
if(dwTemp < LICENSE_MAC_DATA)
{
INVALID_INPUT_RETURN;
}
//Copy MACData
memcpy(pCanonical->MACData, pbTemp, LICENSE_MAC_DATA);
pbTemp += LICENSE_MAC_DATA;
dwTemp -= LICENSE_MAC_DATA;
LS_LOG_RESULT(lsReturn);
LS_RETURN(lsReturn);
ErrorReturn:
if (pCanonical)
{
if(pCanonical->EncryptedNewLicenseInfo.pBlob)
{
free(pCanonical->EncryptedNewLicenseInfo.pBlob);
pCanonical->EncryptedNewLicenseInfo.pBlob = NULL;
}
}
LS_RETURN(lsReturn);
}
/****************************************************************************************
* Function : UnpackHydraServerUpgradeLicense
* Purpose : To unpack a binary blob into a Hydra_Server_Upgrade_License structure.
* Note : The caller should initialize the output pointer. All the necessary
* allocation for different structure components is done by the function itself.
* The caller should free all the memory components once it is no longer needed.
* Internally this function calls UnpackHydraServerUpgradeLicense.
* Return : License_Status
*****************************************************************************************/
LICENSE_STATUS
UnPackHydraServerUpgradeLicense(
IN BYTE FAR * pbMessage,
IN DWORD cbMessage,
OUT PHydra_Server_Upgrade_License pCanonical
)
{
//Call UnpackHydraServerNewLicense as both the messages are same
LS_BEGIN(TEXT("UnpackHydraServerUpgradeLicense\n"));
return UnPackHydraServerNewLicense(pbMessage, cbMessage, pCanonical);
}
#if 0
//
// moved to cryptkey.c
//
/****************************************************************************************
* Function : UnpackHydraServerCertificate
* Purpose : To unpack a binary blob into a Hydra_Server_Cert structure.
* Note : The caller should initialize the output pointer. All the necessary
* allocation for different structure components is done by the function itself.
* The caller should free all the memory components once it is no longer needed.
* Return : License_Status
*****************************************************************************************/
LICENSE_STATUS
UnpackHydraServerCertificate(
IN BYTE FAR * pbMessage,
IN DWORD cbMessage,
OUT PHydra_Server_Cert pCanonical
)
{
LICENSE_STATUS lsReturn = LICENSE_STATUS_OK;
BYTE FAR * pbTemp = NULL;
DWORD dwTemp = 0;
LS_BEGIN(TEXT("UnpackHydraServerCertificate\n"));
if( (pbMessage == NULL) || (pCanonical == NULL ) )
{
INVALID_INPUT_RETURN;
}
dwTemp = 3*sizeof(DWORD) + 4*sizeof(WORD);
if(dwTemp > cbMessage)
{
INVALID_INPUT_RETURN;
}
memset(pCanonical, 0x00, sizeof(Hydra_Server_Cert));
LS_DUMPSTRING(cbMessage, pbMessage);
pbTemp = pbMessage;
dwTemp = cbMessage;
//Assign dwVersion
pCanonical->dwVersion = *( UNALIGNED DWORD* )pbTemp;
pbTemp += sizeof(DWORD);
dwTemp -= sizeof(DWORD);
//Assign dwSigAlgID
pCanonical->dwSigAlgID = *( UNALIGNED DWORD* )pbTemp;
pbTemp += sizeof(DWORD);
dwTemp -= sizeof(DWORD);
//Assign dwSignID
pCanonical->dwKeyAlgID = *( UNALIGNED DWORD* )pbTemp;
pbTemp += sizeof(DWORD);
dwTemp -= sizeof(DWORD);
//Assign PublicKeyData
pCanonical->PublicKeyData.wBlobType = *( UNALIGNED WORD* )pbTemp;
pbTemp += sizeof(WORD);
dwTemp -= sizeof(WORD);
if( pCanonical->PublicKeyData.wBlobType != BB_RSA_KEY_BLOB )
{
INVALID_INPUT_RETURN;
}
pCanonical->PublicKeyData.wBlobLen = *( UNALIGNED WORD* )pbTemp;
pbTemp += sizeof(WORD);
dwTemp -= sizeof(WORD);
if(pCanonical->PublicKeyData.wBlobLen >0)
{
if( NULL ==(pCanonical->PublicKeyData.pBlob = (BYTE FAR *)malloc(pCanonical->PublicKeyData.wBlobLen)) )
{
pCanonical->PublicKeyData.wBlobLen = 0;
lsReturn = LICENSE_STATUS_OUT_OF_MEMORY;
LS_LOG_RESULT(lsReturn);
goto ErrorReturn;
}
memset(pCanonical->PublicKeyData.pBlob, 0x00, pCanonical->PublicKeyData.wBlobLen);
memcpy(pCanonical->PublicKeyData.pBlob, pbTemp, pCanonical->PublicKeyData.wBlobLen);
pbTemp += pCanonical->PublicKeyData.wBlobLen;
dwTemp -= pCanonical->PublicKeyData.wBlobLen;
}
//Assign SignatureBlob
pCanonical->SignatureBlob.wBlobType = *( UNALIGNED WORD* )pbTemp;
pbTemp += sizeof(WORD);
dwTemp -= sizeof(WORD);
if( pCanonical->SignatureBlob.wBlobType != BB_RSA_SIGNATURE_BLOB )
{
INVALID_INPUT_RETURN;
}
pCanonical->SignatureBlob.wBlobLen = *( UNALIGNED WORD* )pbTemp;
pbTemp += sizeof(WORD);
dwTemp -= sizeof(WORD);
if(pCanonical->SignatureBlob.wBlobLen >0)
{
if( NULL ==(pCanonical->SignatureBlob.pBlob = (BYTE FAR *)malloc(pCanonical->SignatureBlob.wBlobLen)) )
{
pCanonical->SignatureBlob.wBlobLen = 0;
lsReturn = LICENSE_STATUS_OUT_OF_MEMORY;
LS_LOG_RESULT(lsReturn);
goto ErrorReturn;
}
memset(pCanonical->SignatureBlob.pBlob, 0x00, pCanonical->SignatureBlob.wBlobLen);
memcpy(pCanonical->SignatureBlob.pBlob, pbTemp, pCanonical->SignatureBlob.wBlobLen);
pbTemp += pCanonical->SignatureBlob.wBlobLen;
dwTemp -= pCanonical->SignatureBlob.wBlobLen;
}
LS_LOG_RESULT(lsReturn);
LS_RETURN(lsReturn);
ErrorReturn:
if (pCanonical)
{
if(pCanonical->PublicKeyData.pBlob)
{
free(pCanonical->PublicKeyData.pBlob);
pCanonical->PublicKeyData.pBlob = NULL;
}
if(pCanonical->SignatureBlob.pBlob)
{
free(pCanonical->SignatureBlob.pBlob);
pCanonical->SignatureBlob.pBlob = NULL;
}
memset(pCanonical, 0x00, sizeof(Hydra_Server_Cert));
}
LS_RETURN(lsReturn);
}
#endif
/****************************************************************************************
* Function : UnpackNewLicenseInfo
* Purpose : To unpack a binary blob into a New_license_Info structure
* Note : The caller should initialize the output pointer. All the necessary
* allocation for different structure components is done by the function itself.
* The caller should free all the memory components once it is no longer needed.
* Return : License_Status
*****************************************************************************************/
LICENSE_STATUS
UnpackNewLicenseInfo(
BYTE FAR * pbMessage,
DWORD cbMessage,
PNew_License_Info pCanonical
)
{
LICENSE_STATUS lsReturn = LICENSE_STATUS_OK;
BYTE FAR * pbTemp = NULL;
DWORD dwTemp = 0, dw = 0;
LS_BEGIN(TEXT("UnpackNewLicenseInfo\n"));
//Check for the validity of the inputs
if( (pbMessage == NULL) || (pCanonical == 0) )
{
INVALID_INPUT_RETURN;
}
dwTemp = 5*sizeof(DWORD);
if(dwTemp > cbMessage)
{
INVALID_INPUT_RETURN;
}
memset(pCanonical, 0x00, sizeof(New_License_Info));
LS_DUMPSTRING(cbMessage, pbMessage);
dwTemp = cbMessage;
pbTemp = pbMessage;
//Assign version
pCanonical->dwVersion = *( UNALIGNED DWORD* )pbTemp;
pbTemp += sizeof(DWORD);
dwTemp -= sizeof(DWORD);
//Assign Scope Data
pCanonical->cbScope = *( UNALIGNED DWORD* )pbTemp;
pbTemp += sizeof(DWORD);
dwTemp -= sizeof(DWORD);
dw = pCanonical->cbScope + 3*sizeof(DWORD);
if( dw>dwTemp )
{
INVALID_INPUT_RETURN;
}
if( pCanonical->cbScope>0 )
{
if( NULL == (pCanonical->pbScope = (BYTE FAR *)malloc(pCanonical->cbScope)) )
{
pCanonical->cbScope = 0;
lsReturn = LICENSE_STATUS_OUT_OF_MEMORY;
LS_LOG_RESULT(lsReturn);
goto ErrorReturn;
}
memset(pCanonical->pbScope, 0x00, pCanonical->cbScope);
memcpy(pCanonical->pbScope, pbTemp, pCanonical->cbScope);
pbTemp += pCanonical->cbScope;
dwTemp -= pCanonical->cbScope;
}
//Assign CompanyName Data
pCanonical->cbCompanyName = *( UNALIGNED DWORD* )pbTemp;
pbTemp += sizeof(DWORD);
dwTemp -= sizeof(DWORD);
dw = pCanonical->cbCompanyName + 2*sizeof(DWORD);
if( dw>dwTemp)
{
INVALID_INPUT_RETURN;
}
if( pCanonical->cbCompanyName>0 )
{
if( NULL == (pCanonical->pbCompanyName = (BYTE FAR *)malloc(pCanonical->cbCompanyName)) )
{
pCanonical->cbCompanyName = 0;
lsReturn = LICENSE_STATUS_OUT_OF_MEMORY;
LS_LOG_RESULT(lsReturn);
goto ErrorReturn;
}
memset(pCanonical->pbCompanyName, 0x00, pCanonical->cbCompanyName);
memcpy(pCanonical->pbCompanyName, pbTemp, pCanonical->cbCompanyName);
pbTemp += pCanonical->cbCompanyName;
dwTemp -= pCanonical->cbCompanyName;
}
//Assign ProductID data
pCanonical->cbProductID = *( UNALIGNED DWORD* )pbTemp;
pbTemp += sizeof(DWORD);
dwTemp -= sizeof(DWORD);
dw = pCanonical->cbProductID + sizeof(DWORD);
if(dw>dwTemp)
{
INVALID_INPUT_RETURN;
}
if( pCanonical->cbProductID>0 )
{
if( NULL == (pCanonical->pbProductID = (BYTE FAR *)malloc(pCanonical->cbProductID)) )
{
pCanonical->cbProductID = 0;
lsReturn = LICENSE_STATUS_OUT_OF_MEMORY;
goto ErrorReturn;
}
memset(pCanonical->pbProductID, 0x00, pCanonical->cbProductID);
memcpy(pCanonical->pbProductID, pbTemp, pCanonical->cbProductID);
pbTemp += pCanonical->cbProductID;
dwTemp -= pCanonical->cbProductID;
}
//Assign LicenseInfo data
pCanonical->cbLicenseInfo = *( UNALIGNED DWORD* )pbTemp;
pbTemp += sizeof(DWORD);
dwTemp -= sizeof(DWORD);
dw = pCanonical->cbLicenseInfo;
if( dw>dwTemp )
{
INVALID_INPUT_RETURN;
}
if( pCanonical->cbLicenseInfo>0 )
{
if( NULL == (pCanonical->pbLicenseInfo = (BYTE FAR *)malloc(pCanonical->cbLicenseInfo)) )
{
pCanonical->cbLicenseInfo = 0;
lsReturn = LICENSE_STATUS_OUT_OF_MEMORY;
LS_LOG_RESULT(lsReturn);
goto ErrorReturn;
}
memset(pCanonical->pbLicenseInfo, 0x00, pCanonical->cbLicenseInfo);
memcpy(pCanonical->pbLicenseInfo, pbTemp, pCanonical->cbLicenseInfo);
pbTemp += pCanonical->cbLicenseInfo;
dwTemp -= pCanonical->cbLicenseInfo;
}
LS_LOG_RESULT(lsReturn);
LS_RETURN(lsReturn);
ErrorReturn:
if (pCanonical)
{
if(pCanonical->pbScope)
{
free(pCanonical->pbScope);
pCanonical->pbScope = NULL;
}
if(pCanonical->pbCompanyName)
{
free(pCanonical->pbCompanyName);
pCanonical->pbCompanyName = NULL;
}
if(pCanonical->pbProductID)
{
free(pCanonical->pbProductID);
pCanonical->pbProductID = NULL;
}
if(pCanonical->pbLicenseInfo)
{
free(pCanonical->pbLicenseInfo);
pCanonical->pbLicenseInfo = NULL;
}
}
LS_RETURN(lsReturn);
}
///////////////////////////////////////////////////////////////////////////////
LICENSE_STATUS
UnPackExtendedErrorInfo(
UINT32 *puiExtendedErrorInfo,
Binary_Blob *pbbErrorInfo)
{
LICENSE_STATUS lsReturn = LICENSE_STATUS_OK;
BYTE FAR * pbTemp = NULL;
DWORD dwTemp = 0;
WORD wVersion;
LS_BEGIN(TEXT("UnpackExtendedErrorInfo\n"));
//Check for the validity of the inputs
if( (puiExtendedErrorInfo == NULL) || (pbbErrorInfo == NULL) )
{
INVALID_INPUT_RETURN;
}
dwTemp = sizeof(WORD) + sizeof(WORD) + sizeof(UINT32);
if(dwTemp > pbbErrorInfo->wBlobLen)
{
INVALID_INPUT_RETURN;
}
pbTemp = pbbErrorInfo->pBlob;
wVersion = *(UNALIGNED WORD*)pbTemp;
pbTemp += sizeof(WORD);
if (wVersion < BB_ERROR_BLOB_VERSION)
{
//
// Old version
//
INVALID_INPUT_RETURN;
}
//
// skip reserved field
//
pbTemp += sizeof(WORD);
*puiExtendedErrorInfo = *(UNALIGNED UINT32*)pbTemp;
LS_LOG_RESULT(lsReturn);
LS_RETURN(lsReturn);
ErrorReturn:
LS_RETURN(lsReturn);
}