//+--------------------------------------------------------------------------- // // 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 #ifdef OS_WINCE #include #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; iScopeList.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; iScopeList.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); }