/// <summary> /// Decode Fast-path Update PDU /// </summary> /// <param name="data">data to be parsed</param> /// <returns>decoded Fast-path Update PDU</returns> 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; }
public static TS_FP_UPDATE_PDU CreateFPUpdatePDU(RdpbcgrServerSessionContext context, TS_FP_UPDATE update) { TS_FP_UPDATE_PDU fpOutput = new TS_FP_UPDATE_PDU(context); fpOutput.fpOutputHeader = (byte)(((int)nested_TS_FP_UPDATE_PDU_fpOutputHeader_actionCode_Values.FASTPATH_OUTPUT_ACTION_FASTPATH & 0x03) | ((int)((int)reserved_Values.V1 & 0x0f) << 2)); fpOutput.dataSignature = null; fpOutput.length1 = 0; fpOutput.length2 = 0; fpOutput.fpOutputUpdates = new TS_FP_UPDATE[1]; fpOutput.fpOutputUpdates[0] = update; return fpOutput; }