public StackPacket DecodeTsFpUpdatePDU(byte[] data)
{
// initialize
int currentIndex = 0;
TS_FP_UPDATE_PDU pdu = new TS_FP_UPDATE_PDU();
// TS_FP_UPDATE_PDU: fpOutputHeader
pdu.fpOutputHeader = ParseByte(data, ref currentIndex);
// Get infomation from fpOutputHeader
nested_TS_FP_UPDATE_PDU_fpOutputHeader_actionCode_Values actionCode;
encryptionFlagsChgd_Values encryptionFlags;
GetFpOutputHeaderInfo(pdu.fpOutputHeader, out actionCode, out encryptionFlags);
// TS_FP_UPDATE_PDU: length1
pdu.length1 = ParseByte(data, ref currentIndex);
// TS_FP_UPDATE_PDU: length2 (optional)
if ((ConstValue.MOST_SIGNIFICANT_BIT_FILTER & pdu.length1) != pdu.length1)
{
// length2 is present (since the most significant bit of length1 is set)
pdu.length2 = ParseByte(data, ref currentIndex);
}
// TS_FP_UPDATE_PDU: fipsInformation
if (EncryptionLevel.ENCRYPTION_LEVEL_FIPS == clientContext.RdpEncryptionLevel)
{
pdu.fipsInformation = ParseTsFpFipsInfo(data, ref currentIndex);
}
// TS_FP_UPDATE_PDU: dataSignature
if (IsFlagExist((byte)encryptionFlags, (byte)encryptionFlagsChgd_Values.FASTPATH_OUTPUT_ENCRYPTED))
{
// pdu were encrypted, data signature exists
pdu.dataSignature = GetBytes(data, ref currentIndex,
ConstValue.TS_FP_UPDATE_PDU_DATA_SIGNATURE_LENGTH);
}
else
{
pdu.dataSignature = null;
}
// Decryption
bool isSalted = IsFlagExist((byte)encryptionFlags,
(byte)encryptionFlagsChgd_Values.FASTPATH_OUTPUT_SECURE_CHECKSUM);
byte[] remainData = GetBytes(data, ref currentIndex, (data.Length - currentIndex));
byte[] decryptedData = DecryptFastPathUpdateData(remainData, pdu.dataSignature, isSalted);
// Decrypted data index
int decryptedDataIndex = 0;
// TS_FP_UPDATE_PDU: fpOutputUpdates
pdu.fpOutputUpdates = ParseTsFpUpdates(decryptedData, ref decryptedDataIndex);
// Check if data length exceeded expectation
VerifyDataLength(decryptedData.Length, decryptedDataIndex, ConstValue.ERROR_MESSAGE_DATA_LENGTH_EXCEEDED);
return pdu;
}